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
This commit is contained in:
Adel Gadllah 2015-07-23 17:22:22 +02:00
parent 9df6cda3e3
commit 070cd27786
3 changed files with 27 additions and 2 deletions

View File

@ -39,6 +39,7 @@
struct _MetaSurfaceActorWaylandPrivate struct _MetaSurfaceActorWaylandPrivate
{ {
MetaWaylandSurface *surface; MetaWaylandSurface *surface;
struct wl_list frame_callback_list;
}; };
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate; typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
@ -279,6 +280,15 @@ meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
return is_on_monitor; 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 * static MetaWindow *
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor) meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
{ {
@ -331,8 +341,14 @@ meta_surface_actor_wayland_paint (ClutterActor *actor)
meta_surface_actor_wayland_get_instance_private (self); meta_surface_actor_wayland_get_instance_private (self);
if (priv->surface) if (priv->surface)
{
MetaWaylandCompositor *compositor = priv->surface->compositor;
meta_wayland_surface_update_outputs (priv->surface); 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); 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 ()); g_assert (meta_is_wayland_compositor ());
wl_list_init (&priv->frame_callback_list);
priv->surface = surface; priv->surface = surface;
return META_SURFACE_ACTOR (self); return META_SURFACE_ACTOR (self);

View File

@ -30,6 +30,7 @@
#include "meta-surface-actor.h" #include "meta-surface-actor.h"
#include "wayland/meta-wayland.h" #include "wayland/meta-wayland.h"
#include "wayland/meta-wayland-private.h"
#include "backends/meta-monitor-manager-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, gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
MetaMonitorInfo *monitor); MetaMonitorInfo *monitor);
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
struct wl_list *frame_callbacks);
G_END_DECLS G_END_DECLS
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ #endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */

View File

@ -541,6 +541,10 @@ apply_pending_state (MetaWaylandSurface *surface,
} }
/* wl_surface.frame */ /* wl_surface.frame */
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_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list); wl_list_init (&pending->frame_callback_list);