st/vega: Fix vgReadPixels with a subrectangle.
authorChia-I Wu <olv@lunarg.com>
Sun, 21 Nov 2010 10:58:47 +0000 (18:58 +0800)
committerChia-I Wu <olv@lunarg.com>
Sun, 21 Nov 2010 11:32:22 +0000 (19:32 +0800)
Fix a crash when the subrectangle is not inside the fb.  Fix wrong
pipe transfer when sx > 0 or sy + height != fb->height.

This fixes "readpixels" demo.

src/gallium/state_trackers/vega/api_images.c

index 7054d9bb7ed2f8dad3d8e721552cde6292515829..e9f038c5f9278558f7e1202cbb702d6064994309 100644 (file)
@@ -37,6 +37,7 @@
 #include "pipe/p_screen.h"
 #include "util/u_inlines.h"
 #include "util/u_tile.h"
+#include "util/u_math.h"
 
 static INLINE VGboolean supported_image_format(VGImageFormat format)
 {
@@ -402,7 +403,6 @@ void vegaReadPixels(void * data, VGint dataStride,
 
    VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
    VGfloat *df = (VGfloat*)temp;
-   VGint y = (fb->height - sy) - 1, yStep = -1;
    VGint i;
    VGubyte *dst = (VGubyte *)data;
    VGint xoffset = 0, yoffset = 0;
@@ -430,18 +430,26 @@ void vegaReadPixels(void * data, VGint dataStride,
    }
    if (sy < 0) {
       yoffset = -sy;
+      yoffset *= dataStride;
       height += sy;
       sy = 0;
-      y = (fb->height - sy) - 1;
-      yoffset *= dataStride;
+   }
+
+   if (sx + width > fb->width || sy + height > fb->height) {
+      width = fb->width - sx;
+      height = fb->height - sy;
+      /* nothing to read */
+      if (width <= 0 || height <= 0)
+         return;
    }
 
    {
+      VGint y = (fb->height - sy) - 1, yStep = -1;
       struct pipe_transfer *transfer;
 
       transfer = pipe_get_transfer(pipe, strb->texture,  0, 0, 0,
                                   PIPE_TRANSFER_READ,
-                                  0, 0, width, height);
+                                  0, 0, sx + width, fb->height - sy);
 
       /* Do a row at a time to flip image data vertically */
       for (i = 0; i < height; i++) {