Enabled HW acceleration for CopyRegion(). Tested on Haiku and it works. I also implemented FillRegion and InvertRegion. But using different acceleration hooks after one another freezes Haiku, app_server, the accelerant or whatever. I have no clue about accelerants, so if a knowledgable someone would have a look at AccelerantHWInterface.cpp, that'd be great. The software cursor stuff has a cosmetical bug with regards to CopyRegion() too, I don't understand it yet. I also tried to improve StringWidth() and DrawString() preformance. I confirmed that the glyph cache is actually used, but AGGTextRenderer::RenderString() is a dog.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12573 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-05-04 23:48:19 +00:00
parent da95c7c14b
commit fbf48e6437
14 changed files with 373 additions and 77 deletions
+3
View File
@@ -52,6 +52,9 @@ class Painter {
void DetachFromBuffer(); void DetachFromBuffer();
void ConstrainClipping(const BRegion& region); void ConstrainClipping(const BRegion& region);
const BRegion* ClippingRegion() const
{ return fClippingRegion; }
void SetDrawData(const DrawData* data); void SetDrawData(const DrawData* data);
// object settings // object settings
+14 -10
View File
@@ -47,14 +47,14 @@ public:
RGBColor(uint16 col); RGBColor(uint16 col);
RGBColor(uint8 col); RGBColor(uint8 col);
RGBColor(const RGBColor &col); RGBColor(const RGBColor &col);
RGBColor(void); RGBColor();
void PrintToStream(void) const; void PrintToStream() const;
uint8 GetColor8(void); uint8 GetColor8() const;
uint16 GetColor15(void); uint16 GetColor15() const;
uint16 GetColor16(void); uint16 GetColor16() const;
rgb_color GetColor32(void) const; rgb_color GetColor32() const;
void SetColor(uint8 r, uint8 g, uint8 b, uint8 a=255); void SetColor(uint8 r, uint8 g, uint8 b, uint8 a=255);
void SetColor(int r, int g, int b, int a=255); void SetColor(int r, int g, int b, int a=255);
@@ -71,10 +71,14 @@ public:
bool operator==(const RGBColor &col); bool operator==(const RGBColor &col);
protected: protected:
rgb_color color32; rgb_color color32;
uint16 color16;
uint16 color15; // caching
uint8 color8; mutable uint16 color16;
bool update8,update15,update16; mutable uint16 color15;
mutable uint8 color8;
mutable bool update8;
mutable bool update15;
mutable bool update16;
}; };
#endif #endif
+1 -1
View File
@@ -64,7 +64,7 @@
# define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans" # define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans"
# define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT" # define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT"
# define DEFAULT_BOLD_FONT_STYLE "Bold" # define DEFAULT_BOLD_FONT_STYLE "Bold"
# define DEFAULT_BOLD_FONT_SIZE 12 # define DEFAULT_BOLD_FONT_SIZE 11
# define DEFAULT_FIXED_FONT_FAMILY "Bitstream Vera Sans Mono" # define DEFAULT_FIXED_FONT_FAMILY "Bitstream Vera Sans Mono"
# define FALLBACK_FIXED_FONT_FAMILY "Courier10 BT" # define FALLBACK_FIXED_FONT_FAMILY "Courier10 BT"
# define DEFAULT_FIXED_FONT_STYLE "Roman" # define DEFAULT_FIXED_FONT_STYLE "Roman"
+12
View File
@@ -1280,6 +1280,12 @@ Layer::move_layer(float x, float y)
BPoint pt(x, y); BPoint pt(x, y);
BRect rect(fFull.Frame().OffsetByCopy(pt)); BRect rect(fFull.Frame().OffsetByCopy(pt));
if (!fParent) {
printf("no parent in Layer::move_layer() (%s)\n", GetName());
fFrameAction = B_LAYER_ACTION_NONE;
return;
}
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt); fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
@@ -1305,6 +1311,12 @@ Layer::resize_layer(float x, float y)
rect.right += x; rect.right += x;
rect.bottom += y; rect.bottom += y;
if (!fParent) {
printf("no parent in Layer::resize_layer() (%s)\n", GetName());
fFrameAction = B_LAYER_ACTION_NONE;
return;
}
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt); fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible); fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
+5 -5
View File
@@ -100,7 +100,7 @@ RGBColor::RGBColor(const RGBColor &col)
/*! /*!
\brief Create an RGBColor with the values(0,0,0,0) \brief Create an RGBColor with the values(0,0,0,0)
*/ */
RGBColor::RGBColor(void) RGBColor::RGBColor()
{ {
SetColor(0,0,0,0); SetColor(0,0,0,0);
update8=update16=false; update8=update16=false;
@@ -110,7 +110,7 @@ RGBColor::RGBColor(void)
\brief Returns the color as the closest 8-bit color in the palette \brief Returns the color as the closest 8-bit color in the palette
\return The palette index for the current color \return The palette index for the current color
*/ */
uint8 RGBColor::GetColor8(void) uint8 RGBColor::GetColor8() const
{ {
if(update8) if(update8)
{ {
@@ -125,7 +125,7 @@ uint8 RGBColor::GetColor8(void)
\brief Returns the color as the closest 15-bit color \brief Returns the color as the closest 15-bit color
\return 15-bit value of the current color plus 1-bit alpha \return 15-bit value of the current color plus 1-bit alpha
*/ */
uint16 RGBColor::GetColor15(void) uint16 RGBColor::GetColor15() const
{ {
if(update15) if(update15)
{ {
@@ -140,7 +140,7 @@ uint16 RGBColor::GetColor15(void)
\brief Returns the color as the closest 16-bit color \brief Returns the color as the closest 16-bit color
\return 16-bit value of the current color \return 16-bit value of the current color
*/ */
uint16 RGBColor::GetColor16(void) uint16 RGBColor::GetColor16() const
{ {
if(update16) if(update16)
{ {
@@ -155,7 +155,7 @@ uint16 RGBColor::GetColor16(void)
\brief Returns the color as a 32-bit color \brief Returns the color as a 32-bit color
\return current color, including alpha \return current color, including alpha
*/ */
rgb_color RGBColor::GetColor32(void) const rgb_color RGBColor::GetColor32() const
{ {
return color32; return color32;
} }
@@ -14,13 +14,7 @@
#include <stdio.h> #include <stdio.h>
#include <Bitmap.h>
#include <Cursor.h> #include <Cursor.h>
#include <Locker.h>
#include <Message.h>
#include <MessageRunner.h>
#include <Region.h>
#include <Screen.h>
#include <Accelerant.h> #include <Accelerant.h>
#include <graphic_driver.h> #include <graphic_driver.h>
@@ -30,11 +24,11 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "PortLink.h" //#include "PortLink.h"
#include "RGBColor.h"
#include "ServerConfig.h" #include "ServerConfig.h"
#include "ServerCursor.h" #include "ServerCursor.h"
#include "ServerProtocol.h" #include "ServerProtocol.h"
#include "UpdateQueue.h"
#include "AccelerantHWInterface.h" #include "AccelerantHWInterface.h"
#include "AccelerantBuffer.h" #include "AccelerantBuffer.h"
@@ -55,6 +49,7 @@ AccelerantHWInterface::AccelerantHWInterface()
fAccelerantImage(-1), fAccelerantImage(-1),
fAccelerantHook(NULL), fAccelerantHook(NULL),
fEngineToken(NULL), fEngineToken(NULL),
fSyncToken(),
// required hooks // required hooks
fAccAcquireEngine(NULL), fAccAcquireEngine(NULL),
@@ -89,6 +84,11 @@ AccelerantHWInterface::AccelerantHWInterface()
fDisplayMode.virtual_width = 640; fDisplayMode.virtual_width = 640;
fDisplayMode.virtual_height = 480; fDisplayMode.virtual_height = 480;
fDisplayMode.space = B_RGB32; fDisplayMode.space = B_RGB32;
// NOTE: I have no clue what I'm doing here.
// fSyncToken.counter = 0;
// fSyncToken.engine_id = 0;
memset(&fSyncToken, 0, sizeof(sync_token));
} }
// destructor // destructor
@@ -507,6 +507,104 @@ AccelerantHWInterface::DPMSCapabilities() const
return fAccDPMSCapabilities(); return fAccDPMSCapabilities();
} }
// AvailableHardwareAcceleration
uint32
AccelerantHWInterface::AvailableHWAcceleration() const
{
uint32 flags = 0;
if (fAccScreenBlit)
flags |= HW_ACC_COPY_REGION;
// if (fAccFillRect)
// flags |= HW_ACC_FILL_REGION;
// if (fAccInvertRect)
// flags |= HW_ACC_INVERT_REGION;
return flags;
}
// CopyRegion
void
AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
uint32 count, int32 xOffset, int32 yOffset)
{
if (fAccScreenBlit && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0, &fSyncToken, &fEngineToken) >= B_OK) {
// 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].dest_left = (uint16)sortedRectList[i].left + xOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
// NOTE: width and height are expressed as distance, not pixel count!
params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
}
// go
fAccScreenBlit(fEngineToken, params, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
delete[] params;
}
}
}
// FillRegion
void
AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const RGBColor& color)
{
if (fAccFillRect && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0, &fSyncToken, &fEngineToken) >= B_OK) {
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
// go
fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
delete[] fillParams;
}
}
}
// InvertRegion
void
AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
{
if (fAccInvertRect && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0, &fSyncToken, &fEngineToken) >= B_OK) {
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
// go
fAccInvertRect(fEngineToken, fillParams, count);
// done
if (fAccReleaseEngine)
fAccReleaseEngine(fEngineToken, &fSyncToken);
delete[] fillParams;
}
}
}
// SetCursor // SetCursor
void void
AccelerantHWInterface::SetCursor(ServerCursor* cursor) AccelerantHWInterface::SetCursor(ServerCursor* cursor)
@@ -575,3 +673,56 @@ AccelerantHWInterface::_DrawCursor(BRect area) const
// a hardware cursor for some reason // a hardware cursor for some reason
} }
// _RegionToRectParams
void
AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const
{
*count = region->CountRects();
*params = new fill_rect_params[*count];
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;
}
}
// _NativeColor
uint32
AccelerantHWInterface::_NativeColor(const RGBColor& color) const
{
// NOTE: This functions looks somehow suspicios to me.
// It assumes that all graphics cards have the same native endianess, no?
switch (fDisplayMode.space) {
case B_CMAP8:
case B_GRAY8:
return color.GetColor8();
case B_RGB15_BIG:
case B_RGBA15_BIG:
case B_RGB15_LITTLE:
case B_RGBA15_LITTLE:
return color.GetColor15();
case B_RGB16_BIG:
case B_RGB16_LITTLE:
return color.GetColor16();
case B_RGB32_BIG:
case B_RGBA32_BIG:
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE: {
rgb_color c = color.GetColor32();
uint32 native = (c.alpha << 24) |
(c.red << 16) |
(c.green << 8) |
(c.blue);
return native;
}
}
return 0;
}
@@ -19,7 +19,6 @@
class MallocBuffer; class MallocBuffer;
class AccelerantBuffer; class AccelerantBuffer;
class UpdateQueue;
class AccelerantHWInterface : public HWInterface { class AccelerantHWInterface : public HWInterface {
public: public:
@@ -49,6 +48,16 @@ virtual status_t SetDPMSMode(const uint32 &state);
virtual uint32 DPMSMode() const; virtual uint32 DPMSMode() const;
virtual uint32 DPMSCapabilities() const; virtual uint32 DPMSCapabilities() const;
// query for available hardware accleration and perform it
virtual uint32 AvailableHWAcceleration() const;
virtual void CopyRegion(const clipping_rect* sortedRectList,
uint32 count,
int32 xOffset, int32 yOffset);
virtual void FillRegion(/*const*/ BRegion& region,
const RGBColor& color);
virtual void InvertRegion(/*const*/ BRegion& region);
// cursor handling // cursor handling
virtual void SetCursor(ServerCursor* cursor); virtual void SetCursor(ServerCursor* cursor);
virtual void SetCursorVisible(bool visible); virtual void SetCursorVisible(bool visible);
@@ -67,11 +76,16 @@ private:
status_t SetupDefaultHooks(); status_t SetupDefaultHooks();
status_t UpdateModeList(); status_t UpdateModeList();
status_t UpdateFrameBufferConfig(); status_t UpdateFrameBufferConfig();
void _RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const;
uint32 _NativeColor(const RGBColor& color) const;
int fCardFD; int fCardFD;
image_id fAccelerantImage; image_id fAccelerantImage;
GetAccelerantHook fAccelerantHook; GetAccelerantHook fAccelerantHook;
engine_token *fEngineToken; engine_token *fEngineToken;
sync_token fSyncToken;
// required hooks - guaranteed to be valid // required hooks - guaranteed to be valid
acquire_engine fAccAcquireEngine; acquire_engine fAccAcquireEngine;
@@ -107,8 +121,6 @@ private:
display_mode fDisplayMode; display_mode fDisplayMode;
UpdateQueue *fUpdateExecutor;
}; };
#endif // ACCELERANT_HW_INTERFACE_H #endif // ACCELERANT_HW_INTERFACE_H
+111 -32
View File
@@ -52,10 +52,11 @@ DisplayDriverPainter::DisplayDriverPainter()
: DisplayDriver(), : DisplayDriver(),
fPainter(new Painter()), fPainter(new Painter()),
#if USE_ACCELERANT #if USE_ACCELERANT
fGraphicsCard(new AccelerantHWInterface()) fGraphicsCard(new AccelerantHWInterface()),
#else #else
fGraphicsCard(new ViewHWInterface()) fGraphicsCard(new ViewHWInterface()),
#endif #endif
fAvailableHWAccleration(0)
{ {
} }
@@ -72,8 +73,10 @@ DisplayDriverPainter::Initialize()
status_t err = fGraphicsCard->Initialize(); status_t err = fGraphicsCard->Initialize();
if (err < B_OK) if (err < B_OK)
fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err)); fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err));
if (err >= B_OK) if (err >= B_OK) {
fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration();
return DisplayDriver::Initialize(); return DisplayDriver::Initialize();
}
return false; return false;
} }
@@ -218,7 +221,7 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
int32 xOffset, int32 yOffset) int32 xOffset, int32 yOffset)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(region->Frame())); fGraphicsCard->HideSoftwareCursor(region->Frame());
int32 count = region->CountRects(); int32 count = region->CountRects();
@@ -284,12 +287,30 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
// currently on the stack and to which the current rect pointed // currently on the stack and to which the current rect pointed
// to. If their "indegree" count reaches zero, put them onto the // to. If their "indegree" count reaches zero, put them onto the
// stack as well. // stack as well.
clipping_rect* sortedRectList = NULL;
int32 nextSortedIndex = 0;
if (fAvailableHWAccleration & HW_ACC_COPY_REGION)
sortedRectList = new clipping_rect[count];
while (!inDegreeZeroNodes.empty()) { while (!inDegreeZeroNodes.empty()) {
node* n = inDegreeZeroNodes.top(); node* n = inDegreeZeroNodes.top();
inDegreeZeroNodes.pop(); inDegreeZeroNodes.pop();
BRect touched = _CopyRect(n->rect, xOffset, yOffset); // do the software implementation or add to sorted
fGraphicsCard->Invalidate(touched); // rect list for using the HW accelerated version
// later
if (sortedRectList) {
sortedRectList[nextSortedIndex].left = (int32)n->rect.left;
sortedRectList[nextSortedIndex].top = (int32)n->rect.top;
sortedRectList[nextSortedIndex].right = (int32)n->rect.right;
sortedRectList[nextSortedIndex].bottom = (int32)n->rect.bottom;
nextSortedIndex++;
} else {
BRect touched = _CopyRect(n->rect, xOffset, yOffset);
fGraphicsCard->Invalidate(touched);
}
for (int32 k = 0; k < n->next_pointer; k++) { for (int32 k = 0; k < n->next_pointer; k++) {
n->pointers[k]->in_degree--; n->pointers[k]->in_degree--;
@@ -297,6 +318,13 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
inDegreeZeroNodes.push(n->pointers[k]); inDegreeZeroNodes.push(n->pointers[k]);
} }
} }
// trigger the HW accelerated version if is was available
if (sortedRectList)
fGraphicsCard->CopyRegion(sortedRectList, count, xOffset, yOffset);
delete[] sortedRectList;
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
@@ -456,7 +484,7 @@ DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
// FillRect // FillRect
void void
DisplayDriverPainter::FillRect(const BRect &r, const RGBColor &color) DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color)
{ {
if (Lock()) { if (Lock()) {
BRect vr(min_c(r.left, r.right), BRect vr(min_c(r.left, r.right),
@@ -467,9 +495,17 @@ DisplayDriverPainter::FillRect(const BRect &r, const RGBColor &color)
fGraphicsCard->HideSoftwareCursor(vr); fGraphicsCard->HideSoftwareCursor(vr);
fPainter->FillRect(vr, color.GetColor32()); // try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_FILL_REGION) {
BRegion region(vr);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, color);
} else {
fPainter->FillRect(vr, color.GetColor32());
fGraphicsCard->Invalidate(vr);
}
fGraphicsCard->Invalidate(vr);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
@@ -489,10 +525,32 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
fGraphicsCard->HideSoftwareCursor(vr); fGraphicsCard->HideSoftwareCursor(vr);
fPainter->SetDrawData(d); bool doInSoftware = true;
BRect touched = fPainter->FillRect(vr); // try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) &&
(d->GetDrawingMode() == B_OP_COPY ||
d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) {
BRegion region(vr);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->HighColor());
doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW) {
BRegion region(vr);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->LowColor());
doInSoftware = false;
}
}
if (doInSoftware) {
fPainter->SetDrawData(d);
BRect touched = fPainter->FillRect(vr);
fGraphicsCard->Invalidate(touched);
}
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
@@ -507,16 +565,34 @@ DisplayDriverPainter::FillRegion(BRegion& r, const DrawData *d)
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r.Frame())); fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r.Frame()));
fPainter->SetDrawData(d); bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) &&
(d->GetDrawingMode() == B_OP_COPY ||
d->GetDrawingMode() == B_OP_OVER)) {
BRect touched = fPainter->FillRect(r.RectAt(0)); if (d->GetPattern() == B_SOLID_HIGH) {
fGraphicsCard->FillRegion(r, d->HighColor());
doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW) {
fGraphicsCard->FillRegion(r, d->LowColor());
doInSoftware = false;
}
}
if (doInSoftware) {
int32 count = r.CountRects(); fPainter->SetDrawData(d);
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->FillRect(r.RectAt(i)); BRect touched = fPainter->FillRect(r.RectAt(0));
int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->FillRect(r.RectAt(i));
}
fGraphicsCard->Invalidate(touched);
} }
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
@@ -899,11 +975,21 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
const BPoint &pt, DrawData *d) const BPoint &pt, DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); //bigtime_t now = system_time();
// TODO: BoundingBox is quite slow!! Optimizing it will be beneficial.
// Cursiously, the actual DrawString after it is actually faster!?!
// TODO: make the availability of the hardware cursor part of the
// HW acceleration flags and skip all calculations for HideSoftwareCursor
// in case we don't need one.
BRect b = fPainter->BoundingBox(string, length, pt);
//printf("bounding box '%s': %lld µs\n", string, system_time() - now);
fGraphicsCard->HideSoftwareCursor(b);
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
//now = system_time();
BRect touched = fPainter->DrawString(string, length, pt); BRect touched = fPainter->DrawString(string, length, pt);
//printf("drawing string: %lld µs\n", system_time() - now);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
@@ -920,7 +1006,7 @@ DisplayDriverPainter::StringWidth(const char *string, int32 length,
float width = 0.0; float width = 0.0;
if (Lock()) { if (Lock()) {
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
BPoint dummy(0.0, 0.0); static BPoint dummy(0.0, 0.0);
width = fPainter->BoundingBox(string, length, dummy).Width(); width = fPainter->BoundingBox(string, length, dummy).Width();
Unlock(); Unlock();
} }
@@ -932,16 +1018,9 @@ float
DisplayDriverPainter::StringWidth(const char *string, int32 length, DisplayDriverPainter::StringWidth(const char *string, int32 length,
const ServerFont &font) const ServerFont &font)
{ {
float width = 0.0; static DrawData d;
if (Lock()) { d.SetFont(font);
DrawData d; return StringWidth(string, length, &d);
d.SetFont(font);
fPainter->SetDrawData(&d);
BPoint dummy(0.0, 0.0);
width = fPainter->BoundingBox(string, length, dummy).Width();
Unlock();
}
return width;
} }
// StringHeight // StringHeight
@@ -952,7 +1031,7 @@ DisplayDriverPainter::StringHeight(const char *string, int32 length,
float height = 0.0; float height = 0.0;
if (Lock()) { if (Lock()) {
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
BPoint dummy(0.0, 0.0); static BPoint dummy(0.0, 0.0);
height = fPainter->BoundingBox(string, length, dummy).Height(); height = fPainter->BoundingBox(string, length, dummy).Height();
Unlock(); Unlock();
} }
@@ -275,6 +275,7 @@ class DisplayDriverPainter : public DisplayDriver {
Painter* fPainter; Painter* fPainter;
HWInterface* fGraphicsCard; HWInterface* fGraphicsCard;
uint32 fAvailableHWAccleration;
}; };
#endif // _DISPLAY_DRIVER_PAINTER_H_ #endif // _DISPLAY_DRIVER_PAINTER_H_
+1 -1
View File
@@ -625,7 +625,7 @@ HWInterface::_RestoreCursorArea(const BRect& area) const
uint8* src = fCursorAreaBackup->buffer; uint8* src = fCursorAreaBackup->buffer;
if (fCursorAreaBackup->left < left) if (fCursorAreaBackup->left < left)
src += left - fCursorAreaBackup->left; src += (left - fCursorAreaBackup->left) * 4;
if (fCursorAreaBackup->top < top) if (fCursorAreaBackup->top < top)
src += (top - fCursorAreaBackup->top) * fCursorAreaBackup->bpr; src += (top - fCursorAreaBackup->top) * fCursorAreaBackup->bpr;
+25 -5
View File
@@ -13,12 +13,19 @@
#include <GraphicsCard.h> #include <GraphicsCard.h>
#include <Locker.h> #include <Locker.h>
#include <OS.h> #include <OS.h>
#include <Rect.h> #include <Region.h>
class RenderingBuffer; class RenderingBuffer;
class RGBColor;
class ServerCursor; class ServerCursor;
class UpdateQueue; class UpdateQueue;
enum {
HW_ACC_COPY_REGION = 0x00000001,
HW_ACC_FILL_REGION = 0x00000002,
HW_ACC_INVERT_REGION = 0x00000004,
};
class HWInterface : public BLocker { class HWInterface : public BLocker {
public: public:
HWInterface(bool doubleBuffered = false); HWInterface(bool doubleBuffered = false);
@@ -48,6 +55,18 @@ class HWInterface : public BLocker {
virtual uint32 DPMSMode() const = 0; virtual uint32 DPMSMode() const = 0;
virtual uint32 DPMSCapabilities() const = 0; virtual uint32 DPMSCapabilities() const = 0;
// query for available hardware accleration and perform it
// (Initialize() must have been called already)
virtual uint32 AvailableHWAcceleration() const
{ return 0; }
virtual void CopyRegion(const clipping_rect* sortedRectList,
uint32 count,
int32 xOffset, int32 yOffset) {}
virtual void FillRegion(/*const*/ BRegion& region,
const RGBColor& color) {}
virtual void InvertRegion(/*const*/ BRegion& region) {}
// cursor handling // cursor handling
virtual void SetCursor(ServerCursor* cursor); virtual void SetCursor(ServerCursor* cursor);
virtual void SetCursorVisible(bool visible); virtual void SetCursorVisible(bool visible);
@@ -70,10 +89,11 @@ class HWInterface : public BLocker {
// TODO: Just a quick and primitive way to get single buffered mode working. // TODO: Just a quick and primitive way to get single buffered mode working.
// Later, the implementation should be smarter, right now, it will // Later, the implementation should be smarter, right now, it will
// draw the cursor for almost every drawing operation. // draw the cursor for almost every drawing operation.
// It seems to me, BeOS hides the cursor (in laymans words) before // It seems to me BeOS hides the cursor (in laymans words) before
// BView::Draw() is called, then, after all drawing commands that triggered // BView::Draw() is called (if the cursor is within that views clipping region),
// have been caried out, it shows the cursor again. This approach would // then, after all drawing commands that triggered have been caried out,
// have the adventage of the code not cluttering/slowing down DisplayDriverPainter. // it shows the cursor again. This approach would have the adventage of
// the code not cluttering/slowing down DisplayDriverPainter.
void HideSoftwareCursor(const BRect& area); void HideSoftwareCursor(const BRect& area);
void HideSoftwareCursor(); void HideSoftwareCursor();
void ShowSoftwareCursor(); void ShowSoftwareCursor();
+1 -1
View File
@@ -946,7 +946,7 @@ Painter::BoundingBox(const char* utf8String, uint32 length,
Transformable transform; Transformable transform;
transform.TranslateBy(baseLine); transform.TranslateBy(baseLine);
BRect dummy; static BRect dummy;
return fTextRenderer->RenderString(utf8String, return fTextRenderer->RenderString(utf8String,
length, length,
fFontRendererSolid, fFontRendererSolid,
@@ -1,6 +1,7 @@
// AGGTextRenderer.cpp // AGGTextRenderer.cpp
#include <math.h> #include <math.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -44,6 +45,7 @@ rect_to_int(BRect r,
bottom = (int32)ceilf(r.bottom); bottom = (int32)ceilf(r.bottom);
} }
#define DEFAULT_UNI_CODE_BUFFER_SIZE 2048
// constructor // constructor
AGGTextRenderer::AGGTextRenderer() AGGTextRenderer::AGGTextRenderer()
@@ -51,7 +53,9 @@ AGGTextRenderer::AGGTextRenderer()
fFontEngine(ftlib), fFontEngine(ftlib),
fFontManager(fFontEngine), fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()), fCurves(fFontManager.path_adaptor()),
fContour(fCurves) fContour(fCurves),
fUnicodeBuffer((char*)malloc(DEFAULT_UNI_CODE_BUFFER_SIZE)),
fUnicodeBufferSize(DEFAULT_UNI_CODE_BUFFER_SIZE)
{ {
fCurves.approximation_scale(2.0); fCurves.approximation_scale(2.0);
fContour.auto_detect_orientation(false); fContour.auto_detect_orientation(false);
@@ -63,7 +67,9 @@ AGGTextRenderer::AGGTextRenderer(BMessage* archive)
fFontEngine(ftlib), fFontEngine(ftlib),
fFontManager(fFontEngine), fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()), fCurves(fFontManager.path_adaptor()),
fContour(fCurves) fContour(fCurves),
fUnicodeBuffer((char*)malloc(DEFAULT_UNI_CODE_BUFFER_SIZE)),
fUnicodeBufferSize(DEFAULT_UNI_CODE_BUFFER_SIZE)
{ {
//printf("AGGTextRenderer::AGGTextRenderer(BMessage*)\n"); //printf("AGGTextRenderer::AGGTextRenderer(BMessage*)\n");
fCurves.approximation_scale(2.0); fCurves.approximation_scale(2.0);
@@ -77,7 +83,9 @@ AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
fFontEngine(ftlib), fFontEngine(ftlib),
fFontManager(fFontEngine), fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()), fCurves(fFontManager.path_adaptor()),
fContour(fCurves) fContour(fCurves),
fUnicodeBuffer((char*)malloc(DEFAULT_UNI_CODE_BUFFER_SIZE)),
fUnicodeBufferSize(DEFAULT_UNI_CODE_BUFFER_SIZE)
{ {
fCurves.approximation_scale(2.0); fCurves.approximation_scale(2.0);
fContour.auto_detect_orientation(false); fContour.auto_detect_orientation(false);
@@ -88,6 +96,7 @@ AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
AGGTextRenderer::~AGGTextRenderer() AGGTextRenderer::~AGGTextRenderer()
{ {
Unset(); Unset();
free(fUnicodeBuffer);
} }
// SetTo // SetTo
@@ -215,18 +224,21 @@ AGGTextRenderer::RenderString(const char* string,
int32 srcLength = min_c(length, strlen(string)); int32 srcLength = min_c(length, strlen(string));
int32 dstLength = srcLength * 4; int32 dstLength = srcLength * 4;
char* buffer = new char[dstLength]; if (dstLength > fUnicodeBufferSize) {
fUnicodeBufferSize = dstLength;
fUnicodeBuffer = (char*)realloc((void*)fUnicodeBuffer, fUnicodeBufferSize);
}
int32 state = 0; int32 state = 0;
status_t ret; status_t ret;
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION, if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
string, &srcLength, string, &srcLength,
buffer, &dstLength, fUnicodeBuffer, &dstLength,
&state, B_SUBSTITUTE)) >= B_OK &state, B_SUBSTITUTE)) >= B_OK
&& (ret = swap_data(B_INT16_TYPE, buffer, dstLength, && (ret = swap_data(B_INT16_TYPE, fUnicodeBuffer, dstLength,
B_SWAP_BENDIAN_TO_HOST)) >= B_OK) { B_SWAP_BENDIAN_TO_HOST)) >= B_OK) {
uint16* p = (uint16*)buffer; uint16* p = (uint16*)fUnicodeBuffer;
double x = 0.0; double x = 0.0;
double y0 = 0.0; double y0 = 0.0;
@@ -299,7 +311,7 @@ AGGTextRenderer::RenderString(const char* string,
case agg::glyph_data_outline: case agg::glyph_data_outline:
fRasterizer.reset(); fRasterizer.reset();
// NOTE: this function can be easily extended to handle // NOTE: this function can be easily extended to handle
// conversion to contours, to that's why there is a lot of // conversion to contours, so that's why there is a lot of
// commented out code, I leave here because I think it // commented out code, I leave here because I think it
// will be needed again. // will be needed again.
@@ -341,7 +353,6 @@ AGGTextRenderer::RenderString(const char* string,
} else { } else {
fprintf(stderr, "UTF8 -> Unicode conversion failed: %s\n", strerror(ret)); fprintf(stderr, "UTF8 -> Unicode conversion failed: %s\n", strerror(ret));
} }
delete[] buffer;
// return transform.TransformBounds(bounds); // return transform.TransformBounds(bounds);
return bounds; return bounds;
@@ -57,7 +57,10 @@ class AGGTextRenderer : public TextRenderer {
conv_font_contour_type fContour; conv_font_contour_type fContour;
agg::scanline_u8 fScanline; agg::scanline_u8 fScanline;
agg::rasterizer_scanline_aa<> fRasterizer;; agg::rasterizer_scanline_aa<> fRasterizer;
char* fUnicodeBuffer;
int32 fUnicodeBufferSize;
}; };
#endif // AGG_TEXT_RENDERER_H #endif // AGG_TEXT_RENDERER_H