From 90a5582a7394d6dd5371aa95aa7b610217d849d3 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 27 Jan 2019 15:49:41 +0100 Subject: [PATCH] background-actor: Clip obscured background areas The MetaBackgroundActor was ignoring the unobscured area altogether, and just painted according to the clip area. Check the unobscured area too, as it might well be covered by client windows. https://gitlab.gnome.org/GNOME/mutter/merge_requests/698 --- src/compositor/meta-background-actor.c | 70 +++++++++++++++++++------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c index 7c0f82d1a..48f745b38 100644 --- a/src/compositor/meta-background-actor.c +++ b/src/compositor/meta-background-actor.c @@ -179,6 +179,7 @@ struct _MetaBackgroundActor gboolean force_bilinear; cairo_region_t *clip_region; + cairo_region_t *unobscured_region; }; static void cullable_iface_init (MetaCullableInterface *iface); @@ -195,12 +196,22 @@ set_clip_region (MetaBackgroundActor *self, self->clip_region = cairo_region_copy (clip_region); } +static void +set_unobscured_region (MetaBackgroundActor *self, + cairo_region_t *unobscured_region) +{ + g_clear_pointer (&self->unobscured_region, cairo_region_destroy); + if (unobscured_region) + self->unobscured_region = cairo_region_copy (unobscured_region); +} + static void meta_background_actor_dispose (GObject *object) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); set_clip_region (self, NULL); + set_unobscured_region (self, NULL); meta_background_actor_set_background (self, NULL); if (self->pipeline) { @@ -502,7 +513,8 @@ meta_background_actor_paint (ClutterActor *actor) ClutterActorBox actor_box; cairo_rectangle_int_t actor_pixel_rect; CoglFramebuffer *fb; - int i; + cairo_region_t *region; + int i, n_rects; if ((self->clip_region && cairo_region_is_empty (self->clip_region))) return; @@ -524,27 +536,43 @@ meta_background_actor_paint (ClutterActor *actor) /* Now figure out what to actually paint. */ - if (self->clip_region != NULL) + if (self->clip_region) { - int n_rects = cairo_region_num_rectangles (self->clip_region); - if (n_rects <= MAX_RECTS) - { - for (i = 0; i < n_rects; i++) - { - cairo_rectangle_int_t rect; - cairo_region_get_rectangle (self->clip_region, i, &rect); - - if (!gdk_rectangle_intersect (&actor_pixel_rect, &rect, &rect)) - continue; - - paint_clipped_rectangle (fb, self->pipeline, &rect, &self->texture_area); - } - - return; - } + region = cairo_region_copy (self->clip_region); + cairo_region_intersect_rectangle (region, &actor_pixel_rect); + } + else + { + region = cairo_region_create_rectangle (&actor_pixel_rect); } - paint_clipped_rectangle (fb, self->pipeline, &actor_pixel_rect, &self->texture_area); + if (self->unobscured_region) + cairo_region_intersect (region, self->unobscured_region); + + if (cairo_region_is_empty (region)) + { + cairo_region_destroy (region); + return; + } + + n_rects = cairo_region_num_rectangles (region); + if (n_rects <= MAX_RECTS) + { + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + paint_clipped_rectangle (fb, self->pipeline, &rect, + &self->texture_area); + } + } + else + { + cairo_rectangle_int_t rect; + cairo_region_get_extents (region, &rect); + paint_clipped_rectangle (fb, self->pipeline, &rect, + &self->texture_area); + } } static void @@ -798,6 +826,8 @@ meta_background_actor_cull_out (MetaCullable *cullable, cairo_region_t *clip_region) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); + + set_unobscured_region (self, unobscured_region); set_clip_region (self, clip_region); } @@ -805,6 +835,8 @@ static void meta_background_actor_reset_culling (MetaCullable *cullable) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); + + set_unobscured_region (self, NULL); set_clip_region (self, NULL); }