mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
clutter/stage-cogl: Ensure redraw_clip is a superset of fb_clip_region
Initially we generate the new part of fb_clip_region from the new part of redraw_clip, scale it up and clamp. But the clamping means the new part of fb_clip_region might now represent a slightly larger area than the new part of redraw_clip, by one pixel. In some rare cases where a foreground actor honours redraw_clip, but the background actor does not (meaning it might fill all fb_clip_region), you could find 1px rendering glitches in that gap as the background actor paints there but the foreground actor does not. To ensure such glitches can never happen we now regenerate the final redraw_clip as a clamped superset of the final fb_clip_region. That's the minimum area we must paint to ensure no gaps appear inside fb_clip_region. Although the fix here sounds like the intent of the old code, the old code forgot to include the new part of fb_clip_region in the clamping of the final redraw_clip. So the new part of redraw_clip was sometimes kept too small for the new part of fb_clip_region. We also move the code to the main path because technically it's also needed when `has_buffer_age == FALSE`. Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1500 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1554>
This commit is contained in:
parent
f512d4fefa
commit
88600c8985
@ -549,7 +549,6 @@ clutter_stage_cogl_redraw_view_primary (ClutterStageCogl *stage_cogl,
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
cairo_region_t *fb_damage;
|
||||
cairo_region_t *view_damage;
|
||||
int age;
|
||||
|
||||
fb_damage = cairo_region_create ();
|
||||
@ -566,15 +565,6 @@ clutter_stage_cogl_redraw_view_primary (ClutterStageCogl *stage_cogl,
|
||||
/* Update the fb clip region with the extra damage. */
|
||||
cairo_region_union (fb_clip_region, fb_damage);
|
||||
|
||||
/* Update the redraw clip with the extra damage done to the view */
|
||||
view_damage = scale_offset_and_clamp_region (fb_damage,
|
||||
1.0f / fb_scale,
|
||||
view_rect.x,
|
||||
view_rect.y);
|
||||
|
||||
cairo_region_union (redraw_clip, view_damage);
|
||||
|
||||
cairo_region_destroy (view_damage);
|
||||
cairo_region_destroy (fb_damage);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
|
||||
@ -587,6 +577,23 @@ clutter_stage_cogl_redraw_view_primary (ClutterStageCogl *stage_cogl,
|
||||
clutter_damage_history_step (view_priv->damage_history);
|
||||
}
|
||||
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
/* Regenerate redraw_clip because:
|
||||
* 1. It's missing the regions added from damage_history above; and
|
||||
* 2. If using fractional scaling then it might be a fraction of a
|
||||
* logical pixel (or one physical pixel) smaller than
|
||||
* fb_clip_region, due to the clamping from
|
||||
* offset_scale_and_clamp_region. So we need to ensure redraw_clip
|
||||
* is a superset of fb_clip_region to avoid such gaps.
|
||||
*/
|
||||
cairo_region_destroy (redraw_clip);
|
||||
redraw_clip = scale_offset_and_clamp_region (fb_clip_region,
|
||||
1.0 / fb_scale,
|
||||
view_rect.x,
|
||||
view_rect.y);
|
||||
}
|
||||
|
||||
if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)
|
||||
{
|
||||
cairo_region_t *debug_redraw_clip;
|
||||
|
Loading…
Reference in New Issue
Block a user