-EGLint dri2_to_egl_attribute_map[] = {
- 0,
- EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */
- EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */
- EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */
- EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */
- EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */
- EGL_LUMINANCE_SIZE, /* __DRI_ATTRIB_LUMINANCE_SIZE */
- EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */
- 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */
- EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */
- EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */
- 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */
- 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */
- 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */
- 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */
- EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */
- EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */
- 0, /* __DRI_ATTRIB_RENDER_TYPE, */
- 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */
- 0, /* __DRI_ATTRIB_CONFORMANT */
- 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */
- 0, /* __DRI_ATTRIB_STEREO */
- 0, /* __DRI_ATTRIB_AUX_BUFFERS */
- 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */
- 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */
- 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */
- 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */
- 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */
- 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */
- 0, /* __DRI_ATTRIB_FLOAT_MODE (deprecated) */
- 0, /* __DRI_ATTRIB_RED_MASK */
- 0, /* __DRI_ATTRIB_GREEN_MASK */
- 0, /* __DRI_ATTRIB_BLUE_MASK */
- 0, /* __DRI_ATTRIB_ALPHA_MASK */
- EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */
- EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */
- EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */
- 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */
- 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */
- 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */
- 0, /* __DRI_ATTRIB_SWAP_METHOD */
- EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */
- EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */
- 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */
- 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
- 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
- 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
- EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */
- 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */
+static void
+dri2_get_pbuffer_drawable_info(__DRIdrawable * draw,
+ int *x, int *y, int *w, int *h,
+ void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+ *x = *y = 0;
+ *w = dri2_surf->base.Width;
+ *h = dri2_surf->base.Height;
+}
+
+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 = dri2_put_image,
+ .getImage = dri2_get_image,
+};
+
+static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
+ [__DRI_ATTRIB_BUFFER_SIZE ] = EGL_BUFFER_SIZE,
+ [__DRI_ATTRIB_LEVEL] = EGL_LEVEL,
+ [__DRI_ATTRIB_LUMINANCE_SIZE] = EGL_LUMINANCE_SIZE,
+ [__DRI_ATTRIB_DEPTH_SIZE] = EGL_DEPTH_SIZE,
+ [__DRI_ATTRIB_STENCIL_SIZE] = EGL_STENCIL_SIZE,
+ [__DRI_ATTRIB_SAMPLE_BUFFERS] = EGL_SAMPLE_BUFFERS,
+ [__DRI_ATTRIB_SAMPLES] = EGL_SAMPLES,
+ [__DRI_ATTRIB_MAX_PBUFFER_WIDTH] = EGL_MAX_PBUFFER_WIDTH,
+ [__DRI_ATTRIB_MAX_PBUFFER_HEIGHT] = EGL_MAX_PBUFFER_HEIGHT,
+ [__DRI_ATTRIB_MAX_PBUFFER_PIXELS] = EGL_MAX_PBUFFER_PIXELS,
+ [__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL,
+ [__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL,
+ [__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK,