surface-actor-x11: Unredirect ARGB32 windows with full opaque regions

We can detect that these windows are already fully opaque, so allow them
to unredirect. Allows unredirecting Totem during video playback, giving
a significant speed boost.
This commit is contained in:
Jasper St. Pierre 2016-03-21 13:43:50 -07:00
parent 92c8a51ba6
commit 190357c561
5 changed files with 46 additions and 3 deletions

View File

@ -36,5 +36,6 @@ void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
guint fallback_width, guint fallback_width,
guint fallback_height); guint fallback_height);
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self); gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
#endif #endif

View File

@ -790,6 +790,13 @@ meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
priv->opaque_region = NULL; priv->opaque_region = NULL;
} }
cairo_region_t *
meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex)
{
MetaShapedTexturePrivate *priv = stex->priv;
return priv->opaque_region;
}
/** /**
* meta_shaped_texture_get_image: * meta_shaped_texture_get_image:
* @stex: A #MetaShapedTexture * @stex: A #MetaShapedTexture

View File

@ -238,6 +238,33 @@ meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor)
return is_visible (self); return is_visible (self);
} }
static gboolean
meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor)
{
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
/* If we're not ARGB32, then we're opaque. */
if (!meta_surface_actor_is_argb32 (actor))
return TRUE;
cairo_region_t *opaque_region = meta_surface_actor_get_opaque_region (actor);
/* If we have no opaque region, then no pixels are opaque. */
if (!opaque_region)
return FALSE;
MetaWindow *window = priv->window;
cairo_rectangle_int_t client_area;
meta_window_get_client_area_rect (window, &client_area);
/* Otherwise, check if our opaque region covers our entire surface. */
if (cairo_region_contains_rectangle (opaque_region, &client_area) == CAIRO_REGION_OVERLAP_IN)
return TRUE;
return FALSE;
}
static gboolean static gboolean
meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor)
{ {
@ -255,15 +282,15 @@ meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor)
if (window->shape_region != NULL) if (window->shape_region != NULL)
return FALSE; return FALSE;
if (meta_surface_actor_is_argb32 (actor) && !meta_window_requested_bypass_compositor (window))
return FALSE;
if (!meta_window_is_monitor_sized (window)) if (!meta_window_is_monitor_sized (window))
return FALSE; return FALSE;
if (meta_window_requested_bypass_compositor (window)) if (meta_window_requested_bypass_compositor (window))
return TRUE; return TRUE;
if (!meta_surface_actor_x11_is_opaque (actor))
return FALSE;
if (meta_window_is_override_redirect (window)) if (meta_window_is_override_redirect (window))
return TRUE; return TRUE;

View File

@ -235,6 +235,13 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
meta_shaped_texture_set_opaque_region (priv->texture, region); meta_shaped_texture_set_opaque_region (priv->texture, region);
} }
cairo_region_t *
meta_surface_actor_get_opaque_region (MetaSurfaceActor *actor)
{
MetaSurfaceActorPrivate *priv = actor->priv;
return meta_shaped_texture_get_opaque_region (priv->texture);
}
static gboolean static gboolean
is_frozen (MetaSurfaceActor *self) is_frozen (MetaSurfaceActor *self)
{ {

View File

@ -60,6 +60,7 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
cairo_region_t *region); cairo_region_t *region);
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
cairo_region_t *region); cairo_region_t *region);
cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self);
void meta_surface_actor_process_damage (MetaSurfaceActor *actor, void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
int x, int y, int width, int height); int x, int y, int width, int height);