forked from AuroraMiddleware/gtk
gdk/frameclock: Make surfaces inhibit freeze
To make a frame clock tick as long as any of the associated surfaces expect to receive ticks, make the surfaces inhibit freezing the clock, instead of directly tell the frame clock to freeze itself. This makes it so that as long as any surface using a certain frame clock is not frozen (e.g. just received a frame event from the display server), the frame clock will not be frozen. With this, the frame clock is initiated as frozen, and won't be thawed until any surface inhibits freeze. It will be frozen again, when every surface has that previously inhibited freeze uninhibited freeze.
This commit is contained in:
parent
a2ff6af4b3
commit
5db079b052
@ -88,10 +88,10 @@ gdk_broadway_surface_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
thaw_clock_cb (GdkFrameClock *clock)
|
||||
thaw_updates_cb (GdkSurface *surface)
|
||||
{
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
g_object_unref (clock);
|
||||
gdk_surface_thaw_updates (surface);
|
||||
g_object_unref (surface);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@ -109,9 +109,9 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
|
||||
|
||||
/* If there is no remote web client, rate limit update to once a second */
|
||||
if (local_reply)
|
||||
g_timeout_add_seconds (1, (GSourceFunc)thaw_clock_cb, g_object_ref (clock));
|
||||
g_timeout_add_seconds (1, (GSourceFunc)thaw_updates_cb, g_object_ref (surface));
|
||||
else
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
gdk_surface_thaw_updates (surface);
|
||||
|
||||
if (timings)
|
||||
{
|
||||
@ -140,7 +140,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
GdkBroadwayDisplay *broadway_display;
|
||||
|
||||
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
|
||||
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
|
||||
gdk_surface_freeze_updates (surface);
|
||||
|
||||
broadway_display = GDK_BROADWAY_DISPLAY (display);
|
||||
|
||||
|
@ -97,10 +97,14 @@ struct _GdkFrameClockPrivate
|
||||
gint n_timings;
|
||||
gint current;
|
||||
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
|
||||
gint n_freeze_inhibitors;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
_gdk_frame_clock_freeze (GdkFrameClock *clock);
|
||||
|
||||
static void
|
||||
gdk_frame_clock_finalize (GObject *object)
|
||||
{
|
||||
@ -114,12 +118,21 @@ gdk_frame_clock_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_frame_clock_constructed (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->constructed (object);
|
||||
|
||||
_gdk_frame_clock_freeze (GDK_FRAME_CLOCK (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_frame_clock_class_init (GdkFrameClockClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass*) klass;
|
||||
|
||||
gobject_class->finalize = gdk_frame_clock_finalize;
|
||||
gobject_class->constructed = gdk_frame_clock_constructed;
|
||||
|
||||
/**
|
||||
* GdkFrameClock::flush-events:
|
||||
@ -335,7 +348,7 @@ gdk_frame_clock_end_updating (GdkFrameClock *frame_clock)
|
||||
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
_gdk_frame_clock_freeze (GdkFrameClock *clock)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
@ -344,7 +357,7 @@ _gdk_frame_clock_freeze (GdkFrameClock *clock)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
_gdk_frame_clock_thaw (GdkFrameClock *clock)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
@ -352,6 +365,35 @@ _gdk_frame_clock_thaw (GdkFrameClock *clock)
|
||||
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
|
||||
priv = clock->priv;
|
||||
|
||||
priv->n_freeze_inhibitors++;
|
||||
if (priv->n_freeze_inhibitors == 1)
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
|
||||
priv = clock->priv;
|
||||
|
||||
priv->n_freeze_inhibitors--;
|
||||
if (priv->n_freeze_inhibitors == 0)
|
||||
_gdk_frame_clock_freeze (clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_frame_clock_get_frame_counter:
|
||||
* @frame_clock: a #GdkFrameClock
|
||||
|
@ -105,8 +105,8 @@ struct _GdkFrameTimings
|
||||
guint slept_before : 1;
|
||||
};
|
||||
|
||||
void _gdk_frame_clock_freeze (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_thaw (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
|
||||
|
||||
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
|
@ -1341,10 +1341,14 @@ gdk_surface_schedule_update (GdkSurface *surface)
|
||||
{
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (surface &&
|
||||
(surface->update_freeze_count ||
|
||||
gdk_surface_is_toplevel_frozen (surface)))
|
||||
return;
|
||||
g_return_if_fail (surface);
|
||||
|
||||
if (surface->update_freeze_count ||
|
||||
gdk_surface_is_toplevel_frozen (surface))
|
||||
{
|
||||
surface->pending_schedule_update = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there's no frame clock (a foreign surface), then the invalid
|
||||
* region will just stick around unless gdk_surface_process_updates()
|
||||
@ -1581,13 +1585,17 @@ gdk_surface_freeze_updates (GdkSurface *surface)
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
surface->update_freeze_count++;
|
||||
if (surface->update_freeze_count == 1)
|
||||
_gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_surface_thaw_updates:
|
||||
* @surface: a #GdkSurface
|
||||
*
|
||||
* Thaws a surface frozen with gdk_surface_freeze_updates().
|
||||
* Thaws a surface frozen with gdk_surface_freeze_updates(). Note that this
|
||||
* will not necessarily schedule updates if the surface freeze count reaches
|
||||
* zero.
|
||||
**/
|
||||
void
|
||||
gdk_surface_thaw_updates (GdkSurface *surface)
|
||||
@ -1597,7 +1605,15 @@ gdk_surface_thaw_updates (GdkSurface *surface)
|
||||
g_return_if_fail (surface->update_freeze_count > 0);
|
||||
|
||||
if (--surface->update_freeze_count == 0)
|
||||
gdk_surface_schedule_update (surface);
|
||||
{
|
||||
_gdk_frame_clock_inhibit_freeze (surface->frame_clock);
|
||||
|
||||
if (surface->pending_schedule_update)
|
||||
{
|
||||
surface->pending_schedule_update = FALSE;
|
||||
gdk_surface_schedule_update (surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1606,7 +1622,7 @@ gdk_surface_freeze_toplevel_updates (GdkSurface *surface)
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
surface->update_and_descendants_freeze_count++;
|
||||
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
|
||||
gdk_surface_freeze_updates (surface);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1616,9 +1632,9 @@ gdk_surface_thaw_toplevel_updates (GdkSurface *surface)
|
||||
g_return_if_fail (surface->update_and_descendants_freeze_count > 0);
|
||||
|
||||
surface->update_and_descendants_freeze_count--;
|
||||
_gdk_frame_clock_thaw (gdk_surface_get_frame_clock (surface));
|
||||
|
||||
gdk_surface_schedule_update (surface);
|
||||
gdk_surface_thaw_updates (surface);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3718,6 +3734,9 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
|
||||
G_CALLBACK (gdk_surface_paint_on_clock),
|
||||
surface);
|
||||
}
|
||||
|
||||
if (surface->update_freeze_count == 0)
|
||||
_gdk_frame_clock_inhibit_freeze (clock);
|
||||
}
|
||||
|
||||
if (surface->frame_clock)
|
||||
@ -3737,6 +3756,10 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
|
||||
G_CALLBACK (gdk_surface_paint_on_clock),
|
||||
surface);
|
||||
}
|
||||
|
||||
if (surface->update_freeze_count == 0)
|
||||
_gdk_frame_clock_uninhibit_freeze (surface->frame_clock);
|
||||
|
||||
g_object_unref (surface->frame_clock);
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ struct _GdkSurface
|
||||
|
||||
cairo_region_t *update_area;
|
||||
guint update_freeze_count;
|
||||
gboolean pending_schedule_update;
|
||||
/* This is the update_area that was in effect when the current expose
|
||||
started. It may be smaller than the expose area if we'e painting
|
||||
more than we have to, but it represents the "true" damage. */
|
||||
|
@ -349,7 +349,7 @@ frame_callback (void *data,
|
||||
return;
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
gdk_surface_thaw_updates (surface);
|
||||
|
||||
timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter);
|
||||
impl->pending_frame_counter = 0;
|
||||
@ -465,8 +465,9 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
g_signal_emit (impl, signals[COMMITTED], 0);
|
||||
}
|
||||
|
||||
if (impl->awaiting_frame)
|
||||
_gdk_frame_clock_freeze (clock);
|
||||
if (impl->awaiting_frame &&
|
||||
impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
|
||||
gdk_surface_freeze_updates (surface);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2577,12 +2578,8 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
|
||||
if (impl->awaiting_frame)
|
||||
{
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
frame_clock = gdk_surface_get_frame_clock (surface);
|
||||
if (frame_clock)
|
||||
_gdk_frame_clock_thaw (frame_clock);
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
if (impl->display_server.gtk_surface)
|
||||
|
@ -874,7 +874,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
surface_impl->toplevel->frame_pending)
|
||||
{
|
||||
surface_impl->toplevel->frame_pending = FALSE;
|
||||
_gdk_frame_clock_thaw (gdk_surface_get_frame_clock (event->any.surface));
|
||||
gdk_surface_thaw_updates (event->any.surface);
|
||||
}
|
||||
|
||||
if (toplevel)
|
||||
@ -1238,7 +1238,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
|
||||
if (surface_impl->toplevel->frame_pending)
|
||||
{
|
||||
surface_impl->toplevel->frame_pending = FALSE;
|
||||
_gdk_frame_clock_thaw (clock);
|
||||
gdk_surface_thaw_updates (event->any.surface);
|
||||
}
|
||||
|
||||
gdk_frame_clock_get_refresh_info (clock,
|
||||
|
@ -397,7 +397,7 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
|
||||
g_intern_static_string ("_NET_WM_FRAME_DRAWN")))
|
||||
{
|
||||
impl->toplevel->frame_pending = TRUE;
|
||||
_gdk_frame_clock_freeze (gdk_surface_get_frame_clock (surface));
|
||||
gdk_surface_freeze_updates (surface);
|
||||
timings->cookie = impl->toplevel->current_counter_value;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user