vulkan: Support fractional scaling
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Mon, 3 Apr 2023 13:39:25 +0000 (10:39 -0300)
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Mon, 3 Apr 2023 14:10:27 +0000 (11:10 -0300)
Basically what GL does, but without any debug or feature flag
to gatekeep it, since the Vulkan backend itself is experimental
already.

Ceil surface sizes, and floor coordinates, to the fractional scale
value.

gdk/gdkvulkancontext.c
gsk/vulkan/gskvulkanrender.c
gsk/vulkan/gskvulkanrenderer.c

index 3f669bfc4da4a3b55604c8ecf38fe0e90b924f2a..f1f41ce6c9657ffc65f8a40d8a6c81db28312f5f 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "gdkdisplayprivate.h"
 #include <glib/gi18n-lib.h>
+#include <math.h>
 
 /**
  * GdkVulkanContext:
@@ -339,8 +340,10 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext  *context,
    */
   if (capabilities.currentExtent.width == -1 || capabilities.currentExtent.height == -1)
     {
-      capabilities.currentExtent.width = MAX (1, gdk_surface_get_width (surface) * gdk_surface_get_scale_factor (surface));
-      capabilities.currentExtent.height = MAX (1, gdk_surface_get_height (surface) * gdk_surface_get_scale_factor (surface));
+      double scale = gdk_surface_get_scale (surface);
+
+      capabilities.currentExtent.width = MAX (1, (int) ceil (gdk_surface_get_width (surface) * scale));
+      capabilities.currentExtent.height = MAX (1, (int) ceil (gdk_surface_get_height (surface) * scale));
     }
 
   res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
@@ -475,10 +478,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
   VkPresentRegionsKHR *regionsptr = VK_NULL_HANDLE;
   VkPresentRegionsKHR regions;
   VkRectLayerKHR *rectangles;
+  double scale;
   int n_regions;
-  int scale;
 
-  scale = gdk_surface_get_scale_factor (surface);
+  scale = gdk_surface_get_scale (surface);
   n_regions = cairo_region_num_rectangles (painted);
   rectangles = g_alloca (sizeof (VkRectLayerKHR) * n_regions);
 
@@ -490,10 +493,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
 
       rectangles[i] = (VkRectLayerKHR) {
           .layer = 0,
-          .offset.x = r.x * scale,
-          .offset.y = r.y * scale,
-          .extent.width = r.width * scale,
-          .extent.height = r.height * scale,
+          .offset.x = (int) floor (r.x * scale),
+          .offset.y = (int) floor (r.y * scale),
+          .extent.width = (int) ceil (r.width * scale),
+          .extent.height = (int) ceil (r.height * scale),
       };
     }
 
index b0d4f1f10a8e86e664276d175271e6d9fdb3a578..586678c2e4c7b554d7a6397a6e5fce86ea571bfc 100644 (file)
@@ -31,7 +31,7 @@ struct _GskVulkanRender
   GskRenderer *renderer;
   GdkVulkanContext *vulkan;
 
-  int scale_factor;
+  double scale;
   graphene_rect_t viewport;
   cairo_region_t *clip;
 
@@ -75,14 +75,14 @@ gsk_vulkan_render_setup (GskVulkanRender       *self,
   if (rect)
     {
       self->viewport = *rect;
-      self->scale_factor = 1;
+      self->scale = 1.0;
     }
   else
     {
-      self->scale_factor = gdk_surface_get_scale_factor (surface);
+      self->scale = gdk_surface_get_scale (surface);
       self->viewport = GRAPHENE_RECT_INIT (0, 0,
-                                           gdk_surface_get_width (surface) * self->scale_factor,
-                                           gdk_surface_get_height (surface) * self->scale_factor);
+                                           (int) ceil (gdk_surface_get_width (surface) * self->scale),
+                                           (int) ceil (gdk_surface_get_height (surface) * self->scale));
     }
   if (clip)
     {
@@ -340,12 +340,12 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
   GskVulkanRenderPass *pass;
   graphene_matrix_t mv;
 
-  graphene_matrix_init_scale (&mv, self->scale_factor, self->scale_factor, 1.0);
+  graphene_matrix_init_scale (&mv, self->scale, self->scale, 1.0);
 
   pass = gsk_vulkan_render_pass_new (self->vulkan,
                                      self->target,
-                                     self->scale_factor,
-                                     self->scale_factor,
+                                     self->scale,
+                                     self->scale,
                                      &mv,
                                      &self->viewport,
                                      self->clip,
index 217cdab7175486c6de13673b600b7945b741e1c1..71ec47b543faa46a1a3c70674a15f1047aef87e4 100644 (file)
@@ -79,11 +79,11 @@ get_render_region (GskVulkanRenderer *self)
   GdkRectangle whole_surface;
   GdkRectangle extents;
   GdkSurface *surface;
-  int scale;
+  double scale;
 
   render_region = NULL;
   surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->vulkan));
-  scale = gdk_surface_get_scale_factor (surface);
+  scale = gdk_surface_get_scale (surface);
 
   whole_surface.x = 0;
   whole_surface.y = 0;
@@ -97,10 +97,10 @@ get_render_region (GskVulkanRenderer *self)
       cairo_rectangle_int_t rect;
       cairo_region_get_rectangle (damage, i, &rect);
       cairo_region_union_rectangle (scaled_damage, &(cairo_rectangle_int_t) {
-                                      .x = rect.x * scale,
-                                      .y = rect.y * scale,
-                                      .width = rect.width * scale,
-                                      .height = rect.height * scale,
+                                      .x = (int) floor (rect.x * scale),
+                                      .y = (int) floor (rect.y * scale),
+                                      .width = (int) ceil ((rect.x + rect.width) * scale) - floor (rect.x * scale),
+                                      .height = (int) ceil ((rect.y + rect.height) * scale) - floor (rect.y * scale),
                                     });
     }
 
@@ -138,7 +138,7 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext  *context,
                                       GskVulkanRenderer *self)
 {
   GdkSurface *window;
-  int scale_factor;
+  double scale;
   gsize width, height;
   guint i;
 
@@ -148,9 +148,9 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext  *context,
   self->targets = g_new (GskVulkanImage *, self->n_targets);
 
   window = gsk_renderer_get_surface (GSK_RENDERER (self));
-  scale_factor = gdk_surface_get_scale_factor (window);
-  width = gdk_surface_get_width (window) * scale_factor;
-  height = gdk_surface_get_height (window) * scale_factor;
+  scale = gdk_surface_get_scale (window);
+  width = (int) ceil (gdk_surface_get_width (window) * scale);
+  height = (int) ceil (gdk_surface_get_height (window) * scale);
 
   for (i = 0; i < self->n_targets; i++)
     {