gl-renderer: add support for (a|x)bgr2101010 shm formats

Adding these formats makes it possible for clients using wl_shm to
submit buffers with 10 bits per pixel, and thus (if Weston is
configured with an xrgb2101010 frame buffer) display more precise
colors on some computer monitors.

Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
This commit is contained in:
Manuel Stoeckl 2021-10-20 20:52:11 -04:00 committed by Pekka Paalanen
parent b02149e43b
commit c7fbc97120
2 changed files with 44 additions and 7 deletions

View File

@ -151,6 +151,7 @@ struct gl_renderer {
struct wl_list dmabuf_images; struct wl_list dmabuf_images;
struct wl_list dmabuf_formats; struct wl_list dmabuf_formats;
bool has_texture_type_2_10_10_10_rev;
bool has_gl_texture_rg; bool has_gl_texture_rg;
struct gl_shader *current_shader; struct gl_shader *current_shader;

View File

@ -1821,6 +1821,8 @@ gl_format_from_internal(GLenum internal_format)
return GL_RED_EXT; return GL_RED_EXT;
case GL_RG8_EXT: case GL_RG8_EXT:
return GL_RG_EXT; return GL_RG_EXT;
case GL_RGB10_A2:
return GL_RGBA;
default: default:
return internal_format; return internal_format;
} }
@ -1959,6 +1961,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
GLenum gl_pixel_type; GLenum gl_pixel_type;
int pitch; int pitch;
int num_planes; int num_planes;
bool using_glesv2 = gr->gl_version < gr_gl_version(3, 0);
buffer->shm_buffer = shm_buffer; buffer->shm_buffer = shm_buffer;
buffer->width = wl_shm_buffer_get_width(shm_buffer); buffer->width = wl_shm_buffer_get_width(shm_buffer);
@ -1991,6 +1994,28 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
gl_pixel_type = GL_UNSIGNED_SHORT_5_6_5; gl_pixel_type = GL_UNSIGNED_SHORT_5_6_5;
es->is_opaque = true; es->is_opaque = true;
break; break;
#if __BYTE_ORDER == __LITTLE_ENDIAN
case WL_SHM_FORMAT_ABGR2101010:
if (!gr->has_texture_type_2_10_10_10_rev) {
goto unsupported;
}
gs->shader_variant = SHADER_VARIANT_RGBA;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = using_glesv2 ? GL_RGBA : GL_RGB10_A2;
gl_pixel_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
es->is_opaque = false;
break;
case WL_SHM_FORMAT_XBGR2101010:
if (!gr->has_texture_type_2_10_10_10_rev) {
goto unsupported;
}
gs->shader_variant = SHADER_VARIANT_RGBX;
pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
gl_format[0] = using_glesv2 ? GL_RGBA : GL_RGB10_A2;
gl_pixel_type = GL_UNSIGNED_INT_2_10_10_10_REV_EXT;
es->is_opaque = true;
break;
#endif
case WL_SHM_FORMAT_YUV420: case WL_SHM_FORMAT_YUV420:
gs->shader_variant = SHADER_VARIANT_Y_U_V; gs->shader_variant = SHADER_VARIANT_Y_U_V;
pitch = wl_shm_buffer_get_stride(shm_buffer); pitch = wl_shm_buffer_get_stride(shm_buffer);
@ -2061,7 +2086,8 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
es->is_opaque = true; es->is_opaque = true;
break; break;
default: default:
weston_log("warning: unknown shm buffer format: %08x\n", unsupported:
weston_log("warning: unknown or unsupported shm buffer format: %08x\n",
wl_shm_buffer_get_format(shm_buffer)); wl_shm_buffer_get_format(shm_buffer));
return; return;
} }
@ -3654,12 +3680,6 @@ gl_renderer_display_create(struct weston_compositor *ec,
goto fail_with_error; goto fail_with_error;
} }
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_YUV420);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_NV12);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_YUYV);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_XYUV8888);
wl_signal_init(&gr->destroy_signal); wl_signal_init(&gr->destroy_signal);
if (gl_renderer_setup(ec, gr->dummy_surface) < 0) { if (gl_renderer_setup(ec, gr->dummy_surface) < 0) {
@ -3669,6 +3689,18 @@ gl_renderer_display_create(struct weston_compositor *ec,
goto fail_with_error; goto fail_with_error;
} }
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_YUV420);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_NV12);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_YUYV);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_XYUV8888);
#if __BYTE_ORDER == __LITTLE_ENDIAN
if (gr->has_texture_type_2_10_10_10_rev) {
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_ABGR2101010);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_XBGR2101010);
}
#endif
if (gr->gl_supports_color_transforms) if (gr->gl_supports_color_transforms)
ec->capabilities |= WESTON_CAP_COLOR_OPS; ec->capabilities |= WESTON_CAP_COLOR_OPS;
@ -3830,6 +3862,10 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
return -1; return -1;
} }
if (gr->gl_version >= gr_gl_version(3, 0) ||
weston_check_egl_extension(extensions, "GL_EXT_texture_type_2_10_10_10_REV"))
gr->has_texture_type_2_10_10_10_rev = true;
if (gr->gl_version >= gr_gl_version(3, 0) || if (gr->gl_version >= gr_gl_version(3, 0) ||
weston_check_egl_extension(extensions, "GL_EXT_texture_rg")) weston_check_egl_extension(extensions, "GL_EXT_texture_rg"))
gr->has_gl_texture_rg = true; gr->has_gl_texture_rg = true;