diff --git a/include/render/wlr_renderer.h b/include/render/wlr_renderer.h index 0ef1ef82..8e113ac8 100644 --- a/include/render/wlr_renderer.h +++ b/include/render/wlr_renderer.h @@ -4,5 +4,11 @@ #include bool wlr_renderer_bind_buffer(struct wlr_renderer *r, struct wlr_buffer *buffer); +/** + * Get the DMA-BUF formats supporting rendering usage. Buffers allocated with + * a format from this list may be attached via wlr_renderer_bind_buffer. + */ +const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_render_formats( + struct wlr_renderer *renderer); #endif diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h index 4ab672d3..f2d04049 100644 --- a/include/wlr/render/egl.h +++ b/include/wlr/render/egl.h @@ -78,6 +78,7 @@ struct wlr_egl { struct wl_display *wl_display; struct wlr_drm_format_set dmabuf_formats; + struct wlr_drm_format_set dmabuf_render_formats; EGLBoolean **external_only_dmabuf_formats; }; @@ -126,6 +127,11 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl, * Get DMA-BUF formats suitable for sampling usage. */ const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl); +/** + * Get DMA-BUF formats suitable for rendering usage. + */ +const struct wlr_drm_format_set *wlr_egl_get_dmabuf_render_formats( + struct wlr_egl *egl); bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image, int32_t width, int32_t height, uint32_t flags, diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 625ab198..44b5a48c 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -52,6 +52,8 @@ struct wlr_renderer_impl { struct wl_resource *buffer, int *width, int *height); const struct wlr_drm_format_set *(*get_dmabuf_formats)( struct wlr_renderer *renderer); + const struct wlr_drm_format_set *(*get_dmabuf_render_formats)( + struct wlr_renderer *renderer); enum wl_shm_format (*preferred_read_format)(struct wlr_renderer *renderer); bool (*read_pixels)(struct wlr_renderer *renderer, enum wl_shm_format fmt, uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height, diff --git a/render/egl.c b/render/egl.c index 6382c0c3..2180c7a1 100644 --- a/render/egl.c +++ b/render/egl.c @@ -158,10 +158,16 @@ static void init_dmabuf_formats(struct wlr_egl *egl) { if (modifiers_len == 0) { wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, DRM_FORMAT_MOD_INVALID); + wlr_drm_format_set_add(&egl->dmabuf_render_formats, fmt, + DRM_FORMAT_MOD_INVALID); } for (int j = 0; j < modifiers_len; j++) { wlr_drm_format_set_add(&egl->dmabuf_formats, fmt, modifiers[j]); + if (!external_only[j]) { + wlr_drm_format_set_add(&egl->dmabuf_render_formats, fmt, + modifiers[j]); + } } free(modifiers); @@ -397,6 +403,7 @@ void wlr_egl_finish(struct wlr_egl *egl) { } free(egl->external_only_dmabuf_formats); + wlr_drm_format_set_finish(&egl->dmabuf_render_formats); wlr_drm_format_set_finish(&egl->dmabuf_formats); eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -809,6 +816,11 @@ const struct wlr_drm_format_set *wlr_egl_get_dmabuf_formats(struct wlr_egl *egl) return &egl->dmabuf_formats; } +const struct wlr_drm_format_set *wlr_egl_get_dmabuf_render_formats( + struct wlr_egl *egl) { + return &egl->dmabuf_render_formats; +} + bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image, int32_t width, int32_t height, uint32_t flags, struct wlr_dmabuf_attributes *attribs) { diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index fbf27e49..e5bdcd75 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -435,6 +435,12 @@ static const struct wlr_drm_format_set *gles2_get_dmabuf_formats( return wlr_egl_get_dmabuf_formats(renderer->egl); } +static const struct wlr_drm_format_set *gles2_get_dmabuf_render_formats( + struct wlr_renderer *wlr_renderer) { + struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer); + return wlr_egl_get_dmabuf_render_formats(renderer->egl); +} + static enum wl_shm_format gles2_preferred_read_format( struct wlr_renderer *wlr_renderer) { struct wlr_gles2_renderer *renderer = @@ -703,6 +709,7 @@ static const struct wlr_renderer_impl renderer_impl = { .resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer, .wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size, .get_dmabuf_formats = gles2_get_dmabuf_formats, + .get_dmabuf_render_formats = gles2_get_dmabuf_render_formats, .preferred_read_format = gles2_preferred_read_format, .read_pixels = gles2_read_pixels, .texture_from_pixels = gles2_texture_from_pixels, diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index 0fb7fbda..f366f80f 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -173,6 +173,14 @@ const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_formats( return r->impl->get_dmabuf_formats(r); } +const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_render_formats( + struct wlr_renderer *r) { + if (!r->impl->get_dmabuf_render_formats) { + return NULL; + } + return r->impl->get_dmabuf_render_formats(r); +} + bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt, uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height, uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,