wayland: Rewrite Cairo rendering
authorBenjamin Otte <otte@redhat.com>
Tue, 17 Apr 2018 21:05:41 +0000 (23:05 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 24 Apr 2018 21:16:58 +0000 (23:16 +0200)
Also, split it into its own file - which was the original reason for
looking at this code, the rewrite was an unintentional side effect.

This changes the context to create surfaces on demand.
So whenever the compositor holds onto a surface while GDK wants to
render, it just creates a new surface. If the compositor releases
surfaces, we will retain one for the next frame to be rendered, but free
all extra ones.
This way, we should get to a stage where we have exactly as many
surfaces as needed and never allocate/free any.

gdk/wayland/gdkcairocontext-wayland.c
gdk/wayland/gdkcairocontext-wayland.h
gdk/wayland/gdkprivate-wayland.h
gdk/wayland/gdksurface-wayland.c

index f5ee327543291a0e8b1bb2e17a338e30c836698a..fe4237f63df69673ecfc86a0a4d940ec3b344777 100644 (file)
 
 #include "config.h"
 
-#include "gdkconfig.h"
-
 #include "gdkcairocontext-wayland.h"
 
+#include "gdkprivate-wayland.h"
+
+#include "gdkinternals.h"
+
+static const cairo_user_data_key_t gdk_wayland_cairo_context_key;
+static const cairo_user_data_key_t gdk_wayland_cairo_region_key;
+
 G_DEFINE_TYPE (GdkWaylandCairoContext, gdk_wayland_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
 
+static void
+gdk_wayland_cairo_context_surface_add_region (cairo_surface_t      *surface,
+                                              const cairo_region_t *region)
+{
+  cairo_region_t *surface_region;
+
+  surface_region = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_region_key);
+  if (surface_region == NULL)
+    {
+      surface_region = cairo_region_copy (region);
+      cairo_surface_set_user_data (surface,
+                                   &gdk_wayland_cairo_region_key,
+                                   surface_region,
+                                   (cairo_destroy_func_t) cairo_region_destroy);
+    }
+  else
+    {
+      cairo_region_union (surface_region, region);
+    }
+}
+
+static void
+gdk_wayland_cairo_context_surface_clear_region (cairo_surface_t *surface)
+{
+  cairo_surface_set_user_data (surface, &gdk_wayland_cairo_region_key, NULL, NULL);
+}
+
+static const cairo_region_t *
+gdk_wayland_cairo_context_surface_get_region (cairo_surface_t *surface)
+{
+  return cairo_surface_get_user_data (surface, &gdk_wayland_cairo_region_key);
+}
+
+static GdkWaylandCairoContext *
+gdk_wayland_cairo_context_get_from_surface (cairo_surface_t *surface)
+{
+  return cairo_surface_get_user_data (surface, &gdk_wayland_cairo_context_key);
+}
+
+static void
+gdk_wayland_cairo_context_add_surface (GdkWaylandCairoContext *self,
+                                       cairo_surface_t        *surface)
+{
+  cairo_surface_reference (surface);
+  cairo_surface_set_user_data (surface, &gdk_wayland_cairo_context_key, self, NULL);
+
+  self->surfaces = g_slist_prepend (self->surfaces, surface);
+}
+
+static void
+gdk_wayland_cairo_context_remove_surface (GdkWaylandCairoContext *self,
+                                          cairo_surface_t        *surface)
+{
+  self->surfaces = g_slist_remove (self->surfaces, surface);
+
+  cairo_surface_set_user_data (surface, &gdk_wayland_cairo_context_key, NULL, NULL);
+  cairo_surface_destroy (surface);
+}
+
+static void
+gdk_wayland_cairo_context_buffer_release (void             *_data,
+                                          struct wl_buffer *wl_buffer)
+{
+  cairo_surface_t *cairo_surface = _data;
+  GdkWaylandCairoContext *self = gdk_wayland_cairo_context_get_from_surface (cairo_surface);
+
+  /* context was destroyed before compositor released this buffer */
+  if (self == NULL)
+    return;
+
+  /* Cache one surface for reuse when drawing */
+  if (self->cached_surface == NULL)
+    {
+      self->cached_surface = cairo_surface;
+      return;
+    }
+
+  /* Get rid of all the extra ones */
+  gdk_wayland_cairo_context_remove_surface (self, cairo_surface);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+  gdk_wayland_cairo_context_buffer_release
+};
+
+static cairo_surface_t *
+gdk_wayland_cairo_context_create_surface (GdkWaylandCairoContext *self)
+{
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)));
+  GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
+  cairo_surface_t *cairo_surface;
+  struct wl_buffer *buffer;
+  cairo_region_t *region;
+  int width, height;
+
+  width = gdk_surface_get_width (surface);
+  height = gdk_surface_get_height (surface);
+  cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
+                                                           width, height,
+                                                           gdk_surface_get_scale_factor (surface));
+  buffer = _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface);
+  wl_buffer_add_listener (buffer, &buffer_listener, cairo_surface);
+  gdk_wayland_cairo_context_add_surface (self, cairo_surface);
+
+  region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 0, 0, width, height });
+  gdk_wayland_cairo_context_surface_add_region (cairo_surface, region);
+  cairo_region_destroy (region);
+
+  return cairo_surface;
+}
+
+static void
+gdk_wayland_cairo_context_begin_frame (GdkDrawContext *draw_context,
+                                       cairo_region_t *region)
+{
+  GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (draw_context);
+  const cairo_region_t *surface_region;
+  GSList *l;
+  cairo_t *cr;
+
+  if (self->cached_surface)
+    self->paint_surface = g_steal_pointer (&self->cached_surface);
+  else
+    self->paint_surface = gdk_wayland_cairo_context_create_surface (self);
+
+  surface_region = gdk_wayland_cairo_context_surface_get_region (self->paint_surface);
+  if (surface_region)
+    cairo_region_union (region, surface_region);
+
+  for (l = self->surfaces; l; l = l->next)
+    {
+      gdk_wayland_cairo_context_surface_add_region (l->data, region);
+    }
+
+  /* clear the repaint area */
+  cr = cairo_create (self->paint_surface);
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  gdk_cairo_region (cr, region);
+  cairo_fill (cr);
+  cairo_destroy (cr);
+}
+
+static void
+gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
+                                     cairo_region_t *painted,
+                                     cairo_region_t *damage)
+{
+  GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (draw_context);
+  GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
+
+  gdk_wayland_surface_attach_image (surface, self->paint_surface, painted);
+  gdk_wayland_surface_sync (surface);
+
+  gdk_wayland_cairo_context_surface_clear_region (self->paint_surface);
+  self->paint_surface = NULL;
+}
+
+static void
+gdk_wayland_cairo_context_clear_all_cairo_surfaces (GdkWaylandCairoContext *self)
+{
+  self->cached_surface = NULL;
+  while (self->surfaces)
+    gdk_wayland_cairo_context_remove_surface (self, self->surfaces->data);
+}
+
+static void
+gdk_wayland_cairo_context_surface_resized (GdkDrawContext *draw_context)
+{
+  GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (draw_context);
+
+  gdk_wayland_cairo_context_clear_all_cairo_surfaces (self);
+}
+
+static cairo_t *
+gdk_wayland_cairo_context_cairo_create (GdkCairoContext *context)
+{
+  GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (context);
+  cairo_t *cr;
+
+  if (self->paint_surface == NULL)
+    return NULL;
+
+  cr = cairo_create (self->paint_surface);
+  gdk_cairo_region (cr, gdk_wayland_cairo_context_surface_get_region (self->paint_surface));
+  cairo_clip (cr);
+
+  return cr;
+}
+
+static void
+gdk_wayland_cairo_context_dispose (GObject *object)
+{
+  GdkWaylandCairoContext *self = GDK_WAYLAND_CAIRO_CONTEXT (object);
+
+  gdk_wayland_cairo_context_clear_all_cairo_surfaces (self);
+
+  G_OBJECT_CLASS (gdk_wayland_cairo_context_parent_class)->dispose (object);
+}
+
 static void
 gdk_wayland_cairo_context_class_init (GdkWaylandCairoContextClass *klass)
 {
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
+  GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
+
+  gobject_class->dispose = gdk_wayland_cairo_context_dispose;
+
+  draw_context_class->begin_frame = gdk_wayland_cairo_context_begin_frame;
+  draw_context_class->end_frame = gdk_wayland_cairo_context_end_frame;
+  draw_context_class->surface_resized = gdk_wayland_cairo_context_surface_resized;
+
+  cairo_context_class->cairo_create = gdk_wayland_cairo_context_cairo_create;
 }
 
 static void
