mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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
@ -42,7 +42,6 @@ struct _MetaSurfaceActorWayland
|
|||||||
MetaSurfaceActor parent;
|
MetaSurfaceActor parent;
|
||||||
|
|
||||||
MetaWaylandSurface *surface;
|
MetaWaylandSurface *surface;
|
||||||
struct wl_list frame_callback_list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaSurfaceActorWayland,
|
G_DEFINE_TYPE (MetaSurfaceActorWayland,
|
||||||
@ -72,23 +71,6 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
|
|||||||
return meta_shaped_texture_is_opaque (stex);
|
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 *
|
CoglScanout *
|
||||||
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||||
CoglOnscreen *onscreen)
|
CoglOnscreen *onscreen)
|
||||||
@ -101,35 +83,13 @@ meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
|||||||
if (!scanout)
|
if (!scanout)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
queue_frame_callbacks (self);
|
|
||||||
|
|
||||||
return scanout;
|
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
|
static void
|
||||||
meta_surface_actor_wayland_dispose (GObject *object)
|
meta_surface_actor_wayland_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
|
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
|
||||||
MetaWaylandFrameCallback *cb, *next;
|
|
||||||
MetaShapedTexture *stex;
|
MetaShapedTexture *stex;
|
||||||
|
|
||||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||||
@ -143,9 +103,6 @@ meta_surface_actor_wayland_dispose (GObject *object)
|
|||||||
self->surface = NULL;
|
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);
|
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)
|
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||||
{
|
{
|
||||||
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
|
||||||
GObjectClass *object_class = G_OBJECT_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->process_damage = meta_surface_actor_wayland_process_damage;
|
||||||
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
||||||
surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
|
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 ());
|
g_assert (meta_is_wayland_compositor ());
|
||||||
|
|
||||||
wl_list_init (&self->frame_callback_list);
|
|
||||||
self->surface = surface;
|
self->surface = surface;
|
||||||
g_object_add_weak_pointer (G_OBJECT (self->surface),
|
g_object_add_weak_pointer (G_OBJECT (self->surface),
|
||||||
(gpointer *) &self->surface);
|
(gpointer *) &self->surface);
|
||||||
|
@ -107,9 +107,15 @@ meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
|
||||||
meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (priv->actor),
|
if (wl_list_empty (&surface->unassigned.pending_frame_callback_list))
|
||||||
&surface->pending_frame_callback_list);
|
return;
|
||||||
wl_list_init (&surface->pending_frame_callback_list);
|
|
||||||
|
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
|
void
|
||||||
@ -118,18 +124,37 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor
|
|||||||
{
|
{
|
||||||
MetaWaylandActorSurfacePrivate *priv =
|
MetaWaylandActorSurfacePrivate *priv =
|
||||||
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
||||||
MetaSurfaceActorWayland *surface_actor_wayland =
|
MetaWaylandSurfaceRole *surface_role =
|
||||||
META_SURFACE_ACTOR_WAYLAND (priv->actor);
|
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;
|
return;
|
||||||
|
|
||||||
meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland,
|
wl_list_insert_list (priv->frame_callback_list.prev,
|
||||||
&priv->frame_callback_list);
|
&pending->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_init (&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
|
double
|
||||||
@ -265,18 +290,17 @@ meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandActorSurfacePrivate *priv =
|
MetaWaylandActorSurfacePrivate *priv =
|
||||||
meta_wayland_actor_surface_get_instance_private (actor_surface);
|
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) &&
|
if (!wl_list_empty (&pending->frame_callback_list) &&
|
||||||
cairo_region_is_empty (pending->surface_damage) &&
|
priv->actor &&
|
||||||
cairo_region_is_empty (pending->buffer_damage))
|
!meta_surface_actor_is_obscured (priv->actor))
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (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);
|
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,
|
void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||||||
MetaWaylandSurfaceState *pending);
|
MetaWaylandSurfaceState *pending);
|
||||||
|
|
||||||
|
void meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface,
|
||||||
|
uint32_t timestamp_ms);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_ACTOR_SURFACE_H */
|
#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);
|
meta_wayland_cursor_surface_get_instance_private (cursor_surface);
|
||||||
|
|
||||||
wl_list_insert_list (&priv->frame_callbacks,
|
wl_list_insert_list (&priv->frame_callbacks,
|
||||||
&surface->pending_frame_callback_list);
|
&surface->unassigned.pending_frame_callback_list);
|
||||||
wl_list_init (&surface->pending_frame_callback_list);
|
wl_list_init (&surface->unassigned.pending_frame_callback_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "compositor/meta-feedback-actor-private.h"
|
#include "compositor/meta-feedback-actor-private.h"
|
||||||
|
#include "wayland/meta-wayland.h"
|
||||||
|
|
||||||
struct _MetaWaylandSurfaceRoleDND
|
struct _MetaWaylandSurfaceRoleDND
|
||||||
{
|
{
|
||||||
@ -42,7 +43,11 @@ dnd_surface_assigned (MetaWaylandSurfaceRole *surface_role)
|
|||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
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
|
static void
|
||||||
@ -56,7 +61,8 @@ dnd_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_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_x = pending->dx;
|
||||||
surface_role_dnd->pending_offset_y = pending->dy;
|
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);
|
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
|
||||||
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
|
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
|
||||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandActorSurface *actor_surface =
|
||||||
|
META_WAYLAND_ACTOR_SURFACE (xdg_surface);
|
||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
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);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,14 +1220,10 @@ meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg
|
|||||||
static void
|
static void
|
||||||
zxdg_surface_v6_destructor (struct wl_resource *resource)
|
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);
|
MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandZxdgSurfaceV6Private *priv =
|
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
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,
|
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
|
||||||
xdg_surface);
|
xdg_surface);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ struct _MetaWaylandCompositor
|
|||||||
struct wl_display *wayland_display;
|
struct wl_display *wayland_display;
|
||||||
char *display_name;
|
char *display_name;
|
||||||
GHashTable *outputs;
|
GHashTable *outputs;
|
||||||
struct wl_list frame_callbacks;
|
GList *frame_callback_surfaces;
|
||||||
|
|
||||||
MetaXWaylandManager xwayland_manager;
|
MetaXWaylandManager xwayland_manager;
|
||||||
|
|
||||||
|
@ -362,9 +362,6 @@ wl_subsurface_destructor (struct wl_resource *resource)
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (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);
|
g_node_unlink (surface->subsurface_branch_node);
|
||||||
unparent_actor (surface);
|
unparent_actor (surface);
|
||||||
|
|
||||||
|
@ -409,15 +409,6 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||||||
cairo_region_destroy (transformed_region);
|
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 *
|
MetaWaylandBuffer *
|
||||||
meta_wayland_surface_get_buffer (MetaWaylandSurface *surface)
|
meta_wayland_surface_get_buffer (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
@ -632,15 +623,6 @@ meta_wayland_surface_state_class_init (MetaWaylandSurfaceStateClass *klass)
|
|||||||
G_TYPE_NONE, 0);
|
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
|
static void
|
||||||
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||||
MetaWaylandSurfaceState *state)
|
MetaWaylandSurfaceState *state)
|
||||||
@ -776,7 +758,9 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
|||||||
}
|
}
|
||||||
else
|
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)
|
if (state->newly_attached)
|
||||||
{
|
{
|
||||||
@ -1358,14 +1342,16 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
if (surface->input_region)
|
if (surface->input_region)
|
||||||
cairo_region_destroy (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,
|
g_hash_table_foreach (surface->outputs,
|
||||||
surface_output_disconnect_signals,
|
surface_output_disconnect_signals,
|
||||||
surface);
|
surface);
|
||||||
g_hash_table_destroy (surface->outputs);
|
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);
|
wl_resource_destroy (cb->resource);
|
||||||
|
|
||||||
if (surface->resource)
|
if (surface->resource)
|
||||||
@ -1412,7 +1398,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
|||||||
surface,
|
surface,
|
||||||
wl_surface_destructor);
|
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->outputs = g_hash_table_new (NULL, NULL);
|
||||||
surface->shortcut_inhibited_seats = 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;
|
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 *
|
cairo_region_t *
|
||||||
meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
|
meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
|
@ -168,13 +168,9 @@ struct _MetaWaylandSurface
|
|||||||
/* Buffer renderer state. */
|
/* Buffer renderer state. */
|
||||||
gboolean buffer_held;
|
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. */
|
/* Intermediate state for when no role has been assigned. */
|
||||||
struct {
|
struct {
|
||||||
|
struct wl_list pending_frame_callback_list;
|
||||||
MetaWaylandBuffer *buffer;
|
MetaWaylandBuffer *buffer;
|
||||||
} unassigned;
|
} unassigned;
|
||||||
|
|
||||||
@ -288,9 +284,6 @@ gboolean meta_wayland_surface_should_cache_state (MetaWaylandSurface
|
|||||||
|
|
||||||
MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
|
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_frame_callbacks (MetaWaylandSurface *surface);
|
||||||
|
|
||||||
void meta_wayland_surface_queue_pending_state_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);
|
surface_from_wl_shell_surface_resource (resource);
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
meta_wayland_compositor_destroy_frame_callbacks (surface->compositor,
|
|
||||||
surface);
|
|
||||||
|
|
||||||
if (wl_shell_surface->popup)
|
if (wl_shell_surface->popup)
|
||||||
meta_wayland_popup_dismiss (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);
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel);
|
||||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandActorSurface *actor_surface =
|
||||||
|
META_WAYLAND_ACTOR_SURFACE (xdg_toplevel);
|
||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
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);
|
window = meta_wayland_surface_get_window (surface);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
meta_wayland_surface_cache_pending_frame_callbacks (surface, pending);
|
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface->buffer_ref->buffer && xdg_surface_priv->first_buffer_attached)
|
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_xdg_surface_reset (xdg_surface);
|
||||||
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
|
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface,
|
||||||
pending);
|
pending);
|
||||||
@ -1089,6 +1088,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
|||||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||||
|
MetaWaylandActorSurface *actor_surface =
|
||||||
|
META_WAYLAND_ACTOR_SURFACE (xdg_popup);
|
||||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||||
MetaWaylandSurface *surface =
|
MetaWaylandSurface *surface =
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
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)
|
if (!surface->buffer_ref->buffer && xdg_surface_priv->first_buffer_attached)
|
||||||
{
|
{
|
||||||
meta_wayland_xdg_surface_reset (xdg_surface);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1380,14 +1381,10 @@ meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_sur
|
|||||||
static void
|
static void
|
||||||
xdg_surface_destructor (struct wl_resource *resource)
|
xdg_surface_destructor (struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource);
|
|
||||||
MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource);
|
MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandXdgSurfacePrivate *priv =
|
MetaWaylandXdgSurfacePrivate *priv =
|
||||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
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,
|
priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces,
|
||||||
xdg_surface);
|
xdg_surface);
|
||||||
|
|
||||||
|
@ -197,15 +197,35 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
|||||||
void
|
void
|
||||||
meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
|
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 =
|
GList *l_cur = l;
|
||||||
wl_container_of (compositor->frame_callbacks.next, callback, link);
|
MetaWaylandSurface *surface = l->data;
|
||||||
|
MetaSurfaceActor *actor;
|
||||||
|
MetaWaylandActorSurface *actor_surface;
|
||||||
|
|
||||||
wl_callback_send_done (callback->resource, current_time / 1000);
|
l = l->next;
|
||||||
wl_resource_destroy (callback->resource);
|
|
||||||
|
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
|
void
|
||||||
meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
|
meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||||
MetaWaylandSurface *surface)
|
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)
|
compositor->frame_callback_surfaces =
|
||||||
{
|
g_list_prepend (compositor->frame_callback_surfaces, surface);
|
||||||
if (callback->surface == surface)
|
}
|
||||||
wl_resource_destroy (callback->resource);
|
|
||||||
}
|
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
|
static void
|
||||||
@ -313,8 +339,6 @@ meta_wayland_log_func (const char *fmt,
|
|||||||
static void
|
static void
|
||||||
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
||||||
{
|
{
|
||||||
wl_list_init (&compositor->frame_callbacks);
|
|
||||||
|
|
||||||
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
wl_log_set_handler_server (meta_wayland_log_func);
|
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_paint_finished (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
void meta_wayland_compositor_destroy_frame_callbacks (MetaWaylandCompositor *compositor,
|
void meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||||
MetaWaylandSurface *surface);
|
MetaWaylandSurface *surface);
|
||||||
|
|
||||||
|
void meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
|
||||||
|
MetaWaylandSurface *surface);
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor);
|
const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor);
|
||||||
|
Loading…
Reference in New Issue
Block a user