sna/video: Correct handling of cropped images along packed fast path
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Nov 2013 21:13:33 +0000 (21:13 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 28 Nov 2013 22:00:11 +0000 (22:00 +0000)
In particular, it was offseting the read from the source image, but not
correcting the length to read - causing a read from beyond the end of
the source and a segfault.

Reported-by: Jan Engelhardt <jengelh@inai.de>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/sna_video.c

index 7f1eeb2..e4d3315 100644 (file)
@@ -520,11 +520,25 @@ sna_video_copy_data(struct sna_video *video,
                                return true;
                        }
                } else {
-                       if (frame->width*2 == frame->pitch[0]) {
+                       int x, y, w, h;
+
+                       if (video->textured) {
+                               /* XXX support copying cropped extents */
+                               x = y = 0;
+                               w = frame->width;
+                               h = frame->height;
+                       } else {
+                               x = frame->image.x1;
+                               y = frame->image.y1;
+                               w = frame->image.x2 - frame->image.x1;
+                               h = frame->image.y2 - frame->image.y1;
+                       }
+
+                       if (w*2 == frame->pitch[0]) {
+                               buf += (2U*y * frame->width) + (x << 1);
                                if (frame->bo) {
                                        kgem_bo_write(&video->sna->kgem, frame->bo,
-                                                     buf + (2U*frame->image.y1 * frame->width) + (frame->image.x1 << 1),
-                                                     2U*(frame->image.y2-frame->image.y1)*frame->width);
+                                                     buf, 2U*h*frame->width);
                                } else {
                                        frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size,
                                                                       KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE,
@@ -532,9 +546,7 @@ sna_video_copy_data(struct sna_video *video,
                                        if (frame->bo == NULL)
                                                return false;
 
-                                       memcpy(dst,
-                                              buf + (frame->image.y1 * frame->width*2) + (frame->image.x1 << 1),
-                                              2U*(frame->image.y2-frame->image.y1)*frame->width);
+                                       memcpy(dst, buf, 2U*h*frame->width);
                                }
                                return true;
                        }