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