summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2014-11-19 17:21:56 +0100
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2014-11-20 04:52:58 +0100
commitd76bba5cb42bed9716fdcf9e58fd074d4aee0cf5 (patch)
tree45041ce584c15b2679e97e33d293e031eb6950e6
parent99d849412baf14e6cecde7268e1609a411de733d (diff)
downloadgtk+-d76bba5cb42bed9716fdcf9e58fd074d4aee0cf5.tar.gz
mir: swap buffer async only when a repaint has been requestedwip/mir-async-swaps
And ignore swapping while still processing a request.
-rw-r--r--gdk/mir/gdkmir-private.h2
-rw-r--r--gdk/mir/gdkmirdisplay.c2
-rw-r--r--gdk/mir/gdkmirscreen.c2
-rw-r--r--gdk/mir/gdkmirwindowimpl.c68
4 files changed, 62 insertions, 12 deletions
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
index 053615a210..06193c7161 100644
--- a/gdk/mir/gdkmir-private.h
+++ b/gdk/mir/gdkmir-private.h
@@ -81,7 +81,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 dd71ac63ee..fba89f90d4 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 2b53cef76e..d7ac7a5bc3 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 57cd70d0f9..57c351c10e 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -28,6 +28,7 @@
#include "gdkintl.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))
@@ -79,6 +80,9 @@ struct _GdkMirWindowImpl
/* TRUE if cursor is inside this window */
gboolean cursor_inside;
+
+ gboolean pending_commit;
+ gboolean pending_swap;
};
struct _GdkMirWindowImplClass
@@ -89,10 +93,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);
}
@@ -274,6 +284,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);
}
@@ -289,10 +302,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)
{
@@ -328,11 +374,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 *
@@ -669,8 +719,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
@@ -680,7 +730,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 *