[gtk+/wip/simple-draw4: 14/20] wayland: Don't use double buffers for wayland when not needed



commit d4968d8140e6055abda7c0b2c1945d3a9de02dcc
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Apr 29 21:49:12 2013 +0200

    wayland: Don't use double buffers for wayland when not needed
    
    If we got the release event for the last buffer then we're
    fine with writing directly to the window surface, as wayland
    will not be looing at it. This saves us from allocating
    and copying more data.

 gdk/wayland/gdkwindow-wayland.c |   58 +++++++++++++++++++++++++++++++-------
 1 files changed, 47 insertions(+), 11 deletions(-)
---
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index a55f355..146e0a1 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -382,11 +382,24 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
     }
 }
 
+static const cairo_user_data_key_t gdk_wayland_cairo_key;
+
+typedef struct _GdkWaylandCairoSurfaceData {
+  gpointer buf;
+  size_t buf_length;
+  struct wl_shm_pool *pool;
+  struct wl_buffer *buffer;
+  GdkWaylandDisplay *display;
+  int32_t width, height;
+  gboolean busy;
+} GdkWaylandCairoSurfaceData;
+
 static void
 on_frame_clock_after_paint (GdkFrameClock *clock,
                             GdkWindow     *window)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkWaylandCairoSurfaceData *data;
   struct wl_callback *callback;
 
   if (!impl->pending_commit)
@@ -400,6 +413,10 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
   _gdk_frame_clock_freeze (clock);
 
   wl_surface_commit (impl->surface);
+
+  data = cairo_surface_get_user_data (impl->cairo_surface,
+                                     &gdk_wayland_cairo_key);
+  data->busy = TRUE;
 }
 
 void
@@ -462,17 +479,6 @@ _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
                     G_CALLBACK (on_frame_clock_after_paint), window);
 }
 
-static const cairo_user_data_key_t gdk_wayland_cairo_key;
-
-typedef struct _GdkWaylandCairoSurfaceData {
-  gpointer buf;
-  size_t buf_length;
-  struct wl_shm_pool *pool;
-  struct wl_buffer *buffer;
-  GdkWaylandDisplay *display;
-  int32_t width, height;
-} GdkWaylandCairoSurfaceData;
-
 static void
 gdk_wayland_window_attach_image (GdkWindow *window)
 {
@@ -588,6 +594,19 @@ _create_shm_pool (struct wl_shm  *shm,
   return pool;
 }
 
+
+static void
+buffer_release_callback (void *_data, struct wl_buffer *wl_buffer)
+{
+  GdkWaylandCairoSurfaceData *data = _data;
+
+  data->busy = FALSE;
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+  buffer_release_callback
+};
+
 static cairo_surface_t *
 gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
                                  int width, int height)
@@ -602,6 +621,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
   data->buffer = NULL;
   data->width = width;
   data->height = height;
+  data->busy = FALSE;
 
   stride = width * 4;
 
@@ -613,6 +633,7 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
   data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
                                             width, height,
                                             stride, WL_SHM_FORMAT_ARGB8888);
+  wl_buffer_add_listener (data->buffer, &buffer_listener, data);
 
   surface = cairo_image_surface_create_for_data (data->buf,
                                                  CAIRO_FORMAT_ARGB32,
@@ -668,6 +689,20 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
 }
 
 
+static gboolean
+gdk_window_impl_wayland_begin_paint_region (GdkWindow       *window,
+                                           const cairo_region_t *region)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkWaylandCairoSurfaceData *data;
+
+  gdk_wayland_window_ensure_cairo_surface (window);
+  data = cairo_surface_get_user_data (impl->cairo_surface,
+                                     &gdk_wayland_cairo_key);
+
+  return data->busy;
+}
+
 static void
 gdk_window_impl_wayland_finalize (GObject *object)
 {
@@ -1904,6 +1939,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
   impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
   impl_class->get_shape = gdk_wayland_window_get_shape;
   impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
+  impl_class->begin_paint_region = gdk_window_impl_wayland_begin_paint_region;
   /* impl_class->beep */
 
   impl_class->focus = gdk_wayland_window_focus;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]