From df2adce2f57e3e86072358007c94c255367ffe72 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 27 Dec 2018 23:30:20 -0200 Subject: [PATCH] window-content: Track subsurfaces invalidations WIP https://gitlab.gnome.org/GNOME/mutter/merge_requests/861 --- src/compositor/meta-shaped-texture-private.h | 8 +++ src/compositor/meta-shaped-texture.c | 36 +++++++++++ src/compositor/meta-window-content.c | 64 ++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index 87527e884..e39bc9502 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -68,4 +68,12 @@ void meta_shaped_texture_paint_node (MetaShapedTexture *stex, ClutterActorBox *box, guchar opacity); +typedef void (*MetaShapedTextureInvalidateFunc) (MetaShapedTexture *stex, + gboolean size_changed, + gpointer user_data); + +void meta_shaped_texture_set_invalidate_func (MetaShapedTexture *stex, + MetaShapedTextureInvalidateFunc func, + gpointer user_data); + #endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 29b70cfb0..e7b76ca8d 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -107,6 +107,9 @@ struct _MetaShapedTexture int buffer_scale; + MetaShapedTextureInvalidateFunc invalidate_func; + gpointer invalidate_user_data; + guint create_mipmaps : 1; }; @@ -774,11 +777,35 @@ meta_shaped_texture_get_preferred_size (ClutterContent *content, return TRUE; } +static void +meta_shaped_texture_invalidate (ClutterContent *content) +{ + MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); + + if (!stex->invalidate_func) + return; + + stex->invalidate_func (stex, FALSE, stex->invalidate_user_data); +} + +static void +meta_shaped_texture_invalidate_size (ClutterContent *content) +{ + MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); + + if (!stex->invalidate_func) + return; + + stex->invalidate_func (stex, TRUE, stex->invalidate_user_data); +} + static void clutter_content_iface_init (ClutterContentInterface *iface) { iface->paint_content = meta_shaped_texture_paint_content; iface->get_preferred_size = meta_shaped_texture_get_preferred_size; + iface->invalidate = meta_shaped_texture_invalidate; + iface->invalidate_size = meta_shaped_texture_invalidate_size; } void @@ -1445,3 +1472,12 @@ meta_shaped_texture_paint_node (MetaShapedTexture *stex, do_paint_content (stex, root_node, stex->texture, box, opacity); } + +void +meta_shaped_texture_set_invalidate_func (MetaShapedTexture *stex, + MetaShapedTextureInvalidateFunc func, + gpointer user_data) +{ + stex->invalidate_func = func; + stex->invalidate_user_data = user_data; +} diff --git a/src/compositor/meta-window-content.c b/src/compositor/meta-window-content.c index cd41b0e52..5632a84a1 100644 --- a/src/compositor/meta-window-content.c +++ b/src/compositor/meta-window-content.c @@ -82,6 +82,53 @@ enum static GParamSpec *properties [N_PROPS]; +static void +texture_invalidate_func (MetaShapedTexture *stex, + gboolean size_changed, + gpointer user_data) +{ + MetaWindowContent *window_content = (MetaWindowContent*) user_data; + + if (window_content->attached_actors == 0) + return; + + if (size_changed) + clutter_content_invalidate_size (CLUTTER_CONTENT (user_data)); + else + clutter_content_invalidate (CLUTTER_CONTENT (user_data)); +} + +static void +set_surface_invalidate_func (MetaWindowContent *window_content, + MetaShapedTextureInvalidateFunc func) +{ + ClutterActor *window_actor = CLUTTER_ACTOR (window_content->window_actor); + ClutterActor *child; + + for (child = clutter_actor_get_first_child (window_actor); + child != NULL; + child = clutter_actor_get_next_sibling (child)) + { + MetaShapedTexture *stex; + + if (!META_IS_SURFACE_ACTOR (child)) + continue; + + stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (child)); + + if (!stex) + continue; + + meta_shaped_texture_set_invalidate_func (stex, func, window_content); + } +} + +static void +ensure_shaped_textures_invalidate_func (MetaWindowContent *window_content) +{ + set_surface_invalidate_func (window_content, texture_invalidate_func); +} + static void add_surface_paint_nodes (MetaSurfaceActor *surface_actor, ClutterActor *actor, @@ -136,6 +183,8 @@ meta_window_content_paint_content (ClutterContent *content, g_assert (!META_IS_WINDOW_ACTOR (actor)); g_assert (!META_IS_SURFACE_ACTOR (actor)); + ensure_shaped_textures_invalidate_func (window_content); + /* Horizontal and vertical scales */ clutter_actor_get_size (window_actor, &width, &height); clutter_actor_get_size (actor, &dst_width, &dst_height); @@ -162,6 +211,8 @@ meta_window_content_get_preferred_size (ClutterContent *content, { MetaWindowContent *window_content = META_WINDOW_CONTENT (content); + ensure_shaped_textures_invalidate_func (window_content); + clutter_actor_get_size (CLUTTER_ACTOR (window_content->window_actor), width, height); return TRUE; @@ -174,6 +225,8 @@ meta_window_content_attached (ClutterContent *content, MetaWindowContent *window_content = META_WINDOW_CONTENT (content); window_content->attached_actors++; + + ensure_shaped_textures_invalidate_func (window_content); } static void @@ -235,11 +288,22 @@ meta_window_content_set_property (GObject *object, } } +static void +meta_window_content_dispose (GObject *object) +{ + MetaWindowContent *window_content = META_WINDOW_CONTENT (object); + + set_surface_invalidate_func (window_content, surface_actor, NULL); + + G_OBJECT_CLASS (meta_window_content_parent_class)->dispose (object); +} + static void meta_window_content_class_init (MetaWindowContentClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->dispose = meta_window_content_dispose; object_class->get_property = meta_window_content_get_property; object_class->set_property = meta_window_content_set_property;