[gtk/wip/otte/gl-hdr: 18/18] egl: Implement HDR support
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/gl-hdr: 18/18] egl: Implement HDR support
- Date: Wed, 6 Oct 2021 01:45:28 +0000 (UTC)
commit cdc85232b22758b99b2574838bdfda473b978f27
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 6 03:33:24 2021 +0200
egl: Implement HDR support
If EGL supports:
* no-config contexts
* >8bits pixel formats
* (optionally) floating point pixel formats
Then select such a profile as the HDR format and use it when HDR is
requested.
gdk/gdkdisplay.c | 48 +++++++++++++++++++++++++++++++++++++++---------
gdk/gdkdisplayprivate.h | 2 ++
gdk/gdkglcontext.c | 9 ++++++++-
gdk/gdksurface.c | 29 +++++++++++++++++++++++------
gdk/gdksurfaceprivate.h | 2 ++
5 files changed, 74 insertions(+), 16 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index cedd0856bc..25f940c47b 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -93,6 +93,7 @@ struct _GdkDisplayPrivate {
#ifdef HAVE_EGL
EGLDisplay egl_display;
EGLConfig egl_config;
+ EGLConfig egl_config_hdr;
#endif
guint rgba : 1;
@@ -1437,6 +1438,14 @@ gdk_display_get_egl_config (GdkDisplay *self)
return priv->egl_config;
}
+gpointer
+gdk_display_get_egl_config_hdr (GdkDisplay *self)
+{
+ GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+
+ return priv->egl_config;
+}
+
static EGLDisplay
gdk_display_create_egl_display (EGLenum platform,
gpointer native_display)
@@ -1477,7 +1486,8 @@ out:
#define MAX_EGL_ATTRS 30
typedef enum {
- GDK_EGL_CONFIG_PERFECT = (1 << 0)
+ GDK_EGL_CONFIG_PERFECT = (1 << 0),
+ GDK_EGL_CONFIG_HDR = (1 << 1),
} GdkEGLConfigCreateFlags;
static EGLConfig
@@ -1502,14 +1512,21 @@ gdk_display_create_egl_config (GdkDisplay *self,
attrs[i++] = EGL_RGB_BUFFER;
attrs[i++] = EGL_RED_SIZE;
- attrs[i++] = 8;
+ attrs[i++] = (flags & GDK_EGL_CONFIG_HDR) ? 9 : 8;
attrs[i++] = EGL_GREEN_SIZE;
- attrs[i++] = 8;
+ attrs[i++] = (flags & GDK_EGL_CONFIG_HDR) ? 9 : 8;
attrs[i++] = EGL_BLUE_SIZE;
- attrs[i++] = 8;
+ attrs[i++] = (flags & GDK_EGL_CONFIG_HDR) ? 9 : 8;
attrs[i++] = EGL_ALPHA_SIZE;
attrs[i++] = 8;
+ if (flags & GDK_EGL_CONFIG_HDR &&
+ self->have_egl_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);
@@ -1700,23 +1717,36 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_swap_buffers_with_damage");
self->have_egl_no_config_context =
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
+ self->have_egl_pixel_format_float =
+ epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
+
+ if (self->have_egl_no_config_context)
+ priv->egl_config_hdr = gdk_display_create_egl_config (self,
+ GDK_EGL_CONFIG_HDR,
+ error);
+ if (priv->egl_config_hdr == NULL)
+ priv->egl_config_hdr = priv->egl_config;
GDK_DISPLAY_NOTE (self, OPENGL, {
char *ext = describe_extensions (priv->egl_display);
- char *cfg = describe_egl_config (priv->egl_display, priv->egl_config);
+ char *sdr_cfg = describe_egl_config (priv->egl_display, priv->egl_config);
+ char *hdr_cfg = describe_egl_config (priv->egl_display, priv->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"
- " - Selected fbconfig: %s",
+ "\t%s\n"
+ " - Selected fbconfig: %s\n"
+ " HDR fbconfig: %s",
major, minor,
eglQueryString (priv->egl_display, EGL_VENDOR),
eglQueryString (priv->egl_display, EGL_VERSION),
eglQueryString (priv->egl_display, EGL_CLIENT_APIS),
- ext, cfg);
- g_free (cfg);
+ ext, sdr_cfg,
+ priv->egl_config_hdr == priv->egl_config ? "none" : hdr_cfg);
+ g_free (hdr_cfg);
+ g_free (sdr_cfg);
g_free (ext);
});
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 3b7a18f4b3..4cb85b2ea4 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -109,6 +109,7 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_swap_buffers_with_damage : 1;
guint have_egl_no_config_context : 1;
+ guint have_egl_pixel_format_float : 1;
};
struct _GdkDisplayClass
@@ -225,6 +226,7 @@ gboolean gdk_display_init_egl (GdkDisplay *display
GError **error);
gpointer gdk_display_get_egl_display (GdkDisplay *display);
gpointer gdk_display_get_egl_config (GdkDisplay *display);
+gpointer gdk_display_get_egl_config_hdr (GdkDisplay *display);
void gdk_display_set_rgba (GdkDisplay *display,
gboolean rgba);
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 73b82e8d41..11c3f77dd4 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -633,10 +633,18 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *region)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
+ G_GNUC_UNUSED GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkSurface *surface;
cairo_region_t *damage;
int ww, wh;
+ surface = gdk_draw_context_get_surface (draw_context);
+
+#ifdef HAVE_EGL
+ if (priv->egl_context)
+ gdk_surface_ensure_egl_surface (surface, request_hdr);
+#endif
+
damage = GDK_GL_CONTEXT_GET_CLASS (context)->get_damage (context);
if (context->old_updated_area[1])
@@ -647,7 +655,6 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
cairo_region_union (region, damage);
cairo_region_destroy (damage);
- surface = gdk_draw_context_get_surface (draw_context);
ww = gdk_surface_get_width (surface) * gdk_surface_get_scale_factor (surface);
wh = gdk_surface_get_height (surface) * gdk_surface_get_scale_factor (surface);
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index c64c2a6a47..13d779a817 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -71,6 +71,7 @@ struct _GdkSurfacePrivate
gpointer egl_native_window;
#ifdef HAVE_EGL
EGLSurface egl_surface;
+ gboolean egl_surface_hdr;
#endif
gpointer widget;
@@ -1103,19 +1104,35 @@ gdk_surface_get_egl_surface (GdkSurface *self)
{
GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
- g_return_val_if_fail (priv->egl_native_window != NULL, NULL);
+ return priv->egl_surface;
+}
- if (priv->egl_surface == NULL)
+void
+gdk_surface_ensure_egl_surface (GdkSurface *self,
+ gboolean hdr)
+{
+ GdkSurfacePrivate *priv = gdk_surface_get_instance_private (self);
+ GdkDisplay *display = gdk_surface_get_display (self);
+
+ g_return_if_fail (priv->egl_native_window != NULL);
+
+ if (priv->egl_surface_hdr != hdr &&
+ priv->egl_surface != NULL &&
+ gdk_display_get_egl_config_hdr (display) != gdk_display_get_egl_config (display))
{
- GdkDisplay *display = gdk_surface_get_display (self);
+ eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
+ priv->egl_surface = NULL;
+ }
+ if (priv->egl_surface == NULL)
+ {
priv->egl_surface = eglCreateWindowSurface (gdk_display_get_egl_display (display),
- gdk_display_get_egl_config (display),
+ hdr ? gdk_display_get_egl_config_hdr (display)
+ : gdk_display_get_egl_config (display),
(EGLNativeWindowType) priv->egl_native_window,
NULL);
+ priv->egl_surface_hdr = hdr;
}
-
- return priv->egl_surface;
#endif
}
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index ec9f177e5e..c53368574d 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -294,6 +294,8 @@ void gdk_surface_get_geometry (GdkSurface *surface,
void gdk_surface_set_egl_native_window (GdkSurface *self,
gpointer native_window);
+void gdk_surface_ensure_egl_surface (GdkSurface *self,
+ gboolean hdr);
gpointer /*EGLSurface*/ gdk_surface_get_egl_surface (GdkSurface *self);
void gdk_surface_set_widget (GdkSurface *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]