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(®ion, &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(®ion, &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(®ion, &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(®ion, &extents, 1);
if (gc->pCompositeClip)
RegionIntersect(®ion, ®ion, gc->pCompositeClip);
- if (!RegionNotEmpty(®ion))
+ if (!RegionNotEmpty(®ion)) {
+ DBG(("%s: nothing to do, all clipped\n", __FUNCTION__));
return;
+ }
sna_gc_move_to_cpu(gc);
sna_drawable_move_region_to_cpu(draw, ®ion, 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