diff options
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 92 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.h | 3 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_device.c | 3 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_surfaceless.c | 3 |
5 files changed, 97 insertions, 6 deletions
diff --git a/.pick_status.json b/.pick_status.json index bbb6d9df41c..2b9063a6fad 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -247,7 +247,7 @@ "description": "egl: Implement getImage/putImage on pbuffer swrast.", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "d6edccee8da38d4802020d5aa4d9e11bb7aae801" }, diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 23d0e469427..36828847e75 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -66,6 +66,7 @@ #include "util/u_vector.h" #include "mapi/glapi/glapi.h" #include "util/bitscan.h" +#include "util/u_math.h" /* Additional definitions not yet in the drm_fourcc.h. */ @@ -162,15 +163,96 @@ dri2_get_pbuffer_drawable_info(__DRIdrawable * draw, *h = dri2_surf->base.Height; } -/* HACK: technically we should have swrast_null, instead of these. We - * get away since only pbuffers are supported, thus the callbacks are - * unused. +static int +dri2_get_bytes_per_pixel(struct dri2_egl_surface *dri2_surf) +{ + const int depth = dri2_surf->base.Config->BufferSize; + return depth ? util_next_power_of_two(depth / 8) : 0; +} + +static void +dri2_put_image(__DRIdrawable * draw, int op, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + const int bpp = dri2_get_bytes_per_pixel(dri2_surf); + const int width = dri2_surf->base.Width; + const int height = dri2_surf->base.Height; + const int dst_stride = width*bpp; + const int src_stride = w*bpp; + const int x_offset = x*bpp; + int copy_width = src_stride; + + if (!dri2_surf->swrast_device_buffer) + dri2_surf->swrast_device_buffer = malloc(height*dst_stride); + + if (dri2_surf->swrast_device_buffer) { + const char *src = data; + char *dst = dri2_surf->swrast_device_buffer; + + dst += x_offset; + dst += y*dst_stride; + + /* Drivers are allowed to submit OOB PutImage requests, so clip here. */ + if (copy_width > dst_stride - x_offset) + copy_width = dst_stride - x_offset; + if (h > height - y) + h = height - y; + + for (; 0 < h; --h) { + memcpy(dst, src, copy_width); + dst += dst_stride; + src += src_stride; + } + } +} + +static void +dri2_get_image(__DRIdrawable * read, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + const int bpp = dri2_get_bytes_per_pixel(dri2_surf); + const int width = dri2_surf->base.Width; + const int height = dri2_surf->base.Height; + const int src_stride = width*bpp; + const int dst_stride = w*bpp; + const int x_offset = x*bpp; + int copy_width = dst_stride; + const char *src = dri2_surf->swrast_device_buffer; + char *dst = data; + + if (!src) { + memset(data, 0, copy_width * h); + return; + } + + src += x_offset; + src += y*src_stride; + + /* Drivers are allowed to submit OOB GetImage requests, so clip here. */ + if (copy_width > src_stride - x_offset) + copy_width = src_stride - x_offset; + if (h > height - y) + h = height - y; + + for (; 0 < h; --h) { + memcpy(dst, src, copy_width); + src += src_stride; + dst += dst_stride; + } + +} + +/* HACK: technically we should have swrast_null, instead of these. */ const __DRIswrastLoaderExtension swrast_pbuffer_loader_extension = { .base = { __DRI_SWRAST_LOADER, 1 }, .getDrawableInfo = dri2_get_pbuffer_drawable_info, - .putImage = NULL, - .getImage = NULL, + .putImage = dri2_put_image, + .getImage = dri2_get_image, }; static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = { diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 146f954eacf..8272da886ee 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -338,6 +338,9 @@ struct dri2_egl_surface int out_fence_fd; EGLBoolean enable_out_fence; + + /* swrast device */ + char *swrast_device_buffer; }; struct dri2_egl_config diff --git a/src/egl/drivers/dri2/platform_device.c b/src/egl/drivers/dri2/platform_device.c index 9bd7a93270d..eb2a743b01d 100644 --- a/src/egl/drivers/dri2/platform_device.c +++ b/src/egl/drivers/dri2/platform_device.c @@ -66,6 +66,9 @@ device_free_images(struct dri2_egl_surface *dri2_surf) dri2_dpy->image->destroyImage(dri2_surf->front); dri2_surf->front = NULL; } + + free(dri2_surf->swrast_device_buffer); + dri2_surf->swrast_device_buffer = NULL; } static int diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c index 1a2d3be0aad..19d28aa61ab 100644 --- a/src/egl/drivers/dri2/platform_surfaceless.c +++ b/src/egl/drivers/dri2/platform_surfaceless.c @@ -60,6 +60,9 @@ surfaceless_free_images(struct dri2_egl_surface *dri2_surf) dri2_dpy->image->destroyImage(dri2_surf->front); dri2_surf->front = NULL; } + + free(dri2_surf->swrast_device_buffer); + dri2_surf->swrast_device_buffer = NULL; } static int |