[gtk/matthiasc/color-profiles: 19/32] wayland: Implement set_hdr
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profiles: 19/32] wayland: Implement set_hdr
- Date: Sun, 3 Oct 2021 20:23:25 +0000 (UTC)
commit 672d55cee1f98657deb6c6960aa24b6e275a9dc1
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Oct 1 20:25:56 2021 -0400
wayland: Implement set_hdr
Keep both an HDR and an SDR EGLConfig around,
and implement set_hdr by recreating the EGL surface
with the right config.
gdk/wayland/gdkdisplay-wayland.h | 3 +-
gdk/wayland/gdkglcontext-wayland.c | 80 +++++++++++++++++++++++++++++++-------
gdk/wayland/gdksurface-wayland.c | 46 ++++++++++++++++++++--
3 files changed, 112 insertions(+), 17 deletions(-)
---
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 932f39cb6c..4789331ddd 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -152,7 +152,8 @@ struct _GdkWaylandDisplay
/* egl info */
EGLDisplay egl_display;
- EGLConfig egl_config;
+ EGLConfig egl_config_sdr;
+ EGLConfig egl_config_hdr;
int egl_major_version;
int egl_minor_version;
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index f47bc0eb69..5931dfce31 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -435,13 +435,23 @@ out:
#define MAX_EGL_ATTRS 30
-static EGLConfig
-get_eglconfig (EGLDisplay dpy)
+static void
+get_eglconfig (EGLDisplay dpy,
+ EGLConfig *config_sdr,
+ EGLConfig *config_hdr)
{
EGLint attrs[MAX_EGL_ATTRS];
- EGLint count;
- EGLConfig config;
- int i = 0;
+ EGLint n_configs;
+ EGLConfig *configs;
+ EGLint type_hdr;
+ int i;
+
+ *config_sdr = 0;
+ *config_hdr = 0;
+
+ n_configs = 0;
+
+ i = 0;
attrs[i++] = EGL_SURFACE_TYPE;
attrs[i++] = EGL_WINDOW_BIT;
@@ -458,14 +468,55 @@ get_eglconfig (EGLDisplay dpy)
attrs[i++] = EGL_ALPHA_SIZE;
attrs[i++] = 8;
+ if (epoxy_has_egl_extension (dpy, "EGL_EXT_pixel_format_float"))
+ {
+ attrs[i++] = EGL_COLOR_COMPONENT_TYPE_EXT;
+ attrs[i++] = EGL_DONT_CARE;
+ }
+
attrs[i++] = EGL_NONE;
g_assert (i < MAX_EGL_ATTRS);
- /* Pick first valid configuration i guess? */
- if (!eglChooseConfig (dpy, attrs, &config, 1, &count) || count < 1)
- return NULL;
+ eglChooseConfig (dpy, attrs, NULL, -1, &n_configs);
+
+ configs = g_alloca (sizeof (EGLConfig) * n_configs);
+
+ eglChooseConfig (dpy, attrs, configs, n_configs, &n_configs);
+
+ type_hdr = 0;
+
+ for (i = 0; i < n_configs; i++)
+ {
+ EGLint red, green, blue, alpha, type;
+
+ if (!eglGetConfigAttrib (dpy, configs[i], EGL_RED_SIZE, &red) ||
+ !eglGetConfigAttrib (dpy, configs[i], EGL_GREEN_SIZE, &green) ||
+ !eglGetConfigAttrib (dpy, configs[i], EGL_BLUE_SIZE, &blue) ||
+ !eglGetConfigAttrib (dpy, configs[i], EGL_ALPHA_SIZE, &alpha))
+ continue;
+
+ if (epoxy_has_egl_extension (dpy, "EGL_EXT_pixel_format_float"))
+ {
+ if (!eglGetConfigAttrib (dpy, configs[i], EGL_COLOR_COMPONENT_TYPE_EXT, &type))
+ type = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+ }
+ else
+ type = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
- return config;
+ if (*config_sdr == 0 &&
+ type == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT &&
+ red == 8 && green == 8 && blue == 8 && alpha == 8)
+ {
+ *config_sdr = configs[i];
+ }
+
+ if ((type_hdr == 0 || type == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) &&
+ red == 16 && green == 16 && blue == 16 && alpha == 16)
+ {
+ *config_hdr = configs[i];
+ type_hdr = type;
+ }
+ }
}
#undef MAX_EGL_ATTRS
@@ -649,22 +700,25 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
GDK_DISPLAY_NOTE (display, OPENGL, {
char *ext = describe_extensions (dpy);
- char *cfg = describe_egl_config (dpy, display_wayland->egl_config);
+ char *cfg_sdr = describe_egl_config (dpy, display_wayland->egl_config_sdr);
+ char *cfg_hdr = describe_egl_config (dpy, display_wayland->egl_config_hdr);
g_message ("EGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Version: %s\n"
" - Client APIs: %s\n"
" - Extensions:\n"
"\t%s\n"
- " - Selected fbconfig: %s",
+ " - SDR config: %s\n"
+ " - HDR config: %s",
display_wayland->egl_major_version,
display_wayland->egl_minor_version,
eglQueryString (dpy, EGL_VENDOR),
eglQueryString (dpy, EGL_VERSION),
eglQueryString (dpy, EGL_CLIENT_APIS),
- ext, cfg);
- g_free (cfg);
+ ext, cfg_sdr, cfg_hdr);
g_free (ext);
+ g_free (cfg_sdr);
+ g_free (cfg_hdr);
});
ctx = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 4d1951e66d..f7308d7c52 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -123,6 +123,7 @@ struct _GdkWaylandSurface
unsigned int awaiting_frame : 1;
unsigned int awaiting_frame_frozen : 1;
unsigned int is_drag_surface : 1;
+ unsigned int hdr : 1;
int pending_buffer_offset_x;
int pending_buffer_offset_y;
@@ -346,6 +347,7 @@ gdk_wayland_surface_init (GdkWaylandSurface *impl)
impl->saved_width = -1;
impl->saved_height = -1;
impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
+ impl->hdr = FALSE;
}
static void
@@ -4262,6 +4264,33 @@ gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface)
return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION;
}
+static void
+gdk_wayland_surface_set_hdr (GdkSurface *surface,
+ gboolean hdr)
+{
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ GdkWaylandDisplay *display_wayland =
+ GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+
+ if (impl->hdr == hdr)
+ return;
+
+ if (!display_wayland->egl_config_hdr)
+ return;
+
+ impl->hdr = hdr;
+
+ if (impl->egl_surface)
+ {
+ GDK_DISPLAY_NOTE (GDK_DISPLAY (display_wayland), OPENGL,
+ g_message ("Rendering changed to %s, resetting egl surface",
+ hdr ? "HDR" : "SDR"));
+
+ eglDestroySurface (display_wayland->egl_display, impl->egl_surface);
+ impl->egl_surface = NULL;
+ }
+}
+
static void
gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
{
@@ -4279,6 +4308,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->set_input_region = gdk_wayland_surface_set_input_region;
impl_class->destroy = gdk_wayland_surface_destroy;
impl_class->beep = gdk_wayland_surface_beep;
+ impl_class->set_hdr = gdk_wayland_surface_set_hdr;
impl_class->destroy_notify = gdk_wayland_surface_destroy_notify;
impl_class->drag_begin = _gdk_wayland_surface_drag_begin;
@@ -4353,7 +4383,6 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
{
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSurface *impl;
- struct wl_egl_window *egl_window;
g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
@@ -4361,10 +4390,22 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface)
if (impl->egl_surface == NULL)
{
+ struct wl_egl_window *egl_window;
+ EGLConfig config;
+
egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
+ if (impl->hdr && display->egl_config_hdr)
+ config = display->egl_config_hdr;
+ else
+ config = display->egl_config_sdr;
+
+ GDK_DISPLAY_NOTE (GDK_DISPLAY (display), OPENGL,
+ g_message ("Create EGL surface with config: %s",
+ describe_egl_config (display->egl_display, config)));
+
impl->egl_surface =
- eglCreateWindowSurface (display->egl_display, display->egl_config, egl_window, NULL);
+ eglCreateWindowSurface (display->egl_display, config, egl_window, NULL);
}
return impl->egl_surface;
@@ -5175,4 +5216,3 @@ gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
{
iface->present = gdk_wayland_drag_surface_present;
}
-
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]