diff options
author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-11-19 17:21:56 +0100 |
---|---|---|
committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-11-20 04:52:58 +0100 |
commit | d76bba5cb42bed9716fdcf9e58fd074d4aee0cf5 (patch) | |
tree | 45041ce584c15b2679e97e33d293e031eb6950e6 | |
parent | 99d849412baf14e6cecde7268e1609a411de733d (diff) | |
download | gtk+-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.h | 2 | ||||
-rw-r--r-- | gdk/mir/gdkmirdisplay.c | 2 | ||||
-rw-r--r-- | gdk/mir/gdkmirscreen.c | 2 | ||||
-rw-r--r-- | 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 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 * |