[gtk+] broadway: Sync surface updates with paint clock
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] broadway: Sync surface updates with paint clock
- Date: Fri, 29 Mar 2013 13:03:05 +0000 (UTC)
commit 71b4557210f07a4e300e8c36740f6b8004f82a54
Author: Alexander Larsson <alexl redhat com>
Date: Thu Mar 28 19:22:42 2013 +0100
broadway: Sync surface updates with paint clock
We now only update surface data after we have painted. Before we painted
in an idle, which meant we might send black data some times if we e.g.
resized the window and had not painted yet. Also, it means we're updating
less often to the daemon, saving resources.
We still have to queue a flush in the idle for non-draw operations,
otherwise e.g. resize of a toplevel will never be flushed if the clock
is frozen (e.g. during toplevel resize).
gdk/broadway/gdkwindow-broadway.c | 65 ++++++++++++++++++++++++++++--------
1 files changed, 50 insertions(+), 15 deletions(-)
---
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index e9f2b06..02fb04c 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -83,18 +83,16 @@ G_DEFINE_TYPE (GdkWindowImplBroadway,
gdk_window_impl_broadway,
GDK_TYPE_WINDOW_IMPL)
-static guint dirty_flush_id = 0;
-
-static gboolean
-dirty_flush_idle (gpointer data)
+static void
+update_dirty_windows_and_sync (void)
{
GList *l;
GdkBroadwayDisplay *display;
-
- dirty_flush_id = 0;
+ gboolean updated_surface;
display = GDK_BROADWAY_DISPLAY (gdk_display_get_default ());
+ updated_surface = FALSE;
for (l = display->toplevels; l != NULL; l = l->next)
{
GdkWindowImplBroadway *impl = l->data;
@@ -102,6 +100,7 @@ dirty_flush_idle (gpointer data)
if (impl->dirty)
{
impl->dirty = FALSE;
+ updated_surface = TRUE;
_gdk_broadway_server_window_update (display->server,
impl->id,
impl->surface);
@@ -110,16 +109,32 @@ dirty_flush_idle (gpointer data)
/* We sync here to ensure all references to the impl->surface memory
is done, as we may later paint new data in them. */
- gdk_display_sync (GDK_DISPLAY (display));
+ if (updated_surface)
+ gdk_display_sync (GDK_DISPLAY (display));
+ else
+ gdk_display_flush (GDK_DISPLAY (display));
+}
+
+static guint flush_id = 0;
+
+static gboolean
+flush_idle (gpointer data)
+{
+ flush_id = 0;
+
+ gdk_display_flush (gdk_display_get_default ());
return FALSE;
}
+/* We need to flush in an idle rather than AFTER_PAINT, as the clock
+ is frozen during e.g. window resizes so the paint will not happen
+ and the window resize request is never flushed. */
static void
-queue_dirty_flush (GdkBroadwayDisplay *display)
+queue_flush (GdkWindow *window)
{
- if (dirty_flush_id == 0)
- dirty_flush_id = gdk_threads_add_idle (dirty_flush_idle, NULL);
+ if (flush_id == 0)
+ flush_id = gdk_threads_add_idle (flush_idle, NULL);
}
static void
@@ -197,6 +212,25 @@ _gdk_broadway_screen_init_root_window (GdkScreen * screen)
_gdk_window_update_size (broadway_screen->root_window);
}
+static void
+on_frame_clock_after_paint (GdkFrameClock *clock,
+ GdkWindow *window)
+{
+ update_dirty_windows_and_sync ();
+}
+
+static void
+connect_frame_clock (GdkWindow *window)
+{
+ if (WINDOW_IS_TOPLEVEL (window))
+ {
+ GdkFrameClock *frame_clock = gdk_window_get_frame_clock (window);
+
+ g_signal_connect (frame_clock, "after-paint",
+ G_CALLBACK (on_frame_clock_after_paint), window);
+ }
+}
+
void
_gdk_broadway_display_create_window_impl (GdkDisplay *display,
GdkWindow *window,
@@ -229,6 +263,8 @@ _gdk_broadway_display_create_window_impl (GdkDisplay *display,
g_assert (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT);
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
+
+ connect_frame_clock (window);
}
void
@@ -384,7 +420,7 @@ gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
if (_gdk_broadway_server_window_show (broadway_display->server, impl->id))
- queue_dirty_flush (broadway_display);
+ queue_flush (window);
}
@@ -405,7 +441,7 @@ gdk_window_broadway_hide (GdkWindow *window)
broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
if (_gdk_broadway_server_window_hide (broadway_display->server, impl->id))
- queue_dirty_flush (broadway_display);
+ queue_flush (window);
_gdk_window_clear_update_area (window);
}
@@ -460,7 +496,7 @@ gdk_window_broadway_move_resize (GdkWindow *window,
with_move,
x, y,
window->width, window->height);
- queue_dirty_flush (broadway_display);
+ queue_flush (window);
if (size_changed)
window->resize_count++;
}
@@ -1327,7 +1363,6 @@ gdk_broadway_window_process_updates_recurse (GdkWindow *window,
impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
impl->dirty = TRUE;
- queue_dirty_flush (GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)));
}
void
@@ -1393,7 +1428,7 @@ _gdk_broadway_window_translate (GdkWindow *window,
if (_gdk_broadway_server_window_translate (broadway_display->server,
impl->id,
area, dx, dy))
- queue_dirty_flush (broadway_display);
+ queue_flush (window);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]