index 278415ddedb6526449954d9d56f4da38efc7050b..1cad7a6547bd3db5da8e5defe297f552a93a4138 100644 (file)
@@ -38,6 +38,10 @@ typedef struct _GdkWaylandCairoContextClass GdkWaylandCairoContextClass;
 struct _GdkWaylandCairoContext
 {
   GdkCairoContext parent_instance;
+
+  GSList *surfaces;
+  cairo_surface_t *cached_surface;
+  cairo_surface_t *paint_surface;
 };
 
 struct _GdkWaylandCairoContextClass
index 8de1b6383192a0cca163f9193591243376dd1c3e..db1c91626425630f0c4c1d267f910fe8cecafe33 100644 (file)
@@ -90,6 +90,9 @@ guint      _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
 
 void       gdk_wayland_surface_sync (GdkSurface *surface);
 void       gdk_wayland_surface_request_frame (GdkSurface *surface);
+void            gdk_wayland_surface_attach_image           (GdkSurface           *surface,
+                                                            cairo_surface_t      *cairo_surface,
+                                                            const cairo_region_t *damage);
 
 void            _gdk_wayland_surface_register_dnd          (GdkSurface *surface);
 GdkDragContext *_gdk_wayland_surface_drag_begin            (GdkSurface *surface,
index 7823589938c595c2ec05f30ff497a2de47f97d2a..f774ad13dd15c62e67300e064733daf1eb55a6d3 100644 (file)
@@ -123,7 +123,6 @@ struct _GdkSurfaceImplWayland
   unsigned int initial_configure_received : 1;
   unsigned int mapped : 1;
   unsigned int use_custom_surface : 1;
-  unsigned int pending_buffer_attached : 1;
   unsigned int pending_commit : 1;
   unsigned int awaiting_frame : 1;
   GdkSurfaceTypeHint hint;
@@ -131,10 +130,6 @@ struct _GdkSurfaceImplWayland
   GdkSurface *popup_parent;
   PositionMethod position_method;
 
-  cairo_surface_t *staging_cairo_surface;
-  cairo_surface_t *committed_cairo_surface;
-  cairo_surface_t *backfill_cairo_surface;
-
   int pending_buffer_offset_x;
   int pending_buffer_offset_y;
 
@@ -173,8 +168,6 @@ struct _GdkSurfaceImplWayland
   cairo_region_t *input_region;
   gboolean input_region_dirty;
 
-  cairo_region_t *staged_updates_region;
-
   int saved_width;
   int saved_height;
 
@@ -262,20 +255,6 @@ _gdk_wayland_screen_add_orphan_dialog (GdkSurface *surface)
       g_list_prepend (display_wayland->orphan_dialogs, surface);
 }
 
