app_server: do not flush back buffer outside of clipping

Introduce DrawTransaction that automatically hide/show floating overlays
and flush back buffer.

Fixes #15574.

Change-Id: I30088b74fc66cfcd5b2b433b34141e7d496f68a1
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3496
Reviewed-by: Axel Dörfler <[email protected]>
This commit is contained in:
X512
2020-12-15 12:00:12 +00:00
committed by Adrien Destugues
parent 799e367afd
commit ebe6011c58
6 changed files with 229 additions and 263 deletions
+223 -257
View File
@@ -97,6 +97,81 @@ class AutoFloatingOverlaysHider {
};
class DrawTransaction {
public:
DrawTransaction(DrawingEngine *engine, const BRect &bounds)
:
fEngine(engine),
fOverlaysHidden(false)
{
fDirty.Set(bounds);
fDirty.IntersectWith(fEngine->fPainter->ClippingRegion());
if (fDirty.CountRects() == 0)
return;
fOverlaysHidden
= fEngine->fGraphicsCard->HideFloatingOverlays(fDirty.Frame());
}
DrawTransaction(DrawingEngine *engine)
:
fEngine(engine),
fOverlaysHidden(false)
{
fDirty = *fEngine->fPainter->ClippingRegion();
if (fDirty.CountRects() == 0)
return;
fOverlaysHidden
= fEngine->fGraphicsCard->HideFloatingOverlays(fDirty.Frame());
}
DrawTransaction(DrawingEngine *engine, const BRegion &region)
:
fEngine(engine),
fOverlaysHidden(false)
{
// region is already clipped
fDirty = region;
if (fDirty.CountRects() == 0)
return;
fOverlaysHidden
= fEngine->fGraphicsCard->HideFloatingOverlays(fDirty.Frame());
}
~DrawTransaction()
{
if (fEngine->fCopyToFront)
fEngine->fGraphicsCard->InvalidateRegion(fDirty);
if (fOverlaysHidden)
fEngine->fGraphicsCard->ShowFloatingOverlays();
}
bool IsDirty() const
{
return fDirty.CountRects() > 0;
}
void SetDirty(const BRect &rect)
{
fDirty.Set(rect);
fDirty.IntersectWith(fEngine->fPainter->ClippingRegion());
}
const BRegion &DirtyRegion() const
{
return fDirty;
}
bool WasOverlaysHidden() const
{
return fOverlaysHidden;
}
private:
DrawingEngine *fEngine;
bool fOverlaysHidden;
BRegion fDirty;
};
// #pragma mark -
@@ -476,6 +551,7 @@ void
DrawingEngine::CopyRegion(/*const*/ BRegion* region, int32 xOffset,
int32 yOffset)
{
// NOTE: region is already clipped
ASSERT_PARALLEL_LOCKED();
BRect frame = region->Frame();
@@ -604,12 +680,10 @@ DrawingEngine::InvertRect(BRect r)
make_rect_valid(r);
// NOTE: Currently ignores view transformation, so no TransformAndClipRect()
r = fPainter->ClipRect(r);
if (!r.IsValid())
DrawTransaction transaction(this, fPainter->ClipRect(r));
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider _(fGraphicsCard, r);
// try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) {
BRegion region(r);
@@ -618,8 +692,6 @@ DrawingEngine::InvertRect(BRect r)
} else {
fPainter->InvertRect(r);
}
_CopyToFront(r);
}
@@ -629,14 +701,9 @@ DrawingEngine::DrawBitmap(ServerBitmap* bitmap, const BRect& bitmapRect,
{
ASSERT_PARALLEL_LOCKED();
BRect clipped = fPainter->TransformAndClipRect(viewRect);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(viewRect));
if (transaction.IsDirty())
fPainter->DrawBitmap(bitmap, bitmapRect, viewRect, options);
_CopyToFront(clipped);
}
}
@@ -649,26 +716,22 @@ DrawingEngine::DrawArc(BRect r, const float& angle, const float& span,
make_rect_valid(r);
fPainter->AlignEllipseRect(&r, filled);
BRect clipped(r);
if (!filled)
extend_by_stroke_width(r, fPainter->PenSize());
extend_by_stroke_width(clipped, fPainter->PenSize());
DrawTransaction transaction(this, fPainter->TransformAndClipRect(clipped));
if (!transaction.IsDirty())
return;
BRect clipped(fPainter->TransformAndClipRect(r));
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius,
r.top + yRadius);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius,
r.top + yRadius);
if (filled)
fPainter->FillArc(center, xRadius, yRadius, angle, span);
else
fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
_CopyToFront(clipped);
}
if (filled)
fPainter->FillArc(center, xRadius, yRadius, angle, span);
else
fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
}
@@ -680,20 +743,16 @@ DrawingEngine::FillArc(BRect r, const float& angle, const float& span,
make_rect_valid(r);
fPainter->AlignEllipseRect(&r, true);
BRect clipped(fPainter->TransformAndClipRect(r));
DrawTransaction transaction(this, fPainter->TransformAndClipRect(r));
if (!transaction.IsDirty())
return;
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius,
r.top + yRadius);
float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius,
r.top + yRadius);
fPainter->FillArc(center, xRadius, yRadius, angle, span, gradient);
_CopyToFront(clipped);
}
fPainter->FillArc(center, xRadius, yRadius, angle, span, gradient);
}
@@ -703,11 +762,9 @@ DrawingEngine::DrawBezier(BPoint* pts, bool filled)
ASSERT_PARALLEL_LOCKED();
// TODO: figure out bounds and hide cursor depending on that
AutoFloatingOverlaysHider _(fGraphicsCard);
DrawTransaction transaction(this);
BRect touched = fPainter->DrawBezier(pts, filled);
_CopyToFront(touched);
transaction.SetDirty(fPainter->DrawBezier(pts, filled));
}
@@ -717,11 +774,9 @@ DrawingEngine::FillBezier(BPoint* pts, const BGradient& gradient)
ASSERT_PARALLEL_LOCKED();
// TODO: figure out bounds and hide cursor depending on that
AutoFloatingOverlaysHider _(fGraphicsCard);
DrawTransaction transaction(this);
BRect touched = fPainter->FillBezier(pts, gradient);
_CopyToFront(touched);
transaction.SetDirty(fPainter->FillBezier(pts, gradient));
}
@@ -742,15 +797,11 @@ DrawingEngine::DrawEllipse(BRect r, bool filled)
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
clipped = fPainter->TransformAndClipRect(clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(clipped));
if (!transaction.IsDirty())
return;
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
fPainter->DrawEllipse(r, filled);
_CopyToFront(clipped);
}
fPainter->DrawEllipse(r, filled);
}
@@ -768,15 +819,11 @@ DrawingEngine::FillEllipse(BRect r, const BGradient& gradient)
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
clipped = fPainter->TransformAndClipRect(clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(clipped));
if (!transaction.IsDirty())
return;
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
fPainter->FillEllipse(r, gradient);
_CopyToFront(clipped);
}
fPainter->FillEllipse(r, gradient);
}
@@ -789,14 +836,11 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts, BRect bounds,
make_rect_valid(bounds);
if (!filled)
extend_by_stroke_width(bounds, fPainter->PenSize());
bounds = fPainter->TransformAndClipRect(bounds);
if (bounds.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, bounds);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(bounds));
if (!transaction.IsDirty())
return;
fPainter->DrawPolygon(ptlist, numpts, filled, closed);
_CopyToFront(bounds);
}
fPainter->DrawPolygon(ptlist, numpts, filled, closed);
}
@@ -807,14 +851,11 @@ DrawingEngine::FillPolygon(BPoint* ptlist, int32 numpts, BRect bounds,
ASSERT_PARALLEL_LOCKED();
make_rect_valid(bounds);
bounds = fPainter->TransformAndClipRect(bounds);
if (bounds.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, bounds);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(bounds));
if (!transaction.IsDirty())
return;
fPainter->FillPolygon(ptlist, numpts, gradient, closed);
_CopyToFront(bounds);
}
fPainter->FillPolygon(ptlist, numpts, gradient, closed);
}
@@ -840,7 +881,7 @@ DrawingEngine::StrokeLine(const BPoint& start, const BPoint& end,
BRect touched(start, end);
make_rect_valid(touched);
touched = fPainter->ClipRect(touched);
AutoFloatingOverlaysHider _(fGraphicsCard, touched);
DrawTransaction transaction(this, touched);
if (!fPainter->StraightLine(start, end, color)) {
rgb_color previousColor = fPainter->HighColor();
@@ -853,8 +894,6 @@ DrawingEngine::StrokeLine(const BPoint& start, const BPoint& end,
fPainter->SetDrawingMode(previousMode);
fPainter->SetHighColor(previousColor);
}
_CopyToFront(touched);
}
@@ -865,14 +904,11 @@ DrawingEngine::StrokeRect(BRect r, const rgb_color& color)
ASSERT_PARALLEL_LOCKED();
make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, fPainter->ClipRect(r));
if (!transaction.IsDirty())
return;
fPainter->StrokeRect(r, color);
_CopyToFront(clipped);
}
fPainter->StrokeRect(r, color);
}
@@ -886,22 +922,19 @@ DrawingEngine::FillRect(BRect r, const rgb_color& color)
// gut feeling.
make_rect_valid(r);
r = fPainter->ClipRect(r);
if (!r.IsValid())
DrawTransaction transaction(this, r);
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, r);
// try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_FILL_REGION) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, color,
fSuspendSyncLevel == 0 || overlaysHider.WasHidden());
fSuspendSyncLevel == 0 || transaction.WasOverlaysHidden());
} else {
fPainter->FillRect(r, color);
}
_CopyToFront(r);
}
@@ -927,20 +960,18 @@ DrawingEngine::FillRegion(BRegion& r, const rgb_color& color)
return;
}
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, frame);
DrawTransaction transaction(this, r);
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
&& frame.Width() * frame.Height() > 100) {
fGraphicsCard->FillRegion(r, color, fSuspendSyncLevel == 0
|| overlaysHider.WasHidden());
|| transaction.WasOverlaysHidden());
} else {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++)
fPainter->FillRectNoClipping(r.RectAtInt(i), color);
}
_CopyToFront(frame);
}
@@ -956,14 +987,11 @@ DrawingEngine::StrokeRect(BRect r)
make_rect_valid(r);
BRect clipped(r);
extend_by_stroke_width(clipped, fPainter->PenSize());
clipped = fPainter->TransformAndClipRect(clipped);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(clipped));
if (!transaction.IsDirty())
return;
fPainter->StrokeRect(r);
_CopyToFront(clipped);
}
fPainter->StrokeRect(r);
}
@@ -976,14 +1004,10 @@ DrawingEngine::FillRect(BRect r)
r = fPainter->AlignRect(r);
BRect dirty = fPainter->TransformAndClipRect(r);
if (!dirty.IsValid())
DrawTransaction transaction(this, fPainter->TransformAndClipRect(r));
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, dirty);
bool doInSoftware = true;
if (fPainter->IsIdentityTransform()) {
// TODO the accelerated code path may also be used for transforms that
// only scale and translate (but don't shear or rotate).
@@ -998,34 +1022,32 @@ DrawingEngine::FillRect(BRect r)
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, fPainter->HighColor(),
fSuspendSyncLevel == 0 || overlaysHider.WasHidden());
doInSoftware = false;
fSuspendSyncLevel == 0
|| transaction.WasOverlaysHidden());
return;
} else if (fPainter->Pattern() == B_SOLID_LOW
&& fPainter->DrawingMode() == B_OP_COPY) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, fPainter->LowColor(),
fSuspendSyncLevel == 0 || overlaysHider.WasHidden());
doInSoftware = false;
fSuspendSyncLevel == 0
|| transaction.WasOverlaysHidden());
return;
}
}
}
if (doInSoftware
&& (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
if ((fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
&& fPainter->Pattern() == B_SOLID_HIGH
&& fPainter->DrawingMode() == B_OP_INVERT) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->InvertRegion(region);
doInSoftware = false;
return;
}
}
if (doInSoftware)
fPainter->FillRect(r);
_CopyToFront(dirty);
fPainter->FillRect(r);
}
@@ -1037,15 +1059,11 @@ DrawingEngine::FillRect(BRect r, const BGradient& gradient)
make_rect_valid(r);
r = fPainter->AlignRect(r);
BRect dirty = fPainter->TransformAndClipRect(r);
if (!dirty.IsValid())
DrawTransaction transaction(this, fPainter->TransformAndClipRect(r));
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, dirty);
fPainter->FillRect(r, gradient);
_CopyToFront(dirty);
}
@@ -1055,13 +1073,10 @@ DrawingEngine::FillRegion(BRegion& r)
ASSERT_PARALLEL_LOCKED();
BRect clipped = fPainter->TransformAndClipRect(r.Frame());
if (!clipped.IsValid())
DrawTransaction transaction(this, clipped);
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, clipped);
bool doInSoftware = true;
if (fPainter->IsIdentityTransform()) {
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
@@ -1070,36 +1085,29 @@ DrawingEngine::FillRegion(BRegion& r)
|| fPainter->DrawingMode() == B_OP_OVER)) {
r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, fPainter->HighColor(),
fSuspendSyncLevel == 0 || overlaysHider.WasHidden());
doInSoftware = false;
fSuspendSyncLevel == 0 || transaction.WasOverlaysHidden());
return;
} else if (fPainter->Pattern() == B_SOLID_LOW
&& fPainter->DrawingMode() == B_OP_COPY) {
r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, fPainter->LowColor(),
fSuspendSyncLevel == 0 || overlaysHider.WasHidden());
doInSoftware = false;
fSuspendSyncLevel == 0 || transaction.WasOverlaysHidden());
return;
}
}
if (doInSoftware
&& (fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
if ((fAvailableHWAccleration & HW_ACC_INVERT_REGION) != 0
&& fPainter->Pattern() == B_SOLID_HIGH
&& fPainter->DrawingMode() == B_OP_INVERT) {
r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->InvertRegion(r);
doInSoftware = false;
return;
}
}
if (doInSoftware) {
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));
}
_CopyToFront(r.Frame());
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++)
fPainter->FillRect(r.RectAt(i));
}
@@ -1109,18 +1117,13 @@ DrawingEngine::FillRegion(BRegion& r, const BGradient& gradient)
ASSERT_PARALLEL_LOCKED();
BRect clipped = fPainter->TransformAndClipRect(r.Frame());
if (!clipped.IsValid())
DrawTransaction transaction(this, clipped);
if (!transaction.IsDirty())
return;
AutoFloatingOverlaysHider overlaysHider(fGraphicsCard, clipped);
BRect touched = fPainter->FillRect(r.RectAt(0), gradient);
int32 count = r.CountRects();
for (int32 i = 1; i < count; i++)
touched = touched | fPainter->FillRect(r.RectAt(i), gradient);
_CopyToFront(r.Frame());
for (int32 i = 0; i < count; i++)
fPainter->FillRect(r.RectAt(i), gradient);
}
@@ -1139,14 +1142,14 @@ DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad, bool filled)
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, clipped);
if (!transaction.IsDirty())
return;
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
: fPainter->StrokeRoundRect(r, xrad, yrad);
_CopyToFront(touched);
}
if (filled)
fPainter->FillRoundRect(r, xrad, yrad);
else
fPainter->StrokeRoundRect(r, xrad, yrad);
}
@@ -1164,13 +1167,11 @@ DrawingEngine::FillRoundRect(BRect r, float xrad, float yrad,
clipped.right = ceilf(clipped.right);
clipped.bottom = ceilf(clipped.bottom);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, clipped);
if (!transaction.IsDirty())
return;
BRect touched = fPainter->FillRoundRect(r, xrad, yrad, gradient);
_CopyToFront(touched);
}
fPainter->FillRoundRect(r, xrad, yrad, gradient);
}
@@ -1192,16 +1193,13 @@ DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
// clipped.right = ceilf(clipped.right);
// clipped.bottom = ceilf(clipped.bottom);
//
// if (!clipped.IsValid())
// DrawTransaction transaction(this, clipped);
// if (!transaction.IsDirty())
// return;
//
// AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
AutoFloatingOverlaysHider _(fGraphicsCard);
DrawTransaction transaction(this);
BRect touched = fPainter->DrawShape(opCount, opList, ptCount, ptList,
filled, viewToScreenOffset, viewScale);
_CopyToFront(touched);
transaction.SetDirty(fPainter->DrawShape(opCount, opList, ptCount, ptList,
filled, viewToScreenOffset, viewScale));
}
@@ -1221,16 +1219,13 @@ DrawingEngine::FillShape(const BRect& bounds, int32 opCount,
// clipped.right = ceilf(clipped.right);
// clipped.bottom = ceilf(clipped.bottom);
//
// if (!clipped.IsValid())
// DrawTransaction transaction(this, clipped);
// if (!transaction.IsDirty())
// return;
//
// AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
AutoFloatingOverlaysHider _(fGraphicsCard);
DrawTransaction transaction(this);
BRect touched = fPainter->FillShape(opCount, opList, ptCount, ptList,
gradient, viewToScreenOffset, viewScale);
_CopyToFront(touched);
transaction.SetDirty(fPainter->FillShape(opCount, opList, ptCount, ptList,
gradient, viewToScreenOffset, viewScale));
}
@@ -1242,17 +1237,14 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, bool filled)
BRect clipped(bounds);
if (!filled)
extend_by_stroke_width(clipped, fPainter->PenSize());
clipped = fPainter->TransformAndClipRect(clipped);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(clipped));
if (!transaction.IsDirty())
return;
if (filled)
fPainter->FillTriangle(pts[0], pts[1], pts[2]);
else
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
_CopyToFront(clipped);
}
if (filled)
fPainter->FillTriangle(pts[0], pts[1], pts[2]);
else
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
}
@@ -1262,15 +1254,11 @@ DrawingEngine::FillTriangle(BPoint* pts, const BRect& bounds,
{
ASSERT_PARALLEL_LOCKED();
BRect clipped(bounds);
clipped = fPainter->TransformAndClipRect(clipped);
if (clipped.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, clipped);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(bounds));
if (!transaction.IsDirty())
return;
fPainter->FillTriangle(pts[0], pts[1], pts[2], gradient);
_CopyToFront(clipped);
}
fPainter->FillTriangle(pts[0], pts[1], pts[2], gradient);
}
@@ -1282,14 +1270,11 @@ DrawingEngine::StrokeLine(const BPoint& start, const BPoint& end)
BRect touched(start, end);
make_rect_valid(touched);
extend_by_stroke_width(touched, fPainter->PenSize());
touched = fPainter->TransformAndClipRect(touched);
if (touched.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, touched);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(touched));
if (!transaction.IsDirty())
return;
fPainter->StrokeLine(start, end);
_CopyToFront(touched);
}
fPainter->StrokeLine(start, end);
}
@@ -1318,33 +1303,30 @@ DrawingEngine::StrokeLineArray(int32 numLines,
touched = touched | box;
}
extend_by_stroke_width(touched, fPainter->PenSize());
touched = fPainter->TransformAndClipRect(touched);
if (touched.IsValid()) {
AutoFloatingOverlaysHider _(fGraphicsCard, touched);
DrawTransaction transaction(this, fPainter->TransformAndClipRect(touched));
if (!transaction.IsDirty())
return;
data = (const ViewLineArrayInfo*)&(lineData[0]);
data = (const ViewLineArrayInfo*)&(lineData[0]);
// store current graphics state, we mess with the
// high color and pattern...
rgb_color oldColor = fPainter->HighColor();
struct pattern pattern = fPainter->Pattern();
// store current graphics state, we mess with the
// high color and pattern...
rgb_color oldColor = fPainter->HighColor();
struct pattern pattern = fPainter->Pattern();
fPainter->SetHighColor(data->color);
fPainter->SetPattern(B_SOLID_HIGH);
fPainter->StrokeLine(data->startPoint, data->endPoint);
for (int32 i = 1; i < numLines; i++) {
data = (const ViewLineArrayInfo*)&(lineData[i]);
fPainter->SetHighColor(data->color);
fPainter->SetPattern(B_SOLID_HIGH);
fPainter->StrokeLine(data->startPoint, data->endPoint);
for (int32 i = 1; i < numLines; i++) {
data = (const ViewLineArrayInfo*)&(lineData[i]);
fPainter->SetHighColor(data->color);
fPainter->StrokeLine(data->startPoint, data->endPoint);
}
// restore correct drawing state highcolor and pattern
fPainter->SetHighColor(oldColor);
fPainter->SetPattern(pattern);
_CopyToFront(touched);
}
// restore correct drawing state highcolor and pattern
fPainter->SetHighColor(oldColor);
fPainter->SetPattern(pattern);
}
@@ -1388,17 +1370,13 @@ DrawingEngine::DrawString(const char* string, int32 length,
BRect b = fPainter->BoundingBox(string, length, pt, &penLocation, delta,
&cacheReference);
// stop here if we're supposed to render outside of the clipping
b = fPainter->ClipRect(b);
if (b.IsValid()) {
DrawTransaction transaction(this, fPainter->ClipRect(b));
if (transaction.IsDirty()) {
//printf("bounding box '%s': %lld µs\n", string, system_time() - now);
AutoFloatingOverlaysHider _(fGraphicsCard, b);
//now = system_time();
BRect touched = fPainter->DrawString(string, length, pt, delta,
&cacheReference);
fPainter->DrawString(string, length, pt, delta, &cacheReference);
//printf("drawing string: %lld µs\n", system_time() - now);
_CopyToFront(touched);
}
return penLocation;
@@ -1419,17 +1397,13 @@ DrawingEngine::DrawString(const char* string, int32 length,
BRect b = fPainter->BoundingBox(string, length, offsets, &penLocation,
&cacheReference);
// stop here if we're supposed to render outside of the clipping
b = fPainter->ClipRect(b);
if (b.IsValid()) {
DrawTransaction transaction(this, fPainter->ClipRect(b));
if (transaction.IsDirty()) {
//printf("bounding box '%s': %lld µs\n", string, system_time() - now);
AutoFloatingOverlaysHider _(fGraphicsCard, b);
//now = system_time();
BRect touched = fPainter->DrawString(string, length, offsets,
&cacheReference);
fPainter->DrawString(string, length, offsets, &cacheReference);
//printf("drawing string: %lld µs\n", system_time() - now);
_CopyToFront(touched);
}
return penLocation;
@@ -1667,11 +1641,3 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
}
}
}
inline void
DrawingEngine::_CopyToFront(const BRect& frame)
{
if (fCopyToFront)
fGraphicsCard->Invalidate(frame);
}
+2 -2
View File
@@ -201,12 +201,12 @@ public:
void SetRendererOffset(int32 offsetX, int32 offsetY);
private:
friend class DrawTransaction;
void _CopyRect(uint8* bits, uint32 width,
uint32 height, uint32 bytesPerRow,
int32 xOffset, int32 yOffset) const;
inline void _CopyToFront(const BRect& frame);
ObjectDeleter<Painter>
fPainter;
HWInterface* fGraphicsCard;
+1 -1
View File
@@ -317,7 +317,7 @@ HWInterface::IsDoubleBuffered() const
/*! The object needs to be already locked!
*/
status_t
HWInterface::InvalidateRegion(BRegion& region)
HWInterface::InvalidateRegion(const BRegion& region)
{
int32 count = region.CountRects();
for (int32 i = 0; i < count; i++) {
+1 -1
View File
@@ -168,7 +168,7 @@ public:
virtual bool IsDoubleBuffered() const;
// Invalidate is used for scheduling an area for updating
virtual status_t InvalidateRegion(BRegion& region);
virtual status_t InvalidateRegion(const BRegion& region);
virtual status_t Invalidate(const BRect& frame);
// while as CopyBackToFront() actually performs the operation
// either directly or asynchronously by the UpdateQueue thread
@@ -575,7 +575,7 @@ RemoteHWInterface::IsDoubleBuffered() const
status_t
RemoteHWInterface::InvalidateRegion(BRegion& region)
RemoteHWInterface::InvalidateRegion(const BRegion& region)
{
RemoteMessage message(NULL, fSendBuffer.Get());
message.Start(RP_INVALIDATE_REGION);
@@ -76,7 +76,7 @@ virtual RenderingBuffer* FrontBuffer() const;
virtual RenderingBuffer* BackBuffer() const;
virtual bool IsDoubleBuffered() const;
virtual status_t InvalidateRegion(BRegion& region);
virtual status_t InvalidateRegion(const BRegion& region);
virtual status_t Invalidate(const BRect& frame);
virtual status_t CopyBackToFront(const BRect& frame);