[gtk: 3/5] gdk/frameclock: Make surfaces inhibit freeze
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 3/5] gdk/frameclock: Make surfaces inhibit freeze
- Date: Wed, 3 Jul 2019 16:22:01 +0000 (UTC)
commit 5db079b052fcb934566f69ea49dd7fc3f6314813
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Fri Jun 28 18:45:44 2019 +0200
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.
gdk/broadway/gdksurface-broadway.c | 12 +++++-----
gdk/gdkframeclock.c | 46 ++++++++++++++++++++++++++++++++++++--
gdk/gdkframeclockprivate.h | 4 ++--
gdk/gdksurface.c | 41 +++++++++++++++++++++++++--------
gdk/gdksurfaceprivate.h | 1 +
gdk/wayland/gdksurface-wayland.c | 13 +++++------
gdk/x11/gdkdisplay-x11.c | 4 ++--
gdk/x11/gdksurface-x11.c | 2 +-
8 files changed, 93 insertions(+), 30 deletions(-)
---
diff --git a/gdk/broadway/gdksurface-broadway.c b/gdk/broadway/gdksurface-broadway.c
index 88f1b9de85..6d072359ac 100644
--- a/gdk/broadway/gdksurface-broadway.c
+++ b/gdk/broadway/gdksurface-broadway.c
@@ -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);
diff --git a/gdk/gdkframeclock.c b/gdk/gdkframeclock.c
index 6d79b1810e..cf3ae0b16d 100644
--- a/gdk/gdkframeclock.c
+++ b/gdk/gdkframeclock.c
@@ -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
diff --git a/gdk/gdkframeclockprivate.h b/gdk/gdkframeclockprivate.h
index 17d063b434..7ddceedb80 100644
--- a/gdk/gdkframeclockprivate.h
+++ b/gdk/gdkframeclockprivate.h
@@ -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,
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 44c66a66cd..70c2c409a0 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -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);
}
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index ce81b23a84..5f86e3c60a 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -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. */
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 1bc06568c7..af42ff267f 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -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)
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 60a8892c59..58ca9f1aa5 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -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,
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index f4ecd5d2f8..654876e2b8 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -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;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]