clutter/stage-view: Only blit the damage part of the shadow buffer

This fixes the last "copy everything" paths when clutter doesn't
directly paint onto the onscreen framebuffer. It adds a new hook into
the stage view called before the swap buffer, as at this point, we have
the swap buffer damag regions ready, which corresponds to the regions we
must blit according to the damage reported to clutter.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237
This commit is contained in:
Jonas Ådahl 2020-05-05 19:25:23 +02:00 committed by Georges Basile Stavracas Neto
parent 9e34028742
commit 8798325489
3 changed files with 40 additions and 4 deletions

View File

@ -23,6 +23,9 @@
void clutter_stage_view_after_paint (ClutterStageView *view, void clutter_stage_view_after_paint (ClutterStageView *view,
cairo_region_t *redraw_clip); cairo_region_t *redraw_clip);
void clutter_stage_view_before_swap_buffer (ClutterStageView *view,
const cairo_region_t *swap_region);
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view); gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
void clutter_stage_view_invalidate_viewport (ClutterStageView *view); void clutter_stage_view_invalidate_viewport (ClutterStageView *view);

View File

@ -370,11 +370,22 @@ clutter_stage_view_after_paint (ClutterStageView *view,
redraw_clip); redraw_clip);
} }
} }
}
if (priv->shadow.framebuffer) void
clutter_stage_view_before_swap_buffer (ClutterStageView *view,
const cairo_region_t *swap_region)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
g_autoptr (GError) error = NULL;
if (!priv->shadow.framebuffer)
return;
if (cairo_region_is_empty (swap_region))
{ {
int width, height; int width, height;
g_autoptr (GError) error = NULL;
width = cogl_framebuffer_get_width (priv->framebuffer); width = cogl_framebuffer_get_width (priv->framebuffer);
height = cogl_framebuffer_get_height (priv->framebuffer); height = cogl_framebuffer_get_height (priv->framebuffer);
@ -384,9 +395,29 @@ clutter_stage_view_after_paint (ClutterStageView *view,
0, 0, 0, 0,
width, height, width, height,
&error)) &error))
g_warning ("Failed to blit shadow buffer: %s", error->message);
}
else
{
int n_rects;
int i;
n_rects = cairo_region_num_rectangles (swap_region);
for (i = 0; i < n_rects; i++)
{ {
g_warning ("Failed to blit shadow buffer: %s", error->message); cairo_rectangle_int_t rect;
return;
cairo_region_get_rectangle (swap_region, i, &rect);
if (!cogl_blit_framebuffer (priv->shadow.framebuffer,
priv->framebuffer,
rect.x, rect.y,
rect.x, rect.y,
rect.width, rect.height,
&error))
{
g_warning ("Failed to blit shadow buffer: %s", error->message);
return;
}
} }
} }
} }

View File

@ -379,6 +379,8 @@ swap_framebuffer (ClutterStageWindow *stage_window,
{ {
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
clutter_stage_view_before_swap_buffer (view, swap_region);
if (cogl_is_onscreen (framebuffer)) if (cogl_is_onscreen (framebuffer))
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);