xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna.h src/sna/sna_video.c src/sna/sna_video.h src/sna/sna_video_overlay.c src/sna/sna_video_sprite.c src/sna/sna_video_textured.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Aug 16 13:33:17 PDT 2013


 src/sna/sna.h                |    5 ++
 src/sna/sna_accel.c          |    5 --
 src/sna/sna_video.c          |   56 ++++++++++++++++++++++---------
 src/sna/sna_video.h          |   34 ++++++++++++++++--
 src/sna/sna_video_overlay.c  |   55 +++++++++++++++++++++++-------
 src/sna/sna_video_sprite.c   |   77 +++++++++++++++++++++++++++++++------------
 src/sna/sna_video_textured.c |    8 +++-
 7 files changed, 179 insertions(+), 61 deletions(-)

New commits:
commit 85e89f2121bad96d34ff8df9456e2fbaa9ff7881
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 16 21:11:33 2013 +0100

    sna/video: YUV420 is not supported by sprites, replace it with a RGB passthrough
    
    As YUV420 is not supported by any of the current sprite implementations
    drop it. Instead implement some RGB passthroughs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 833e6f2..2f4a7e4 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -226,26 +226,50 @@ sna_video_frame_init(struct sna_video *video,
 		}
 		frame->size *= frame->pitch[0] + frame->pitch[1];
 	} else {
-		if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-			frame->pitch[0] = ALIGN((height << 1), align);
-			frame->size = (int)frame->pitch[0] * width;
-		} else {
-			frame->pitch[0] = ALIGN((width << 1), align);
-			frame->size = (int)frame->pitch[0] * height;
+		switch (frame->id) {
+		case FOURCC_RGB888:
+			if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+				frame->pitch[0] = ALIGN((height << 2), align);
+				frame->size = (int)frame->pitch[0] * width;
+			} else {
+				frame->pitch[0] = ALIGN((width << 2), align);
+				frame->size = (int)frame->pitch[0] * height;
+			}
+			frame->UBufOffset = frame->VBufOffset = 0;
+			break;
+		case FOURCC_RGB565:
+			if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+				frame->pitch[0] = ALIGN((height << 1), align);
+				frame->size = (int)frame->pitch[0] * width;
+			} else {
+				frame->pitch[0] = ALIGN((width << 1), align);
+				frame->size = (int)frame->pitch[0] * height;
+			}
+			frame->UBufOffset = frame->VBufOffset = 0;
+			break;
+
+		default:
+			if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+				frame->pitch[0] = ALIGN((height << 1), align);
+				frame->size = (int)frame->pitch[0] * width;
+			} else {
+				frame->pitch[0] = ALIGN((width << 1), align);
+				frame->size = (int)frame->pitch[0] * height;
+			}
+			if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+				frame->UBufOffset = (int)frame->pitch[1] * width;
+				frame->VBufOffset =
+					frame->UBufOffset + (int)frame->pitch[0] * width / 2;
+			} else {
+				frame->UBufOffset = (int)frame->pitch[1] * height;
+				frame->VBufOffset =
+					frame->UBufOffset + (int)frame->pitch[0] * height / 2;
+			}
+			break;
 		}
 		frame->pitch[1] = 0;
 	}
 
-	if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-		frame->UBufOffset = (int)frame->pitch[1] * width;
-		frame->VBufOffset =
-			frame->UBufOffset + (int)frame->pitch[0] * width / 2;
-	} else {
-		frame->UBufOffset = (int)frame->pitch[1] * height;
-		frame->VBufOffset =
-			frame->UBufOffset + (int)frame->pitch[0] * height / 2;
-	}
-
 	assert(frame->size);
 }
 
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index f0ad28f..f3978f8 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -35,6 +35,10 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define SNA_XVMC 1
 #endif
 
