* got the "cloned accelerant" based DWindowHWInterface to work, though without

using the clipping info from a BDirectWindow... I made it so that the window
  used stays on top always, until I can think of something better. The other
  problem is that you should not move the window, since Painter doesn't update
  it's pointer into the frame buffer.
* Now the test environment is running at pretty much the same speed as it would
  under Haiku, completely by-passing the BeOS app_server. It shows that Painter
  needs to be optimized for writing to graphics memory, and also that we need to
  figure out a way to distribute update sessions more equally. What happens is
  this: The first invalidation of a window triggers an update on the client
  side... the client cannot keep up with drawing, since it is pretty much
  blocked all the time because the desktop thread moves a window and because
  the clipping constantly changes. In the meantime, new update request are
  added to the pending session because the client has still not finished with
  the current session. Only when things settle a bit, the next update session
  can be startet. On the bright side of things, the earlier problems with
  scrolling seem to be fixed for good.
* some documentation updates on Painter


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15478 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-12-10 21:45:41 +00:00
parent 901f399036
commit 62b965a65f
10 changed files with 138 additions and 83 deletions

View File

@ -31,6 +31,7 @@ using std::nothrow;
# include "AccelerantHWInterface.h"
#else
# include "ViewHWInterface.h"
# include "DWindowHWInterface.h"
#endif
@ -144,7 +145,8 @@ ScreenManager::_ScanDrivers()
#if USE_ACCELERANT
interface = new AccelerantHWInterface();
#else
interface = new ViewHWInterface();
interface = new DWindowHWInterface();
// interface = new ViewHWInterface();
#endif
_AddHWInterface(interface);

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <Accelerant.h>
#include <DirectWindow.h>
#include "DWindowBuffer.h"
@ -69,7 +70,6 @@ DWindowBuffer::Height() const
void
DWindowBuffer::SetTo(direct_buffer_info* info)
{
printf("DWindowBuffer::SetTo(%p)\n", info);
fWindowClipping.MakeEmpty();
if (info) {
@ -86,9 +86,8 @@ printf("DWindowBuffer::SetTo(%p)\n", info);
fFormat = info->pixel_format;
fWidth = info->window_bounds.right - info->window_bounds.left + 1;
fHeight = info->window_bounds.bottom - info->window_bounds.top + 1;
printf(" width: %ld, height: %ld\n", fWidth, fHeight);
// offset bits to left top corner of window
fBits += xOffset * 4 + yOffset * fBytesPerRow;
// offset bits to left top corner of window
fBits += xOffset * 4 + yOffset * fBytesPerRow;
} else {
fBits = NULL;
fWidth = 0;
@ -98,3 +97,17 @@ fBits += xOffset * 4 + yOffset * fBytesPerRow;
}
}
// SetTo
void
DWindowBuffer::SetTo(frame_buffer_config* config,
uint32 x, uint32 y,
uint32 width, uint32 height,
color_space format)
{
fBits = (uint8*)config->frame_buffer;
fBytesPerRow = config->bytes_per_row;
fBits += x * 4 + y * fBytesPerRow;
fWidth = width;
fHeight = height;
fFormat = format;
}

View File

