diff --git a/gdk/gdk.c b/gdk/gdk.c index 3d1457e075..8c0bdaff00 100644 --- a/gdk/gdk.c +++ b/gdk/gdk.c @@ -121,6 +121,7 @@ static const GdkDebugKey gdk_debug_keys[] = { { "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE }, { "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE }, { "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE }, + { "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE }, { "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE }, { "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE }, { "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE }, diff --git a/gdk/gdkdebugprivate.h b/gdk/gdkdebugprivate.h index bbcf2d4630..d41cf3178f 100644 --- a/gdk/gdkdebugprivate.h +++ b/gdk/gdkdebugprivate.h @@ -41,6 +41,7 @@ typedef enum { GDK_DEBUG_PORTALS = 1 << 12, GDK_DEBUG_NO_PORTALS = 1 << 13, GDK_DEBUG_GL_DISABLE = 1 << 14, + GDK_DEBUG_GL_FRACTIONAL = 1 << 15, GDK_DEBUG_GL_LEGACY = 1 << 16, GDK_DEBUG_GL_GLES = 1 << 17, GDK_DEBUG_GL_DEBUG = 1 << 18, diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index b8972e57f8..8614ec3e83 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -560,6 +560,23 @@ gdk_gl_context_real_make_current (GdkGLContext *context, #endif } +double +gdk_gl_context_get_scale (GdkGLContext *self) +{ + GdkDisplay *display; + GdkSurface *surface; + double scale; + + surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self)); + scale = gdk_surface_get_scale (surface); + + display = gdk_gl_context_get_display (self); + if (!(gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL)) + scale = ceil (scale); + + return scale; +} + static void gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context, gboolean prefers_high_depth, @@ -569,9 +586,11 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context, G_GNUC_UNUSED GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); GdkSurface *surface; cairo_region_t *damage; + double scale; int ww, wh; surface = gdk_draw_context_get_surface (draw_context); + scale = gdk_gl_context_get_scale (context); #ifdef HAVE_EGL if (priv->egl_context) @@ -588,8 +607,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context, cairo_region_union (region, damage); cairo_region_destroy (damage); - ww = (int) ceil (gdk_surface_get_width (surface) * gdk_surface_get_scale (surface)); - wh = (int) ceil (gdk_surface_get_height (surface) * gdk_surface_get_scale (surface)); + ww = (int) ceil (gdk_surface_get_width (surface) * scale); + wh = (int) ceil (gdk_surface_get_height (surface) * scale); gdk_gl_context_make_current (context); @@ -633,7 +652,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context, EGLint *heap_rects = NULL; int i, j, n_rects = cairo_region_num_rectangles (painted); int surface_height = gdk_surface_get_height (surface); - double scale = gdk_surface_get_scale (surface); + double scale = gdk_gl_context_get_scale (context); EGLint *rects; if (n_rects < G_N_ELEMENTS (stack_rects) / 4) diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index 2f19e96b1c..847b1c54a0 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -167,5 +167,7 @@ gboolean gdk_gl_context_use_es_bgra (GdkGLContext gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext *self) G_GNUC_PURE; +double gdk_gl_context_get_scale (GdkGLContext *self); + G_END_DECLS diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index f51f081a43..ca27f65373 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -230,6 +230,30 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, gdk_wayland_surface_create_wl_surface (surface); } +static inline void +get_egl_window_size (GdkSurface *surface, + int *width, + int *height) +{ + GdkDisplay *display = gdk_surface_get_display (surface); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL) + { + GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window", gdk_fractional_scale_to_double (&impl->scale)); + + *width = gdk_fractional_scale_scale (&impl->scale, surface->width), + *height = gdk_fractional_scale_scale (&impl->scale, surface->height); + } + else + { + GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window", gdk_fractional_scale_to_int (&impl->scale)); + + *width = surface->width * gdk_fractional_scale_to_int (&impl->scale); + *height = surface->height * gdk_fractional_scale_to_int (&impl->scale); + } +} + void gdk_wayland_surface_update_size (GdkSurface *surface, int32_t width, @@ -258,10 +282,11 @@ gdk_wayland_surface_update_size (GdkSurface *surface, impl->viewport_dirty = TRUE; if (impl->display_server.egl_window) - wl_egl_window_resize (impl->display_server.egl_window, - gdk_fractional_scale_scale (scale, width), - gdk_fractional_scale_scale (scale, height), - 0, 0); + { + int w, h; + get_egl_window_size (surface, &w, &h); + wl_egl_window_resize (impl->display_server.egl_window, w, h, 0, 0); + } gdk_surface_invalidate_rect (surface, NULL); @@ -1363,10 +1388,11 @@ gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface) if (impl->display_server.egl_window == NULL) { + int width, height; + + get_egl_window_size (surface, &width, &height); impl->display_server.egl_window = - wl_egl_window_create (impl->display_server.wl_surface, - gdk_fractional_scale_scale (&impl->scale, surface->width), - gdk_fractional_scale_scale (&impl->scale, surface->height)); + wl_egl_window_create (impl->display_server.wl_surface, width, height); gdk_surface_set_egl_native_window (surface, impl->display_server.egl_window); } } diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index eb3c77c72f..8451ad9563 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -288,7 +288,7 @@ gsk_gl_renderer_render (GskRenderer *renderer, g_assert (root != NULL); surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context)); - scale = gdk_surface_get_scale (surface); + scale = gdk_gl_context_get_scale (self->context); viewport.origin.x = 0; viewport.origin.y = 0;