-static void
-drop_cairo_surfaces (GdkSurface *surface)
-{
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-
-  g_clear_pointer (&impl->staging_cairo_surface, cairo_surface_destroy);
-  g_clear_pointer (&impl->backfill_cairo_surface, cairo_surface_destroy);
-
-  /* We nullify this so if a buffer release comes in later, we won't
-   * try to reuse that buffer since it's no longer suitable
-   */
-  impl->committed_cairo_surface = NULL;
-}
-
 static void
 _gdk_wayland_surface_save_size (GdkSurface *surface)
 {
@@ -320,8 +299,6 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
       (impl->scale == scale))
     return;
 
-  drop_cairo_surfaces (surface);
-
   surface->width = width;
   surface->height = height;
   impl->scale = scale;
@@ -392,37 +369,6 @@ fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
     }
 }
 
-static void
-read_back_cairo_surface (GdkSurface *surface)
-{
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-  cairo_t *cr;
-  cairo_region_t *paint_region = NULL;
-
-  if (!impl->backfill_cairo_surface)
-    goto out;
-
-  paint_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 0, 0, surface->width, surface->height });
-  cairo_region_subtract (paint_region, impl->staged_updates_region);
-
-  if (cairo_region_is_empty (paint_region))
-    goto out;
-
-  cr = cairo_create (impl->staging_cairo_surface);
-  cairo_set_source_surface (cr, impl->backfill_cairo_surface, 0, 0);
-  gdk_cairo_region (cr, paint_region);
-  cairo_clip (cr);
-  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
-  cairo_paint (cr);
-  cairo_destroy (cr);
-  cairo_surface_flush (impl->staging_cairo_surface);
-
-out:
-  g_clear_pointer (&paint_region, cairo_region_destroy);
-  g_clear_pointer (&impl->staged_updates_region, cairo_region_destroy);
-  g_clear_pointer (&impl->backfill_cairo_surface, cairo_surface_destroy);
-}
-
 static void
 frame_callback (void               *data,
                 struct wl_callback *callback,
@@ -544,12 +490,6 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
 
       gdk_wayland_surface_request_frame (surface);
 
-      /* Before we commit a new buffer, make sure we've backfilled
-       * undrawn parts from any old committed buffer
-       */
-      if (impl->pending_buffer_attached)
-        read_back_cairo_surface (surface);
-
       /* From this commit forward, we can't write to the buffer,
        * it's "live".  In the future, if we need to stage more changes
        * we have to allocate a new staging buffer and draw to it instead.
@@ -560,10 +500,6 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
        */
       wl_surface_commit (impl->display_server.wl_surface);
 
-      if (impl->pending_buffer_attached)
-        impl->committed_cairo_surface = g_steal_pointer (&impl->staging_cairo_surface);
-
-      impl->pending_buffer_attached = FALSE;
       impl->pending_commit = FALSE;
 
       g_signal_emit (impl, signals[COMMITTED], 0);
@@ -667,20 +603,24 @@ _gdk_wayland_display_create_surface_impl (GdkDisplay    *display,
   g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
 }
 
-static void
-gdk_wayland_surface_attach_image (GdkSurface *surface)
+void
+gdk_wayland_surface_attach_image (GdkSurface           *surface,
+                                  cairo_surface_t      *cairo_surface,
+                                  const cairo_region_t *damage)
 {
-  GdkWaylandDisplay *display;
   GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandDisplay *display;
+  cairo_rectangle_int_t rect;
+  int i, n;
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
 
-  g_assert (_gdk_wayland_is_shm_surface (impl->staging_cairo_surface));
+  g_assert (_gdk_wayland_is_shm_surface (cairo_surface));
 
   /* Attach this new buffer to the surface */
   wl_surface_attach (impl->display_server.wl_surface,
-                     _gdk_wayland_shm_surface_get_wl_buffer (impl->staging_cairo_surface),
+                     _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
                      impl->pending_buffer_offset_x,
                      impl->pending_buffer_offset_y);
   impl->pending_buffer_offset_x = 0;
@@ -691,185 +631,13 @@ gdk_wayland_surface_attach_image (GdkSurface *surface)
   if (display->compositor_version >= WL_SURFACE_HAS_BUFFER_SCALE)
     wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale);
 
-  impl->pending_buffer_attached = TRUE;
-  impl->pending_commit = TRUE;
-}
-
-static const cairo_user_data_key_t gdk_wayland_surface_cairo_key;
-
-static void
-buffer_release_callback (void             *_data,
-                         struct wl_buffer *wl_buffer)
-{
-  cairo_surface_t *cairo_surface = _data;
-  GdkSurfaceImplWayland *impl = cairo_surface_get_user_data (cairo_surface, &gdk_wayland_surface_cairo_key);
-
-  g_return_if_fail (GDK_IS_SURFACE_IMPL_WAYLAND (impl));
-
-  /* The released buffer isn't the latest committed one, we have no further
-   * use for it, so clean it up.
-   */
-  if (impl->committed_cairo_surface != cairo_surface)
-    {
-      /* If this fails, then the surface buffer got reused before it was
-       * released from the compositor
-       */
-      g_warn_if_fail (impl->staging_cairo_surface != cairo_surface);
-
-      cairo_surface_destroy (cairo_surface);
-      return;
-    }
-
-  if (impl->staged_updates_region != NULL)
-    {
-      /* If this fails, then we're tracking staged updates on a staging surface
-       * that doesn't exist.
-       */
-      g_warn_if_fail (impl->staging_cairo_surface != NULL);
-
-      /* If we've staged updates into a new buffer before the release for this
-       * buffer came in, then we can't reuse this buffer, so unref it. It may still
-       * be alive as a readback buffer though (via impl->backfill_cairo_surface).
-       *
-       * It's possible a staging surface was allocated but no updates were staged.
-       * If that happened, clean up that staging surface now, since the old commit
-       * buffer is available again, and reusing the old commit buffer for future
-       * updates will save having to do a read back later.
-       */
-      if (!cairo_region_is_empty (impl->staged_updates_region))
-        {
-          g_clear_pointer (&impl->committed_cairo_surface, cairo_surface_destroy);
-          return;
-        }
-      else
-        {
-          g_clear_pointer (&impl->staged_updates_region, cairo_region_destroy);
-          g_clear_pointer (&impl->staging_cairo_surface, cairo_surface_destroy);
-        }
-    }
-
-  /* Release came in, we haven't done any interim updates, so we can just use
-   * the old committed buffer again.
-   */
-  impl->staging_cairo_surface = g_steal_pointer (&impl->committed_cairo_surface);
-}
-
-static const struct wl_buffer_listener buffer_listener = {
-  buffer_release_callback
-};
-
-static void
-gdk_wayland_surface_ensure_cairo_surface (GdkSurface *surface)
-{
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-
-  /* If we are drawing using OpenGL then we only need a logical 1x1 surface. */
-  if (impl->display_server.egl_window)
-    {
-      if (impl->staging_cairo_surface &&
-          _gdk_wayland_is_shm_surface (impl->staging_cairo_surface))
-        g_clear_pointer (&impl->staging_cairo_surface, cairo_surface_destroy);
-
-      if (!impl->staging_cairo_surface)
-        {
-          impl->staging_cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                                                    impl->scale,
-                                                                    impl->scale);
-          cairo_surface_set_device_scale (impl->staging_cairo_surface,
-                                          impl->scale, impl->scale);
-        }
-    }
-  else if (!impl->staging_cairo_surface)
+  n = cairo_region_num_rectangles (damage);
+  for (i = 0; i < n; i++)
     {
-      GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (impl->wrapper));
-      struct wl_buffer *buffer;
-
-      impl->staging_cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
-                                                                             impl->wrapper->width,
-                                                                             impl->wrapper->height,
-                                                                             impl->scale);
-      cairo_surface_set_user_data (impl->staging_cairo_surface,
-                                   &gdk_wayland_surface_cairo_key,
-                                   g_object_ref (impl),
-                                   (cairo_destroy_func_t)
-                                   g_object_unref);
-      buffer = _gdk_wayland_shm_surface_get_wl_buffer (impl->staging_cairo_surface);
-      wl_buffer_add_listener (buffer, &buffer_listener, impl->staging_cairo_surface);
+      cairo_region_get_rectangle (damage, i, &rect);
+      wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
     }
