xf86-video-intel: src/sna/sna_accel.c src/sna/sna_composite.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Jul 9 07:00:37 PDT 2011


 src/sna/sna_accel.c     |   75 +++++++++++++++++++++++++++++++-----------------
 src/sna/sna_composite.c |   12 ++++++-
 2 files changed, 59 insertions(+), 28 deletions(-)

New commits:
commit 9f22ea7ca440c788f8104647356393c96c62d155
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jul 9 14:54:33 2011 +0100

    sna: Clamp results for computing BoxRec coords from xRectangle
    
    As the width/height in the rectangle is specified as uint16_t, the
    result may be larger than is storagable in the int16_t of the box. Of
    course it would take a really inane client to do attempt to draw
    something much larger than the largest possible surface... Is it strange
    that first example I've found to do so is a Java application?
    
    Reported-by: Nicolas Kalkhof <nkalkhof at web.de>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1cd1a2e..409b20d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -869,17 +869,29 @@ static inline void box_add_pt(BoxPtr box, int16_t x, int16_t y)
 		box->y2 = y;
 }
 
+static int16_t bound(int16_t a, uint16_t b)
+{
+	int v = (int)a + (int)b;
+	if (v > MAXSHORT)
+		return MAXSHORT;
+	return v;
+}
+
 static inline void box_add_rect(BoxPtr box, const xRectangle *r)
 {
+	int v;
+
 	if (box->x1 > r->x)
 		box->x1 = r->x;
-	if (box->x2 < r->x + r->width)
-		box->x2 = r->x + r->width;
+	v = bound(r->x, r->width);
+	if (box->x2 < v)
+		box->x2 = v;
 
 	if (box->y1 > r->y)
 		box->y1 = r->y;
-	if (box->y2 < r->y + r->height)
-		box->y2 = r->y + r->height;
+	v =bound(r->y, r->height);
+	if (box->y2 < v)
+		box->y2 = v;
 }
 
 static inline bool box_empty(const BoxRec *box)
@@ -1037,6 +1049,8 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 		return;
 
 	if (priv == NULL) {
+		DBG(("%s: fbPutImage, unattached(%d, %d, %d, %d)\n",
+		     __FUNCTION__, x, y, w, h));
 		fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits);
 		return;
 	}
