wayland: Drive frame callbacks from stage updates
Don't tie frame callbacks to actor painting, as it may end up in situations where we miss sending frame callbacks when we should have. An example of this is when a surface is partially off screen, and then reports damage that is fully off screen. When this happen, we are likely not to repaint anything, thus we won't send any frame callbacks even though it's "suitable" for rendering again, as the surface is not on a separate workspace or fully obscured. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/817 Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1152 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218
This commit is contained in:
parent
e8b09df8d2
commit
066bc5986d
14 changed files with 123 additions and 150 deletions
|
@ -42,7 +42,6 @@ struct _MetaSurfaceActorWayland
|
|||
MetaSurfaceActor parent;
|
||||
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_list frame_callback_list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaSurfaceActorWayland,
|
||||
|
@ -72,23 +71,6 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
|
|||
return meta_shaped_texture_is_opaque (stex);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_frame_callbacks (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandCompositor *wayland_compositor;
|
||||
|
||||
if (!self->surface)
|
||||
return;
|
||||
|
||||
if (meta_surface_actor_is_obscured (META_SURFACE_ACTOR (self)))
|
||||
return;
|
||||
|
||||
wayland_compositor = self->surface->compositor;
|
||||
wl_list_insert_list (&wayland_compositor->frame_callbacks,
|
||||
&self->frame_callback_list);
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
CoglOnscreen *onscreen)
|
||||
|
@ -101,35 +83,13 @@ meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
|||
if (!scanout)
|
||||
return NULL;
|
||||
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
return scanout;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks)
|
||||
{
|
||||
wl_list_insert_list (&self->frame_callback_list, frame_callbacks);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
|
||||
paint_context);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
MetaShapedTexture *stex;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
|
@ -143,9 +103,6 @@ meta_surface_actor_wayland_dispose (GObject *object)
|
|||
self->surface = NULL;
|
||||
}
|
||||
|
||||
wl_list_for_each_safe (cb, next, &self->frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
@ -153,11 +110,8 @@ static void
|
|||
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
{
|
||||
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
actor_class->paint = meta_surface_actor_wayland_paint;
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
|
||||
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
||||
surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
|
||||
|
@ -177,7 +131,6 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
|
|||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
self->surface = surface;
|
||||
g_object_add_weak_pointer (G_OBJECT (self->surface),
|
||||
(gpointer *) &self->surface);
|
||||
|
|
|
@ -107,9 +107,15 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
if (wl_list_empty (&surface->unassigned.pending_frame_callback_list))
|
||||
return;
|
||||
|
||||
wl_list_insert_list (priv->frame_callback_list.prev,
|
||||
&surface->unassigned.pending_frame_callback_list);
|
||||
wl_list_init (&surface->unassigned.pending_frame_callback_list);
|
||||
|
||||
meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
|
||||
surface);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -118,18 +124,37 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor
|
|||
{
|
||||
MetaWaylandActorSurfacePrivate *priv =
|
||||
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||||
MetaSurfaceActorWayland *surface_actor_wayland =
|
||||
META_SURFACE_ACTOR_WAYLAND (priv->actor);
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
if (!priv->actor)
|
||||
if (wl_list_empty (&pending->frame_callback_list))
|
||||
return;
|
||||
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
|
||||
&priv->frame_callback_list);
|
||||
wl_list_init (&priv->frame_callback_list);
|
||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_insert_list (priv->frame_callback_list.prev,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
|
||||
meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
|
||||
surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||||
uint32_t timestamp_ms)
|
||||
{
|
||||
MetaWaylandActorSurfacePrivate *priv =
|
||||
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||||
|
||||
while (!wl_list_empty (&priv->frame_callback_list))
|
||||
{
|
||||
MetaWaylandFrameCallback *callback =
|
||||
wl_container_of (priv->frame_callback_list.next, callback, link);
|
||||
|
||||
wl_callback_send_done (callback->resource, timestamp_ms);
|
||||
wl_resource_destroy (callback->resource);
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -265,18 +290,17 @@ meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
MetaWaylandActorSurfacePrivate *priv =
|
||||
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||||
|
||||
if (!priv->actor)
|
||||
{
|
||||
wl_list_insert_list (&priv->frame_callback_list,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wl_list_empty (&pending->frame_callback_list) &&
|
||||
cairo_region_is_empty (pending->surface_damage) &&
|
||||
cairo_region_is_empty (pending->buffer_damage))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->actor));
|
||||
priv->actor &&
|
||||
!meta_surface_actor_is_obscured (priv->actor))
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaBackend *backend = surface->compositor->backend;
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
clutter_stage_schedule_update (CLUTTER_STAGE (stage));
|
||||
}
|
||||
|
||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||
|
||||
|
|
|
@ -48,4 +48,7 @@ void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surf
|
|||
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
|
||||
void meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||||
uint32_t timestamp_ms);
|
||||
|
||||
#endif /* META_WAYLAND_ACTOR_SURFACE_H */
|
||||
|
|
|
@ -124,8 +124,8 @@ meta_wayland_cursor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||
meta_wayland_cursor_surface_get_instance_private (cursor_surface);
|
||||
|
||||
wl_list_insert_list (&priv->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
&surface->unassigned.pending_frame_callback_list);
|
||||
wl_list_init (&surface->unassigned.pending_frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-feedback-actor-private.h"
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
struct _MetaWaylandSurfaceRoleDND
|
||||
{
|
||||
|
@ -42,7 +43,11 @@ dnd_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
meta_wayland_surface_queue_pending_frame_callbacks (surface);
|
||||
if (wl_list_empty (&surface->unassigned.pending_frame_callback_list))
|
||||
return;
|
||||
|
||||
meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
|
||||
surface);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -56,7 +61,8 @@ dnd_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_class);
|
||||
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
|
||||
surface);
|
||||
|
||||
surface_role_dnd->pending_offset_x = pending->dx;
|
||||
surface_role_dnd->pending_offset_y = pending->dy;
|
||||
|
|
|
@ -658,6 +658,8 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
|
||||
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
|
||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (xdg_surface);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
@ -668,7 +670,7 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
|||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
{
|
||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1218,14 +1220,10 @@ meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg
|
|||
static void
|
||||
zxdg_surface_v6_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||
surface);
|
||||
|
||||
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
|
||||
xdg_surface);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ struct _MetaWaylandCompositor
|
|||
struct wl_display *wayland_display;
|
||||
char *display_name;
|
||||
GHashTable *outputs;
|
||||
struct wl_list frame_callbacks;
|
||||
GList *frame_callback_surfaces;
|
||||
|
||||
MetaXWaylandManager xwayland_manager;
|
||||
|
||||
|
|
|
@ -362,9 +362,6 @@ wl_subsurface_destructor (struct wl_resource *resource)
|
|||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||
surface);
|
||||
|
||||
g_node_unlink (surface->subsurface_branch_node);
|
||||
unparent_actor (surface);
|
||||
|
||||
|
|
|
@ -409,15 +409,6 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||
cairo_region_destroy (transformed_region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
MetaWaylandBuffer *
|
||||
meta_wayland_surface_get_buffer (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
@ -632,15 +623,6 @@ meta_wayland_surface_state_class_init (MetaWaylandSurfaceStateClass *klass)
|
|||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
wl_list_insert_list (&surface->pending_frame_callback_list,
|
||||
&pending->frame_callback_list);
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *state)
|
||||
|
@ -776,7 +758,9 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
|||
}
|
||||
else
|
||||
{
|
||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, state);
|
||||
wl_list_insert_list (surface->unassigned.pending_frame_callback_list.prev,
|
||||
&state->frame_callback_list);
|
||||
wl_list_init (&state->frame_callback_list);
|
||||
|
||||
if (state->newly_attached)
|
||||
{
|
||||
|
@ -1358,14 +1342,16 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||
if (surface->input_region)
|
||||
cairo_region_destroy (surface->input_region);
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
|
||||
meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
|
||||
|
||||
g_hash_table_foreach (surface->outputs,
|
||||
surface_output_disconnect_signals,
|
||||
surface);
|
||||
g_hash_table_destroy (surface->outputs);
|
||||
|
||||
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
|
||||
wl_list_for_each_safe (cb, next,
|
||||
&surface->unassigned.pending_frame_callback_list,
|
||||
link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
if (surface->resource)
|
||||
|
@ -1412,7 +1398,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
|||
surface,
|
||||
wl_surface_destructor);
|
||||
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->unassigned.pending_frame_callback_list);
|
||||
|
||||
surface->outputs = g_hash_table_new (NULL, NULL);
|
||||
surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
|
||||
|
@ -1872,14 +1858,6 @@ meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
|
|||
return priv->surface;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface)
|
||||
{
|
||||
wl_list_insert_list (&surface->compositor->frame_callbacks,
|
||||
&surface->pending_frame_callback_list);
|
||||
wl_list_init (&surface->pending_frame_callback_list);
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
|
|
@ -168,13 +168,9 @@ struct _MetaWaylandSurface
|
|||
/* Buffer renderer state. */
|
||||
gboolean buffer_held;
|
||||
|
||||
/* List of pending frame callbacks that needs to stay queued longer than one
|
||||
* commit sequence, such as when it has not yet been assigned a role.
|
||||
*/
|
||||
struct wl_list pending_frame_callback_list;
|
||||
|
||||
/* Intermediate state for when no role has been assigned. */
|
||||
struct {
|
||||
struct wl_list pending_frame_callback_list;
|
||||
MetaWaylandBuffer *buffer;
|
||||
} unassigned;
|
||||
|
||||
|
@ -288,9 +284,6 @@ gboolean meta_wayland_surface_should_cache_state (MetaWaylandSurface
|
|||
|
||||
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_cache_pending_frame_callbacks (MetaWaylandSurface *surface,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
|
||||
void meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface,
|
||||
|
|
|
@ -103,9 +103,6 @@ wl_shell_surface_destructor (struct wl_resource *resource)
|
|||
surface_from_wl_shell_surface_resource (resource);
|
||||
GList *l;
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||
surface);
|
||||
|
||||
if (wl_shell_surface->popup)
|
||||
meta_wayland_popup_dismiss (wl_shell_surface->popup);
|
||||
|
||||
|
|
|
@ -740,6 +740,8 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel);
|
||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
@ -750,15 +752,12 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
{
|
||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!surface->buffer_ref->buffer && xdg_surface_priv->first_buffer_attached)
|
||||
{
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
|
||||
|
||||
meta_wayland_xdg_surface_reset (xdg_surface);
|
||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
|
||||
pending);
|
||||
|
@ -1089,6 +1088,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (xdg_popup);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
@ -1103,7 +1104,7 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||
if (!surface->buffer_ref->buffer && xdg_surface_priv->first_buffer_attached)
|
||||
{
|
||||
meta_wayland_xdg_surface_reset (xdg_surface);
|
||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1380,14 +1381,10 @@ meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_sur
|
|||
static void
|
||||
xdg_surface_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
|
||||
MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandXdgSurfacePrivate *priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
|
||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
||||
surface);
|
||||
|
||||
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
|
||||
xdg_surface);
|
||||
|
||||
|
|
|
@ -197,15 +197,35 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
|||
void
|
||||
meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
gint64 current_time = g_get_monotonic_time ();
|
||||
GList *l;
|
||||
int64_t now_us;
|
||||
|
||||
while (!wl_list_empty (&compositor->frame_callbacks))
|
||||
now_us = g_get_monotonic_time ();
|
||||
|
||||
l = compositor->frame_callback_surfaces;
|
||||
while (l)
|
||||
{
|
||||
MetaWaylandFrameCallback *callback =
|
||||
wl_container_of (compositor->frame_callbacks.next, callback, link);
|
||||
GList *l_cur = l;
|
||||
MetaWaylandSurface *surface = l->data;
|
||||
MetaSurfaceActor *actor;
|
||||
MetaWaylandActorSurface *actor_surface;
|
||||
|
||||
wl_callback_send_done (callback->resource, current_time / 1000);
|
||||
wl_resource_destroy (callback->resource);
|
||||
l = l->next;
|
||||
|
||||
actor = meta_wayland_surface_get_actor (surface);
|
||||
if (!actor)
|
||||
continue;
|
||||
|
||||
if (!clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)) &&
|
||||
meta_surface_actor_is_obscured (actor))
|
||||
continue;
|
||||
|
||||
actor_surface = META_WAYLAND_ACTOR_SURFACE (surface->role);
|
||||
meta_wayland_actor_surface_emit_frame_callbacks (actor_surface,
|
||||
now_us / 1000);
|
||||
|
||||
compositor->frame_callback_surfaces =
|
||||
g_list_delete_link (compositor->frame_callback_surfaces, l_cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,16 +272,22 @@ meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor,
|
|||
}
|
||||
|
||||
void
|
||||
meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface)
|
||||
meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandFrameCallback *callback, *next;
|
||||
if (g_list_find (compositor->frame_callback_surfaces, surface))
|
||||
return;
|
||||
|
||||
wl_list_for_each_safe (callback, next, &compositor->frame_callbacks, link)
|
||||
{
|
||||
if (callback->surface == surface)
|
||||
wl_resource_destroy (callback->resource);
|
||||
}
|
||||
compositor->frame_callback_surfaces =
|
||||
g_list_prepend (compositor->frame_callback_surfaces, surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
compositor->frame_callback_surfaces =
|
||||
g_list_remove (compositor->frame_callback_surfaces, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -313,8 +339,6 @@ meta_wayland_log_func (const char *fmt,
|
|||
static void
|
||||
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
wl_list_init (&compositor->frame_callbacks);
|
||||
|
||||
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
||||
|
||||
wl_log_set_handler_server (meta_wayland_log_func);
|
||||
|
|
|
@ -62,8 +62,11 @@ void meta_wayland_compositor_set_input_focus (MetaWaylandComp
|
|||
|
||||
void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface);
|
||||
void meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
META_EXPORT_TEST
|
||||
const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor);
|
||||
|
|
Loading…
Reference in a new issue