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
This commit is contained in:
Stephan Aßmus
2005-04-15 09:55:15 +00:00
parent 94176e0118
commit 3d16cf4bce
3 changed files with 113 additions and 165 deletions
+20 -36
View File
@@ -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;
@@ -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();
}
+51 -88
View File
@@ -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<agg::path_storage> 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<agg::path_storage> 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<agg::bezier_arc> 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