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:
@@ -52,6 +52,9 @@ class Painter {
|
||||
void DetachFromBuffer();
|
||||
|
||||
void ConstrainClipping(const BRegion& region);
|
||||
const BRegion* ClippingRegion() const
|
||||
{ return fClippingRegion; }
|
||||
|
||||
void SetDrawData(const DrawData* data);
|
||||
|
||||
// object settings
|
||||
|
||||
@@ -47,14 +47,14 @@ public:
|
||||
RGBColor(uint16 col);
|
||||
RGBColor(uint8 col);
|
||||
RGBColor(const RGBColor &col);
|
||||
RGBColor(void);
|
||||
RGBColor();
|
||||
|
||||
void PrintToStream(void) const;
|
||||
void PrintToStream() const;
|
||||
|
||||
uint8 GetColor8(void);
|
||||
uint16 GetColor15(void);
|
||||
uint16 GetColor16(void);
|
||||
rgb_color GetColor32(void) const;
|
||||
uint8 GetColor8() const;
|
||||
uint16 GetColor15() const;
|
||||
uint16 GetColor16() const;
|
||||
rgb_color GetColor32() const;
|
||||
|
||||
void SetColor(uint8 r, uint8 g, uint8 b, uint8 a=255);
|
||||
void SetColor(int r, int g, int b, int a=255);
|
||||
@@ -71,10 +71,14 @@ public:
|
||||
bool operator==(const RGBColor &col);
|
||||
protected:
|
||||
rgb_color color32;
|
||||
uint16 color16;
|
||||
uint16 color15;
|
||||
uint8 color8;
|
||||
bool update8,update15,update16;
|
||||
|
||||
// caching
|
||||
mutable uint16 color16;
|
||||
mutable uint16 color15;
|
||||
mutable uint8 color8;
|
||||
mutable bool update8;
|
||||
mutable bool update15;
|
||||
mutable bool update16;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
# define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans"
|
||||
# define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT"
|
||||
# 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 FALLBACK_FIXED_FONT_FAMILY "Courier10 BT"
|
||||
# define DEFAULT_FIXED_FONT_STYLE "Roman"
|
||||
|
||||
@@ -1280,6 +1280,12 @@ Layer::move_layer(float x, float y)
|
||||
BPoint pt(x, y);
|
||||
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);
|
||||
|
||||
fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
|
||||
@@ -1291,7 +1297,7 @@ Layer::move_layer(float x, float y)
|
||||
|
||||
EmptyGlobals();
|
||||
|
||||
fFrameAction = B_LAYER_ACTION_NONE;
|
||||
fFrameAction = B_LAYER_ACTION_NONE;
|
||||
}
|
||||
|
||||
// resize_layer
|
||||
@@ -1305,6 +1311,12 @@ Layer::resize_layer(float x, float y)
|
||||
rect.right += x;
|
||||
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);
|
||||
|
||||
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
|
||||
|
||||
@@ -100,7 +100,7 @@ RGBColor::RGBColor(const RGBColor &col)
|
||||
/*!
|
||||
\brief Create an RGBColor with the values(0,0,0,0)
|
||||
*/
|
||||
RGBColor::RGBColor(void)
|
||||
RGBColor::RGBColor()
|
||||
{
|
||||
SetColor(0,0,0,0);
|
||||
update8=update16=false;
|
||||
@@ -110,7 +110,7 @@ RGBColor::RGBColor(void)
|
||||
\brief Returns the color as the closest 8-bit color in the palette
|
||||
\return The palette index for the current color
|
||||
*/
|
||||
uint8 RGBColor::GetColor8(void)
|
||||
uint8 RGBColor::GetColor8() const
|
||||
{
|
||||
if(update8)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ uint8 RGBColor::GetColor8(void)
|
||||
\brief Returns the color as the closest 15-bit color
|
||||
\return 15-bit value of the current color plus 1-bit alpha
|
||||
*/
|
||||
uint16 RGBColor::GetColor15(void)
|
||||
uint16 RGBColor::GetColor15() const
|
||||
{
|
||||
if(update15)
|
||||
{
|
||||
@@ -140,7 +140,7 @@ uint16 RGBColor::GetColor15(void)
|
||||
\brief Returns the color as the closest 16-bit color
|
||||
\return 16-bit value of the current color
|
||||
*/
|
||||
uint16 RGBColor::GetColor16(void)
|
||||
uint16 RGBColor::GetColor16() const
|
||||
{
|
||||
if(update16)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ uint16 RGBColor::GetColor16(void)
|
||||
\brief Returns the color as a 32-bit color
|
||||
\return current color, including alpha
|
||||
*/
|
||||
rgb_color RGBColor::GetColor32(void) const
|
||||
rgb_color RGBColor::GetColor32() const
|
||||
{
|
||||
return color32;
|
||||
}
|
||||
|
||||
@@ -14,13 +14,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Cursor.h>
|
||||
#include <Locker.h>
|
||||
#include <Message.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <Region.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include <graphic_driver.h>
|
||||
@@ -30,11 +24,11 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "PortLink.h"
|
||||
//#include "PortLink.h"
|
||||
#include "RGBColor.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerCursor.h"
|
||||
#include "ServerProtocol.h"
|
||||
#include "UpdateQueue.h"
|
||||
|
||||
#include "AccelerantHWInterface.h"
|
||||
#include "AccelerantBuffer.h"
|
||||
@@ -55,6 +49,7 @@ AccelerantHWInterface::AccelerantHWInterface()
|
||||
fAccelerantImage(-1),
|
||||
fAccelerantHook(NULL),
|
||||
fEngineToken(NULL),
|
||||
fSyncToken(),
|
||||
|
||||
// required hooks
|
||||
fAccAcquireEngine(NULL),
|
||||
@@ -89,6 +84,11 @@ AccelerantHWInterface::AccelerantHWInterface()
|
||||
fDisplayMode.virtual_width = 640;
|
||||
fDisplayMode.virtual_height = 480;
|
||||
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
|
||||
@@ -507,6 +507,104 @@ AccelerantHWInterface::DPMSCapabilities() const
|
||||
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(®ion, &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(®ion, &fillParams, &count);
|
||||
|
||||
// go
|
||||
fAccInvertRect(fEngineToken, fillParams, count);
|
||||
|
||||
// done
|
||||
if (fAccReleaseEngine)
|
||||
fAccReleaseEngine(fEngineToken, &fSyncToken);
|
||||
|
||||
delete[] fillParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetCursor
|
||||
void
|
||||
AccelerantHWInterface::SetCursor(ServerCursor* cursor)
|
||||
@@ -575,3 +673,56 @@ AccelerantHWInterface::_DrawCursor(BRect area) const
|
||||
// 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 AccelerantBuffer;
|
||||
class UpdateQueue;
|
||||
|
||||
class AccelerantHWInterface : public HWInterface {
|
||||
public:
|
||||
@@ -49,6 +48,16 @@ virtual status_t SetDPMSMode(const uint32 &state);
|
||||
virtual uint32 DPMSMode() 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
|
||||
virtual void SetCursor(ServerCursor* cursor);
|
||||
virtual void SetCursorVisible(bool visible);
|
||||
@@ -67,11 +76,16 @@ private:
|
||||
status_t SetupDefaultHooks();
|
||||
status_t UpdateModeList();
|
||||
status_t UpdateFrameBufferConfig();
|
||||
void _RegionToRectParams(/*const*/ BRegion* region,
|
||||
fill_rect_params** params,
|
||||
uint32* count) const;
|
||||
uint32 _NativeColor(const RGBColor& color) const;
|
||||
|
||||
int fCardFD;
|
||||
image_id fAccelerantImage;
|
||||
GetAccelerantHook fAccelerantHook;
|
||||
engine_token *fEngineToken;
|
||||
sync_token fSyncToken;
|
||||
|
||||
// required hooks - guaranteed to be valid
|
||||
acquire_engine fAccAcquireEngine;
|
||||
@@ -107,8 +121,6 @@ private:
|
||||
|
||||
|
||||
display_mode fDisplayMode;
|
||||
|
||||
UpdateQueue *fUpdateExecutor;
|
||||
};
|
||||
|
||||
#endif // ACCELERANT_HW_INTERFACE_H
|
||||
|
||||
@@ -52,10 +52,11 @@ DisplayDriverPainter::DisplayDriverPainter()
|
||||
: DisplayDriver(),
|
||||
fPainter(new Painter()),
|
||||
#if USE_ACCELERANT
|
||||
fGraphicsCard(new AccelerantHWInterface())
|
||||
fGraphicsCard(new AccelerantHWInterface()),
|
||||
#else
|
||||
fGraphicsCard(new ViewHWInterface())
|
||||
fGraphicsCard(new ViewHWInterface()),
|
||||
#endif
|
||||
fAvailableHWAccleration(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -72,8 +73,10 @@ DisplayDriverPainter::Initialize()
|
||||
status_t err = fGraphicsCard->Initialize();
|
||||
if (err < B_OK)
|
||||
fprintf(stderr, "HWInterface::Initialize() failed: %s\n", strerror(err));
|
||||
if (err >= B_OK)
|
||||
if (err >= B_OK) {
|
||||
fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration();
|
||||
return DisplayDriver::Initialize();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -218,7 +221,7 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
|
||||
int32 xOffset, int32 yOffset)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(region->Frame()));
|
||||
fGraphicsCard->HideSoftwareCursor(region->Frame());
|
||||
|
||||
int32 count = region->CountRects();
|
||||
|
||||
@@ -284,12 +287,30 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
|
||||
// currently on the stack and to which the current rect pointed
|
||||
// to. If their "indegree" count reaches zero, put them onto the
|
||||
// stack as well.
|
||||
|
||||
clipping_rect* sortedRectList = NULL;
|
||||
int32 nextSortedIndex = 0;
|
||||
|
||||
if (fAvailableHWAccleration & HW_ACC_COPY_REGION)
|
||||
sortedRectList = new clipping_rect[count];
|
||||
|
||||
while (!inDegreeZeroNodes.empty()) {
|
||||
node* n = inDegreeZeroNodes.top();
|
||||
inDegreeZeroNodes.pop();
|
||||
inDegreeZeroNodes.pop();
|
||||
|
||||
BRect touched = _CopyRect(n->rect, xOffset, yOffset);
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
// do the software implementation or add to sorted
|
||||
// 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++) {
|
||||
n->pointers[k]->in_degree--;
|
||||
@@ -297,6 +318,13 @@ DisplayDriverPainter::CopyRegion(/*const*/ BRegion* region,
|
||||
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();
|
||||
|
||||
Unlock();
|
||||
@@ -456,7 +484,7 @@ DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
|
||||
|
||||
// FillRect
|
||||
void
|
||||
DisplayDriverPainter::FillRect(const BRect &r, const RGBColor &color)
|
||||
DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color)
|
||||
{
|
||||
if (Lock()) {
|
||||
BRect vr(min_c(r.left, r.right),
|
||||
@@ -467,9 +495,17 @@ DisplayDriverPainter::FillRect(const BRect &r, const RGBColor &color)
|
||||
|
||||
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();
|
||||
|
||||
Unlock();
|
||||
@@ -489,10 +525,32 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillRect(vr);
|
||||
bool doInSoftware = true;
|
||||
// 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();
|
||||
|
||||
Unlock();
|
||||
@@ -507,16 +565,34 @@ DisplayDriverPainter::FillRegion(BRegion& r, const DrawData *d)
|
||||
|
||||
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();
|
||||
for (int32 i = 1; i < count; i++) {
|
||||
touched = touched | fPainter->FillRect(r.RectAt(i));
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
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();
|
||||
|
||||
Unlock();
|
||||
@@ -899,11 +975,21 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
const BPoint &pt, DrawData *d)
|
||||
{
|
||||
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);
|
||||
|
||||
//now = system_time();
|
||||
BRect touched = fPainter->DrawString(string, length, pt);
|
||||
//printf("drawing string: %lld µs\n", system_time() - now);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
@@ -920,7 +1006,7 @@ DisplayDriverPainter::StringWidth(const char *string, int32 length,
|
||||
float width = 0.0;
|
||||
if (Lock()) {
|
||||
fPainter->SetDrawData(d);
|
||||
BPoint dummy(0.0, 0.0);
|
||||
static BPoint dummy(0.0, 0.0);
|
||||
width = fPainter->BoundingBox(string, length, dummy).Width();
|
||||
Unlock();
|
||||
}
|
||||
@@ -932,16 +1018,9 @@ float
|
||||
DisplayDriverPainter::StringWidth(const char *string, int32 length,
|
||||
const ServerFont &font)
|
||||
{
|
||||
float width = 0.0;
|
||||
if (Lock()) {
|
||||
DrawData d;
|
||||
d.SetFont(font);
|
||||
fPainter->SetDrawData(&d);
|
||||
BPoint dummy(0.0, 0.0);
|
||||
width = fPainter->BoundingBox(string, length, dummy).Width();
|
||||
Unlock();
|
||||
}
|
||||
return width;
|
||||
static DrawData d;
|
||||
d.SetFont(font);
|
||||
return StringWidth(string, length, &d);
|
||||
}
|
||||
|
||||
// StringHeight
|
||||
@@ -952,7 +1031,7 @@ DisplayDriverPainter::StringHeight(const char *string, int32 length,
|
||||
float height = 0.0;
|
||||
if (Lock()) {
|
||||
fPainter->SetDrawData(d);
|
||||
BPoint dummy(0.0, 0.0);
|
||||
static BPoint dummy(0.0, 0.0);
|
||||
height = fPainter->BoundingBox(string, length, dummy).Height();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ class DisplayDriverPainter : public DisplayDriver {
|
||||
|
||||
Painter* fPainter;
|
||||
HWInterface* fGraphicsCard;
|
||||
uint32 fAvailableHWAccleration;
|
||||
};
|
||||
|
||||
#endif // _DISPLAY_DRIVER_PAINTER_H_
|
||||
|
||||
@@ -625,7 +625,7 @@ HWInterface::_RestoreCursorArea(const BRect& area) const
|
||||
|
||||
uint8* src = fCursorAreaBackup->buffer;
|
||||
if (fCursorAreaBackup->left < left)
|
||||
src += left - fCursorAreaBackup->left;
|
||||
src += (left - fCursorAreaBackup->left) * 4;
|
||||
if (fCursorAreaBackup->top < top)
|
||||
src += (top - fCursorAreaBackup->top) * fCursorAreaBackup->bpr;
|
||||
|
||||
|
||||
@@ -13,12 +13,19 @@
|
||||
#include <GraphicsCard.h>
|
||||
#include <Locker.h>
|
||||
#include <OS.h>
|
||||
#include <Rect.h>
|
||||
#include <Region.h>
|
||||
|
||||
class RenderingBuffer;
|
||||
class RGBColor;
|
||||
class ServerCursor;
|
||||
class UpdateQueue;
|
||||
|
||||
enum {
|
||||
HW_ACC_COPY_REGION = 0x00000001,
|
||||
HW_ACC_FILL_REGION = 0x00000002,
|
||||
HW_ACC_INVERT_REGION = 0x00000004,
|
||||
};
|
||||
|
||||
class HWInterface : public BLocker {
|
||||
public:
|
||||
HWInterface(bool doubleBuffered = false);
|
||||
@@ -48,6 +55,18 @@ class HWInterface : public BLocker {
|
||||
virtual uint32 DPMSMode() 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
|
||||
virtual void SetCursor(ServerCursor* cursor);
|
||||
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.
|
||||
// Later, the implementation should be smarter, right now, it will
|
||||
// draw the cursor for almost every drawing operation.
|
||||
// It seems to me, BeOS hides the cursor (in laymans words) before
|
||||
// BView::Draw() is called, then, after all drawing commands that triggered
|
||||
// have been caried out, it shows the cursor again. This approach would
|
||||
// have the adventage of the code not cluttering/slowing down DisplayDriverPainter.
|
||||
// It seems to me BeOS hides the cursor (in laymans words) before
|
||||
// BView::Draw() is called (if the cursor is within that views clipping region),
|
||||
// then, after all drawing commands that triggered have been caried out,
|
||||
// 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();
|
||||
void ShowSoftwareCursor();
|
||||
|
||||
@@ -946,7 +946,7 @@ Painter::BoundingBox(const char* utf8String, uint32 length,
|
||||
Transformable transform;
|
||||
transform.TranslateBy(baseLine);
|
||||
|
||||
BRect dummy;
|
||||
static BRect dummy;
|
||||
return fTextRenderer->RenderString(utf8String,
|
||||
length,
|
||||
fFontRendererSolid,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// AGGTextRenderer.cpp
|
||||
|
||||
#include <math.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -44,6 +45,7 @@ rect_to_int(BRect r,
|
||||
bottom = (int32)ceilf(r.bottom);
|
||||
}
|
||||
|
||||
#define DEFAULT_UNI_CODE_BUFFER_SIZE 2048
|
||||
|
||||
// constructor
|
||||
AGGTextRenderer::AGGTextRenderer()
|
||||
@@ -51,7 +53,9 @@ AGGTextRenderer::AGGTextRenderer()
|
||||
fFontEngine(ftlib),
|
||||
fFontManager(fFontEngine),
|
||||
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);
|
||||
fContour.auto_detect_orientation(false);
|
||||
@@ -63,7 +67,9 @@ AGGTextRenderer::AGGTextRenderer(BMessage* archive)
|
||||
fFontEngine(ftlib),
|
||||
fFontManager(fFontEngine),
|
||||
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");
|
||||
fCurves.approximation_scale(2.0);
|
||||
@@ -77,7 +83,9 @@ AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
|
||||
fFontEngine(ftlib),
|
||||
fFontManager(fFontEngine),
|
||||
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);
|
||||
fContour.auto_detect_orientation(false);
|
||||
@@ -88,6 +96,7 @@ AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
|
||||
AGGTextRenderer::~AGGTextRenderer()
|
||||
{
|
||||
Unset();
|
||||
free(fUnicodeBuffer);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
@@ -215,18 +224,21 @@ AGGTextRenderer::RenderString(const char* string,
|
||||
int32 srcLength = min_c(length, strlen(string));
|
||||
int32 dstLength = srcLength * 4;
|
||||
|
||||
char* buffer = new char[dstLength];
|
||||
if (dstLength > fUnicodeBufferSize) {
|
||||
fUnicodeBufferSize = dstLength;
|
||||
fUnicodeBuffer = (char*)realloc((void*)fUnicodeBuffer, fUnicodeBufferSize);
|
||||
}
|
||||
|
||||
int32 state = 0;
|
||||
status_t ret;
|
||||
if ((ret = convert_from_utf8(B_UNICODE_CONVERSION,
|
||||
string, &srcLength,
|
||||
buffer, &dstLength,
|
||||
fUnicodeBuffer, &dstLength,
|
||||
&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) {
|
||||
|
||||
uint16* p = (uint16*)buffer;
|
||||
uint16* p = (uint16*)fUnicodeBuffer;
|
||||
|
||||
double x = 0.0;
|
||||
double y0 = 0.0;
|
||||
@@ -299,7 +311,7 @@ AGGTextRenderer::RenderString(const char* string,
|
||||
case agg::glyph_data_outline:
|
||||
fRasterizer.reset();
|
||||
// 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
|
||||
// will be needed again.
|
||||
|
||||
@@ -341,7 +353,6 @@ AGGTextRenderer::RenderString(const char* string,
|
||||
} else {
|
||||
fprintf(stderr, "UTF8 -> Unicode conversion failed: %s\n", strerror(ret));
|
||||
}
|
||||
delete[] buffer;
|
||||
|
||||
// return transform.TransformBounds(bounds);
|
||||
return bounds;
|
||||
|
||||
@@ -57,7 +57,10 @@ class AGGTextRenderer : public TextRenderer {
|
||||
conv_font_contour_type fContour;
|
||||
|
||||
agg::scanline_u8 fScanline;
|
||||
agg::rasterizer_scanline_aa<> fRasterizer;;
|
||||
agg::rasterizer_scanline_aa<> fRasterizer;
|
||||
|
||||
char* fUnicodeBuffer;
|
||||
int32 fUnicodeBufferSize;
|
||||
};
|
||||
|
||||
#endif // AGG_TEXT_RENDERER_H
|
||||
|
||||
Reference in New Issue
Block a user