+#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
+#define FOURCC_RGB565 ((16 << 24) + ('B' << 16) + ('G' << 8) + 'R')
+#define FOURCC_RGB888 ((24 << 24) + ('B' << 16) + ('G' << 8) + 'R')
+
 /*
  * Below, a dummy picture type that is used in XvPutImage
  * only to do an overlay update.
@@ -49,6 +53,22 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 	XvTopToBottom \
 }
 
+#define XVMC_RGB565 { \
+	FOURCC_RGB565, XvRGB, LSBFirst, \
+	{'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '1', '6'}, \
+	16, XvPacked, 1, 16, 0x1f<<11, 0x3f<<5, 0x1f<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	{'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+	XvTopToBottom \
+}
+
+#define XVMC_RGB888 { \
+	FOURCC_RGB888, XvRGB, LSBFirst, \
+	{'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '2', '4'}, \
+	32, XvPacked, 1, 24, 0xff<<16, 0xff<<8, 0xff<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	{'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+	XvTopToBottom \
+}
+
 struct sna_video {
 	struct sna *sna;
 
@@ -116,11 +136,16 @@ int sna_xv_fixup_formats(ScreenPtr screen,
 int sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out);
 int sna_xv_free_port(XvPortPtr port);
 
-#define FOURCC_XVMC     (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
-
 static inline int xvmc_passthrough(int id)
 {
-	return id == FOURCC_XVMC;
+	switch (id) {
+	case FOURCC_XVMC:
+	case FOURCC_RGB565:
+	case FOURCC_RGB888:
+		return true;
+	default:
+		return false;
+	}
 }
 
 static inline int is_planar_fourcc(int id)
@@ -130,8 +155,6 @@ static inline int is_planar_fourcc(int id)
 	case FOURCC_I420:
 	case FOURCC_XVMC:
 		return 1;
-	case FOURCC_UYVY:
-	case FOURCC_YUY2:
 	default:
 		return 0;
 	}
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 434d11f..7a5b5db 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -600,6 +600,7 @@ sna_video_overlay_query(ClientPtr client,
 			int *offsets)
 {
 	struct sna_video *video = port->devPriv.ptr;
+	struct sna_video_frame frame;
 	struct sna *sna = video->sna;
 	int size, tmp;
 
@@ -624,9 +625,17 @@ sna_video_overlay_query(ClientPtr client,
 	switch (format->id) {
 	case FOURCC_XVMC:
 		*h = (*h + 1) & ~1;
+		sna_video_frame_init(video, format->id, *w, *h, &frame);
 		size = sizeof(uint32_t);
-		if (pitches)
-			pitches[0] = size;
+		if (pitches) {
+			pitches[0] = frame.pitch[1];
+			pitches[1] = frame.pitch[0];
+			pitches[2] = frame.pitch[0];
+		}
+		if (offsets) {
+			offsets[1] = frame.UBufOffset;
+			offsets[2] = frame.VBufOffset;
+		}
 		break;
 
 		/* IA44 is for XvMC only */
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index a20e9b9..221ba79 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -51,7 +51,7 @@
 static Atom xvColorKey, xvAlwaysOnTop;
 
 static XvFormatRec formats[] = { {15}, {16}, {24} };
-static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV };
+static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, XVMC_RGB565 };
 static const XvAttributeRec attribs[] = {
 	{ XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" },
 };
@@ -232,7 +232,17 @@ sna_video_sprite_show(struct sna *sna,
 		uint32_t offsets[4], pitches[4], handles[4];
 		uint32_t pixel_format;
 
+		handles[0] = frame->bo->handle;
+		pitches[0] = frame->pitch[0];
+		offsets[0] = 0;
+
 		switch (frame->id) {
+		case FOURCC_RGB565:
+			pixel_format = DRM_FORMAT_RGB565;
+			break;
+		case FOURCC_RGB888:
+			pixel_format = DRM_FORMAT_XRGB8888;
+			break;
 		case FOURCC_UYVY:
 			pixel_format = DRM_FORMAT_UYVY;
 			break;
@@ -242,13 +252,9 @@ sna_video_sprite_show(struct sna *sna,
 			break;
 		}
 
-		handles[0] = frame->bo->handle;
-		pitches[0] = frame->pitch[0];
-		offsets[0] = 0;
-
 		DBG(("%s: creating new fb for handle=%d, width=%d, height=%d, stride=%d\n",
 		     __FUNCTION__, frame->bo->handle,
-		     frame->width, frame->height, frame->pitch[0]));
+		     frame->width, frame->height, pitches[0]));
 
 		if (drmModeAddFB2(sna->kgem.fd,
 				  frame->width, frame->height, pixel_format,
@@ -420,6 +426,8 @@ static int sna_video_sprite_query(ClientPtr client,
 				  int *pitches,
 				  int *offsets)
 {
+	struct sna_video *video = port->devPriv.ptr;
+	struct sna_video_frame frame;
 	int size;
 
 	if (*w > IMAGE_MAX_WIDTH)
@@ -427,20 +435,22 @@ static int sna_video_sprite_query(ClientPtr client,
 	if (*h > IMAGE_MAX_HEIGHT)
 		*h = IMAGE_MAX_HEIGHT;
 
-	*w = (*w + 1) & ~1;
 	if (offsets)
 		offsets[0] = 0;
 
 	switch (format->id) {
-	case FOURCC_XVMC:
-		*h = (*h + 1) & ~1;
-		size = sizeof(uint32_t);
+	case FOURCC_RGB888:
+	case FOURCC_RGB565:
+		sna_video_frame_init(video, format->id, *w, *h, &frame);
 		if (pitches)
-			pitches[0] = size;
+			pitches[0] = frame.pitch[0];
+		size = 4;
 		break;
 
-	case FOURCC_YUY2:
 	default:
+		*w = (*w + 1) & ~1;
+		*h = (*h + 1) & ~1;
+
 		size = *w << 1;
 		if (pitches)
 			pitches[0] = size;
@@ -518,8 +528,11 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 						 ARRAY_SIZE(formats));
 	adaptor->nAttributes = ARRAY_SIZE(attribs);
 	adaptor->pAttributes = (XvAttributeRec *)attribs;
-	adaptor->nImages = ARRAY_SIZE(images);
 	adaptor->pImages = (XvImageRec *)images;
+	adaptor->nImages = 3;
+	if (sna->kgem.gen == 071)
+		adaptor->nImages = 4;
+
 	adaptor->ddAllocatePort = sna_xv_alloc_port;
 	adaptor->ddFreePort = sna_xv_free_port;
 	adaptor->ddPutVideo = NULL;
commit c610d37dae7e025027fd09a6889bf94853af8b8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 16 18:22:45 2013 +0100

    sna/video: Expose an attribute to keep the overlay always on top
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index b5613bd..14b3c14 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -548,6 +548,11 @@ inline static int16_t clamp(int16_t a, int16_t b)
 	return v;
 }
 
+static inline bool box_empty(const BoxRec *box)
+{
+	return box->x2 <= box->x1 || box->y2 <= box->y1;
+}
+
 static inline bool
 box_inplace(PixmapPtr pixmap, const BoxRec *box)
 {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c54c254..8409d5e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2217,11 +2217,6 @@ static inline bool region_inplace(struct sna *sna,
 		>= sna->kgem.half_cpu_cache_pages;
 }
 
-static inline bool box_empty(const BoxRec *box)
-{
-	return box->x2 <= box->x1 || box->y2 <= box->y1;
-}
-
 bool
 sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				RegionPtr region,
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index 593a8cc..f0ad28f 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -80,6 +80,7 @@ struct sna_video {
 	int plane;
 
 	int SyncToVblank;	/* -1: auto, 0: off, 1: on */
+	int AlwaysOnTop;
 };
 
 struct sna_video_frame {
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index cfdc83d..434d11f 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -43,9 +43,8 @@
 
 #define HAS_GAMMA(sna) ((sna)->kgem.gen >= 030)
 
-static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe;
+static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvAlwaysOnTop;
 static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
-static Atom xvSyncToVblank;
 
 /* Limits for the overlay/textured video source sizes.  The documented hardware
  * limits are 2048x2048 or better for overlay and both of our textured video
@@ -116,6 +115,9 @@ static bool sna_video_overlay_update_attrs(struct sna_video *video)
 	attrs.gamma4 = video->gamma4;
 	attrs.gamma5 = video->gamma5;
 
+	if (video->AlwaysOnTop)
+		attrs.flags |= 1<<2;
+
 	return drmIoctl(video->sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0;
 }
 
@@ -150,6 +152,7 @@ sna_video_overlay_set_attribute(ClientPtr client,
 	struct sna_video *video = port->devPriv.ptr;
 	struct sna *sna = video->sna;
 
+	DBG(("%s: set(%lx) to %d\n", __FUNCTION__, (long)attribute, (int)value));
 	if (attribute == xvBrightness) {
 		if ((value < -128) || (value > 127))
 			return BadValue;
@@ -176,6 +179,10 @@ sna_video_overlay_set_attribute(ClientPtr client,
 			video->desired_crtc = NULL;
 		else
 			video->desired_crtc = xf86_config->crtc[value];
+	} else if (attribute == xvAlwaysOnTop) {
+		DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__,
+		     video->AlwaysOnTop, !!value));
+		video->AlwaysOnTop = !!value;
 	} else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
 		video->gamma0 = value;
 	} else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
@@ -236,6 +243,8 @@ sna_video_overlay_get_attribute(ClientPtr client,
 		if (c == xf86_config->num_crtc)
 			c = -1;
 		*value = c;
+	} else if (attribute == xvAlwaysOnTop) {
+		*value = video->AlwaysOnTop;
 	} else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
 		*value = video->gamma0;
 	} else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
@@ -250,8 +259,6 @@ sna_video_overlay_get_attribute(ClientPtr client,
 		*value = video->gamma5;
 	} else if (attribute == xvColorKey) {
 		*value = video->color_key;
-	} else if (attribute == xvSyncToVblank) {
-		*value = video->SyncToVblank;
 	} else
 		return BadMatch;
 
@@ -483,8 +490,10 @@ sna_video_overlay_put_image(ClientPtr client,
 	clip.extents.y2 = clip.extents.y1 + drw_h;
 	clip.data = NULL;
 
-	RegionIntersect(&clip, &clip, gc->pCompositeClip);
-	if (!RegionNotEmpty(&clip))
+	DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
+	if (!video->AlwaysOnTop)
+		RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	if (box_empty(&clip.extents))
 		goto invisible;
 
 	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
@@ -550,11 +559,15 @@ sna_video_overlay_put_image(ClientPtr client,
 	ret = Success;
 	if (sna_video_overlay_show
 	    (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) {
-		if (!RegionEqual(&video->clip, &clip)) {
+		//xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+		if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) &&
+		    sna_blt_fill_boxes(sna, GXcopy,
+				       __sna_pixmap_get_bo(sna->front),
+				       sna->front->drawable.bitsPerPixel,
+				       video->color_key,
+				       RegionRects(&clip),
+				       RegionNumRects(&clip)))
 			RegionCopy(&video->clip, &clip);
-			xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
-		}
-
 		sna_window_set_port((WindowPtr)draw, port);
 	} else {
 		DBG(("%s: failed to show video frame\n", __FUNCTION__));
@@ -791,6 +804,7 @@ void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen)
 
 	/* Allow the pipe to be switched from pipe A to B when in clone mode */
 	xvPipe = MAKE_ATOM("XV_PIPE");
+	xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
 
 	if (HAS_GAMMA(sna)) {
 		xvGamma0 = MAKE_ATOM("XV_GAMMA0");
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index cab2cda..a20e9b9 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -48,7 +48,7 @@
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true)
 
-static Atom xvColorKey;
+static Atom xvColorKey, xvAlwaysOnTop;
 
 static XvFormatRec formats[] = { {15}, {16}, {24} };
 static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV };
@@ -88,6 +88,10 @@ static int sna_video_sprite_set_attr(ClientPtr client,
 		video->color_key_changed = true;
 		video->color_key = value;
 		DBG(("COLORKEY = %ld\n", (long)value));
+	} else if (attribute == xvAlwaysOnTop) {
+		DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__,
+		     video->AlwaysOnTop, !!value));
+		video->AlwaysOnTop = !!value;
 	} else
 		return BadMatch;
 
@@ -103,6 +107,8 @@ static int sna_video_sprite_get_attr(ClientPtr client,
 
 	if (attribute == xvColorKey)
 		*value = video->color_key;
+	else if (attribute == xvAlwaysOnTop)
+		*value = video->AlwaysOnTop;
 	else
 		return BadMatch;
 
@@ -208,6 +214,9 @@ sna_video_sprite_show(struct sna *sna,
 
 		set.plane_id = s.plane_id;
 		set.value = video->color_key;
+		set.flags = 0;
+		if (!video->AlwaysOnTop)
+			set.flags = I915_SET_COLORKEY_DESTINATION;
 
 		if (drmIoctl(sna->kgem.fd,
 			     DRM_IOCTL_I915_SET_SPRITE_DESTKEY,
@@ -310,8 +319,10 @@ static int sna_video_sprite_put_image(ClientPtr client,
 	clip.extents.y2 = clip.extents.y1 + drw_h;
 	clip.data = NULL;
 
-	RegionIntersect(&clip, &clip, gc->pCompositeClip);
-	if (!RegionNotEmpty(&clip))
+	DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
+	if (!video->AlwaysOnTop)
+		RegionIntersect(&clip, &clip, gc->pCompositeClip);
+	if (box_empty(&clip.extents))
 		goto invisible;
 
 	DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
@@ -377,10 +388,14 @@ static int sna_video_sprite_put_image(ClientPtr client,
 		DBG(("%s: failed to show video frame\n", __FUNCTION__));
 		ret = BadAlloc;
 	} else {
-		if (!RegionEqual(&video->clip, &clip)) {
-			RegionCopy(&video->clip, &clip);
-			xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
-		}
+		//xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+		if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) &&
+		    sna_blt_fill_boxes(sna, GXcopy,
+				       __sna_pixmap_get_bo(sna->front),
+				       sna->front->drawable.bitsPerPixel,
+				       video->color_key,
+				       RegionRects(&clip),
+				       RegionNumRects(&clip)))
 		sna_window_set_port((WindowPtr)draw, port);
 	}
 
@@ -549,6 +564,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
 	RegionNull(&video->clip);
 
 	xvColorKey = MAKE_ATOM("XV_COLORKEY");
+	xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
 }
 #else
 void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
commit 7a6bd55da90382459db072bffbd4aa36d18f9a17
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 16 15:38:18 2013 +0100

    sna/video: Don't assert on a client error, return BadAlloc
    
    If the client sends a BO that is too small to satifsy the PutImage, then
    reject with BadAlloc rather than die with an assert.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index a68a173..cfdc83d 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -523,7 +523,13 @@ sna_video_overlay_put_image(ClientPtr client,
 			return BadAlloc;
 		}
 
-		assert(kgem_bo_size(frame.bo) >= frame.size);
+		if (kgem_bo_size(frame.bo) < frame.size) {
+			DBG(("%s: bo size=%d, expected=%d\n",
+			     __FUNCTION__, kgem_bo_size(frame.bo), frame.size));
+			kgem_bo_destroy(&sna->kgem, frame.bo);
+			return BadAlloc;
+		}
+
 		frame.image.x1 = 0;
 		frame.image.y1 = 0;
 		frame.image.x2 = frame.width;
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index a8d50ab..cab2cda 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -348,7 +348,13 @@ static int sna_video_sprite_put_image(ClientPtr client,
 		if (frame.bo == NULL)
 			return BadAlloc;
 
-		assert(kgem_bo_size(frame.bo) >= frame.size);
+		if (kgem_bo_size(frame.bo) < frame.size) {
+			DBG(("%s: bo size=%d, expected=%d\n",
+			     __FUNCTION__, kgem_bo_size(frame.bo), frame.size));
+			kgem_bo_destroy(&sna->kgem, frame.bo);
+			return BadAlloc;
+		}
+
 		frame.image.x1 = 0;
 		frame.image.y1 = 0;
 		frame.image.x2 = frame.width;
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index d3ce280..7ec17d1 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -222,7 +222,13 @@ sna_video_textured_put_image(ClientPtr client,
 			return BadAlloc;
 		}
 
-		assert(kgem_bo_size(frame.bo) >= frame.size);
+		if (kgem_bo_size(frame.bo) < frame.size) {
+			DBG(("%s: bo size=%d, expected=%d\n",
+			     __FUNCTION__, kgem_bo_size(frame.bo), frame.size));
+			kgem_bo_destroy(&sna->kgem, frame.bo);
+			return BadAlloc;
+		}
+
 		frame.image.x1 = 0;
 		frame.image.y1 = 0;
 		frame.image.x2 = frame.width;


More information about the xorg-commit mailing list