[PATCH v2] Adapt the EGL_WL_create_wayland_buffer_from_image extension for YUV
Neil Roberts
neil at linux.intel.com
Fri Feb 14 09:46:57 PST 2014
Here is a second version of the patch based on feedback from Kristian.
Instead of modifying the existing eglCreateWaylandBufferFromImageWL
function it adds a second version to support passing multiple images.
The worry is that the original version of the extension is already
being used so it's a bit painful to change it in an incompatible way
now. The original function is probably a good convenience wrapper for
the common case where only one image is used anyway so I don't think
it's too messy to leave it in.
------- >8 --------------- (use git am --scissors to automatically chop here)
An additional function is added to the eglCreateWaylandBufferFromImageWL
extension which instead of just taking a single image can take a set of
images. Each EGLImage will represent a plane from a planar image. The overall
format for the combined set of images isn't stored in the EGLImages so instead
of trying to deduce it the new function also has a format parameter. This
should contain the EGLenum returned in the EGL_TEXTURE_FORMAT attribute
retreived via eglQueryWaylandBufferWL. The exact wl_drm_format value to use is
deduced from the EGL format and the size of the images. The number of images
passed must match the number of planes required by the texture format. The
EGLImages must all point to the same buffer and this is determined by checking
the names of the images. If any of these criteria fail then the function will
report EGL_BAD_MATCH.
---
.../specs/WL_create_wayland_buffer_from_image.spec | 77 ++++--
include/EGL/eglmesaext.h | 2 +
src/egl/drivers/dri2/platform_wayland.c | 274 ++++++++++++++++++---
src/egl/main/eglapi.c | 35 +++
src/egl/main/eglapi.h | 4 +-
5 files changed, 343 insertions(+), 49 deletions(-)
diff --git a/docs/specs/WL_create_wayland_buffer_from_image.spec b/docs/specs/WL_create_wayland_buffer_from_image.spec
index aa5eb4d..b08c8a2 100644
--- a/docs/specs/WL_create_wayland_buffer_from_image.spec
+++ b/docs/specs/WL_create_wayland_buffer_from_image.spec
@@ -22,7 +22,7 @@ Status
Version
- Version 2, October 25, 2013
+ Version 3, February 5, 2014
Number
@@ -35,20 +35,22 @@ Dependencies
EGL_KHR_base_image is required.
+ EGL_WL_bind_wayland_display affects the definition of this extension.
+
Overview
- This extension provides an entry point to create a wl_buffer which shares
- its contents with a given EGLImage. The expected use case for this is in a
- nested Wayland compositor which is using subsurfaces to present buffers
- from its clients. Using this extension it can attach the client buffers
- directly to the subsurface without having to blit the contents into an
- intermediate buffer. The compositing can then be done in the parent
- compositor.
+ This extension provides entry points to create a wl_buffer which shares
+ its contents with a given EGLImage or a set of planar EGLImages. The
+ expected use case for this is in a nested Wayland compositor which is
+ using subsurfaces to present buffers from its clients. Using this
+ extension it can attach the client buffers directly to the subsurface
+ without having to blit the contents into an intermediate buffer. The
+ compositing can then be done in the parent compositor.
- The nested compositor can create an EGLImage from a client buffer resource
- using the existing WL_bind_wayland_display extension. It should also be
- possible to create buffers using other types of images although there is
- no expected use case for that.
+ The nested compositor can create the EGLImages from a client buffer
+ resource using the existing WL_bind_wayland_display extension. It should
+ also be possible to create buffers using other types of images although
+ there is no expected use case for that.
IP Status
@@ -59,6 +61,11 @@ New Procedures and Functions
struct wl_buffer *eglCreateWaylandBufferFromImageWL(EGLDisplay dpy,
EGLImageKHR image);
+ struct wl_buffer *eglCreateWaylandBufferFromPlanarImagesWL(EGLDisplay dpy,
+ EGLenum format,
+ EGLImageKHR *ims,
+ EGLint n_images);
+
New Tokens
None.
@@ -67,8 +74,8 @@ Additions to the EGL 1.4 Specification:
To create a client-side wl_buffer from an EGLImage call
- struct wl_buffer *eglCreateWaylandBufferFromImageWL(EGLDisplay dpy,
- EGLImageKHR image);
+ struct wl_buffer *eglCreateWaylandBufferFromImageWL(EGLDisplay dpy,
+ EGLImageKHR image);
The returned buffer will share the contents with the given EGLImage. Any
updates to the image will also be updated in the wl_buffer. Typically the
@@ -82,13 +89,50 @@ Additions to the EGL 1.4 Specification:
format or tiling mode or that the buffer is in memory that is inaccessible
to the GPU that the given EGLDisplay is using.
+ Alternatively it is possible to create a buffer from a planar image where
+ each plane is contained in a separate EGLImage using the following
+ function:
+
+ struct wl_buffer *eglCreateWaylandBufferFromPlanarImagesWL(EGLDisplay dpy,
+ EGLenum format,
+ EGLImageKHR *ims,
+ EGLint n_images);
+
+ The number of images passed should match the number of planes required for
+ the format given in the format parameter. For non-planar formats this will
+ just be 1. Each image represents one plane within the buffer.
+
+ The formats accepted in the format parameter are:
+
+ EGL_TEXTURE_RGB A single image is used which contains RGB
+ components.
+ EGL_TEXTURE_RGBA A single image is used which contains RGBA
+ components.
+ EGL_TEXTURE_Y_U_V_WL Three images are used; one containing the
+ luminance component, one containing the
+ U component of the chrominance data and another
+ containing the V component.
+ EGL_TEXTURE_Y_UV_WL Two images are used; one containing a single
+ luminance component and the other containing the
+ two chrominance components.
+ EGL_TEXTURE_Y_XUXV_WL Two images are used; one containing a single
+ luminance component and the other containing the
+ two chrominance components along with two unused
+ components.
+
+Dependencies on EGL_WL_bind_wayland_display
+
+ If EGL_WL_bind_wayland_display is not implemented then references to
+ EGL_TEXTURE_Y_U_V_WL, EGL_TEXTURE_Y_UV_WL and EGL_TEXTURE_Y_XUXV_WL are
+ void.
+
Issues
1) Under what circumstances can the EGL_BAD_MATCH error be generated? Does
this include for example unsupported tiling modes?
RESOLVED: Yes, the EGL_BAD_MATCH error can be generated for any reason
- which prevents the implementation from representing the image as a
+ which prevents the implementation from representing the images as a
wl_buffer. For example, these problems can be but are not limited to
unsupported tiling modes, inaccessible memory or an unsupported pixel
format.
@@ -99,3 +143,6 @@ Revision History
Initial draft (Neil Roberts)
Version 2, October 25, 2013
Added a note about more possible reasons for returning EGL_BAD_FORMAT.
+ Version 3, February 5, 2014
+ Support for passing multiple images in order to create a planar
+ buffer.
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index b3229e3..b78aa8b 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -139,8 +139,10 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI struct wl_buffer * EGLAPIENTRY eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image);
+EGLAPI struct wl_buffer * EGLAPIENTRY eglCreateWaylandBufferFromPlanarImagesWL(EGLDisplay dpy, EGLenum format, EGLImageKHR *images, EGLint n_images);
#endif
typedef struct wl_buffer * (EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL) (EGLDisplay dpy, EGLImageKHR image);
+typedef struct wl_buffer * (EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMPLANARIMAGESWL) (EGLDisplay dpy, EGLenum format, EGLImageKHR *images, EGLint n_images);
#endif
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 089ed62..556a45a 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -698,64 +698,238 @@ dri2_can_handle_format(struct dri2_egl_display *dri2_dpy,
return EGL_FALSE;
}
+struct plane_attribs {
+ struct dri2_egl_image *dri2_img;
+ __DRIimage *image;
+ int offset;
+ int stride;
+ int width;
+ int height;
+ int format;
+};
+
+struct planar_format {
+ enum wl_drm_format wl_format;
+ EGLenum components;
+ int n_planes;
+ struct {
+ int width_shift;
+ int height_shift;
+ uint32_t dri_format;
+ } planes[3];
+};
+
+static const struct planar_format
+planar_formats[] = {
+ { WL_DRM_FORMAT_ARGB8888, EGL_TEXTURE_RGBA, 1,
+ { { 0, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } },
+
+ { WL_DRM_FORMAT_XRGB8888, EGL_TEXTURE_RGB, 1,
+ { { 0, 0, __DRI_IMAGE_FORMAT_XRGB8888 }, } },
+
+ { WL_DRM_FORMAT_RGB565, EGL_TEXTURE_RGB, 1,
+ { { 0, 0, __DRI_IMAGE_FORMAT_RGB565 } } },
+
+ { WL_DRM_FORMAT_YUV410, EGL_TEXTURE_Y_U_V_WL, 3,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 2, 2, __DRI_IMAGE_FORMAT_R8 },
+ { 2, 2, __DRI_IMAGE_FORMAT_R8 } } },
+
+ { WL_DRM_FORMAT_YUV411, EGL_TEXTURE_Y_U_V_WL, 3,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 2, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 2, 0, __DRI_IMAGE_FORMAT_R8 } } },
+
+ { WL_DRM_FORMAT_YUV420, EGL_TEXTURE_Y_U_V_WL, 3,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 1, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 1, __DRI_IMAGE_FORMAT_R8 } } },
+
+ { WL_DRM_FORMAT_YUV422, EGL_TEXTURE_Y_U_V_WL, 3,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 0, __DRI_IMAGE_FORMAT_R8 } } },
+
+ { WL_DRM_FORMAT_YUV444, EGL_TEXTURE_Y_U_V_WL, 3,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 0, 0, __DRI_IMAGE_FORMAT_R8 } } },
+
+ { WL_DRM_FORMAT_NV12, EGL_TEXTURE_Y_UV_WL, 2,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 1, __DRI_IMAGE_FORMAT_GR88 } } },
+
+ { WL_DRM_FORMAT_NV16, EGL_TEXTURE_Y_UV_WL, 2,
+ { { 0, 0, __DRI_IMAGE_FORMAT_R8 },
+ { 1, 0, __DRI_IMAGE_FORMAT_GR88 } } },
+
+ { WL_DRM_FORMAT_YUYV, EGL_TEXTURE_Y_XUXV_WL, 2,
+ { { 0, 0, __DRI_IMAGE_FORMAT_GR88 },
+ { 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }
+};
+
+static void
+get_planar_format_max_shifts(const struct planar_format *planar_format,
+ int *max_width_shift,
+ int *max_height_shift)
+{
+ int i;
+
+ *max_width_shift = 0;
+ *max_height_shift = 0;
+
+ for (i = 0; i < planar_format->n_planes; i++) {
+ if (planar_format->planes[i].width_shift > *max_width_shift)
+ *max_width_shift = planar_format->planes[i].width_shift;
+ if (planar_format->planes[i].height_shift > *max_height_shift)
+ *max_height_shift = planar_format->planes[i].height_shift;
+ }
+}
+
+static EGLBoolean
+check_plane_attribs_match_format(const struct plane_attribs *planes,
+ const struct planar_format *planar_format)
+{
+ int width, height;
+ int i;
+
+ for (i = 0; i < planar_format->n_planes; i++) {
+ if (planes[i].format != planar_format->planes[i].dri_format)
+ return EGL_FALSE;
+
+ width = planes[0].width >> planar_format->planes[i].width_shift;
+ height = planes[0].height >> planar_format->planes[i].height_shift;
+
+ if (planes[i].width != width || planes[i].height != height)
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+find_planar_format(EGLenum components,
+ const struct plane_attribs *planes,
+ int n_planes,
+ enum wl_drm_format *wl_format)
+{
+ const struct planar_format *planar_format;
+ int max_width_shift, max_height_shift;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(planar_formats); i++) {
+ planar_format = planar_formats + i;
+
+ if (n_planes != planar_format->n_planes ||
+ components != planar_format->components)
+ continue;
+
+ /* Check if the size of the first plane is a multiple of the maximum
+ * shift */
+ get_planar_format_max_shifts(planar_format,
+ &max_width_shift,
+ &max_height_shift);
+ if ((planes[0].width & ((1 << max_width_shift) - 1)) != 0 ||
+ (planes[0].height & ((1 << max_height_shift) - 1)) != 0)
+ continue;
+
+ if (!check_plane_attribs_match_format(planes, planar_format))
+ continue;
+
+ *wl_format = planar_format->wl_format;
+ return EGL_TRUE;
+ }
+
+ return EGL_FALSE;
+}
+
static struct wl_buffer *
-dri2_create_wayland_buffer_from_image_wl(_EGLDriver *drv,
- _EGLDisplay *disp,
- _EGLImage *img)
+dri2_create_wayland_buffer_from_planar_images_wl(_EGLDriver *drv,
+ _EGLDisplay *disp,
+ EGLenum format,
+ _EGLImage **images,
+ EGLint n_images)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_image *dri2_img = dri2_egl_image(img);
- __DRIimage *image = dri2_img->dri_image;
struct wl_buffer *buffer;
- int width, height, format, pitch;
enum wl_drm_format wl_format;
+ struct plane_attribs plane[3];
+ int name, other_name;
+ int i;
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
+ if (n_images < 1 || n_images > 3)
+ goto bad_format;
- switch (format) {
- case __DRI_IMAGE_FORMAT_ARGB8888:
- if (!dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_ARGB8888))
- goto bad_format;
- wl_format = WL_DRM_FORMAT_ARGB8888;
- break;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- if (!dri2_can_handle_format(dri2_dpy, WL_DRM_FORMAT_XRGB8888))
+ for (i = 0; i < n_images; i++) {
+ plane[i].dri2_img = dri2_egl_image(images[i]);
+ plane[i].image = plane[i].dri2_img->dri_image;
+ }
+
+ /* Verify the all of the images have the same name (ie, they point to the
+ * same buffer) */
+ dri2_dpy->image->queryImage(plane[0].image, __DRI_IMAGE_ATTRIB_NAME, &name);
+ for (i = 1; i < n_images; i++) {
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_NAME,
+ &other_name);
+ if (other_name != name)
goto bad_format;
- wl_format = WL_DRM_FORMAT_XRGB8888;
- break;
- default:
- goto bad_format;
}
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height);
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
+ for (i = 0; i < n_images; i++) {
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_FORMAT,
+ &plane[i].format);
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_WIDTH,
+ &plane[i].width);
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_HEIGHT,
+ &plane[i].height);
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_STRIDE,
+ &plane[i].stride);
+
+ if (dri2_dpy->image->base.version >= 9)
+ dri2_dpy->image->queryImage(plane[i].image,
+ __DRI_IMAGE_ATTRIB_OFFSET,
+ &plane[i].offset);
+ else
+ plane[i].offset = 0;
+ }
+
+ /* We need prime to create planar buffers */
+ if (n_images > 1 &&
+ (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) == 0)
+ goto bad_format;
+
+ if (!find_planar_format(format, plane, n_images, &wl_format))
+ goto bad_format;
+
+ if (!dri2_can_handle_format(dri2_dpy, wl_format))
+ goto bad_format;
if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
int fd;
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd);
+ dri2_dpy->image->queryImage(plane[0].image, __DRI_IMAGE_ATTRIB_FD, &fd);
buffer =
wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
fd,
- width, height,
+ plane[0].width, plane[0].height,
wl_format,
- 0, pitch,
- 0, 0,
- 0, 0);
+ plane[0].offset, plane[0].stride,
+ plane[1].offset, plane[1].stride,
+ plane[2].offset, plane[2].stride);
close(fd);
} else {
- int name;
-
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
-
buffer =
wl_drm_create_buffer(dri2_dpy->wl_drm,
name,
- width, height,
- pitch,
+ plane[0].width, plane[0].height,
+ plane[0].stride,
wl_format);
}
@@ -773,6 +947,38 @@ bad_format:
return NULL;
}
+static struct wl_buffer *
+dri2_create_wayland_buffer_from_image_wl(_EGLDriver *drv,
+ _EGLDisplay *disp,
+ _EGLImage *img)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ __DRIimage *image = dri2_img->dri_image;
+ EGLenum components;
+ int format;
+
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ components = EGL_TEXTURE_RGBA;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ components = EGL_TEXTURE_RGB;
+ break;
+ default:
+ _eglError(EGL_BAD_MATCH, "unsupported image format");
+ return NULL;
+ }
+
+ return dri2_create_wayland_buffer_from_planar_images_wl(drv,
+ disp,
+ components,
+ &img,
+ 1 /* n_imgs */);
+}
+
static int
dri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
{
@@ -1013,6 +1219,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
drv->API.CreateWaylandBufferFromImageWL =
dri2_create_wayland_buffer_from_image_wl;
+ drv->API.CreateWaylandBufferFromPlanarImagesWL =
+ dri2_create_wayland_buffer_from_planar_images_wl;
dri2_dpy = calloc(1, sizeof *dri2_dpy);
if (!dri2_dpy)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 59e214c..b0b4e72 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -975,6 +975,7 @@ eglGetProcAddress(const char *procname)
#endif
#ifdef EGL_WL_create_wayland_buffer_from_image
{ "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
+ { "eglCreateWaylandBufferFromPlanarImagesWL", (_EGLProc) eglCreateWaylandBufferFromPlanarImagesWL },
#endif
{ "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
#ifdef EGL_EXT_swap_buffers_with_damage
@@ -1606,6 +1607,40 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
#ifdef EGL_WL_create_wayland_buffer_from_image
struct wl_buffer * EGLAPIENTRY
+eglCreateWaylandBufferFromPlanarImagesWL(EGLDisplay dpy,
+ EGLenum format,
+ EGLImageKHR *images,
+ EGLint n_images)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLImage *imgs[3];
+ _EGLDriver *drv;
+ struct wl_buffer *ret;
+ int i;
+
+ _EGL_CHECK_DISPLAY(disp, NULL, drv);
+ assert(disp->Extensions.WL_create_wayland_buffer_from_image);
+
+ if (n_images < 0 || n_images > ARRAY_SIZE(imgs))
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
+
+ for (i = 0; i < n_images; i++) {
+ imgs[i] = _eglLookupImage(images[i], disp);
+
+ if (!imgs[i])
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
+ }
+
+ ret = drv->API.CreateWaylandBufferFromPlanarImagesWL(drv,
+ disp,
+ format,
+ imgs,
+ n_images);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+struct wl_buffer * EGLAPIENTRY
eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index 091c09c..7e8d797 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -127,7 +127,8 @@ typedef EGLBoolean (*QueryWaylandBufferWL_t)(_EGLDriver *drv, _EGLDisplay *displ
#endif
#ifdef EGL_WL_create_wayland_buffer_from_image
-typedef struct wl_buffer * (*CreateWaylandBufferFromImageWL_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img);
+typedef struct wl_buffer * (*CreateWaylandBufferFromImageWL_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *images);
+typedef struct wl_buffer * (*CreateWaylandBufferFromPlanarImagesWL_t)(_EGLDriver *drv, _EGLDisplay *disp, EGLenum format, _EGLImage **images, EGLint n_images);
#endif
typedef EGLBoolean (*PostSubBufferNV_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface, EGLint x, EGLint y, EGLint width, EGLint height);
@@ -216,6 +217,7 @@ struct _egl_api
#ifdef EGL_WL_create_wayland_buffer_from_image
CreateWaylandBufferFromImageWL_t CreateWaylandBufferFromImageWL;
+ CreateWaylandBufferFromPlanarImagesWL_t CreateWaylandBufferFromPlanarImagesWL;
#endif
#ifdef EGL_EXT_swap_buffers_with_damage
--
1.8.5.3
More information about the wayland-devel
mailing list