diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 5378b6c75..5328a919e 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -35,6 +35,7 @@ #include "clutter-utils.h" #include "meta-texture-tower.h" +#include "region-utils.h" #include "meta-cullable.h" @@ -416,9 +417,14 @@ meta_shaped_texture_paint (ClutterActor *actor) { MetaShapedTexture *stex = (MetaShapedTexture *) actor; MetaShapedTexturePrivate *priv = stex->priv; + double tex_scale; int tex_width, tex_height; cairo_rectangle_int_t tex_rect; guchar opacity; + gboolean use_opaque_region; + cairo_region_t *clip_tex_region; + cairo_region_t *opaque_tex_region; + cairo_region_t *blended_tex_region; CoglContext *ctx; CoglFramebuffer *fb; CoglTexture *paint_tex = NULL; @@ -476,6 +482,7 @@ meta_shaped_texture_paint (ClutterActor *actor) } } + clutter_actor_get_scale (actor, &tex_scale, NULL); tex_width = priv->tex_width; tex_height = priv->tex_height; @@ -499,40 +506,61 @@ meta_shaped_texture_paint (ClutterActor *actor) opacity = clutter_actor_get_paint_opacity (actor); clutter_actor_get_allocation_box (actor, &alloc); - cairo_region_t *blended_region; - gboolean use_opaque_region = (priv->opaque_region != NULL && opacity == 255); - - if (use_opaque_region) + if (priv->opaque_region && opacity == 255) { - if (priv->clip_region != NULL) - blended_region = cairo_region_copy (priv->clip_region); - else - blended_region = cairo_region_create_rectangle (&tex_rect); - - cairo_region_subtract (blended_region, priv->opaque_region); + opaque_tex_region = + meta_region_scale_double (priv->opaque_region, + 1.0 / tex_scale, + META_ROUNDING_STRATEGY_SHRINK); + use_opaque_region = TRUE; } else { - if (priv->clip_region != NULL) - blended_region = cairo_region_reference (priv->clip_region); + use_opaque_region = FALSE; + } + + if (priv->clip_region) + { + clip_tex_region = + meta_region_scale_double (priv->clip_region, + 1.0 / tex_scale, + META_ROUNDING_STRATEGY_GROW); + } + else + { + clip_tex_region = NULL; + } + + if (use_opaque_region) + { + if (clip_tex_region) + blended_tex_region = cairo_region_copy (clip_tex_region); else - blended_region = NULL; + blended_tex_region = cairo_region_create_rectangle (&tex_rect); + + cairo_region_subtract (blended_tex_region, opaque_tex_region); + } + else + { + if (clip_tex_region) + blended_tex_region = cairo_region_reference (clip_tex_region); + else + blended_tex_region = NULL; } /* Limit to how many separate rectangles we'll draw; beyond this just * fall back and draw the whole thing */ #define MAX_RECTS 16 - if (blended_region != NULL) + if (blended_tex_region) { - int n_rects = cairo_region_num_rectangles (blended_region); + int n_rects = cairo_region_num_rectangles (blended_tex_region); if (n_rects > MAX_RECTS) { /* Fall back to taking the fully blended path. */ use_opaque_region = FALSE; - cairo_region_destroy (blended_region); - blended_region = NULL; + g_clear_pointer (&blended_tex_region, cairo_region_destroy); } } @@ -544,14 +572,14 @@ meta_shaped_texture_paint (ClutterActor *actor) int n_rects; int i; - if (priv->clip_region != NULL) + if (clip_tex_region) { - region = cairo_region_copy (priv->clip_region); - cairo_region_intersect (region, priv->opaque_region); + region = cairo_region_copy (clip_tex_region); + cairo_region_intersect (region, opaque_tex_region); } else { - region = cairo_region_reference (priv->opaque_region); + region = cairo_region_reference (opaque_tex_region); } if (!cairo_region_is_empty (region)) @@ -575,14 +603,14 @@ meta_shaped_texture_paint (ClutterActor *actor) /* Now, go ahead and paint the blended parts. */ /* We have three cases: - * 1) blended_region has rectangles - paint the rectangles. - * 2) blended_region is empty - don't paint anything - * 3) blended_region is NULL - paint fully-blended. + * 1) blended_tex_region has rectangles - paint the rectangles. + * 2) blended_tex_region is empty - don't paint anything + * 3) blended_tex_region is NULL - paint fully-blended. * * 1) and 3) are the times where we have to paint stuff. This tests * for 1) and 3). */ - if (blended_region == NULL || !cairo_region_is_empty (blended_region)) + if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region)) { CoglPipeline *blended_pipeline; @@ -604,16 +632,16 @@ meta_shaped_texture_paint (ClutterActor *actor) cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity); cogl_pipeline_set_color (blended_pipeline, &color); - if (blended_region != NULL) + if (blended_tex_region) { - /* 1) blended_region is not empty. Paint the rectangles. */ + /* 1) blended_tex_region is not empty. Paint the rectangles. */ int i; - int n_rects = cairo_region_num_rectangles (blended_region); + int n_rects = cairo_region_num_rectangles (blended_tex_region); for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - cairo_region_get_rectangle (blended_region, i, &rect); + cairo_region_get_rectangle (blended_tex_region, i, &rect); if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect)) continue; @@ -623,7 +651,7 @@ meta_shaped_texture_paint (ClutterActor *actor) } else { - /* 3) blended_region is NULL. Do a full paint. */ + /* 3) blended_tex_region is NULL. Do a full paint. */ cogl_framebuffer_draw_rectangle (fb, blended_pipeline, 0, 0, alloc.x2 - alloc.x1, @@ -631,8 +659,7 @@ meta_shaped_texture_paint (ClutterActor *actor) } } - if (blended_region != NULL) - cairo_region_destroy (blended_region); + g_clear_pointer (&blended_tex_region, cairo_region_destroy); } static void