diff options
author | Ray Strode <rstrode@redhat.com> | 2016-02-27 16:17:38 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2016-02-29 10:52:00 -0500 |
commit | 316fe1dbbd6e0600e0002cebb4323473b4e2ec64 (patch) | |
tree | 081502dea78c728a2c7cc2d57dfc09c1ab344504 | |
parent | 6ad67451f44d753942905dda574c65e66d071d8e (diff) | |
download | gtk+-316fe1dbbd6e0600e0002cebb4323473b4e2ec64.tar.gz |
wayland: deal with staging buffer getting allocated prematurely
The staging buffer gets allocated any time begin_paint is called
on the window. This can happen even with an empty paint region,
so we should cope with that situation. At the moment we crash
trying to post a runtime warning.
https://bugzilla.gnome.org/show_bug.cgi?id=762755
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index aee1165039..168c1a3d88 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -674,19 +674,32 @@ buffer_release_callback (void *_data, return; } - /* 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. - */ - if (impl->staging_cairo_surface != NULL) + if (impl->staged_updates_region != NULL) { - /* If this fails, then we've allocated a staging buffer prematurely. - * We didn't have any screen updates. + /* If this fails, then we're tracking staged updates on a staging surface + * that doesn't exist. */ - g_warn_if_fail (!cairo_region_is_empty (impl->staged_updates_region)); - - g_clear_pointer (&impl->committed_cairo_surface, cairo_surface_destroy); - return; + 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 |