surface-actor: Add culling offset for geometry scale - take 2

41130b08eb added a fix for culling subsurfaces with geometry scale.
Unfortunately it only did so for the opaque regions, not for clip and
unobscured regions, as the effect was hidden by bug that was only
fixed by 3187fe8ebc.

Apply the same fix to clip and unobscured regions and use the chance
to move most of the slightly hackish geometry scale related code
into a single place.

We need to scale slightly differently in the two cases, indicated by
the new `ScalePerspectiveType` enum, as the scale is dependent on the
perspective - once from outside, once from inside of the scaled actor.

Closes https://gitlab.gnome.org/GNOME/mutter/-/issues/1312
This commit is contained in:
Robert Mader 2020-06-28 23:56:21 +02:00
parent df4eeff6f2
commit 86646679f1

View File

@ -57,6 +57,12 @@ enum
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
typedef enum
{
IN_STAGE_PERSPECTIVE,
IN_ACTOR_PERSPECTIVE
} ScalePerspectiveType;
static cairo_region_t * static cairo_region_t *
effective_unobscured_region (MetaSurfaceActor *surface_actor) effective_unobscured_region (MetaSurfaceActor *surface_actor)
{ {
@ -73,17 +79,38 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
static cairo_region_t* static cairo_region_t*
get_scaled_region (MetaSurfaceActor *surface_actor, get_scaled_region (MetaSurfaceActor *surface_actor,
cairo_region_t *region) cairo_region_t *region,
ScalePerspectiveType scale_perspective)
{ {
MetaWindowActor *window_actor; MetaWindowActor *window_actor;
cairo_region_t *scaled_region;
int geometry_scale; int geometry_scale;
float x, y;
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor)); window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
geometry_scale = meta_window_actor_get_geometry_scale (window_actor); geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
return meta_region_scale_double (region, clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
cairo_region_translate (region, x, y);
switch (scale_perspective)
{
case IN_STAGE_PERSPECTIVE:
scaled_region = meta_region_scale_double (region,
geometry_scale,
META_ROUNDING_STRATEGY_GROW);
break;
case IN_ACTOR_PERSPECTIVE:
scaled_region = meta_region_scale_double (region,
1.0 / geometry_scale, 1.0 / geometry_scale,
META_ROUNDING_STRATEGY_GROW); META_ROUNDING_STRATEGY_GROW);
break;
}
cairo_region_translate (region, -x, -y);
cairo_region_translate (scaled_region, -x, -y);
return scaled_region;
} }
static void static void
@ -113,8 +140,9 @@ set_unobscured_region (MetaSurfaceActor *surface_actor,
.height = height, .height = height,
}; };
priv->unobscured_region = priv->unobscured_region = get_scaled_region (surface_actor,
get_scaled_region (surface_actor, unobscured_region); unobscured_region,
IN_ACTOR_PERSPECTIVE);
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
} }
@ -133,7 +161,9 @@ set_clip_region (MetaSurfaceActor *surface_actor,
{ {
cairo_region_t *region; cairo_region_t *region;
region = get_scaled_region (surface_actor, clip_region); region = get_scaled_region (surface_actor,
clip_region,
IN_ACTOR_PERSPECTIVE);
meta_shaped_texture_set_clip_region (stex, region); meta_shaped_texture_set_clip_region (stex, region);
cairo_region_destroy (region); cairo_region_destroy (region);
@ -261,11 +291,8 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
if (opacity == 0xff) if (opacity == 0xff)
{ {
MetaWindowActor *window_actor;
cairo_region_t *scaled_opaque_region;
cairo_region_t *opaque_region; cairo_region_t *opaque_region;
int geometry_scale; cairo_region_t *scaled_opaque_region;
float x, y;
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture); opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
if (opaque_region) if (opaque_region)
@ -288,14 +315,9 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
return; return;
} }
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor)); scaled_opaque_region = get_scaled_region (surface_actor,
geometry_scale = meta_window_actor_get_geometry_scale (window_actor); opaque_region,
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); IN_STAGE_PERSPECTIVE);
cairo_region_translate (opaque_region, x, y);
scaled_opaque_region = meta_region_scale (opaque_region, geometry_scale);
cairo_region_translate (scaled_opaque_region, -x, -y);
cairo_region_translate (opaque_region, -x, -y);
if (unobscured_region) if (unobscured_region)
cairo_region_subtract (unobscured_region, scaled_opaque_region); cairo_region_subtract (unobscured_region, scaled_opaque_region);