[mutter] wayland: Only call frame callbacks when a surface gets drawn on screen



commit 070cd27786b6b00b9ebd7ea68020573f6a92d047
Author: Adel Gadllah <adel gadllah gmail com>
Date:   Thu Jul 23 17:22:22 2015 +0200

    wayland: Only call frame callbacks when a surface gets drawn on screen
    
    The spec says:
    "A server should avoid signalling the frame callbacks if the surface is not
    visible in any way, e.g. the surface is off-screen, or completely obscured
    by other opaque surfaces."
    
    We actually do have the information to do that but we are always calling
    the frame callbacks in after_stage_paint. So fix that to only call when
    when the surface gets drawn on screen.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=739163

 src/compositor/meta-surface-actor-wayland.c |   19 ++++++++++++++++++-
 src/compositor/meta-surface-actor-wayland.h |    4 ++++
 src/wayland/meta-wayland-surface.c          |    6 +++++-
 3 files changed, 27 insertions(+), 2 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index a9ec558..069f6e9 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -39,6 +39,7 @@
 struct _MetaSurfaceActorWaylandPrivate
 {
   MetaWaylandSurface *surface;
+  struct wl_list frame_callback_list;
 };
 typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
 
@@ -279,6 +280,15 @@ meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
   return is_on_monitor;
 }
 
+void
+meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
+                                                struct wl_list *frame_callbacks)
+{
+  MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
+
+  wl_list_insert_list (&priv->frame_callback_list, frame_callbacks);
+}
+
 static MetaWindow *
 meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
 {
@@ -331,7 +341,13 @@ meta_surface_actor_wayland_paint (ClutterActor *actor)
     meta_surface_actor_wayland_get_instance_private (self);
 
   if (priv->surface)
-    meta_wayland_surface_update_outputs (priv->surface);
+    {
+      MetaWaylandCompositor *compositor = priv->surface->compositor;
+      meta_wayland_surface_update_outputs (priv->surface);
+
+      wl_list_insert_list (&compositor->frame_callbacks, &priv->frame_callback_list);
+      wl_list_init (&priv->frame_callback_list);
+    }
 
   CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor);
 }
@@ -383,6 +399,7 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
 
   g_assert (meta_is_wayland_compositor ());
 
+  wl_list_init (&priv->frame_callback_list);
   priv->surface = surface;
 
   return META_SURFACE_ACTOR (self);
diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h
index 0193480..9882cb2 100644
--- a/src/compositor/meta-surface-actor-wayland.h
+++ b/src/compositor/meta-surface-actor-wayland.h
@@ -30,6 +30,7 @@
 #include "meta-surface-actor.h"
 
 #include "wayland/meta-wayland.h"
+#include "wayland/meta-wayland-private.h"
 
 #include "backends/meta-monitor-manager-private.h"
 
@@ -78,6 +79,9 @@ void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *
 gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
                                                    MetaMonitorInfo         *monitor);
 
+void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
+                                                     struct wl_list *frame_callbacks);
+
 G_END_DECLS
 
 #endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 1849ece..7481d87 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -541,7 +541,11 @@ apply_pending_state (MetaWaylandSurface      *surface,
     }
 
   /* wl_surface.frame */
-  wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
+  if (surface->surface_actor)
+    meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor),
+                                                    &pending->frame_callback_list);
+  else
+    wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
   wl_list_init (&pending->frame_callback_list);
 
   switch (surface->role)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]