diff options
Diffstat (limited to 'src/gallium/state_trackers/vega/api_images.c')
-rw-r--r-- | src/gallium/state_trackers/vega/api_images.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c index 7054d9bb7e..ad95409cd0 100644 --- a/src/gallium/state_trackers/vega/api_images.c +++ b/src/gallium/state_trackers/vega/api_images.c @@ -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) { @@ -302,7 +303,8 @@ void vegaDrawImage(VGImage image) } vg_validate_state(ctx); - image_draw((struct vg_image*)image); + image_draw((struct vg_image*)image, + &ctx->state.vg.image_user_to_surface_matrix); } void vegaSetPixels(VGint dx, VGint dy, @@ -398,11 +400,9 @@ void vegaReadPixels(void * data, VGint dataStride, struct st_framebuffer *stfb = ctx->draw_buffer; struct st_renderbuffer *strb = stfb->strb; - struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; 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 > stfb->width || sy + height > stfb->height) { + width = stfb->width - sx; + height = stfb->height - sy; + /* nothing to read */ + if (width <= 0 || height <= 0) + return; } { + VGint y = (stfb->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); + transfer = pipe_get_transfer(pipe, strb->texture, 0, 0, + PIPE_TRANSFER_READ, + 0, 0, sx + width, stfb->height - sy); /* Do a row at a time to flip image data vertically */ for (i = 0; i < height; i++) { @@ -464,8 +472,8 @@ void vegaCopyPixels(VGint dx, VGint dy, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); - struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb; - struct st_renderbuffer *strb = ctx->draw_buffer->strb; + struct st_framebuffer *stfb = ctx->draw_buffer; + struct st_renderbuffer *strb = stfb->strb; if (width <= 0 || height <= 0) { vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); @@ -473,8 +481,8 @@ void vegaCopyPixels(VGint dx, VGint dy, } /* do nothing if we copy from outside the fb */ - if (dx >= (VGint)fb->width || dy >= (VGint)fb->height || - sx >= (VGint)fb->width || sy >= (VGint)fb->height) + if (dx >= (VGint)stfb->width || dy >= (VGint)stfb->height || + sx >= (VGint)stfb->width || sy >= (VGint)stfb->height) return; vg_validate_state(ctx); |