mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-03 15:00:41 +02:00
render/egl: Apply color representation to dmabuf import
When importing a dmabuf to a new EGLImage, add the option to apply color-representation metadata to specify the color encoding and range. To get this information from the wlr_surface to the new EGLImage, I store it in wlr_dmabuf_v1_buffer. This seems reasonable because we can currently only apply color representation to dmabufs anyway. Note that this currently won't update if color-representation is changed on a surface which has already been rendered (so already has an EGLImage). It only works when color-representation is set before the first render. To fix this I think we'll need some mechanism to re-import the dmabuf if color-repr is changed.
This commit is contained in:
parent
8638735489
commit
eeccea7a20
5 changed files with 67 additions and 4 deletions
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <wlr/render/egl.h>
|
||||
|
||||
struct wlr_color_representation_v1_state;
|
||||
|
||||
struct wlr_egl {
|
||||
EGLDisplay display;
|
||||
EGLContext context;
|
||||
|
|
@ -74,7 +76,8 @@ void wlr_egl_destroy(struct wlr_egl *egl);
|
|||
* of the dmabuf with wlr_egl_check_import_dmabuf once first.
|
||||
*/
|
||||
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||
struct wlr_dmabuf_attributes *attributes, bool *external_only);
|
||||
struct wlr_dmabuf_attributes *attributes, bool *external_only,
|
||||
const struct wlr_color_representation_v1_state *color_repr);
|
||||
|
||||
/**
|
||||
* Get DMA-BUF formats suitable for sampling usage.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/render/color.h>
|
||||
#include <wlr/render/dmabuf.h>
|
||||
#include <wlr/render/drm_format_set.h>
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ struct wlr_dmabuf_v1_buffer {
|
|||
|
||||
struct wl_resource *resource; // can be NULL if the client destroyed it
|
||||
struct wlr_dmabuf_attributes attributes;
|
||||
struct wlr_color_representation_v1_state color_repr;
|
||||
|
||||
struct {
|
||||
struct wl_listener release;
|
||||
|
|
|
|||
39
render/egl.c
39
render/egl.c
|
|
@ -6,6 +6,7 @@
|
|||
#include <unistd.h>
|
||||
#include <gbm.h>
|
||||
#include <wlr/render/egl.h>
|
||||
#include <wlr/types/wlr_color_representation_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <xf86drm.h>
|
||||
|
|
@ -733,7 +734,8 @@ bool wlr_egl_restore_context(struct wlr_egl_context *context) {
|
|||
}
|
||||
|
||||
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||
struct wlr_dmabuf_attributes *attributes, bool *external_only) {
|
||||
struct wlr_dmabuf_attributes *attributes, bool *external_only,
|
||||
const struct wlr_color_representation_v1_state *color_repr) {
|
||||
if (!egl->exts.KHR_image_base || !egl->exts.EXT_image_dma_buf_import) {
|
||||
wlr_log(WLR_ERROR, "dmabuf import extension not present");
|
||||
return NULL;
|
||||
|
|
@ -747,7 +749,7 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
|||
}
|
||||
|
||||
unsigned int atti = 0;
|
||||
EGLint attribs[50];
|
||||
EGLint attribs[54];
|
||||
attribs[atti++] = EGL_WIDTH;
|
||||
attribs[atti++] = attributes->width;
|
||||
attribs[atti++] = EGL_HEIGHT;
|
||||
|
|
@ -805,6 +807,39 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
|||
}
|
||||
}
|
||||
|
||||
// Add color representation metadata, if provided
|
||||
if (color_repr != NULL) {
|
||||
switch (color_repr->coefficients) {
|
||||
case WLR_COLOR_ENCODING_BT601:
|
||||
attribs[atti++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[atti++] = EGL_ITU_REC601_EXT;
|
||||
break;
|
||||
case WLR_COLOR_ENCODING_BT709:
|
||||
attribs[atti++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[atti++] = EGL_ITU_REC709_EXT;
|
||||
break;
|
||||
case WLR_COLOR_ENCODING_BT2020:
|
||||
attribs[atti++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[atti++] = EGL_ITU_REC2020_EXT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (color_repr->range) {
|
||||
case WLR_COLOR_RANGE_FULL:
|
||||
attribs[atti++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[atti++] = EGL_YUV_FULL_RANGE_EXT;
|
||||
break;
|
||||
case WLR_COLOR_RANGE_LIMITED:
|
||||
attribs[atti++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[atti++] = EGL_YUV_NARROW_RANGE_EXT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Our clients don't expect our usage to trash the buffer contents
|
||||
attribs[atti++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[atti++] = EGL_TRUE;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <wlr/render/egl.h>
|
||||
#include <wlr/render/interface.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_color_representation_v1.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xf86drm.h>
|
||||
|
|
@ -143,8 +145,16 @@ struct wlr_gles2_buffer *gles2_buffer_get_or_create(struct wlr_gles2_renderer *r
|
|||
goto error_buffer;
|
||||
}
|
||||
|
||||
// Try to fetch color representation if present
|
||||
const struct wlr_color_representation_v1_state *color_repr = NULL;
|
||||
struct wlr_dmabuf_v1_buffer *dmabuf_v1_buffer =
|
||||
wlr_dmabuf_v1_buffer_try_from_buffer(wlr_buffer);
|
||||
if (dmabuf_v1_buffer != NULL) {
|
||||
color_repr = &dmabuf_v1_buffer->color_repr;
|
||||
}
|
||||
|
||||
buffer->image = wlr_egl_create_image_from_dmabuf(renderer->egl,
|
||||
&dmabuf, &buffer->external_only);
|
||||
&dmabuf, &buffer->external_only, color_repr);
|
||||
if (buffer->image == EGL_NO_IMAGE_KHR) {
|
||||
goto error_buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/render/interface.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/types/wlr_color_representation_v1.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -199,6 +201,17 @@ static void surface_finalize_pending(struct wlr_surface *surface) {
|
|||
}
|
||||
|
||||
if (pending->buffer != NULL) {
|
||||
// If buffer is a dmabuf, copy color representation from surface
|
||||
struct wlr_dmabuf_v1_buffer *dmabuf_buffer =
|
||||
wlr_dmabuf_v1_buffer_try_from_buffer(pending->buffer);
|
||||
if (dmabuf_buffer != NULL) {
|
||||
const struct wlr_color_representation_v1_state *surface_color_repr =
|
||||
wlr_color_representation_v1_get_surface_state(surface);
|
||||
if (surface_color_repr != NULL) {
|
||||
dmabuf_buffer->color_repr = *surface_color_repr;
|
||||
}
|
||||
}
|
||||
|
||||
pending->buffer_width = pending->buffer->width;
|
||||
pending->buffer_height = pending->buffer->height;
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue