[gtk/matthiasc/color-profiles: 8/9] wayland: Allow picking sdr or hdr configs
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profiles: 8/9] wayland: Allow picking sdr or hdr configs
- Date: Fri, 1 Oct 2021 18:24:22 +0000 (UTC)
commit ba439f73e3c93dde2fcd6d2a050a59941b9ca8c5
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Oct 1 14:21:23 2021 -0400
wayland: Allow picking sdr or hdr configs
Add gdk_wayland_surface_set_rendering which lets
applications hint if they would prefer SDR or HDR
rendering, or don't care. We then try to pick a
suitable EGLConfig for creating the surface. This
only works if we have the KHR_no_config_context
extension available.
gdk/wayland/gdkdisplay-wayland.h | 3 +-
gdk/wayland/gdkglcontext-wayland.c | 119 +++++++++++++++++++++----------------
gdk/wayland/gdkprivate-wayland.h | 3 +
gdk/wayland/gdksurface-wayland.c | 39 +++++++++++-
gdk/wayland/gdkwaylandsurface.h | 12 ++++
5 files changed, 121 insertions(+), 55 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 80767ae387..da5410df9a 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -59,6 +59,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS];
+ EGLConfig config;
int major, minor, flags;
gboolean debug_bit, forward_bit, legacy_bit, use_es;
int i = 0;
@@ -121,8 +122,13 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
legacy_bit ? "yes" : "no",
use_es ? "yes" : "no"));
+ if (epoxy_has_egl_extension (display_wayland->egl_display, "KHR_no_config_context"))
+ config = EGL_NO_CONFIG_KHR;
+ else
+ config = display_wayland->egl_config_hdr;
+
ctx = eglCreateContext (display_wayland->egl_display,
- display_wayland->egl_config,
+ config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
: EGL_NO_CONTEXT,
context_attribs);
@@ -148,7 +154,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
GDK_DISPLAY_NOTE (display, OPENGL,
g_message ("eglCreateContext failed, switching to OpenGLĀ ES"));
ctx = eglCreateContext (display_wayland->egl_display,
- display_wayland->egl_config,
+ config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
: EGL_NO_CONTEXT,
context_attribs);
@@ -177,7 +183,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
GDK_DISPLAY_NOTE (display, OPENGL,
g_message ("eglCreateContext failed, switching to legacy"));
ctx = eglCreateContext (display_wayland->egl_display,
- display_wayland->egl_config,
+ config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
: EGL_NO_CONTEXT,
context_attribs);
@@ -430,52 +436,56 @@ 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 n_configs;
EGLConfig *configs;
- int pass, i;
+ EGLint type_hdr;
+ int i;
- n_configs = 0;
+ *config_sdr = 0;
+ *config_hdr = 0;
- for (pass = 0; pass <= 1; pass++)
- {
- i = 0;
+ n_configs = 0;
- attrs[i++] = EGL_SURFACE_TYPE;
- attrs[i++] = EGL_WINDOW_BIT;
+ i = 0;
- attrs[i++] = EGL_COLOR_BUFFER_TYPE;
- attrs[i++] = EGL_RGB_BUFFER;
+ attrs[i++] = EGL_SURFACE_TYPE;
+ attrs[i++] = EGL_WINDOW_BIT;
- attrs[i++] = EGL_RED_SIZE;
- attrs[i++] = 8;
- attrs[i++] = EGL_GREEN_SIZE;
- attrs[i++] = 8;
- attrs[i++] = EGL_BLUE_SIZE;
- attrs[i++] = 8;
- attrs[i++] = EGL_ALPHA_SIZE;
- attrs[i++] = 8;
+ attrs[i++] = EGL_COLOR_BUFFER_TYPE;
+ attrs[i++] = EGL_RGB_BUFFER;
- if (pass == 0 && epoxy_has_egl_extension (dpy, "EGL_EXT_pixel_format_float"))
- {
- attrs[i++] = EGL_COLOR_COMPONENT_TYPE_EXT;
- attrs[i++] = EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
- }
+ attrs[i++] = EGL_RED_SIZE;
+ attrs[i++] = 8;
+ attrs[i++] = EGL_GREEN_SIZE;
+ attrs[i++] = 8;
+ attrs[i++] = EGL_BLUE_SIZE;
+ attrs[i++] = 8;
+ attrs[i++] = EGL_ALPHA_SIZE;
+ attrs[i++] = 8;
- attrs[i++] = EGL_NONE;
- g_assert (i < MAX_EGL_ATTRS);
+ if (epoxy_has_egl_extension (dpy, "EGL_EXT_pixel_format_float"))
+ {
+ attrs[i++] = EGL_COLOR_COMPONENT_TYPE_EXT;
+ attrs[i++] = EGL_DONT_CARE;
+ }
- eglChooseConfig (dpy, attrs, NULL, -1, &n_configs);
+ attrs[i++] = EGL_NONE;
+ g_assert (i < MAX_EGL_ATTRS);
- if (n_configs > 0)
- break;
- }
+ 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;
@@ -494,21 +504,20 @@ get_eglconfig (EGLDisplay dpy)
else
type = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
- if (type == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
+ if (*config_sdr == 0 &&
+ type == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT &&
+ red == 8 && green == 8 && blue == 8 && alpha == 8)
{
- /* return the first fp16 config */
- if (red == 16 && green == 16 && blue == 16 && alpha == 16)
- return configs[i];
+ *config_sdr = configs[i];
}
- else
+
+ if ((type_hdr == 0 || type == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) &&
+ red == 16 && green == 16 && blue == 16 && alpha == 16)
{
- /* return the first rgba8 config */
- if (red == 8 && green == 8 && blue == 8 && alpha == 8)
- return configs[i];
+ *config_hdr = configs[i];
+ type_hdr = type;
}
}
-
- return NULL;
}
#undef MAX_EGL_ATTRS
@@ -544,17 +553,20 @@ describe_extensions (EGLDisplay dpy)
return g_strstrip (ext);
}
-static char *
+char *
describe_egl_config (EGLDisplay dpy,
EGLConfig config)
{
EGLint red, green, blue, alpha, type;
+ if (!config)
+ return g_strdup ("-");
+
if (!eglGetConfigAttrib (dpy, config, EGL_RED_SIZE, &red) ||
!eglGetConfigAttrib (dpy, config, EGL_GREEN_SIZE, &green) ||
!eglGetConfigAttrib (dpy, config, EGL_BLUE_SIZE, &blue) ||
!eglGetConfigAttrib (dpy, config, EGL_ALPHA_SIZE, &alpha))
- return g_strdup ("Undisclosed");
+ return g_strdup ("Unknown");
if (epoxy_has_egl_extension (dpy, "EGL_EXT_pixel_format_float"))
{
@@ -657,14 +669,14 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
}
start_time2 = GDK_PROFILER_CURRENT_TIME;
- display_wayland->egl_config = get_eglconfig (dpy);
+ get_eglconfig (dpy, &display_wayland->egl_config_sdr, &display_wayland->egl_config_hdr);
gdk_profiler_end_mark (start_time2, "get_eglconfig", NULL);
- if (!display_wayland->egl_config)
+ if (!display_wayland->egl_config_sdr && !display_wayland->egl_config_hdr)
{
eglTerminate (dpy);
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- _("No available configurations for the given pixel format"));
+ _("No available configurations"));
return NULL;
}
@@ -680,22 +692,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/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index df072b4f8f..e34e80ff8c 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -202,4 +202,7 @@ GdkSurface * create_dnd_surface (GdkDisplay *display);
GdkModifierType gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap,
guint32 mods);
+char * describe_egl_config (EGLDisplay dpy,
+ EGLConfig config);
+
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 4d1951e66d..232b8d429e 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 rendering : 2;
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->rendering = GDK_RENDERING_NONE;
}
static void
@@ -4353,7 +4355,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 +4362,33 @@ 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);
+ switch (impl->rendering)
+ {
+ case GDK_RENDERING_NONE:
+ case GDK_RENDERING_HDR:
+ if (display->egl_config_hdr)
+ config = display->egl_config_hdr;
+ else
+ config = display->egl_config_sdr;
+ break;
+ case GDK_RENDERING_SDR:
+ config = display->egl_config_sdr;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ 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;
@@ -5176,3 +5200,14 @@ gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
iface->present = gdk_wayland_drag_surface_present;
}
+void
+gdk_wayland_surface_set_rendering (GdkSurface *surface,
+ GdkRendering rendering)
+{
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+ g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
+ g_return_if_fail (impl->egl_surface == 0);
+
+ impl->rendering = rendering;
+}
diff --git a/gdk/wayland/gdkwaylandsurface.h b/gdk/wayland/gdkwaylandsurface.h
index 851a4d5607..03fbc7237e 100644
--- a/gdk/wayland/gdkwaylandsurface.h
+++ b/gdk/wayland/gdkwaylandsurface.h
@@ -83,6 +83,18 @@ GDK_AVAILABLE_IN_ALL
void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
const char *application_id);
+typedef enum
+{
+ GDK_RENDERING_NONE,
+ GDK_RENDERING_SDR,
+ GDK_RENDERING_HDR,
+} GdkRendering;
+
+GDK_AVAILABLE_IN_4_6
+void gdk_wayland_surface_set_rendering (GdkSurface *surface,
+ GdkRendering rendering);
+
+
G_END_DECLS
#endif /* __GDK_WAYLAND_SURFACE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]