-}
-
-/* The cairo surface returned here uses a memory segment that's shared
- * with the display server.  This is not a temporary buffer that gets
- * copied to the display server, but the actual buffer the display server
- * will ultimately end up sending to the GPU. At the time this happens
- * impl->committed_cairo_surface gets set to impl->staging_cairo_surface, and
- * impl->staging_cairo_surface gets nullified.
- */
-static cairo_surface_t *
-gdk_wayland_surface_ref_cairo_surface (GdkSurface *surface)
-{
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-
-  if (GDK_SURFACE_DESTROYED (impl->wrapper))
-    return NULL;
-
-  gdk_wayland_surface_ensure_cairo_surface (surface);
-
-  cairo_surface_reference (impl->staging_cairo_surface);
-
-  return impl->staging_cairo_surface;
-}
-
-static gboolean
-gdk_surface_impl_wayland_begin_paint (GdkSurface *surface)
-{
-  gdk_wayland_surface_ensure_cairo_surface (surface);
-
-  return FALSE;
-}
-
-static void
-gdk_surface_impl_wayland_end_paint (GdkSurface *surface)
-{
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-  cairo_rectangle_int_t rect;
-  int i, n;
-
-  if (impl->staging_cairo_surface &&
-      _gdk_wayland_is_shm_surface (impl->staging_cairo_surface) &&
-      !cairo_region_is_empty (surface->current_paint.region))
-    {
-      gdk_wayland_surface_attach_image (surface);
-
-      /* If there's a committed buffer pending, then track which
-       * updates are staged until the next frame, so we can back
-       * fill the unstaged parts of the staging buffer with the
-       * last frame.
-       */
-      if (impl->committed_cairo_surface != NULL)
-        {
-          if (impl->staged_updates_region == NULL)
-            {
-              impl->staged_updates_region = cairo_region_copy (surface->current_paint.region);
-              impl->backfill_cairo_surface = cairo_surface_reference (impl->committed_cairo_surface);
-            }
-          else
-            {
-              cairo_region_union (impl->staged_updates_region, surface->current_paint.region);
-            }
-        }
-
-      n = cairo_region_num_rectangles (surface->current_paint.region);
-      for (i = 0; i < n; i++)
-        {
-          cairo_region_get_rectangle (surface->current_paint.region, i, &rect);
-          wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
-        }
-
-      impl->pending_commit = TRUE;
-    }
-
-  gdk_wayland_surface_sync (surface);
+  impl->pending_commit = TRUE;
 }
 
 void
