From 1a7fc52717f92fc4631f55810e06ed26bec1db3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 29 Mar 2005 01:43:04 +0000 Subject: [PATCH] added some functions with optimized implementation, optimizes most frequent usage git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12113 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../app/drawing/DisplayDriverPainter.cpp | 18 +- src/servers/app/drawing/Painter/Painter.cpp | 183 ++++++++++++++++-- src/servers/app/drawing/ViewHWInterface.cpp | 2 - 3 files changed, 180 insertions(+), 23 deletions(-) diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index cd8549a445..58a1100a08 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -32,6 +32,11 @@ #include "DisplayDriverPainter.h" +// TODO: fix invalidation, what about pensize, scale, origin? +// Painter calls could return the bounding box arround all +// pixels touched by a drawing operation + + // constructor DisplayDriverPainter::DisplayDriverPainter() : DisplayDriver(), @@ -487,7 +492,8 @@ DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const R if (Lock()) { fPainter->SetHighColor(color); - fPainter->StrokeLine(start, end); + fPainter->SetDrawingMode(B_OP_COPY); + fPainter->StrokeLine(start, end, B_SOLID_HIGH); BRect r(start, end); fGraphicsCard->Invalidate(r); @@ -546,15 +552,19 @@ DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts, } // StrokeRect +// +// this function is used to draw a one pixel wide rect void DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color) { if (Lock()) { - fPainter->SetHighColor(color); - fPainter->StrokeRect(r); + fPainter->StrokeRect(r, color.GetColor32()); - fGraphicsCard->Invalidate(r); + 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)); Unlock(); } diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 897119eda4..99a3259a36 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -289,6 +289,24 @@ Painter::StrokeLine(BPoint a, BPoint b, const pattern& p) _Transform(&a); _Transform(&b); + // first, try an optimized version + float penSize = _Transform(fPenSize); + if (penSize == 1.0 && + (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) { +// TODO: fix me +// pattern p = *fPatternHandler->GetR5Pattern(); + if (p == B_SOLID_HIGH && + StraightLine(a, b, fPatternHandler->HighColor().GetColor32())) { + SetPenLocation(b); + return; + } else if (p == B_SOLID_LOW && + StraightLine(a, b, fPatternHandler->LowColor().GetColor32())) { + SetPenLocation(b); + return; + } + } + + agg::path_storage path; path.move_to(a.x, a.y); path.line_to(b.x, b.y); @@ -306,6 +324,69 @@ Painter::StrokeLine(BPoint b, const pattern& p) StrokeLine(fPenLocation, b); } +// StraightLine +bool +Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const +{ + if (fBuffer) { + if (a.x == b.x) { + // vertical + uint8* dst = fBuffer->row(0); + uint32 bpr = fBuffer->stride(); + int32 x = (int32)a.x; + dst += x * 4; + int32 y1 = (int32)min_c(a.y, b.y); + int32 y2 = (int32)max_c(a.y, b.y); + // draw a line, iterate over clipping boxes + fBaseRenderer->first_clip_box(); + do { + if (fBaseRenderer->xmin() <= x && + fBaseRenderer->xmax() >= x) { + int32 i = max_c(fBaseRenderer->ymin(), y1); + int32 end = min_c(fBaseRenderer->ymax(), y2); + uint8* handle = dst + i * bpr; + for (; i <= end; i++) { + handle[0] = c.blue; + handle[1] = c.green; + handle[2] = c.red; + handle += bpr; + } + } + } while (fBaseRenderer->next_clip_box()); + + return true; + + } else if (a.y == b.y) { + // horizontal + uint8* dst = fBuffer->row(0); + uint32 bpr = fBuffer->stride(); + int32 y = (int32)a.y; + dst += y * bpr; + int32 x1 = (int32)min_c(a.x, b.x); + int32 x2 = (int32)max_c(a.x, b.x); + // draw a line, iterate over clipping boxes + fBaseRenderer->first_clip_box(); + do { + if (fBaseRenderer->ymin() <= y && + fBaseRenderer->ymax() >= y) { + int32 i = max_c(fBaseRenderer->xmin(), x1); + int32 end = min_c(fBaseRenderer->xmax(), x2); + uint8* handle = dst + i * 4; + for (; i <= end; i++) { + handle[0] = c.blue; + handle[1] = c.green; + handle[2] = c.red; + handle += 4; + } + } + } while (fBaseRenderer->next_clip_box()); + + return true; + } + } + return false; +} + // #pragma mark - // StrokeTriangle @@ -409,55 +490,123 @@ void Painter::StrokeRect(const BRect& r, const pattern& p) const { BPoint a(r.left, r.top); - BPoint b(r.right, r.top); - BPoint c(r.right, r.bottom); - BPoint d(r.left, r.bottom); + BPoint b(r.right, r.bottom); _Transform(&a); _Transform(&b); - _Transform(&c); - _Transform(&d); + + // first, try an optimized version + float penSize = _Transform(fPenSize); + if (penSize == 1.0 && + (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) { +// TODO: fix me +// pattern p = *fPatternHandler->GetR5Pattern(); + if (p == B_SOLID_HIGH) { + StrokeRect(BRect(a, b), + fPatternHandler->HighColor().GetColor32()); + return; + } else if (p == B_SOLID_LOW) { + StrokeRect(BRect(a, b), + fPatternHandler->LowColor().GetColor32()); + return; + } + } agg::path_storage path; path.move_to(a.x, a.y); + path.line_to(b.x, a.y); path.line_to(b.x, b.y); - path.line_to(c.x, c.y); - path.line_to(d.x, d.y); + path.line_to(a.x, b.y); path.close_polygon(); _StrokePath(path, p); } +// StrokeRect +void +Painter::StrokeRect(const BRect& r, const rgb_color& c) const +{ + StraightLine(BPoint(r.left, r.top), + BPoint(r.right - 1, r.top), c); + StraightLine(BPoint(r.right, r.top), + BPoint(r.right, r.bottom - 1), c); + StraightLine(BPoint(r.right, r.bottom), + BPoint(r.left + 1, r.bottom), c); + StraightLine(BPoint(r.left, r.bottom), + BPoint(r.left, r.top + 1), c); +} + // FillRect void Painter::FillRect(const BRect& r, const pattern& p) const { BPoint a(r.left, r.top); - BPoint b(r.right, r.top); - BPoint c(r.right, r.bottom); - BPoint d(r.left, r.bottom); + BPoint b(r.right, r.bottom); _Transform(&a, false); _Transform(&b, false); - _Transform(&c, false); - _Transform(&d, false); + + // first, try an optimized version + if (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER) { +// TODO: fix me +// pattern p = *fPatternHandler->GetR5Pattern(); + if (p == B_SOLID_HIGH) { + FillRect(BRect(a, b), fPatternHandler->HighColor().GetColor32()); + return; + } else if (p == B_SOLID_LOW) { + FillRect(BRect(a, b), fPatternHandler->LowColor().GetColor32()); + return; + } + } // account for stricter interpretation of coordinates in AGG // the rectangle ranges from the top-left (.0, .0) // to the bottom-right (.9999, .9999) corner of pixels b.x += 1.0; - c.x += 1.0; - c.y += 1.0; - d.y += 1.0; + b.y += 1.0; agg::path_storage path; path.move_to(a.x, a.y); + path.line_to(b.x, a.y); path.line_to(b.x, b.y); - path.line_to(c.x, c.y); - path.line_to(d.x, d.y); + path.line_to(a.x, b.y); path.close_polygon(); _FillPath(path, p); } +// FillRect +void +Painter::FillRect(const BRect& r, const rgb_color& c) const +{ + if (fBuffer) { + uint8* dst = fBuffer->row(0); + uint32 bpr = fBuffer->stride(); + int32 left = (int32)r.left; + int32 top = (int32)r.top; + int32 right = (int32)r.right; + int32 bottom = (int32)r.bottom; + // fill rects, iterate over clipping boxes + fBaseRenderer->first_clip_box(); + do { + int32 x1 = max_c(fBaseRenderer->xmin(), left); + int32 x2 = min_c(fBaseRenderer->xmax(), right); + if (x1 <= x2) { + int32 y1 = max_c(fBaseRenderer->ymin(), top); + int32 y2 = min_c(fBaseRenderer->ymax(), bottom); + uint8* offset = dst + x1 * 4; + for (; y1 <= y2; y1++) { + uint8* handle = offset + y1 * bpr; + for (int32 x = x1; x <= x2; x++) { + handle[0] = c.blue; + handle[1] = c.green; + handle[2] = c.red; + handle += 4; + } + } + } + } while (fBaseRenderer->next_clip_box()); + } +} + // StrokeRoundRect void Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius, diff --git a/src/servers/app/drawing/ViewHWInterface.cpp b/src/servers/app/drawing/ViewHWInterface.cpp index 0e5e2168a7..e42f164033 100644 --- a/src/servers/app/drawing/ViewHWInterface.cpp +++ b/src/servers/app/drawing/ViewHWInterface.cpp @@ -382,8 +382,6 @@ ViewHWInterface::SetMode(const display_mode &mode) fDisplayMode.virtual_height = mode.virtual_height; fDisplayMode.space = mode.space; -printf("ViewHWInterface::SetMode(%s)\n", string_for_color_space((color_space)fDisplayMode.space)); - BRect frame(0.0, 0.0, fDisplayMode.virtual_width - 1, fDisplayMode.virtual_height - 1);