summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c92
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h3
-rw-r--r--src/egl/drivers/dri2/platform_device.c3
-rw-r--r--src/egl/drivers/dri2/platform_surfaceless.c3
4 files changed, 96 insertions, 5 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index b418d81c56b..5e497b79bc4 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