@ -4,6 +4,7 @@
#include "RenderingBuffer.h"
struct direct_buffer_info;
struct frame_buffer_config;
class DWindowBuffer : public RenderingBuffer {
public:
@ -20,6 +21,11 @@ class DWindowBuffer : public RenderingBuffer {
void SetTo(direct_buffer_info* info);
void SetTo(frame_buffer_config* config,
uint32 x, uint32 y,
uint32 width, uint32 height,
color_space format);
BRegion& WindowClipping()
{ return fWindowClipping; }
private:

View File

@ -79,8 +79,6 @@ class DView : public BView {
DView(BRect bounds);
virtual ~DView();
// virtual void AttachedToWindow();
// DView
void ForwardMessage(BMessage* message = NULL);
@ -88,19 +86,22 @@ private:
port_id fInputPort;
};
class DWindow : public BDirectWindow {
class DWindow : public BWindow {
public:
DWindow(BRect frame,
DWindowHWInterface* interface,
DWindowBuffer* buffer);
virtual ~DWindow();
// virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
virtual void DirectConnected(direct_buffer_info* info);
// virtual void DirectConnected(direct_buffer_info* info);
private:
DWindowBuffer* fBuffer;
virtual void FrameMoved(BPoint newOffset);
private:
DWindowHWInterface* fHWInterface;
DWindowBuffer* fBuffer;
};
class DirectMessageFilter : public BMessageFilter {
@ -119,6 +120,7 @@ class DirectMessageFilter : public BMessageFilter {
DView::DView(BRect bounds)
: BView(bounds, "graphics card view", B_FOLLOW_ALL, 0)
{
SetViewColor(B_TRANSPARENT_COLOR);
#ifndef INPUTSERVER_TEST_MODE
fInputPort = create_port(200, SERVER_INPUT_PORT);
#else
@ -209,9 +211,10 @@ DirectMessageFilter::Filter(BMessage *message, BHandler **target)
// #pragma mark -
DWindow::DWindow(BRect frame, DWindowBuffer* buffer)
: BDirectWindow(frame, "Haiku App Server", B_TITLED_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
DWindow::DWindow(BRect frame, DWindowHWInterface* interface, DWindowBuffer* buffer)
: BWindow(frame, "Haiku App Server", B_TITLED_WINDOW_LOOK,
B_FLOATING_ALL_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
fHWInterface(interface),
fBuffer(buffer)
{
DView* view = new DView(Bounds());
@ -242,7 +245,7 @@ DWindow::QuitRequested()
// we don't quit on ourself, we let us be Quit()!
return false;
}
/*
// DirectConnected
void
DWindow::DirectConnected(direct_buffer_info* info)
@ -268,6 +271,14 @@ DWindow::DirectConnected(direct_buffer_info* info)
//
// fDesktop->UnlockClipping();
}
*/
// FrameMoved
void
DWindow::FrameMoved(BPoint newOffset)
{
fHWInterface->SetOffset((int32)newOffset.x, (int32)newOffset.y);
}
// #pragma mark -
@ -277,6 +288,9 @@ DWindowHWInterface::DWindowHWInterface()
fFrontBuffer(new DWindowBuffer()),
fWindow(NULL),
fXOffset(50),
fYOffset(50),
fCardFD(-1),
fAccelerantImage(-1),
fAccelerantHook(NULL),
@ -304,8 +318,8 @@ DWindowHWInterface::DWindowHWInterface()
fAccMoveCursor(NULL),
fAccShowCursor(NULL)
{
fDisplayMode.virtual_width = 640;
fDisplayMode.virtual_height = 480;
fDisplayMode.virtual_width = 800;
fDisplayMode.virtual_height = 600;
fDisplayMode.space = B_RGBA32;
memset(&fSyncToken, 0, sizeof(sync_token));
@ -511,6 +525,8 @@ sprintf((char*)cloneInfoData, "graphics/%s", fCardNameInDevFS.String());
unload_add_on(fAccelerantImage);
return B_ERROR;
} else {
_UpdateFrameBufferConfig();
}
return B_OK;
@ -555,10 +571,29 @@ fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT,
return B_OK;
}
// _UpdateFrameBufferConfig
status_t
DWindowHWInterface::_UpdateFrameBufferConfig()
{
frame_buffer_config config;
if (fAccGetFrameBufferConfig(&config) != B_OK) {
STRACE(("unable to get frame buffer config\n"));
return B_ERROR;
}
fFrontBuffer->SetTo(&config, fXOffset, fYOffset,
fDisplayMode.virtual_width,
fDisplayMode.virtual_height,
(color_space)fDisplayMode.space);
return B_OK;
}
// Shutdown
status_t
DWindowHWInterface::Shutdown()
{
printf("DWindowHWInterface::Shutdown()\n");
if (fAccelerantHook) {
uninit_accelerant UninitAccelerant = (uninit_accelerant)fAccelerantHook(B_UNINIT_ACCELERANT, NULL);
if (UninitAccelerant)
@ -633,8 +668,8 @@ DWindowHWInterface::SetMode(const display_mode &mode)
if (ret < B_OK)
return ret;
fWindow = new DWindow(frame.OffsetToCopy(BPoint(50.0, 50.0)), fFrontBuffer);
fWindow = new DWindow(frame.OffsetByCopy(fXOffset, fYOffset), this, fFrontBuffer);
// fire up the window thread but don't show it on screen yet
fWindow->Hide();
@ -646,10 +681,6 @@ DWindowHWInterface::SetMode(const display_mode &mode)
// so that the view does not accidentally draw a freed bitmap
if (ret >= B_OK) {
// clear out buffers, alpha is 255 this way
// TODO: maybe this should handle different color spaces in different ways
// memset(fFrontBuffer->Bits(), 255, fFrontBuffer->BitsLength());
// change the window size and update the bitmap used for drawing
fWindow->ResizeTo(frame.Width(), frame.Height());
}
@ -662,6 +693,9 @@ DWindowHWInterface::SetMode(const display_mode &mode)
} else {
ret = B_ERROR;
}
_UpdateFrameBufferConfig();
return ret;
}
@ -722,8 +756,8 @@ DWindowHWInterface::GetModeList(display_mode **_modes, uint32 *_count)
{1280, 1024}, {1400, 1050}, {1600, 1200}
};
uint32 resolutionCount = sizeof(resolutions) / sizeof(resolutions[0]);
const uint32 colors[] = {B_CMAP8, B_RGB15, B_RGB16, B_RGB32};
uint32 count = resolutionCount * 4;
// const uint32 colors[] = {B_CMAP8, B_RGB15, B_RGB16, B_RGB32};
uint32 count = resolutionCount/* * 4*/;
display_mode *modes = new(nothrow) display_mode[count];
if (modes == NULL)
@ -734,31 +768,29 @@ DWindowHWInterface::GetModeList(display_mode **_modes, uint32 *_count)
int32 index = 0;
for (uint32 i = 0; i < resolutionCount; i++) {
for (uint32 c = 0; c < 4; c++) {
modes[index].virtual_width = resolutions[i].width;
modes[index].virtual_height = resolutions[i].height;
modes[index].space = colors[c];
modes[index].virtual_width = resolutions[i].width;
modes[index].virtual_height = resolutions[i].height;
modes[index].space = B_RGB32;
modes[index].h_display_start = 0;
modes[index].v_display_start = 0;
modes[index].timing.h_display = resolutions[i].width;
modes[index].timing.v_display = resolutions[i].height;
modes[index].timing.h_total = 22000;
modes[index].timing.v_total = 22000;
modes[index].timing.pixel_clock = ((uint32)modes[index].timing.h_total
* modes[index].timing.v_total * 60) / 1000;
modes[index].flags = B_PARALLEL_ACCESS;
modes[index].h_display_start = 0;
modes[index].v_display_start = 0;
modes[index].timing.h_display = resolutions[i].width;
modes[index].timing.v_display = resolutions[i].height;
modes[index].timing.h_total = 22000;
modes[index].timing.v_total = 22000;
modes[index].timing.pixel_clock = ((uint32)modes[index].timing.h_total
* modes[index].timing.v_total * 60) / 1000;
modes[index].flags = B_PARALLEL_ACCESS;
index++;
}
index++;
}
#else
// support only a single mode, useful
// for testing a specific mode
display_mode *modes = new(nothrow) display_mode[1];
modes[0].virtual_width = 640;
modes[0].virtual_height = 480;
modes[0].space = B_CMAP8;
modes[0].virtual_width = 800;
modes[0].virtual_height = 600;
modes[0].space = B_BRGB32;
*_modes = modes;
*_count = 1;
@ -860,11 +892,11 @@ DWindowHWInterface::CopyRegion(const clipping_rect* sortedRectList,
// convert the rects
blit_params* params = new blit_params[count];
for (uint32 i = 0; i < count; i++) {
params[i].src_left = (uint16)sortedRectList[i].left;
params[i].src_top = (uint16)sortedRectList[i].top;
params[i].src_left = (uint16)sortedRectList[i].left + fXOffset;
params[i].src_top = (uint16)sortedRectList[i].top + fYOffset;
params[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
params[i].dest_left = (uint16)sortedRectList[i].left + xOffset + fXOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset + fYOffset;
// NOTE: width and height are expressed as distance, not pixel count!
params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
@ -958,7 +990,7 @@ DWindowHWInterface::FrontBuffer() const
RenderingBuffer*
DWindowHWInterface::BackBuffer() const
{
return NULL;
return fFrontBuffer;
}
// IsDoubleBuffered
@ -975,6 +1007,23 @@ DWindowHWInterface::Invalidate(const BRect& frame)
return HWInterface::Invalidate(frame);
}
// SetOffset
void
DWindowHWInterface::SetOffset(int32 left, int32 top)
{
if (!WriteLock())
return;
fXOffset = left;
fYOffset = top;
_UpdateFrameBufferConfig();
// TODO: someone would have to call DrawingEngine::Update() now!
WriteUnlock();
}
// _RegionToRectParams
void
DWindowHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
@ -986,10 +1035,10 @@ DWindowHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
for (uint32 i = 0; i < *count; i++) {
clipping_rect r = region->RectAtInt(i);
(*params)[i].left = (uint16)r.left;
(*params)[i].top = (uint16)r.top;
(*params)[i].right = (uint16)r.right;
(*params)[i].bottom = (uint16)r.bottom;
(*params)[i].left = (uint16)(r.left + fXOffset);
(*params)[i].top = (uint16)(r.top + fYOffset);
(*params)[i].right = (uint16)(r.right + fXOffset);
(*params)[i].bottom = (uint16)(r.bottom + fYOffset);
}
}

View File

@ -69,17 +69,23 @@ class DWindowHWInterface : public HWInterface {
virtual status_t Invalidate(const BRect& frame);
// DWindowHWInterface
void SetOffset(int32 left, int32 top);
private:
DWindowBuffer* fFrontBuffer;
DWindow* fWindow;
display_mode fDisplayMode;
int32 fXOffset;
int32 fYOffset;
// accelerant stuff
int _OpenGraphicsDevice(int deviceNumber);
status_t _OpenAccelerant(int device);
status_t _SetupDefaultHooks();
status_t _UpdateFrameBufferConfig();
void _RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
@ -115,6 +121,8 @@ class DWindowHWInterface : public HWInterface {
move_cursor fAccMoveCursor;
show_cursor fAccShowCursor;
frame_buffer_config fFrameBufferConfig;
BString fCardNameInDevFS;
};

View File

@ -589,7 +589,7 @@ printf("nothing to copy\n");
break;
}
default:
fprintf(stderr, "ViewHWInterface::CopyBackToFront() - unsupported front buffer format!\n");
fprintf(stderr, "HWInterface::CopyBackToFront() - unsupported front buffer format!\n");
break;
}
}

View File

@ -6,10 +6,6 @@ Painter is a class implementing the BView drawing functions with the Anti-Grain
Status:
1) Most of the drawing modes are unimplemented.
I want to work out the effects of the drawing_mode together with the source_alpha and alpha_func. Currently, Painter supports B_OP_COPY, B_OP_OVER and B_OP_INVERT with patterns. It is kind of ignorant towards the orginal app_servers treatment of alpha in the high and low color. I think it acts for the most part as if the BView was SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE), especially for drawing bitmaps, which will of course be fixed, but should be no obstacle in integrating Painter right now.
2) Only 32 bit frame buffers are support yet.
Most of the work in supporting other color spaces is only in the drawing_mode classes. It makes no sense to start work on these before I have even nailed the details once on the 32 bit case.
@ -20,11 +16,7 @@ There is some work involved when trying to make this fast. The conversion should
4) Most of the BView behaviour for DrawString() is missing.
Putting the current pen at the position of the virtual next char is now handled, but I have to figure out the escapment_delta stuff.
5) Font handling is somewhat weird.
There is a FontManager class that is supposed to be an interface between font family/style names and font files on disk loadable by Freetype. There is a TextRenderer interface class and AGGTextRenderer implementation that can be used to get the job done, but this is of course very open for discussion. I didn't really look at what was already available in the Haiku repository, but just took from WonderBrush what I already had. The biggest problem when testing Painter on R5 is the sometimes slightly different naming of font families in Freetype and R5. Sometimes, FontManager is not able to match up the correct file for the given family and style. For the "default" "Swiss911 BT", it works. If the be_plain_font can not be "loaded" by FontManager, it might look like font rendering is not working at all, you might have to tweak this, or maybe hardcode a font that works. Of course, on a "true Haiku system", once such a thing exists, this problem will be non-existent. Fonts will just be named as Freetype suggests, and everything will match up fine.
Putting the current pen at the position of the virtual next char is now handled, but I have to figure out the escapment_delta stuff. Glyph spacing modes need to be supported.
6) The framework is still developing.
@ -32,6 +24,4 @@ I'm still working on many ends of Painter and I might refactor things. The basic
7) Article
I have written a Newsletter article, that explains the concepts of AGG, how Painter is therefor designed and how it can be improved with the knowledge of AGG inner workings. I don't know when this article will appear, but email me if you're interested in the current version.
I have written a Newsletter article, that explains the concepts of AGG, how Painter is therefor designed and how it can be improved with the knowledge of AGG inner workings.

