[gtk+/wip/mir-async-swaps] mir: swap buffer async only when a repaint has been requested
- From: Marco Trevisan <marcotrevi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/mir-async-swaps] mir: swap buffer async only when a repaint has been requested
- Date: Wed, 19 Nov 2014 16:22:49 +0000 (UTC)
commit 4073caf3b47a9c847b30d9238860e9f16118337c
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Wed Nov 19 17:21:56 2014 +0100
mir: swap buffer async only when a repaint has been requested
And ignore swapping while still processing a request.
gdk/mir/gdkmir-private.h | 2 +-
gdk/mir/gdkmirdisplay.c | 2 +-
gdk/mir/gdkmirscreen.c | 2 +-
gdk/mir/gdkmirwindowimpl.c | 68 ++++++++++++++++++++++++++++++++++++++------
4 files changed, 62 insertions(+), 12 deletions(-)
---
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
index 4f1d2ee..234130f 100644
--- a/gdk/mir/gdkmir-private.h
+++ b/gdk/mir/gdkmir-private.h
@@ -59,7 +59,7 @@ GdkCursor *_gdk_mir_cursor_new_for_name (GdkDisplay *display, const gchar *name)
const gchar *_gdk_mir_cursor_get_name (GdkCursor *cursor);
-GdkWindowImpl *_gdk_mir_window_impl_new (void);
+GdkWindowImpl *_gdk_mir_window_impl_new (GdkWindow *window);
void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state);
diff --git a/gdk/mir/gdkmirdisplay.c b/gdk/mir/gdkmirdisplay.c
index b1dbb30..9f026f0 100644
--- a/gdk/mir/gdkmirdisplay.c
+++ b/gdk/mir/gdkmirdisplay.c
@@ -404,7 +404,7 @@ gdk_mir_display_create_window_impl (GdkDisplay *display,
g_printerr ("\n");
if (attributes->wclass != GDK_INPUT_OUTPUT)
return;
- window->impl = _gdk_mir_window_impl_new ();
+ window->impl = _gdk_mir_window_impl_new (window);
}
static GdkKeymap *
diff --git a/gdk/mir/gdkmirscreen.c b/gdk/mir/gdkmirscreen.c
index 2b53cef..d7ac7a5 100644
--- a/gdk/mir/gdkmirscreen.c
+++ b/gdk/mir/gdkmirscreen.c
@@ -257,7 +257,7 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
get_screen_size (GDK_MIR_SCREEN (screen)->display_config, &width, &height);
s->root_window = _gdk_display_create_window (s->display);
- s->root_window->impl = _gdk_mir_window_impl_new ();
+ s->root_window->impl = _gdk_mir_window_impl_new (s->root_window);
s->root_window->impl_window = s->root_window;
s->root_window->visual = s->visual;
s->root_window->window_type = GDK_WINDOW_ROOT;
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 6956502..8831345 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -27,6 +27,7 @@
#include "gdkinternals.h"
#include "gdkdisplayprivate.h"
#include "gdkdeviceprivate.h"
+#include "gdkframeclockprivate.h"
#define GDK_MIR_WINDOW_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_MIR,
GdkMirWindowImplClass))
#define GDK_IS_WINDOW_IMPL_MIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_MIR))
@@ -76,6 +77,9 @@ struct _GdkMirWindowImpl
/* TRUE if cursor is inside this window */
gboolean cursor_inside;
+
+ gboolean pending_commit;
+ gboolean pending_swap;
};
struct _GdkMirWindowImplClass
@@ -86,10 +90,16 @@ struct _GdkMirWindowImplClass
G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
+static void on_frame_clock_after_paint (GdkFrameClock *clock, GdkWindow *window);
GdkWindowImpl *
-_gdk_mir_window_impl_new (void)
+_gdk_mir_window_impl_new (GdkWindow *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);
+
return g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
}
@@ -271,6 +281,9 @@ ensure_no_surface (GdkWindow *window)
g_clear_pointer (&impl->dummy_surface, mir_surface_release_sync);
}
+ impl->pending_commit = FALSE;
+ impl->pending_swap = FALSE;
+
g_clear_pointer(&impl->surface, mir_surface_release_sync);
}
@@ -286,10 +299,43 @@ redraw_transient (GdkWindow *window)
}
static void
-send_buffer (GdkWindow *window)
+on_swap_buffer_completed (MirSurface *surface, void *data)
+{
+ GdkWindow *window = data;
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+ /* The Cairo context is no longer valid */
+ g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
+ impl->pending_swap = FALSE;
+
+ _gdk_frame_clock_thaw (gdk_window_get_frame_clock (window));
+}
+
+static void
+on_frame_clock_after_paint (GdkFrameClock *clock,
+ GdkWindow *window)
{
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+ if (!impl->pending_commit)
+ return;
+
+ impl->pending_commit = FALSE;
+ _gdk_frame_clock_freeze (clock);
+
+ /* Send the completed buffer to Mir */
+ impl->pending_swap = TRUE;
+ mir_surface_swap_buffers (impl->surface, on_swap_buffer_completed, window);
+}
+
+static void
+send_buffer_delayed (GdkWindow *window)
+{
+ GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+ if (impl->pending_swap || impl->pending_commit)
+ return;
+
/* Transient windows draw onto parent instead */
if (impl->transient_for)
{
@@ -325,11 +371,15 @@ send_buffer (GdkWindow *window)
cairo_surface_destroy (surface);
}
- /* Send the completed buffer to Mir */
- mir_surface_swap_buffers_sync (impl->surface);
+ impl->pending_commit = TRUE;
+}
- /* The Cairo context is no longer valid */
- g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
+static void
+send_buffer (GdkWindow *window)
+{
+ send_buffer_delayed (window);
+ gdk_frame_clock_request_phase (gdk_window_get_frame_clock (window),
+ GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
}
static cairo_surface_t *
@@ -666,8 +716,8 @@ gdk_mir_window_impl_begin_paint_region (GdkWindow *window,
const cairo_region_t *region)
{
//g_printerr ("gdk_mir_window_impl_begin_paint_region window=%p\n", window);
- /* Indicate we are ready to be drawn onto directly? */
- return FALSE;
+ /* Indicate we are ready to be drawn right now */
+ return GDK_MIR_WINDOW_IMPL (window->impl)->pending_swap;
}
static void
@@ -677,7 +727,7 @@ gdk_mir_window_impl_end_paint (GdkWindow *window)
//g_printerr ("gdk_mir_window_impl_end_paint window=%p\n", window);
if (impl->visible && !window->current_paint.use_gl)
- send_buffer (window);
+ send_buffer_delayed (window);
}
static cairo_region_t *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]