added fast path to BPicture polygon drawing
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20296 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -133,6 +133,35 @@ ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_polygon_frame(const BPoint *points, int32 numPoints, BRect *_frame)
|
||||||
|
{
|
||||||
|
float l, t, r, b;
|
||||||
|
|
||||||
|
ASSERT(numPoints > 0);
|
||||||
|
|
||||||
|
l = r = points->x;
|
||||||
|
t = b = points->y;
|
||||||
|
|
||||||
|
points++;
|
||||||
|
numPoints--;
|
||||||
|
|
||||||
|
while (numPoints--) {
|
||||||
|
if (points->x < l)
|
||||||
|
l = points->x;
|
||||||
|
if (points->x > r)
|
||||||
|
r = points->x;
|
||||||
|
if (points->y < t)
|
||||||
|
t = points->y;
|
||||||
|
if (points->y > b)
|
||||||
|
b = points->y;
|
||||||
|
points++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_frame->Set(l, t, r, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nop()
|
nop()
|
||||||
{
|
{
|
||||||
@@ -252,58 +281,72 @@ fill_ellipse(ViewLayer *view, BPoint center, BPoint radii)
|
|||||||
static void
|
static void
|
||||||
stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool isClosed)
|
stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool isClosed)
|
||||||
{
|
{
|
||||||
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
|
if (numPoints <= 0) {
|
||||||
if (!points)
|
|
||||||
return;
|
return;
|
||||||
|
} else if (numPoints <= 200) {
|
||||||
|
// fast path: no malloc/free, also avoid constructor/destructor calls
|
||||||
|
char data[200 * sizeof(BPoint)];
|
||||||
|
BPoint *points = (BPoint *)data;
|
||||||
|
|
||||||
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
||||||
|
|
||||||
BRect polyFrame = BRect(points[0], points[0]);
|
BRect polyFrame;
|
||||||
|
get_polygon_frame(points, numPoints, &polyFrame);
|
||||||
|
|
||||||
for (int32 i = 1; i < numPoints; i++) {
|
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
|
||||||
if (points[i].x < polyFrame.left)
|
view->CurrentState(), false,
|
||||||
polyFrame.left = points[i].x;
|
isClosed && numPoints > 2);
|
||||||
if (points[i].y < polyFrame.top)
|
} else {
|
||||||
polyFrame.top = points[i].y;
|
// avoid constructor/destructor calls by using malloc instead of new []
|
||||||
if (points[i].x > polyFrame.right)
|
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
|
||||||
polyFrame.right = points[i].x;
|
if (!points)
|
||||||
if (points[i].y > polyFrame.bottom)
|
return;
|
||||||
polyFrame.bottom = points[i].y;
|
|
||||||
|
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
||||||
|
|
||||||
|
BRect polyFrame;
|
||||||
|
get_polygon_frame(points, numPoints, &polyFrame);
|
||||||
|
|
||||||
|
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
|
||||||
|
view->CurrentState(), false,
|
||||||
|
isClosed && numPoints > 2);
|
||||||
|
free(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->CurrentState(),
|
|
||||||
false, isClosed && numPoints > 2);
|
|
||||||
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints)
|
fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints)
|
||||||
{
|
{
|
||||||
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
|
if (numPoints <= 0) {
|
||||||
if (!points)
|
|
||||||
return;
|
return;
|
||||||
|
} else if (numPoints <= 200) {
|
||||||
|
// fast path: no malloc/free, also avoid constructor/destructor calls
|
||||||
|
char data[200 * sizeof(BPoint)];
|
||||||
|
BPoint *points = (BPoint *)data;
|
||||||
|
|
||||||
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
||||||
|
|
||||||
BRect polyFrame = BRect(points[0], points[0]);
|
BRect polyFrame;
|
||||||
|
get_polygon_frame(points, numPoints, &polyFrame);
|
||||||
|
|
||||||
for (int32 i = 1; i < numPoints; i++) {
|
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
|
||||||
if (points[i].x < polyFrame.left)
|
view->CurrentState(), true, true);
|
||||||
polyFrame.left = points[i].x;
|
} else {
|
||||||
if (points[i].y < polyFrame.top)
|
// avoid constructor/destructor calls by using malloc instead of new []
|
||||||
polyFrame.top = points[i].y;
|
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
|
||||||
if (points[i].x > polyFrame.right)
|
if (!points)
|
||||||
polyFrame.right = points[i].x;
|
return;
|
||||||
if (points[i].y > polyFrame.bottom)
|
|
||||||
polyFrame.bottom = points[i].y;
|
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
|
||||||
|
|
||||||
|
BRect polyFrame;
|
||||||
|
get_polygon_frame(points, numPoints, &polyFrame);
|
||||||
|
|
||||||
|
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
|
||||||
|
view->CurrentState(), true, true);
|
||||||
|
free(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->CurrentState(),
|
|
||||||
true, true);
|
|
||||||
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user