View File

@ -2,32 +2,18 @@ Test:
* "composite" alpha blending modes
* BShape conversion and rendering
* Bezier curve rendering
* other color spaces (currently uses BBitmap::ImportBits(),
which is only available on Haiku)
Implement:
* "escapment_delta" text rendering
* font shearing
(* handling of other BBitmap colorspaces)
Improve:
* make special case versions of some functions:
- horizontal/vertical lines
- horizonzal text rendering, using scanline cache
* make special verions of DrawingModes for B_SOLID_* patterns
* get rid of virtual function use in DrawingMode framework

View File

@ -565,6 +565,7 @@ namespace agg
}
update_transform();
// update_char_size();
}
return ret;
}

View File

@ -46,7 +46,7 @@ SharedLibrary libhwinterfaceimpl.so :
ViewHWInterface.cpp
DWindowHWInterface.cpp
: be game libhwinterface.so
: be libhwinterface.so
;
SharedLibrary libhaikuappserver.so :
@ -71,7 +71,7 @@ SharedLibrary libhaikuappserver.so :
# libraries
:
be game libtextencoding.so libfreetype.so
be libtextencoding.so libfreetype.so
;
AddResources haiku_app_server : app_server.rdef ;
@ -123,7 +123,7 @@ Server haiku_app_server :
# libraries
:
z libpng.so libhaikuappserver.so
libpainter.a be game
libpainter.a be
libhwinterface.so libhwinterfaceimpl.so
libagg.a libfreetype.so libtextencoding.so
;