I think there is a problem with tiling handling in your patch. Thinks of a session compositor running on an other graphic card for example.
Main compositor: card A session compositor: card B. buffer is shared between A and B and when creating it, tiling was disabled (because A and B share no tiling mode) clients in the session compositor: card B. buffer is created on B, when creating it, tiling was enabled. In this configuration, your function should fail or do a copy (because A won't recognize the tiling mode of B) Axel Davy > This adds an extension called EGL_WL_create_wayland_buffer_from_image > which adds the following single function: > > struct wl_buffer * > eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image); > > The function creates a wl_buffer which shares its contents with the 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. > > The extension is only implemented in the Wayland EGL platform because of > course it wouldn't make sense anywhere else. > --- > .../specs/WL_create_wayland_buffer_from_image.spec | 85 > ++++++++++++++++++++++ > include/EGL/eglmesaext.h | 10 +++ > src/egl/drivers/dri2/platform_wayland.c | 71 > ++++++++++++++++++ > src/egl/main/eglapi.c | 25 +++++++ > src/egl/main/eglapi.h | 8 ++ > src/egl/main/egldisplay.h | 1 + > src/egl/main/eglmisc.c | 1 + > 7 files changed, 201 insertions(+) > create mode 100644 docs/specs/WL_create_wayland_buffer_from_image.spec > > diff --git a/docs/specs/WL_create_wayland_buffer_from_image.spec > b/docs/specs/WL_create_wayland_buffer_from_image.spec > new file mode 100644 > index 0000000..7e27695 > --- /dev/null > +++ b/docs/specs/WL_create_wayland_buffer_from_image.spec > @@ -0,0 +1,85 @@ > +Name > + > + WL_create_wayland_buffer_from_image > + > +Name Strings > + > + EGL_WL_create_wayland_buffer_from_image > + > +Contact > + > + Neil Roberts <neil.s.robe...@intel.com> > + > +Status > + > + Proposal > + > +Version > + > + Version 1, September 6, 2013 > + > +Number > + > + EGL Extension #not assigned > + > +Dependencies > + > + Requires EGL 1.4 or later. This extension is written against the > + wording of the EGL 1.4 specification. > + > + EGL_KHR_base_image is required. > + > +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. > + > + 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. > + > +IP Status > + > + Open-source; freely implementable. > + > +New Procedures and Functions > + > + struct wl_buffer *eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, > + EGLImageKHR > image); > + > +New Tokens > + > + None. > + > +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); > + > + 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 > + EGLImage will be generated in a nested Wayland compositor using a > buffer > + resource from a client via the EGL_WL_bind_wayland_display extension. > + > + If there was an error then the function will return NULL. In > particular it > + will generate EGL_BAD_MATCH if the image is not in a format which the > + implementation can represent in a wl_buffer. It is > implementation-defined > + what formats and types of EGLImage will be successfully converted to > a > + wl_buffer without error. > + > +Issues > + > + None. > + > +Revision History > + > + Version 1, September 6, 2013 > + Initial draft (Neil Roberts) > diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h > index e0eae28..0a65cb8 100644 > --- a/include/EGL/eglmesaext.h > +++ b/include/EGL/eglmesaext.h > @@ -132,6 +132,16 @@ typedef EGLBoolean (EGLAPIENTRYP > PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st > > #endif > > +#ifndef EGL_WL_create_wayland_buffer_from_image > +#define EGL_WL_create_wayland_buffer_from_image 1 > + > +#ifdef EGL_EGLEXT_PROTOTYPES > +EGLAPI struct wl_buffer * EGLAPIENTRY > eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image); > +#endif > +typedef struct wl_buffer * (EGLAPIENTRYP > PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL) (EGLDisplay dpy, EGLImageKHR image); > + > +#endif > + > #ifndef EGL_NOK_swap_region > #define EGL_NOK_swap_region 1 > > diff --git a/src/egl/drivers/dri2/platform_wayland.c > b/src/egl/drivers/dri2/platform_wayland.c > index 1d417bb..ee1a6bc 100644 > --- a/src/egl/drivers/dri2/platform_wayland.c > +++ b/src/egl/drivers/dri2/platform_wayland.c > @@ -586,6 +586,74 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, > _EGLSurface *draw) > return dri2_swap_buffers_with_damage (drv, disp, draw, NULL, 0); > } > > +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; > + struct wl_buffer *buffer; > + int width, height, format, pitch; > + enum wl_drm_format wl_format; > + > + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, > &format); > + > + switch (format) { > + case __DRI_IMAGE_FORMAT_ARGB8888: > + if (!(dri2_dpy->formats & HAS_ARGB8888)) > + goto bad_format; > + wl_format = WL_DRM_FORMAT_ARGB8888; > + break; > + case __DRI_IMAGE_FORMAT_XRGB8888: > + if (!(dri2_dpy->formats & HAS_XRGB8888)) > + 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); > + > + if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) { > + int fd; > + > + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd); > + > + buffer = > + wl_drm_create_prime_buffer(dri2_dpy->wl_drm, > + fd, > + width, height, > + wl_format, > + 0, pitch, > + 0, 0, > + 0, 0); > + > + 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, > + wl_format); > + } > + > + return buffer; > + > +bad_format: > + _eglError(EGL_BAD_MATCH, "unsupported image format"); > + return NULL; > +} > + > static int > dri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id) > { > @@ -743,6 +811,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay > *disp) > drv->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage; > drv->API.Terminate = dri2_terminate; > drv->API.QueryBufferAge = dri2_query_buffer_age; > + drv->API.CreateWaylandBufferFromImageWL = > + dri2_create_wayland_buffer_from_image_wl; > > dri2_dpy = calloc(1, sizeof *dri2_dpy); > if (!dri2_dpy) > @@ -820,6 +890,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay > *disp) > } > > disp->Extensions.WL_bind_wayland_display = EGL_TRUE; > + disp->Extensions.WL_create_wayland_buffer_from_image = EGL_TRUE; > disp->Extensions.EXT_buffer_age = EGL_TRUE; > dri2_dpy->authenticate = dri2_wayland_authenticate; > > diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c > index 2d8653f..5399932 100644 > --- a/src/egl/main/eglapi.c > +++ b/src/egl/main/eglapi.c > @@ -967,6 +967,9 @@ eglGetProcAddress(const char *procname) > { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL > }, > { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, > #endif > +#ifdef EGL_WL_create_wayland_buffer_from_image > + { "eglCreateWaylandBufferFromImageWL", (_EGLProc) > eglCreateWaylandBufferFromImageWL }, > +#endif > { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, > #ifdef EGL_EXT_swap_buffers_with_damage > { "eglSwapBuffersWithDamageEXT", (_EGLProc) > eglSwapBuffersWithDamageEXT }, > @@ -1595,6 +1598,28 @@ eglQueryWaylandBufferWL(EGLDisplay dpy, struct > wl_resource *buffer, > } > #endif > > +#ifdef EGL_WL_create_wayland_buffer_from_image > +struct wl_buffer * EGLAPIENTRY > +eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image) > +{ > + _EGLDisplay *disp = _eglLockDisplay(dpy); > + _EGLImage *img; > + _EGLDriver *drv; > + struct wl_buffer *ret; > + > + _EGL_CHECK_DISPLAY(disp, NULL, drv); > + assert(disp->Extensions.WL_create_wayland_buffer_from_image); > + > + img = _eglLookupImage(image, disp); > + > + if (!img) > + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL); > + > + ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img); > + > + RETURN_EGL_EVAL(disp, ret); > +} > +#endif > > EGLBoolean EGLAPIENTRY > eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, > diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h > index 4a4f976..0580344 100644 > --- a/src/egl/main/eglapi.h > +++ b/src/egl/main/eglapi.h > @@ -126,6 +126,10 @@ typedef EGLBoolean > (*UnbindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *dis > typedef EGLBoolean (*QueryWaylandBufferWL_t)(_EGLDriver *drv, _EGLDisplay > *displ, struct wl_resource *buffer, EGLint attribute, EGLint *value); > #endif > > +#ifdef EGL_WL_create_wayland_buffer_from_image > +typedef struct wl_buffer * (*CreateWaylandBufferFromImageWL_t)(_EGLDriver > *drv, _EGLDisplay *disp, _EGLImage *img); > +#endif > + > typedef EGLBoolean (*PostSubBufferNV_t)(_EGLDriver *drv, _EGLDisplay > *disp, _EGLSurface *surface, EGLint x, EGLint y, EGLint width, EGLint > height); > > typedef EGLint (*QueryBufferAge_t)(_EGLDriver *drv, > @@ -210,6 +214,10 @@ struct _egl_api > QueryWaylandBufferWL_t QueryWaylandBufferWL; > #endif > > +#ifdef EGL_WL_create_wayland_buffer_from_image > + CreateWaylandBufferFromImageWL_t CreateWaylandBufferFromImageWL; > +#endif > + > #ifdef EGL_EXT_swap_buffers_with_damage > SwapBuffersWithDamageEXT_t SwapBuffersWithDamageEXT; > #endif /* EGL_EXT_swap_buffers_with_damage */ > diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h > index fefd19c..b95b2f7 100644 > --- a/src/egl/main/egldisplay.h > +++ b/src/egl/main/egldisplay.h > @@ -91,6 +91,7 @@ struct _egl_extensions > EGLBoolean MESA_drm_image; > > EGLBoolean WL_bind_wayland_display; > + EGLBoolean WL_create_wayland_buffer_from_image; > > EGLBoolean KHR_image_base; > EGLBoolean KHR_image_pixmap; > diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c > index 2decc1b..cff6166 100644 > --- a/src/egl/main/eglmisc.c > +++ b/src/egl/main/eglmisc.c > @@ -92,6 +92,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy) > _EGL_CHECK_EXTENSION(MESA_drm_image); > > _EGL_CHECK_EXTENSION(WL_bind_wayland_display); > + _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image); > > _EGL_CHECK_EXTENSION(KHR_image_base); > _EGL_CHECK_EXTENSION(KHR_image_pixmap); > -- > 1.8.3.1 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel