summaryrefslogtreecommitdiff
path: root/glamor/glamor_polylines.c
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@gmail.com>2011-07-01 23:51:42 +0800
committerZhigang Gong <zhigang.gong@linux.intel.com>2011-09-26 16:46:36 +0800
commitfc23334e54b0b90d2f00b017a03cf47b70dc71aa (patch)
tree510016762a2ad775bed9d83b5c16658f6c43f66c /glamor/glamor_polylines.c
parentda66a76f276eccee90855bc0cb28092c3755ed7b (diff)
glamor: Optimize fallback case for the polylines.
When fallback to cpu for the polylines procedure, we can just download required region to CPU rather than to download the whole pixmap. This significant improve the performance if we have to fallback, for example do non-solid filling in the game Mines. Signed-off-by: Zhigang Gong <zhigang.gong@gmail.com>
Diffstat (limited to 'glamor/glamor_polylines.c')
-rw-r--r--glamor/glamor_polylines.c73
1 files changed, 67 insertions, 6 deletions
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
index 914961161..3fdb26426 100644
--- a/glamor/glamor_polylines.c
+++ b/glamor/glamor_polylines.c
@@ -49,6 +49,13 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
xRectangle *rects;
int x1, x2, y1, y2;
int i;
+ int x_min = MAXSHORT;
+ int x_max = MINSHORT;
+ int y_min = MAXSHORT;
+ int y_max = MINSHORT;
+ DrawablePtr temp_dest;
+ PixmapPtr temp_pixmap;
+ GCPtr temp_gc;
/* Don't try to do wide lines or non-solid fill style. */
if (gc->lineWidth != 0) {
/* This ends up in miSetSpans, which is accelerated as well as we
@@ -103,16 +110,70 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
return;
fail:
+ for(i = 0; i < n; i++)
+ {
+ if (x_min > points[i].x)
+ x_min = points[i].x;
+ if (x_max < points[i].x)
+ x_max = points[i].x;
+
+ if (y_min > points[i].y)
+ y_min = points[i].y;
+ if (y_max < points[i].y)
+ y_max = points[i].y;
+ }
+
+ temp_pixmap = drawable->pScreen->CreatePixmap(drawable->pScreen,
+ x_max - x_min + 1, y_max - y_min + 1,
+ drawable->depth,
+ 0);
+ if (temp_pixmap) {
+ temp_dest = &temp_pixmap->drawable;
+ temp_gc = GetScratchGC(temp_dest->depth, temp_dest->pScreen);
+ ValidateGC(temp_dest, temp_gc);
+ for(i = 0; i < n; i++)
+ {
+ points[i].x -= x_min;
+ points[i].y -= y_min;
+ }
+ (void)glamor_copy_area(drawable,
+ temp_dest,
+ temp_gc,
+ x_min, y_min,
+ x_max - x_min + 1, y_max - y_min + 1,
+ 0, 0);
+
+ }
+ else
+ temp_dest = drawable;
+
if (gc->lineWidth == 0) {
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+ if (glamor_prepare_access(temp_dest, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
- fbPolyLine(drawable, gc, mode, n, points);
+ fbPolyLine(temp_dest, gc, mode, n, points);
glamor_finish_access_gc(gc);
}
- glamor_finish_access(drawable);
+ glamor_finish_access(temp_dest);
}
- return;
- }
+ }
+ else {
/* fb calls mi functions in the lineWidth != 0 case. */
- fbPolyLine(drawable, gc, mode, n, points);
+ fbPolyLine(drawable, gc, mode, n, points);
+ }
+ if (temp_dest != drawable) {
+ (void)glamor_copy_area(temp_dest,
+ drawable,
+ temp_gc,
+ 0, 0,
+ x_max - x_min + 1, y_max - y_min + 1,
+ x_min, y_min);
+ drawable->pScreen->DestroyPixmap(temp_pixmap);
+ for(i = 0; i < n; i++)
+ {
+ points[i].x += x_min;
+ points[i].y += y_min;
+ }
+
+ FreeScratchGC(temp_gc);
+ }
}