@@ -913,7 +681,6 @@ gdk_surface_impl_wayland_finalize (GObject *object)
 
   g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
   g_clear_pointer (&impl->input_region, cairo_region_destroy);
-  g_clear_pointer (&impl->staged_updates_region, cairo_region_destroy);
   g_clear_pointer (&impl->shortcuts_inhibitors, g_hash_table_unref);
 
   G_OBJECT_CLASS (_gdk_surface_impl_wayland_parent_class)->finalize (object);
@@ -2389,10 +2156,6 @@ gdk_wayland_surface_show (GdkSurface *surface,
   gdk_wayland_surface_map (surface);
 
   _gdk_make_event (surface, GDK_MAP, NULL, FALSE);
-
-  if (impl->staging_cairo_surface &&
-      _gdk_wayland_is_shm_surface (impl->staging_cairo_surface))
-    gdk_wayland_surface_attach_image (surface);
 }
 
 static void
@@ -2527,7 +2290,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
   unset_transient_for_exported (surface);
 
   _gdk_wayland_surface_clear_saved_size (surface);
-  drop_cairo_surfaces (surface);
   impl->pending_commit = FALSE;
   impl->mapped = FALSE;
 }
@@ -3599,7 +3361,6 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
 
   object_class->finalize = gdk_surface_impl_wayland_finalize;
 
-  impl_class->ref_cairo_surface = gdk_wayland_surface_ref_cairo_surface;
   impl_class->show = gdk_wayland_surface_show;
   impl_class->hide = gdk_wayland_surface_hide;
   impl_class->withdraw = gdk_surface_wayland_withdraw;
@@ -3615,8 +3376,6 @@ _gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
   impl_class->get_device_state = gdk_surface_wayland_get_device_state;
   impl_class->input_shape_combine_region = gdk_surface_wayland_input_shape_combine_region;
   impl_class->destroy = gdk_wayland_surface_destroy;
-  impl_class->begin_paint = gdk_surface_impl_wayland_begin_paint;
-  impl_class->end_paint = gdk_surface_impl_wayland_end_paint;
   impl_class->beep = gdk_surface_impl_wayland_beep;
 
   impl_class->focus = gdk_wayland_surface_focus;