@@ -2286,25 +2300,28 @@ sna_poly_arc_extents(DrawablePtr drawable, GCPtr gc,
 {
 	int extra = gc->lineWidth >> 1;
 	BoxRec box;
+	int v;
 
 	if (n == 0)
 		return true;
 
 	box.x1 = arc->x;
-	box.x2 = box.x1 + arc->width;
+	box.x2 = bound(box.x1, arc->width);
 	box.y1 = arc->y;
-	box.y2 = box.y1 + arc->height;
+	box.y2 = bound(box.y1, arc->height);
 
 	while (--n) {
 		arc++;
 		if (box.x1 > arc->x)
 			box.x1 = arc->x;
-		if (box.x2 < arc->x + arc->width)
-			box.x2 = arc->x + arc->width;
+		v = bound(arc->x, arc->width);
+		if (box.x2 < v)
+			box.x2 = v;
 		if (box.y1 > arc->y)
 			box.y1 = arc->y;
-		if (box.y2 < arc->y + arc->height)
-			box.y2 = arc->y + arc->height;
+		v = bound(arc->y, arc->height);
+		if (box.y2 < v)
+			box.y2 = v;
 	}
 
 	if (extra) {
@@ -2377,8 +2394,8 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 
 			r.x1 = rect->x + drawable->x;
 			r.y1 = rect->y + drawable->y;
-			r.x2 = r.x1 + rect->width;
-			r.y2 = r.y1 + rect->height;
+			r.x2 = bound(r.x1, rect->width);
+			r.y2 = bound(r.y1, rect->height);
 			rect++;
 
 			if (box_intersect(&r, box)) {
@@ -2403,8 +2420,8 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 
 			r.x1 = rect->x + drawable->x;
 			r.y1 = rect->y + drawable->y;
-			r.x2 = r.x1 + rect->width;
-			r.y2 = r.y1 + rect->height;
+			r.x2 = bound(r.x1, rect->width);
+			r.y2 = bound(r.y1, rect->height);
 			rect++;
 
 			RegionInit(&region, &r, 1);
@@ -2485,8 +2502,8 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 
 				r.x1 = rect->x + drawable->x;
 				r.y1 = rect->y + drawable->y;
-				r.x2 = r.x1 + rect->width;
-				r.y2 = r.y1 + rect->height;
+				r.x2 = bound(r.x1, rect->width);
+				r.y2 = bound(r.y1, rect->height);
 				rect++;
 
 				if (box_intersect(&r, box)) {
@@ -2511,8 +2528,8 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 
 				r.x1 = rect->x + drawable->x;
 				r.y1 = rect->y + drawable->y;
-				r.x2 = r.x1 + rect->width;
-				r.y2 = r.y1 + rect->height;
+				r.x2 = bound(r.x1, rect->width);
+				r.y2 = bound(r.y1, rect->height);
 				rect++;
 
 				RegionInit(&region, &r, 1);
@@ -2561,8 +2578,8 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 
 				r.x1 = rect->x + drawable->x;
 				r.y1 = rect->y + drawable->y;
-				r.x2 = r.x1 + rect->width;
-				r.y2 = r.y1 + rect->height;
+				r.x2 = bound(r.x1, rect->width);
+				r.y2 = bound(r.y1, rect->height);
 				rect++;
 
 				if (box_intersect(&r, box)) {
@@ -2614,8 +2631,8 @@ sna_poly_fill_rect_tiled(DrawablePtr drawable,
 
 				r.x1 = rect->x + drawable->x;
 				r.y1 = rect->y + drawable->y;
-				r.x2 = r.x1 + rect->width;
-				r.y2 = r.y1 + rect->height;
+				r.x2 = bound(r.x1, rect->width);
+				r.y2 = bound(r.y1, rect->height);
 				rect++;
 
 				RegionInit(&region, &r, 1);
@@ -2685,10 +2702,12 @@ sna_poly_fill_rect_extents(DrawablePtr drawable, GCPtr gc,
 	if (n == 0)
 		return true;
 
+	DBG(("%s: [0] = (%d, %d)x(%d, %d)\n",
+	     __FUNCTION__, rect->x, rect->y, rect->width, rect->height));
 	box.x1 = rect->x;
-	box.x2 = box.x1 + rect->width;
+	box.x2 = bound(box.x1, rect->width);
 	box.y1 = rect->y;
-	box.y2 = box.y1 + rect->height;
+	box.y2 = bound(box.y1, rect->height);
 
 	while (--n) {
 		rect++;
@@ -2714,8 +2733,10 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 	     gc->fillStyle, gc->tileIsPixel,
 	     gc->alu));
 
-	if (sna_poly_fill_rect_extents(draw, gc, n, rect, &extents))
+	if (sna_poly_fill_rect_extents(draw, gc, n, rect, &extents)) {
+		DBG(("%s, nothing to do\n", __FUNCTION__));
 		return;
+	}
 
 	if (sna->kgem.wedged) {
 		DBG(("%s: fallback -- wedged\n", __FUNCTION__));
@@ -2772,8 +2793,10 @@ fallback:
 	RegionInit(&region, &extents, 1);
 	if (gc->pCompositeClip)
 		RegionIntersect(&region, &region, gc->pCompositeClip);
-	if (!RegionNotEmpty(&region))
+	if (!RegionNotEmpty(&region)) {
+		DBG(("%s: nothing to do, all clipped\n", __FUNCTION__));
 		return;
+	}
 
 	sna_gc_move_to_cpu(gc);
 	sna_drawable_move_region_to_cpu(draw, &region, true);
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 761016a..9c623fd 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -488,6 +488,14 @@ fallback:
 		    width, height);
 }
 
+static int16_t bound(int16_t a, uint16_t b)
+{
+	int v = (int)a + (int)b;
+	if (v > MAXSHORT)
+		return MAXSHORT;
+	return v;
+}
+
 static Bool
 _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
 				       int num_rects, xRectangle *rects,
@@ -513,12 +521,12 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
 		if (boxes[j].y1 < 0)
 			boxes[j].y1 = 0;
 
-		boxes[j].x2 = rects[i].x + rects[i].width;
+		boxes[j].x2 = bound(rects[i].x, rects[i].width);
 		if (boxes[j].x2 > maxx)
 			boxes[j].x2 = maxx;
 		boxes[j].x2 += tx;
 
-		boxes[j].y2 = rects[i].y + rects[i].height;
+		boxes[j].y2 = bound(rects[i].y, rects[i].height);
 		if (boxes[j].y2 > maxy)
 			boxes[j].y2 = maxy;
 		boxes[j].y2 += ty;


More information about the xorg-commit mailing list