summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2023-04-02 19:18:24 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2023-04-03 10:59:45 -0300
commita2a05acc6b82416ed2165d33b351c08fe0b8147b (patch)
treea2a3cd8ce4505c496162a886834d284ba267e300
parent840c72d74db5d3b04c3d7d706c8cd092e3963580 (diff)
downloadgtk+-a2a05acc6b82416ed2165d33b351c08fe0b8147b.tar.gz
gsk/vulkan/renderer: Pass appropriate clip region
This part of the Vulkan renderer is almost exactly equal to the GL renderer, and the GL renderer already does that since at least 2a38cecd3351. Copy that into the Vulkan renderer. A nice side effect from this commit is that resizing a window now actually works again. Sneak in a trivial cleanup by using a variable to hold the draw index.
-rw-r--r--gsk/vulkan/gskvulkanrenderer.c59
1 files changed, 56 insertions, 3 deletions
diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c
index 8f4fa13bf5..b634a2b761 100644
--- a/gsk/vulkan/gskvulkanrenderer.c
+++ b/gsk/vulkan/gskvulkanrenderer.c
@@ -70,6 +70,55 @@ struct _GskVulkanRendererClass
G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_RENDERER)
+static cairo_region_t *
+get_render_region (GskVulkanRenderer *self)
+{
+ const cairo_region_t *damage;
+ cairo_region_t *render_region;
+ cairo_region_t *scaled_damage;
+ GdkRectangle whole_surface;
+ GdkRectangle extents;
+ GdkSurface *surface;
+ int scale;
+
+ render_region = NULL;
+ surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->vulkan));
+ scale = gdk_surface_get_scale_factor (surface);
+
+ whole_surface.x = 0;
+ whole_surface.y = 0;
+ whole_surface.width = gdk_surface_get_width (surface);
+ whole_surface.height = gdk_surface_get_height (surface);
+
+ damage = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->vulkan));
+ scaled_damage = cairo_region_create ();
+ for (int i = 0; i < cairo_region_num_rectangles (damage); i++)
+ {
+ 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,
+ });
+ }
+
+ if (cairo_region_contains_rectangle (scaled_damage, &whole_surface) == CAIRO_REGION_OVERLAP_IN)
+ goto out;
+
+ cairo_region_get_extents (scaled_damage, &extents);
+ if (gdk_rectangle_equal (&extents, &whole_surface))
+ goto out;
+
+ render_region = cairo_region_create_rectangle (&extents);
+
+out:
+ g_clear_pointer (&scaled_damage, cairo_region_destroy);
+
+ return g_steal_pointer (&render_region);
+}
+
static void
gsk_vulkan_renderer_free_targets (GskVulkanRenderer *self)
{
@@ -239,11 +288,12 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GskVulkanRender *render;
- const cairo_region_t *clip;
+ cairo_region_t *render_region;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
#endif
+ uint32_t draw_index;
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
@@ -256,8 +306,9 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->vulkan), region);
render = self->render;
- clip = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->vulkan));
- gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL, clip);
+ render_region = get_render_region (self);
+ draw_index = gdk_vulkan_context_get_draw_index (self->vulkan);
+ gsk_vulkan_render_reset (render, self->targets[draw_index], NULL, render_region);
gsk_vulkan_render_add_node (render, root);
@@ -275,6 +326,8 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
#endif
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->vulkan));
+
+ g_clear_pointer (&render_region, cairo_region_destroy);
}
static void