[gtk/gtk-4-2: 19/91] surface: Always set PHASE_PAINT as pending when updates are scheduled
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-4-2: 19/91] surface: Always set PHASE_PAINT as pending when updates are scheduled
- Date: Tue, 4 May 2021 02:05:40 +0000 (UTC)
commit f7ab0b19c7675fe4f772e363f118dcd9707e8122
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Apr 7 21:04:28 2021 +0200
surface: Always set PHASE_PAINT as pending when updates are scheduled
At times (most often when closing subsurfaces that are scheduling
relayouts) the PHASE_PAINT handling gets broken with the following
sequence:
1. Surface receives wl_callback.done for the previous frame.
Surface is thawed.
2. A new update on the surface is scheduled. PHASE_PAINT is
requested directly on the frame clock. priv->pending_phase is
left unset in the surface.
3. Surface gets frozen
4. Frame clock processes the update scheduled at 2. The surface
is frozen, so paint is prevented. PHASE_PAINT is considered
handled.
5. Compositor emits wl_callback.done again. Surface is thawed.
6. At this point the machinery is off
- The surface didn't paint but has pending update regions
- priv->draw_needed is set in the toplevel and other portions
of the widget tree
- So queueing redraws is ineffective at eventually calling
gdk_surface_schedule_update() again on the toplevel surface.
- We don't paint anymore, so this broken state is not flushed
until other subsurface changes manage to schedule the missing
update.
To fix this, always set PHASE_PAINT in priv->pending_phase when
doing gdk_surface_schedule_update(). If the frame clock turns
around before the surface is thawed, it will still be waiting to
be processed the next iteration.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3750
gdk/gdksurface.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index c55a9a8042..ef6464c43a 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1299,12 +1299,11 @@ gdk_surface_schedule_update (GdkSurface *surface)
g_return_if_fail (surface);
+ surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_PAINT;
+
if (surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
- {
- surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_PAINT;
- return;
- }
+ return;
/* If there's no frame clock (a foreign surface), then the invalid
* region will just stick around unless gdk_surface_process_updates()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]