mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-11 13:10:07 +00:00
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.
This commit is contained in:
parent
5eb42dd9f3
commit
cdc85232b2
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
|
||||
priv->egl_surface = NULL;
|
||||
}
|
||||
|
||||
if (priv->egl_surface == NULL)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (self);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user