diff options
author | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2023-04-02 19:18:24 -0300 |
---|---|---|
committer | Georges Basile Stavracas Neto <georges.stavracas@gmail.com> | 2023-04-03 10:59:45 -0300 |
commit | a2a05acc6b82416ed2165d33b351c08fe0b8147b (patch) | |
tree | a2a3cd8ce4505c496162a886834d284ba267e300 | |
parent | 840c72d74db5d3b04c3d7d706c8cd092e3963580 (diff) | |
download | gtk+-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.c | 59 |
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 |