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)
{
{
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);
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);
#endif
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->vulkan));
+
+ g_clear_pointer (&render_region, cairo_region_destroy);
}
static void