mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 15:40:11 +01:00
egl: Implement getImage/putImage on pbuffer swrast.
This change adds getImage/putImage callbacks to the swrast pbuffer
loader extension.
This fixes a recent crash with Weston as well as a crashing
test with classic swrast without an official gitlab issue.
v2: Determine bytes per pixel differently and fix non X11 builds.
v3: Plug memory leak and fix crash on out of bounds access.
(Daniel Stone)
v4: Follow the code structure of the wayland get/put image
implementation - hopefully being more obvious.
Handle 64 bits formats.
Use BufferSize directly.
(Emil Velikov)
v5: Change pixel size computation.
(Eric Engestrom)
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/2219
Fixes: d6edccee8d "egl: add EGL_platform_device support"
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3711>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3711>
(cherry picked from commit c7617d8908)
This commit is contained in:
parent
59e65b6aa2
commit
a0e6341fe4
5 changed files with 97 additions and 6 deletions
|
|
@ -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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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] = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue