From 3d16cf4bcebc6d7fa9965d773f89f4b2268a27a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 15 Apr 2005 09:55:15 +0000 Subject: [PATCH] Painter drawing functions now return the BRect enclosing all pixels that have changed, use this for invalidating the correct area in the backbuffer git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12407 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/servers/app/Painter.h | 56 +++---- .../app/drawing/DisplayDriverPainter.cpp | 83 +++++------ src/servers/app/drawing/Painter/Painter.cpp | 139 +++++++----------- 3 files changed, 113 insertions(+), 165 deletions(-) diff --git a/headers/private/servers/app/Painter.h b/headers/private/servers/app/Painter.h index 6bce1e6997..e6bba007b2 100644 --- a/headers/private/servers/app/Painter.h +++ b/headers/private/servers/app/Painter.h @@ -23,24 +23,10 @@ class ServerBitmap; class ServerFont; // TODO: API transition: -// * all functions should return BRect of pixels touched by an operation // * most all functions should take a DrawData* context parameter instead // of the current pattern argument, that way, each function can // decide for itself, which pieces of information in DrawData it // needs -// * there would be no "scale" and "origin" within Painter, all -// coordinates are expected in screen coordinates, all other data -// passed in the DrawData is assumed to be already properly -// converted (scaled and offset by origin, converted to screen), -// this is important for a views graphics state local clipping (as -// added by the user) and also font size and so on. For a correct -// handling of a views scale and origin, see the original Painter -// implementation at src/tests/servers/app/Painter -// * Painter should use a custom agg::renderer_mclip, which takes -// a BRegion pointer. The current conversion from BRegion to -// agg::renderer_mclip is quite expensive (arround 190 usecs on -// my machine, which is almost the time it takes for the actual -// drawing which comes after it... // * Painter itself should be made thread safe. Because no // ServerWindow is supposed to draw outside of its clipping region, // there is actually no reason to lock the DisplayDriver. Multiple @@ -108,32 +94,32 @@ class Painter { const rgb_color& c) const; // triangles - void StrokeTriangle( BPoint pt1, + BRect StrokeTriangle( BPoint pt1, BPoint pt2, BPoint pt3) const; - void FillTriangle( BPoint pt1, + BRect FillTriangle( BPoint pt1, BPoint pt2, BPoint pt3) const; // polygons - void StrokePolygon( const BPoint* ptArray, + BRect StrokePolygon( const BPoint* ptArray, int32 numPts, bool closed = true) const; - void FillPolygon( const BPoint* ptArray, + BRect FillPolygon( const BPoint* ptArray, int32 numPts, bool closed = true) const; // bezier curves - void StrokeBezier( const BPoint* controlPoints) const; + BRect StrokeBezier( const BPoint* controlPoints) const; - void FillBezier( const BPoint* controlPoints) const; + BRect FillBezier( const BPoint* controlPoints) const; // shapes - void StrokeShape( /*const */BShape* shape) const; + BRect StrokeShape( /*const */BShape* shape) const; - void FillShape( /*const */BShape* shape) const; + BRect FillShape( /*const */BShape* shape) const; // rects @@ -150,31 +136,31 @@ class Painter { const rgb_color& c) const; // round rects - void StrokeRoundRect(const BRect& r, + BRect StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const; - void FillRoundRect( const BRect& r, + BRect FillRoundRect( const BRect& r, float xRadius, float yRadius) const; // ellipses - void StrokeEllipse( BPoint center, + BRect StrokeEllipse( BPoint center, float xRadius, float yRadius) const; - void FillEllipse( BPoint center, + BRect FillEllipse( BPoint center, float xRadius, float yRadius) const; // arcs - void StrokeArc( BPoint center, + BRect StrokeArc( BPoint center, float xRadius, float yRadius, float angle, float span) const; - void FillArc( BPoint center, + BRect FillArc( BPoint center, float xRadius, float yRadius, float angle, @@ -212,9 +198,9 @@ class Painter { BRect viewRect) const; // some convenience stuff - void FillRegion( const BRegion* region) const; + BRect FillRegion( const BRegion* region) const; - void InvertRect( const BRect& r) const; + BRect InvertRect( const BRect& r) const; BRect BoundingBox( const char* utf8String, uint32 length, @@ -232,23 +218,21 @@ class Painter { bool centerOffset = true) const; BRect _Clipped(const BRect& rect) const; -// void _RebuildClipping(); - void _UpdateFont(); void _UpdateLineWidth(); // drawing functions stroke/fill - void _DrawTriangle( BPoint pt1, + BRect _DrawTriangle( BPoint pt1, BPoint pt2, BPoint pt3, bool fill) const; - void _DrawEllipse( BPoint center, + BRect _DrawEllipse( BPoint center, float xRadius, float yRadius, bool fill) const; - void _DrawShape( /*const */BShape* shape, + BRect _DrawShape( /*const */BShape* shape, bool fill) const; - void _DrawPolygon( const BPoint* ptArray, + BRect _DrawPolygon( const BPoint* ptArray, int32 numPts, bool closed, bool fill) const; diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index 8360b9615f..edc770e6ba 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -144,8 +144,8 @@ DisplayDriverPainter::InvertRect(const BRect &r) { if (Lock()) { - fPainter->InvertRect(r); - fGraphicsCard->Invalidate(r); + BRect touched = fPainter->InvertRect(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -480,9 +480,9 @@ DisplayDriverPainter::FillArc(const BRect &r, const float &angle, BPoint center(r.left + xRadius, r.top + yRadius); - fPainter->FillArc(center, xRadius, yRadius, angle, span); + BRect touched = fPainter->FillArc(center, xRadius, yRadius, angle, span); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -496,9 +496,9 @@ DisplayDriverPainter::FillBezier(BPoint *pts, const DrawData *d) fPainter->SetDrawData(d); - fPainter->FillBezier(pts); + BRect touched = fPainter->FillBezier(pts); - // TODO: Invalidate + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -517,9 +517,9 @@ DisplayDriverPainter::FillEllipse(const BRect &r, const DrawData *d) BPoint center(r.left + xRadius, r.top + yRadius); - fPainter->FillEllipse(center, xRadius, yRadius); + BRect touched = fPainter->FillEllipse(center, xRadius, yRadius); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -533,9 +533,9 @@ DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts, if (Lock()) { fPainter->SetDrawData(d); - fPainter->FillPolygon(ptlist, numpts); + BRect touched = fPainter->FillPolygon(ptlist, numpts); - fGraphicsCard->Invalidate(bounds); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -579,16 +579,14 @@ DisplayDriverPainter::FillRegion(BRegion& r, const DrawData *d) fPainter->SetDrawData(d); - BRect invalid = r.RectAt(0); - fPainter->FillRect(invalid); + BRect touched = fPainter->FillRect(r.RectAt(0)); int32 count = r.CountRects(); for (int32 i = 1; i < count; i++) { - fPainter->FillRect(r.RectAt(i)); - invalid = invalid | r.RectAt(i); + touched = touched | fPainter->FillRect(r.RectAt(i)); } - fGraphicsCard->Invalidate(invalid); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -603,9 +601,9 @@ DisplayDriverPainter::FillRoundRect(const BRect &r, if (Lock()) { fPainter->SetDrawData(d); - fPainter->FillRoundRect(r, xrad, yrad); + BRect touched = fPainter->FillRoundRect(r, xrad, yrad); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -634,9 +632,9 @@ DisplayDriverPainter::FillTriangle(BPoint *pts, const BRect &bounds, if (Lock()) { fPainter->SetDrawData(d); - fPainter->FillTriangle(pts[0], pts[1], pts[2]); + BRect touched = fPainter->FillTriangle(pts[0], pts[1], pts[2]); - fGraphicsCard->Invalidate(bounds); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -656,9 +654,9 @@ DisplayDriverPainter::StrokeArc(const BRect &r, const float &angle, BPoint center(r.left + xRadius, r.top + yRadius); - fPainter->StrokeArc(center, xRadius, yRadius, angle, span); + BRect touched = fPainter->StrokeArc(center, xRadius, yRadius, angle, span); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -671,10 +669,9 @@ DisplayDriverPainter::StrokeBezier(BPoint *pts, const DrawData *d) if (Lock()) { fPainter->SetDrawData(d); + BRect touched = fPainter->StrokeBezier(pts); - fPainter->StrokeBezier(pts); - - // TODO: Invalidate + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -693,9 +690,9 @@ DisplayDriverPainter::StrokeEllipse(const BRect &r, const DrawData *d) BPoint center(r.left + xRadius, r.top + yRadius); - fPainter->StrokeEllipse(center, xRadius, yRadius); + BRect touched = fPainter->StrokeEllipse(center, xRadius, yRadius); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -757,9 +754,9 @@ DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts, if (Lock()) { fPainter->SetDrawData(d); - fPainter->StrokePolygon(ptlist, numpts, closed); + BRect touched = fPainter->StrokePolygon(ptlist, numpts, closed); - fGraphicsCard->Invalidate(bounds); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -774,10 +771,14 @@ DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color) if (Lock()) { fPainter->StrokeRect(r, color.GetColor32()); - fGraphicsCard->Invalidate(BRect(r.left, r.top, r.right, r.top)); - fGraphicsCard->Invalidate(BRect(r.left, r.top + 1, r.left, r.bottom - 1)); - fGraphicsCard->Invalidate(BRect(r.right, r.top + 1, r.right, r.bottom - 1)); - fGraphicsCard->Invalidate(BRect(r.left, r.bottom, r.right, r.bottom)); + fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top, + r.right, r.top))); + fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top + 1, + r.left, r.bottom - 1))); + fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.right, r.top + 1, + r.right, r.bottom - 1))); + fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.bottom, + r.right, r.bottom))); Unlock(); } @@ -806,14 +807,14 @@ DisplayDriverPainter::StrokeRegion(BRegion& r, const DrawData *d) fPainter->SetDrawData(d); - BRect invalid = fPainter->StrokeRect(r.RectAt(0)); + BRect touched = fPainter->StrokeRect(r.RectAt(0)); int32 count = r.CountRects(); for (int32 i = 1; i < count; i++) { - invalid = invalid | fPainter->StrokeRect(r.RectAt(i)); + touched = touched | fPainter->StrokeRect(r.RectAt(i)); } - fGraphicsCard->Invalidate(invalid); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -827,9 +828,9 @@ DisplayDriverPainter::StrokeRoundRect(const BRect &r, const float &xrad, if (Lock()) { fPainter->SetDrawData(d); - fPainter->StrokeRoundRect(r, xrad, yrad); + BRect touched = fPainter->StrokeRoundRect(r, xrad, yrad); - fGraphicsCard->Invalidate(r); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -857,9 +858,9 @@ DisplayDriverPainter::StrokeTriangle(BPoint *pts, const BRect &bounds, if (Lock()) { fPainter->SetDrawData(d); - fPainter->StrokeTriangle(pts[0], pts[1], pts[2]); + BRect touched = fPainter->StrokeTriangle(pts[0], pts[1], pts[2]); - fGraphicsCard->Invalidate(bounds); + fGraphicsCard->Invalidate(touched); Unlock(); } @@ -889,8 +890,8 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length, fPainter->SetDrawData(d); - BRect boundingBox = fPainter->DrawString(string, length, pt); - fGraphicsCard->Invalidate(boundingBox); + BRect touched = fPainter->DrawString(string, length, pt); + fGraphicsCard->Invalidate(touched); Unlock(); } diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index fbe2726d0b..be1eba9f3f 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -105,6 +105,7 @@ Painter::AttachToBuffer(RenderingBuffer* buffer) false)); fBaseRenderer = new renderer_base(*fPixelFormat); + // attach our clipping region to the renderer, it keeps a pointer fBaseRenderer->set_clipping_region(fClippingRegion); // These are the AGG renderes and rasterizes which @@ -134,7 +135,6 @@ rgb_color color = fPatternHandler->HighColor().GetColor32(); fFontRendererBin = new font_renderer_bin_type(*fBaseRenderer); _SetRendererColor(fPatternHandler->HighColor().GetColor32()); -// _RebuildClipping(); } } @@ -175,12 +175,12 @@ Painter::ConstrainClipping(const BRegion& region) // an *empty* clipping region. if (!fClippingRegion) { fClippingRegion = new BRegion(region); - // attach the base renderer to our clipping region + // attach the base renderer to our clipping region, + // it keeps a pointer if (fBaseRenderer) fBaseRenderer->set_clipping_region(fClippingRegion); } else *fClippingRegion = region; -// _RebuildClipping(); } // SetHighColor @@ -408,37 +408,37 @@ Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const // #pragma mark - // StrokeTriangle -void +BRect Painter::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3) const { - _DrawTriangle(pt1, pt2, pt3, false); + return _DrawTriangle(pt1, pt2, pt3, false); } // FillTriangle -void +BRect Painter::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3) const { - _DrawTriangle(pt1, pt2, pt3, true); + return _DrawTriangle(pt1, pt2, pt3, true); } // StrokePolygon -void +BRect Painter::StrokePolygon(const BPoint* ptArray, int32 numPts, bool closed) const { - _DrawPolygon(ptArray, numPts, closed, false); + return _DrawPolygon(ptArray, numPts, closed, false); } // FillPolygon -void +BRect Painter::FillPolygon(const BPoint* ptArray, int32 numPts, bool closed) const { - _DrawPolygon(ptArray, numPts, closed, true); + return _DrawPolygon(ptArray, numPts, closed, true); } // StrokeBezier -void +BRect Painter::StrokeBezier(const BPoint* controlPoints) const { agg::path_storage curve; @@ -460,11 +460,11 @@ Painter::StrokeBezier(const BPoint* controlPoints) const agg::conv_curve path(curve); - _StrokePath(path); + return _StrokePath(path); } // FillBezier -void +BRect Painter::FillBezier(const BPoint* controlPoints) const { agg::path_storage curve; @@ -486,21 +486,21 @@ Painter::FillBezier(const BPoint* controlPoints) const agg::conv_curve path(curve); - _FillPath(path); + return _FillPath(path); } // StrokeShape -void +BRect Painter::StrokeShape(/*const */BShape* shape) const { - _DrawShape(shape, false); + return _DrawShape(shape, false); } // FillShape -void +BRect Painter::FillShape(/*const */BShape* shape) const { - _DrawShape(shape, true); + return _DrawShape(shape, true); } // StrokeRect @@ -627,7 +627,7 @@ Painter::FillRect(const BRect& r, const rgb_color& c) const } // StrokeRoundRect -void +BRect Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const { BPoint lt(r.left, r.top); @@ -639,11 +639,11 @@ Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius) const rect.rect(lt.x, lt.y, rb.x, rb.y); rect.radius(xRadius, yRadius); - _StrokePath(rect); + return _StrokePath(rect); } // FillRoundRect -void +BRect Painter::FillRoundRect(const BRect& r, float xRadius, float yRadius) const { BPoint lt(r.left, r.top); @@ -661,25 +661,25 @@ Painter::FillRoundRect(const BRect& r, float xRadius, float yRadius) const rect.rect(lt.x, lt.y, rb.x, rb.y); rect.radius(xRadius, yRadius); - _FillPath(rect); + return _FillPath(rect); } // StrokeEllipse -void +BRect Painter::StrokeEllipse(BPoint center, float xRadius, float yRadius) const { - _DrawEllipse(center, xRadius, yRadius, false); + return _DrawEllipse(center, xRadius, yRadius, false); } // FillEllipse -void +BRect Painter::FillEllipse(BPoint center, float xRadius, float yRadius) const { - _DrawEllipse(center, xRadius, yRadius, true); + return _DrawEllipse(center, xRadius, yRadius, true); } // StrokeArc -void +BRect Painter::StrokeArc(BPoint center, float xRadius, float yRadius, float angle, float span) const { @@ -692,11 +692,11 @@ Painter::StrokeArc(BPoint center, float xRadius, float yRadius, agg::conv_curve path(arc); - _StrokePath(path); + return _StrokePath(path); } // FillArc -void +BRect Painter::FillArc(BPoint center, float xRadius, float yRadius, float angle, float span) const { @@ -726,7 +726,7 @@ Painter::FillArc(BPoint center, float xRadius, float yRadius, path.close_polygon(); - _FillPath(path); + return _FillPath(path); } // #pragma mark - @@ -853,18 +853,20 @@ Painter::DrawBitmap(const ServerBitmap* bitmap, // #pragma mark - // FillRegion -void +BRect Painter::FillRegion(const BRegion* region) const { BRegion copy(*region); int32 count = copy.CountRects(); - for (int32 i = 0; i < count; i++) { - FillRect(copy.RectAt(i)); + BRect touched = FillRect(copy.RectAt(0)); + for (int32 i = 1; i < count; i++) { + touched = touched | FillRect(copy.RectAt(i)); } + return touched; } // InvertRect -void +BRect Painter::InvertRect(const BRect& r) const { BRegion region(r); @@ -876,6 +878,7 @@ Painter::InvertRect(const BRect& r) const for (int32 i = 0; i < count; i++) { _InvertRect32(region.RectAt(i)); } + return _Clipped(r); } // BoundingBox @@ -968,47 +971,6 @@ Painter::_Clipped(const BRect& rect) const return rect; } -// #pragma mark - -/* -// _RebuildClipping -void -Painter::_RebuildClipping() -{ - if (fBaseRenderer) { - fBaseRenderer->reset_clipping(!fClippingRegion); - if (fClippingRegion) { - int32 count = fClippingRegion->CountRects(); - for (int32 i = 0; i < count; i++) { - BRect r = fClippingRegion->RectAt(i); - // NOTE: The rounding here appears to give somewhat - // different results compared to Be's implementation, - // though I was unable to figure out the difference - BPoint lt(r.LeftTop()); - BPoint rb(r.RightBottom()); - // offset to bottom right corner of pixel before transformation - rb += BPoint(1.0, 1.0); - // apply transformation - lt += fOrigin; - lt.x *= fScale; - lt.y *= fScale; - rb += fOrigin; - rb.x *= fScale; - rb.y *= fScale; - // undo offset to bottom right corner after transformation - rb -= BPoint(1.0, 1.0); -// fBaseRenderer->add_clip_box(floorf(lt.x), -// floorf(lt.y), -// ceilf(rb.x), -// ceilf(rb.y)); - fBaseRenderer->add_clip_box(roundf(lt.x), - roundf(lt.y), - roundf(rb.x), - roundf(rb.y)); - } - } - } -}*/ - // _UpdateFont void Painter::_UpdateFont() @@ -1040,7 +1002,7 @@ Painter::_UpdateLineWidth() // #pragma mark - // _DrawTriangle -inline void +inline BRect Painter::_DrawTriangle(BPoint pt1, BPoint pt2, BPoint pt3, bool fill) const { _Transform(&pt1); @@ -1056,13 +1018,13 @@ Painter::_DrawTriangle(BPoint pt1, BPoint pt2, BPoint pt3, bool fill) const path.close_polygon(); if (fill) - _FillPath(path); + return _FillPath(path); else - _StrokePath(path); + return _StrokePath(path); } // _DrawEllipse -inline void +inline BRect Painter::_DrawEllipse(BPoint center, float xRadius, float yRadius, bool fill) const { @@ -1077,13 +1039,13 @@ Painter::_DrawEllipse(BPoint center, float xRadius, float yRadius, agg::ellipse path(center.x, center.y, xRadius, yRadius, divisions); if (fill) - _FillPath(path); + return _FillPath(path); else - _StrokePath(path); + return _StrokePath(path); } // _DrawShape -inline void +inline BRect Painter::_DrawShape(/*const */BShape* shape, bool fill) const { // TODO: untested @@ -1096,13 +1058,13 @@ Painter::_DrawShape(/*const */BShape* shape, bool fill) const converter.Iterate(shape); if (fill) - _FillPath(path); + return _FillPath(path); else - _StrokePath(path); + return _StrokePath(path); } // _DrawPolygon -inline void +inline BRect Painter::_DrawPolygon(const BPoint* ptArray, int32 numPts, bool closed, bool fill) const { @@ -1122,10 +1084,11 @@ Painter::_DrawPolygon(const BPoint* ptArray, int32 numPts, path.close_polygon(); if (fill) - _FillPath(path); + return _FillPath(path); else - _StrokePath(path); + return _StrokePath(path); } + return BRect(0.0, 0.0, -1.0, -1.0); } // _DrawBitmap