|
|
|
@@ -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 ®ion)
|
|
|
|
|
:
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|