xf86-video-intel: src/sna/sna_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jul 24 01:42:18 PDT 2013


 src/sna/sna_dri.c |   39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

New commits:
commit 6d80bd6a7311926f258cd92f0b22e8d03022b62b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 24 09:03:45 2013 +0100

    sna/dri: Cleanup validation of blit extents
    
    Prompted by a suggestion by Haihao, clarify the intent behind checking
    the incoming maximum blit extents against the recorded sizes of the
    attached bo. Due to the asynchronous nature of DRI2 invalidation, it is
    possible for the DRI2 buffer to be stale and for its bo to be smaller
    than required for the client's blit.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=67210
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: haihao <haihao.xiang at intel.com>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 94721ba..1c71fba 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -905,14 +905,15 @@ can_blit(struct sna *sna,
 	 DRI2BufferPtr src)
 {
 	RegionPtr clip;
-	int w, h;
 	uint32_t s;
+	BoxRec extents;
+	int16_t dx, dy;
 
 	if (draw->type == DRAWABLE_PIXMAP)
 		return true;
 
 	if (STRICT_BLIT && dst->attachment == DRI2BufferFrontLeft) {
-		if (get_private(dst)->pixmap != get_drawable_pixmap(draw)) {
+		if (unlikely(get_private(dst)->pixmap != get_drawable_pixmap(draw))) {
 			DBG(("%s: reject as dst pixmap=%ld, but expecting pixmap=%ld\n",
 						__FUNCTION__,
 						get_private(dst)->pixmap ? get_private(dst)->pixmap->drawable.serialNumber : 0,
@@ -927,9 +928,8 @@ can_blit(struct sna *sna,
 	assert(get_private(src)->bo->flush);
 
 	clip = &((WindowPtr)draw)->clipList;
-	w = clip->extents.x2 - draw->x;
-	h = clip->extents.y2 - draw->y;
-	if ((w|h) <= 0) {
+	if (clip->extents.x1 >= clip->extents.x2 ||
+	    clip->extents.y1 >= clip->extents.y2) {
 		DBG(("%s: reject, outside clip (%d, %d), (%d, %d)\n",
 		     __func__,
 		     clip->extents.x1, clip->extents.y1,
@@ -937,17 +937,34 @@ can_blit(struct sna *sna,
 		return false;
 	}
 
+	/* Check the read/write extents against the size of the attachments */
+	extents = clip->extents;
+	if (get_drawable_deltas(draw, get_drawable_pixmap(draw), &dx, &dy)) {
+		extents.x1 += dx; extents.x2 += dx;
+		extents.y1 += dy; extents.y2 += dy;
+	}
+
+	/* This should never happen as the Drawable->Pixmap is local! */
+	if (unlikely(extents.x1 < 0 || extents.y1 < 0)) {
+		DBG(("%s: reject as read/write extents is out of bounds\n",
+		     __FUNCTION__));
+		return false;
+	}
+
+	/* But the dst/src bo may be stale (older than the Drawable) and be
+	 * too small for the blit.
+	 */
 	s = get_private(dst)->size;
-	if ((s>>16) < h || (s&0xffff) < w) {
-		DBG(("%s: reject front size (%dx%d) < (%dx%d)\n", __func__,
-		       s&0xffff, s>>16, w, h));
+	if (unlikely((s>>16) < extents.y2 || (s&0xffff) < extents.x2)) {
+		DBG(("%s: reject as read/write extents is out of bounds\n",
+		     __FUNCTION__));
 		return false;
 	}
 
 	s = get_private(src)->size;
-	if ((s>>16) < h || (s&0xffff) < w) {
-		DBG(("%s:reject back size (%dx%d) < (%dx%d)\n", __func__,
-		     s&0xffff, s>>16, w, h));
+	if (unlikely((s>>16) < extents.y2 || (s&0xffff) < extents.x2)) {
+		DBG(("%s: reject as read/write extents is out of bounds\n",
+		     __FUNCTION__));
 		return false;
 	}
 


More information about the xorg-commit mailing list