summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Soderlund2023-10-10 18:00:55 +0200
committerJoakim Soderlund2023-10-10 18:00:55 +0200
commitaf873da6f40de5fd42d1e5e29d19847f04532515 (patch)
tree5a5c8b3beabb538719eca0eee91d42dd94d97248
parentcf1c9edc1ed46def9819b30e4c6ae74cb8495123 (diff)
downloadaur-af873da6f40de5fd42d1e5e29d19847f04532515.tar.gz
Upgrade !1441 to commit 04094e9f
-rw-r--r--.SRCINFO2
-rw-r--r--PKGBUILD2
-rw-r--r--mr1441.patch876
3 files changed, 391 insertions, 489 deletions
diff --git a/.SRCINFO b/.SRCINFO
index fe4ec666ea45..0cad6fc81407 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -38,7 +38,7 @@ pkgbase = mutter-dynamic-buffering
source = mutter-dynamic-buffering::git+https://gitlab.gnome.org/GNOME/mutter.git#commit=4f6c91847088d7d6476b88575b3a6601b819b443
source = mr1441.patch
sha256sums = SKIP
- sha256sums = 14ecff144a878dc3cf7b979f5ced04b731a66affeb21fd009843f9c91df6ca7a
+ sha256sums = cefd26a4974160ccdf9a22f9e80ae59cb8c3aa42d76af00ea308d07c34a9dc25
pkgname = mutter-dynamic-buffering
provides = mutter
diff --git a/PKGBUILD b/PKGBUILD
index 5516bb2ac295..6890dd78c025 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -58,7 +58,7 @@ source=(
)
sha256sums=(
'SKIP'
- '14ecff144a878dc3cf7b979f5ced04b731a66affeb21fd009843f9c91df6ca7a'
+ 'cefd26a4974160ccdf9a22f9e80ae59cb8c3aa42d76af00ea308d07c34a9dc25'
)
pkgver() {
diff --git a/mr1441.patch b/mr1441.patch
index a23466e421a1..ef6f6a264705 100644
--- a/mr1441.patch
+++ b/mr1441.patch
@@ -1,10 +1,10 @@
Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
Source: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441
-Commit: 6f3605c8831e55f734a52fd7f6a13db8b842015b
-Rebase: Wed Jun 14 17:45:26 2023 +0800
+Commit: 04094e9ff9b97019a1547f386cbf5d6fc258841e
+Rebase: Fri Sep 22 22:00:38 2023 +0800
diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c
-index 3aeb29042..964215f76 100644
+index 30cc6fb12..d652a6e5f 100644
--- a/clutter/clutter/clutter-frame-clock.c
+++ b/clutter/clutter/clutter-frame-clock.c
@@ -35,6 +35,15 @@ enum
@@ -51,9 +51,20 @@ index 3aeb29042..964215f76 100644
+
+ ClutterFrameHint last_flip_hints;
- /* Last time we promoted short term durations to long term ones */
+ /* Last time we promoted short-term maximum to long-term one */
int64_t longterm_promotion_us;
-@@ -241,6 +255,12 @@ void
+@@ -219,10 +233,6 @@ static void
+ maybe_update_longterm_max_duration_us (ClutterFrameClock *frame_clock,
+ ClutterFrameInfo *frame_info)
+ {
+- /* Do not update long-term max if there has been no measurement */
+- if (!frame_clock->shortterm_max_update_duration_us)
+- return;
+-
+ if ((frame_info->presentation_time - frame_clock->longterm_promotion_us) <
+ G_USEC_PER_SEC)
+ return;
+@@ -249,6 +259,12 @@ void
clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
ClutterFrameInfo *frame_info)
{
@@ -66,12 +77,20 @@ index 3aeb29042..964215f76 100644
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockNotifyPresented,
"Frame Clock (presented)");
-@@ -324,18 +344,38 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
- frame_info->gpu_rendering_duration_ns != 0)
+@@ -328,31 +344,58 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
+
+ frame_clock->got_measurements_last_frame = FALSE;
+
+- if (frame_info->cpu_time_before_buffer_swap_us != 0)
++ if (frame_info->cpu_time_before_buffer_swap_us != 0 ||
++ frame_clock->ever_got_measurements)
{
int64_t dispatch_to_swap_us, swap_to_rendering_done_us, swap_to_flip_us;
+ int64_t dispatch_time_us = 0, flip_time_us = 0;
-+
+
+- dispatch_to_swap_us =
+- frame_info->cpu_time_before_buffer_swap_us -
+- frame_clock->last_dispatch_time_us;
+ switch (frame_clock->state)
+ {
+ case CLUTTER_FRAME_CLOCK_STATE_INIT:
@@ -89,17 +108,25 @@ index 3aeb29042..964215f76 100644
+ flip_time_us = frame_clock->prev_last_flip_time_us;
+ break;
+ }
-
- dispatch_to_swap_us =
- frame_info->cpu_time_before_buffer_swap_us -
-- frame_clock->last_dispatch_time_us;
-+ dispatch_time_us;
++
++ if (frame_info->cpu_time_before_buffer_swap_us == 0)
++ {
++ /* Cursor-only updates with no "swap" or "flip" */
++ dispatch_to_swap_us = 0;
++ swap_to_flip_us = 0;
++ }
++ else
++ {
++ dispatch_to_swap_us = frame_info->cpu_time_before_buffer_swap_us -
++ dispatch_time_us;
++ swap_to_flip_us = flip_time_us -
++ frame_info->cpu_time_before_buffer_swap_us;
++ }
swap_to_rendering_done_us =
frame_info->gpu_rendering_duration_ns / 1000;
- swap_to_flip_us =
+- swap_to_flip_us =
- frame_clock->last_flip_time_us -
-+ flip_time_us -
- frame_info->cpu_time_before_buffer_swap_us;
+- frame_info->cpu_time_before_buffer_swap_us;
CLUTTER_NOTE (FRAME_TIMINGS,
- "update2dispatch %ld µs, dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs",
@@ -108,7 +135,20 @@ index 3aeb29042..964215f76 100644
frame_clock->last_dispatch_lateness_us,
dispatch_to_swap_us,
swap_to_rendering_done_us,
-@@ -352,7 +392,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
+ swap_to_flip_us);
+
+ frame_clock->shortterm_max_update_duration_us =
+- CLAMP (frame_clock->last_dispatch_lateness_us + dispatch_to_swap_us +
+- MAX (swap_to_rendering_done_us, swap_to_flip_us),
+- frame_clock->shortterm_max_update_duration_us,
+- frame_clock->refresh_interval_us);
++ MAX (frame_clock->shortterm_max_update_duration_us,
++ frame_clock->last_dispatch_lateness_us + dispatch_to_swap_us +
++ MAX (swap_to_rendering_done_us, swap_to_flip_us));
+
+ maybe_update_longterm_max_duration_us (frame_clock, frame_info);
+
+@@ -361,7 +404,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
}
else
{
@@ -118,7 +158,7 @@ index 3aeb29042..964215f76 100644
frame_clock->last_dispatch_lateness_us);
}
-@@ -383,11 +424,18 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
+@@ -378,11 +422,18 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
g_warn_if_reached ();
break;
@@ -139,7 +179,7 @@ index 3aeb29042..964215f76 100644
}
}
-@@ -403,11 +451,18 @@ clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock)
+@@ -398,11 +449,18 @@ clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock)
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
g_warn_if_reached ();
break;
@@ -160,25 +200,23 @@ index 3aeb29042..964215f76 100644
}
}
-@@ -426,7 +481,16 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
- if (!frame_clock->got_measurements_last_frame ||
+@@ -417,7 +475,14 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
+ if (!frame_clock->ever_got_measurements ||
G_UNLIKELY (clutter_paint_debug_flags &
CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME))
- return refresh_interval_us * SYNC_DELAY_FALLBACK_FRACTION;
+ {
+ int64_t ret = refresh_interval_us * SYNC_DELAY_FALLBACK_FRACTION;
+
-+ if (frame_clock->state == CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE &&
-+ triple_buffering_mode != TRIPLE_BUFFERING_MODE_NEVER &&
-+ !(frame_clock->last_flip_hints & CLUTTER_FRAME_HINT_NO_REDRAW))
++ if (frame_clock->state == CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE)
+ ret += refresh_interval_us;
+
+ return ret;
+ }
- max_dispatch_lateness_us =
- MAX (frame_clock->longterm.max_dispatch_lateness_us,
-@@ -459,8 +523,6 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
+ /* Max render time shows how early the frame clock needs to be dispatched
+ * to make it to the predicted next presentation time. It is an estimate of
+@@ -437,8 +502,6 @@ clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
frame_clock->vblank_duration_us +
clutter_max_render_time_constant_us;
@@ -187,7 +225,7 @@ index 3aeb29042..964215f76 100644
return max_render_time_us;
}
-@@ -475,7 +537,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
+@@ -453,7 +516,7 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
int64_t refresh_interval_us;
int64_t min_render_time_allowed_us;
int64_t max_render_time_allowed_us;
@@ -196,7 +234,7 @@ index 3aeb29042..964215f76 100644
int64_t next_update_time_us;
now_us = g_get_monotonic_time ();
-@@ -520,7 +582,24 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
+@@ -498,7 +561,24 @@ calculate_next_update_time_us (ClutterFrameClock *frame_clock,
*
*/
last_presentation_time_us = frame_clock->last_presentation_time_us;
@@ -222,7 +260,7 @@ index 3aeb29042..964215f76 100644
/*
* However, the last presentation could have happened more than a frame ago.
-@@ -635,8 +714,12 @@ clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock)
+@@ -613,8 +693,12 @@ clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock)
frame_clock->pending_reschedule = TRUE;
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
break;
@@ -237,7 +275,7 @@ index 3aeb29042..964215f76 100644
break;
}
-@@ -673,9 +756,15 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
+@@ -651,9 +735,15 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
next_update_time_us = g_get_monotonic_time ();
@@ -255,7 +293,7 @@ index 3aeb29042..964215f76 100644
frame_clock->pending_reschedule = TRUE;
frame_clock->pending_reschedule_now = TRUE;
return;
-@@ -685,7 +774,6 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
+@@ -663,7 +753,6 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
frame_clock->next_update_time_us = next_update_time_us;
g_source_set_ready_time (frame_clock->source, next_update_time_us);
@@ -263,18 +301,20 @@ index 3aeb29042..964215f76 100644
frame_clock->is_next_presentation_time_valid = FALSE;
}
-@@ -693,6 +781,10 @@ void
+@@ -671,6 +760,12 @@ void
clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
{
int64_t next_update_time_us = -1;
+ TripleBufferingMode current_mode = triple_buffering_mode;
+
-+ if (frame_clock->last_flip_hints & CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED)
++ if (current_mode == TRIPLE_BUFFERING_MODE_AUTO &&
++ (frame_clock->last_flip_hints &
++ CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED))
+ current_mode = TRIPLE_BUFFERING_MODE_NEVER;
if (frame_clock->inhibit_count > 0)
{
-@@ -704,6 +796,7 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
+@@ -682,6 +777,7 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
{
case CLUTTER_FRAME_CLOCK_STATE_INIT:
next_update_time_us = g_get_monotonic_time ();
@@ -282,7 +322,7 @@ index 3aeb29042..964215f76 100644
break;
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
calculate_next_update_time_us (frame_clock,
-@@ -712,11 +805,37 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
+@@ -690,11 +786,37 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
&frame_clock->min_render_time_allowed_us);
frame_clock->is_next_presentation_time_valid =
(frame_clock->next_presentation_time_us != 0);
@@ -322,7 +362,7 @@ index 3aeb29042..964215f76 100644
frame_clock->pending_reschedule = TRUE;
return;
}
-@@ -725,7 +844,6 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
+@@ -703,7 +825,6 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
frame_clock->next_update_time_us = next_update_time_us;
g_source_set_ready_time (frame_clock->source, next_update_time_us);
@@ -330,7 +370,7 @@ index 3aeb29042..964215f76 100644
}
static void
-@@ -756,7 +874,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
+@@ -734,7 +855,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
frame_clock->refresh_interval_us;
lateness_us = time_us - ideal_dispatch_time_us;
@@ -339,9 +379,9 @@ index 3aeb29042..964215f76 100644
frame_clock->last_dispatch_lateness_us = 0;
else
frame_clock->last_dispatch_lateness_us = lateness_us;
-@@ -765,10 +883,25 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
- MAX (frame_clock->shortterm.max_dispatch_lateness_us,
- frame_clock->last_dispatch_lateness_us);
+@@ -755,10 +876,25 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
+ }
+ #endif
+ frame_clock->prev_last_dispatch_time_us = frame_clock->last_dispatch_time_us;
frame_clock->last_dispatch_time_us = time_us;
@@ -366,7 +406,7 @@ index 3aeb29042..964215f76 100644
frame_count = frame_clock->frame_count++;
-@@ -797,25 +930,31 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
+@@ -787,25 +923,31 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
result = iface->frame (frame_clock, frame, frame_clock->listener.user_data);
COGL_TRACE_END (ClutterFrameClockFrame);
@@ -410,7 +450,7 @@ index 3aeb29042..964215f76 100644
}
break;
}
-@@ -848,10 +987,13 @@ frame_clock_source_dispatch (GSource *source,
+@@ -838,10 +980,13 @@ frame_clock_source_dispatch (GSource *source,
}
void
@@ -426,7 +466,7 @@ index 3aeb29042..964215f76 100644
}
GString *
-@@ -963,8 +1105,6 @@ clutter_frame_clock_dispose (GObject *object)
+@@ -935,8 +1080,6 @@ clutter_frame_clock_dispose (GObject *object)
{
ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object);
@@ -435,7 +475,7 @@ index 3aeb29042..964215f76 100644
if (frame_clock->source)
{
g_signal_emit (frame_clock, signals[DESTROY], 0);
-@@ -985,6 +1125,15 @@ static void
+@@ -957,6 +1100,15 @@ static void
clutter_frame_clock_class_init (ClutterFrameClockClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -452,10 +492,10 @@ index 3aeb29042..964215f76 100644
object_class->dispose = clutter_frame_clock_dispose;
diff --git a/clutter/clutter/clutter-frame-clock.h b/clutter/clutter/clutter-frame-clock.h
-index 6fd5de47a..7f9f655c0 100644
+index 93ebc9438..e1fd6b986 100644
--- a/clutter/clutter/clutter-frame-clock.h
+++ b/clutter/clutter/clutter-frame-clock.h
-@@ -34,6 +34,13 @@ typedef enum _ClutterFrameResult
+@@ -33,6 +33,12 @@ typedef enum _ClutterFrameResult
CLUTTER_FRAME_RESULT_IDLE,
} ClutterFrameResult;
@@ -463,13 +503,12 @@ index 6fd5de47a..7f9f655c0 100644
+{
+ CLUTTER_FRAME_HINT_NONE = 0,
+ CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED = 1 << 0,
-+ CLUTTER_FRAME_HINT_NO_REDRAW = 1 << 1,
+} ClutterFrameHint;
+
#define CLUTTER_TYPE_FRAME_CLOCK (clutter_frame_clock_get_type ())
CLUTTER_EXPORT
G_DECLARE_FINAL_TYPE (ClutterFrameClock, clutter_frame_clock,
-@@ -92,8 +99,9 @@ void clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock,
+@@ -91,7 +97,8 @@ void clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock,
CLUTTER_EXPORT
float clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock);
@@ -480,12 +519,11 @@ index 6fd5de47a..7f9f655c0 100644
+ ClutterFrameHint hints);
GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock);
-
diff --git a/clutter/clutter/clutter-frame-private.h b/clutter/clutter/clutter-frame-private.h
-index 1eceb8bc0..fb97abeaf 100644
+index 0a0226b0a..55c76df72 100644
--- a/clutter/clutter/clutter-frame-private.h
+++ b/clutter/clutter/clutter-frame-private.h
-@@ -35,6 +35,7 @@ struct _ClutterFrame
+@@ -34,6 +34,7 @@ struct _ClutterFrame
gboolean has_result;
ClutterFrameResult result;
@@ -515,10 +553,10 @@ index 85baef274..413ce9c2b 100644
+ return frame->hints;
+}
diff --git a/clutter/clutter/clutter-frame.h b/clutter/clutter/clutter-frame.h
-index 6bac3f4e4..fa97e8bd5 100644
+index 1d5660d68..0e7f618a4 100644
--- a/clutter/clutter/clutter-frame.h
+++ b/clutter/clutter/clutter-frame.h
-@@ -55,6 +55,13 @@ void clutter_frame_set_result (ClutterFrame *frame,
+@@ -54,4 +54,11 @@ void clutter_frame_set_result (ClutterFrame *frame,
CLUTTER_EXPORT
gboolean clutter_frame_has_result (ClutterFrame *frame);
@@ -530,13 +568,11 @@ index 6bac3f4e4..fa97e8bd5 100644
+ClutterFrameHint clutter_frame_get_hints (ClutterFrame *frame);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFrame, clutter_frame_unref)
-
- #endif /* CLUTTER_FRAME_H */
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
-index 5f66d6032..41960fca4 100644
+index 168746dd4..f0e36619e 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
-@@ -1266,14 +1266,22 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
+@@ -1264,14 +1264,21 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
_clutter_stage_window_redraw_view (stage_window, view, frame);
@@ -555,26 +591,24 @@ index 5f66d6032..41960fca4 100644
+ {
+ clutter_frame_clock_record_flip (frame_clock,
+ g_get_monotonic_time (),
-+ clutter_frame_get_hints (frame) |
-+ CLUTTER_FRAME_HINT_NO_REDRAW);
++ clutter_frame_get_hints (frame));
+ }
_clutter_stage_window_finish_frame (stage_window, view, frame);
diff --git a/cogl/cogl/cogl-onscreen-private.h b/cogl/cogl/cogl-onscreen-private.h
-index dffe018d2..e0215f750 100644
+index 9dbecfd0c..681d91d2b 100644
--- a/cogl/cogl/cogl-onscreen-private.h
+++ b/cogl/cogl/cogl-onscreen-private.h
-@@ -97,4 +97,7 @@ cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen);
+@@ -95,3 +95,6 @@ cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen);
+
COGL_EXPORT CoglFrameInfo *
cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen);
-
++
+COGL_EXPORT unsigned int
+cogl_onscreen_count_pending_frames (CoglOnscreen *onscreen);
-+
- #endif /* __COGL_ONSCREEN_PRIVATE_H */
diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c
-index 842ececf7..1e2b11dee 100644
+index 73425e498..02c4474b2 100644
--- a/cogl/cogl/cogl-onscreen.c
+++ b/cogl/cogl/cogl-onscreen.c
@@ -508,6 +508,14 @@ cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen)
@@ -593,10 +627,10 @@ index 842ececf7..1e2b11dee 100644
cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen,
CoglFrameCallback callback,
diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c
-index db94c7e40..aed22960c 100644
+index c35cb36e3..2130e4042 100644
--- a/src/backends/meta-stage-impl.c
+++ b/src/backends/meta-stage-impl.c
-@@ -770,6 +770,8 @@ meta_stage_impl_redraw_view (ClutterStageWindow *stage_window,
+@@ -775,6 +775,8 @@ meta_stage_impl_redraw_view (ClutterStageWindow *stage_window,
{
g_autoptr (GError) error = NULL;
@@ -605,253 +639,11 @@ index db94c7e40..aed22960c 100644
if (meta_stage_impl_scanout_view (stage_impl,
stage_view,
scanout,
-diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c
-index f1b7459fe..8080098a0 100644
---- a/src/backends/native/meta-cursor-renderer-native.c
-+++ b/src/backends/native/meta-cursor-renderer-native.c
-@@ -59,19 +59,6 @@
- #include "wayland/meta-wayland-buffer.h"
- #endif
-
--/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
-- * Though, testing shows that we need to triple buffer the cursor buffer in
-- * order to avoid glitches when animating the cursor, at least when running on
-- * Intel. The reason for this might be (but is not confirmed to be) due to
-- * the user space gbm_bo cache, making us reuse and overwrite the kernel side
-- * buffer content before it was scanned out. To avoid this, we keep a user space
-- * reference to each buffer we set until at least one frame after it was drawn.
-- * In effect, this means we three active cursor gbm_bo's: one that that just has
-- * been set, one that was previously set and may or may not have been scanned
-- * out, and one pending that will be replaced if the cursor sprite changes.
-- */
--#define HW_CURSOR_BUFFER_COUNT 3
--
- static GQuark quark_cursor_sprite = 0;
-
- typedef struct _CrtcCursorData
-@@ -105,19 +92,10 @@ typedef struct _MetaCursorRendererNativeGpuData
- uint64_t cursor_height;
- } MetaCursorRendererNativeGpuData;
-
--typedef enum _MetaCursorBufferState
--{
-- META_CURSOR_BUFFER_STATE_NONE,
-- META_CURSOR_BUFFER_STATE_SET,
-- META_CURSOR_BUFFER_STATE_INVALIDATED,
--} MetaCursorBufferState;
--
- typedef struct _MetaCursorNativeGpuState
- {
- MetaGpu *gpu;
-- unsigned int active_buffer_idx;
-- MetaCursorBufferState pending_buffer_state;
-- MetaDrmBuffer *buffers[HW_CURSOR_BUFFER_COUNT];
-+ MetaDrmBuffer *buffer;
- } MetaCursorNativeGpuState;
-
- typedef struct _MetaCursorNativePrivate
-@@ -198,44 +176,17 @@ meta_cursor_renderer_native_finalize (GObject *object)
- G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
- }
-
--static unsigned int
--get_pending_cursor_sprite_buffer_index (MetaCursorNativeGpuState *cursor_gpu_state)
--{
-- return (cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
--}
--
--static MetaDrmBuffer *
--get_pending_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
--{
-- unsigned int pending_buffer_idx;
--
-- pending_buffer_idx =
-- get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
-- return cursor_gpu_state->buffers[pending_buffer_idx];
--}
--
--static MetaDrmBuffer *
--get_active_cursor_sprite_buffer (MetaCursorNativeGpuState *cursor_gpu_state)
--{
-- return cursor_gpu_state->buffers[cursor_gpu_state->active_buffer_idx];
--}
--
- static void
--set_pending_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
-- MetaGpuKms *gpu_kms,
-- MetaDrmBuffer *buffer)
-+set_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
-+ MetaGpuKms *gpu_kms,
-+ MetaDrmBuffer *buffer)
- {
- MetaCursorNativePrivate *cursor_priv;
- MetaCursorNativeGpuState *cursor_gpu_state;
-- unsigned int pending_buffer_idx;
-
- cursor_priv = ensure_cursor_priv (cursor_sprite);
- cursor_gpu_state = ensure_cursor_gpu_state (cursor_priv, gpu_kms);
--
-- pending_buffer_idx =
-- get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
-- cursor_gpu_state->buffers[pending_buffer_idx] = buffer;
-- cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_STATE_SET;
-+ cursor_gpu_state->buffer = buffer;
- }
-
- static void
-@@ -312,10 +263,7 @@ assign_cursor_plane (MetaCursorRendererNative *native,
- MetaKmsUpdate *kms_update;
- MetaKmsPlaneAssignment *plane_assignment;
-
-- if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
-- buffer = get_pending_cursor_sprite_buffer (cursor_gpu_state);
-- else
-- buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
-+ buffer = cursor_gpu_state->buffer;
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- kms_device = meta_kms_crtc_get_device (kms_crtc);
-@@ -365,13 +313,6 @@ assign_cursor_plane (MetaCursorRendererNative *native,
- native);
-
- crtc_cursor_data->buffer = buffer;
--
-- if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
-- {
-- cursor_gpu_state->active_buffer_idx =
-- (cursor_gpu_state->active_buffer_idx + 1) % HW_CURSOR_BUFFER_COUNT;
-- cursor_gpu_state->pending_buffer_state = META_CURSOR_BUFFER_STATE_NONE;
-- }
- }
-
- static float
-@@ -613,19 +554,7 @@ has_valid_cursor_sprite_buffer (MetaCursorSprite *cursor_sprite,
- if (!cursor_gpu_state)
- return FALSE;
-
-- switch (cursor_gpu_state->pending_buffer_state)
-- {
-- case META_CURSOR_BUFFER_STATE_NONE:
-- return get_active_cursor_sprite_buffer (cursor_gpu_state) != NULL;
-- case META_CURSOR_BUFFER_STATE_SET:
-- return TRUE;
-- case META_CURSOR_BUFFER_STATE_INVALIDATED:
-- return FALSE;
-- }
--
-- g_assert_not_reached ();
--
-- return FALSE;
-+ return cursor_gpu_state->buffer != NULL;
- }
-
- static void
-@@ -1132,16 +1061,14 @@ unset_crtc_cursor_renderer_privates (MetaGpu *gpu,
- static void
- cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state)
- {
-- int i;
- MetaDrmBuffer *active_buffer;
-
-- active_buffer = get_active_cursor_sprite_buffer (cursor_gpu_state);
-+ active_buffer = cursor_gpu_state->buffer;
- if (active_buffer)
- unset_crtc_cursor_renderer_privates (cursor_gpu_state->gpu,
- active_buffer);
-
-- for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
-- g_clear_object (&cursor_gpu_state->buffers[i]);
-+ g_clear_object (&cursor_gpu_state->buffer);
- g_free (cursor_gpu_state);
- }
-
-@@ -1178,14 +1105,7 @@ invalidate_cursor_gpu_state (MetaCursorSprite *cursor_sprite)
-
- g_hash_table_iter_init (&iter, cursor_priv->gpu_states);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &cursor_gpu_state))
-- {
-- unsigned int pending_buffer_idx;
--
-- pending_buffer_idx = get_pending_cursor_sprite_buffer_index (cursor_gpu_state);
-- g_clear_object (&cursor_gpu_state->buffers[pending_buffer_idx]);
-- cursor_gpu_state->pending_buffer_state =
-- META_CURSOR_BUFFER_STATE_INVALIDATED;
-- }
-+ g_clear_object (&cursor_gpu_state->buffer);
- }
-
- static void
-@@ -1423,35 +1343,7 @@ load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native,
- return;
- }
-
-- set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms, buffer);
--}
--
--static gboolean
--is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite,
-- MetaGpuKms *gpu_kms)
--{
-- MetaCursorNativePrivate *cursor_priv;
-- MetaCursorNativeGpuState *cursor_gpu_state;
--
-- cursor_priv = get_cursor_priv (cursor_sprite);
-- if (!cursor_priv)
-- return FALSE;
--
-- cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
-- if (!cursor_gpu_state)
-- return FALSE;
--
-- switch (cursor_gpu_state->pending_buffer_state)
-- {
-- case META_CURSOR_BUFFER_STATE_SET:
-- case META_CURSOR_BUFFER_STATE_NONE:
-- return TRUE;
-- case META_CURSOR_BUFFER_STATE_INVALIDATED:
-- return FALSE;
-- }
--
-- g_assert_not_reached ();
-- return FALSE;
-+ set_cursor_sprite_buffer (cursor_sprite, gpu_kms, buffer);
- }
-
- static gboolean
-@@ -1638,7 +1530,7 @@ realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
- if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
- return;
-
-- if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) &&
-+ if (has_valid_cursor_sprite_buffer (cursor_sprite, gpu_kms) &&
- is_cursor_scale_and_transform_valid (renderer, cursor_sprite))
- return;
-
-@@ -1783,8 +1675,8 @@ realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
- return;
- }
-
-- set_pending_cursor_sprite_buffer (cursor_sprite, gpu_kms,
-- META_DRM_BUFFER (buffer_gbm));
-+ set_cursor_sprite_buffer (cursor_sprite, gpu_kms,
-+ META_DRM_BUFFER (buffer_gbm));
- }
- }
- #endif
-@@ -1808,7 +1700,7 @@ realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
- if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
- return;
-
-- if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) &&
-+ if (has_valid_cursor_sprite_buffer (cursor_sprite, gpu_kms) &&
- is_cursor_scale_and_transform_valid (renderer, cursor_sprite))
- return;
-
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
-index e5405428c..48e864ca8 100644
+index 707da9dc1..932e5e6a0 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
-@@ -46,6 +46,8 @@ struct _MetaKmsCrtc
+@@ -48,6 +48,8 @@ struct _MetaKmsCrtc
MetaKmsCrtcState current_state;
MetaKmsCrtcPropTable prop_table;
@@ -860,7 +652,7 @@ index e5405428c..48e864ca8 100644
};
G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
-@@ -97,6 +99,12 @@ meta_kms_crtc_get_prop_drm_value (MetaKmsCrtc *crtc,
+@@ -99,6 +101,12 @@ meta_kms_crtc_get_prop_drm_value (MetaKmsCrtc *crtc,
return meta_kms_prop_convert_value (prop, value);
}
@@ -873,7 +665,7 @@ index e5405428c..48e864ca8 100644
gboolean
meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
{
-@@ -463,12 +471,23 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
+@@ -465,12 +473,23 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
return crtc;
}
@@ -897,7 +689,7 @@ index e5405428c..48e864ca8 100644
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
}
-@@ -478,6 +497,7 @@ meta_kms_crtc_init (MetaKmsCrtc *crtc)
+@@ -480,6 +499,7 @@ meta_kms_crtc_init (MetaKmsCrtc *crtc)
{
crtc->current_state.gamma.size = 0;
crtc->current_state.gamma.value = NULL;
@@ -905,18 +697,19 @@ index e5405428c..48e864ca8 100644
}
static void
-@@ -485,5 +505,6 @@ meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
+@@ -487,6 +507,7 @@ meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = meta_kms_crtc_dispose;
object_class->finalize = meta_kms_crtc_finalize;
}
+
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
-index 25fb71edb..61013bebd 100644
+index b26b682dd..a30a6de6e 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
-@@ -25,6 +25,7 @@
+@@ -22,6 +22,7 @@
#include <xf86drmMode.h>
#include "backends/native/meta-kms-types.h"
@@ -924,18 +717,17 @@ index 25fb71edb..61013bebd 100644
#include "backends/meta-backend-types.h"
#include "core/util-private.h"
#include "meta/boxes.h"
-@@ -64,4 +65,6 @@ int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
+@@ -60,3 +61,5 @@ int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
+
META_EXPORT_TEST
gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
-
-+MetaSwapChain * meta_kms_crtc_get_swap_chain (MetaKmsCrtc *crtc);
+
- #endif /* META_KMS_CRTC_H */
++MetaSwapChain * meta_kms_crtc_get_swap_chain (MetaKmsCrtc *crtc);
diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c
-index 83b217274..5024b876d 100644
+index d3fd77268..e7497607b 100644
--- a/src/backends/native/meta-kms-impl-device-atomic.c
+++ b/src/backends/native/meta-kms-impl-device-atomic.c
-@@ -507,6 +507,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
+@@ -505,6 +505,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
{
MetaKmsPlaneAssignment *plane_assignment = update_entry;
MetaKmsPlane *plane = plane_assignment->plane;
@@ -943,7 +735,7 @@ index 83b217274..5024b876d 100644
MetaDrmBuffer *buffer;
MetaKmsFbDamage *fb_damage;
uint32_t prop_id;
-@@ -659,6 +660,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
+@@ -657,6 +658,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
error))
return FALSE;
}
@@ -956,7 +748,7 @@ index 83b217274..5024b876d 100644
return TRUE;
}
-@@ -1002,7 +1009,7 @@ meta_kms_impl_device_atomic_process_update (MetaKmsImplDevice *impl_device,
+@@ -1001,7 +1008,7 @@ meta_kms_impl_device_atomic_process_update (MetaKmsImplDevice *impl_device,
req,
blob_ids,
meta_kms_update_get_plane_assignments (update),
@@ -966,10 +758,10 @@ index 83b217274..5024b876d 100644
&error))
goto err;
diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c
-index 341d54cc7..c739788ae 100644
+index 2d68ba11f..f4e23df07 100644
--- a/src/backends/native/meta-kms-impl-device-simple.c
+++ b/src/backends/native/meta-kms-impl-device-simple.c
-@@ -486,6 +486,8 @@ process_mode_set (MetaKmsImplDevice *impl_device,
+@@ -485,6 +485,8 @@ process_mode_set (MetaKmsImplDevice *impl_device,
return FALSE;
}
@@ -978,7 +770,7 @@ index 341d54cc7..c739788ae 100644
if (drm_mode)
{
g_hash_table_replace (impl_device_simple->cached_mode_sets,
-@@ -555,7 +557,7 @@ is_timestamp_earlier_than (uint64_t ts1,
+@@ -554,7 +556,7 @@ is_timestamp_earlier_than (uint64_t ts1,
typedef struct _RetryPageFlipData
{
MetaKmsCrtc *crtc;
@@ -987,7 +779,7 @@ index 341d54cc7..c739788ae 100644
MetaKmsPageFlipData *page_flip_data;
float refresh_rate;
uint64_t retry_time_us;
-@@ -568,6 +570,7 @@ retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data)
+@@ -567,6 +569,7 @@ retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data)
g_assert (!retry_page_flip_data->page_flip_data);
g_clear_pointer (&retry_page_flip_data->custom_page_flip,
meta_kms_custom_page_flip_free);
@@ -995,7 +787,7 @@ index 341d54cc7..c739788ae 100644
g_free (retry_page_flip_data);
}
-@@ -635,16 +638,21 @@ retry_page_flips (gpointer user_data)
+@@ -634,16 +637,21 @@ retry_page_flips (gpointer user_data)
}
else
{
@@ -1019,7 +811,7 @@ index 341d54cc7..c739788ae 100644
DRM_MODE_PAGE_FLIP_EVENT,
retry_page_flip_data->page_flip_data);
}
-@@ -731,7 +739,7 @@ retry_page_flips (gpointer user_data)
+@@ -730,7 +738,7 @@ retry_page_flips (gpointer user_data)
static void
schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsCrtc *crtc,
@@ -1028,7 +820,7 @@ index 341d54cc7..c739788ae 100644
float refresh_rate,
MetaKmsPageFlipData *page_flip_data,
MetaKmsCustomPageFlip *custom_page_flip)
-@@ -746,7 +754,7 @@ schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple,
+@@ -745,7 +753,7 @@ schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple,
retry_page_flip_data = g_new0 (RetryPageFlipData, 1);
*retry_page_flip_data = (RetryPageFlipData) {
.crtc = crtc,
@@ -1037,7 +829,7 @@ index 341d54cc7..c739788ae 100644
.page_flip_data = page_flip_data,
.refresh_rate = refresh_rate,
.retry_time_us = retry_time_us,
-@@ -880,6 +888,8 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
+@@ -877,6 +885,8 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
return FALSE;
}
@@ -1045,8 +837,8 @@ index 341d54cc7..c739788ae 100644
+
if (!impl_device_simple->mode_set_fallback_feedback_source)
{
- GSource *source;
-@@ -1004,20 +1014,20 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
+ MetaKmsImpl *impl = meta_kms_impl_device_get_impl (impl_device);
+@@ -1003,20 +1013,20 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
cached_mode_set = get_cached_mode_set (impl_device_simple, crtc);
if (cached_mode_set)
{
@@ -1071,7 +863,7 @@ index 341d54cc7..c739788ae 100644
refresh_rate,
page_flip_data,
g_steal_pointer (&custom_page_flip));
-@@ -1298,7 +1308,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
+@@ -1299,7 +1309,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
{
case META_KMS_PLANE_TYPE_PRIMARY:
/* Handled as part of the mode-set and page flip. */
@@ -1080,7 +872,7 @@ index 341d54cc7..c739788ae 100644
case META_KMS_PLANE_TYPE_CURSOR:
if (!process_cursor_plane_assignment (impl_device, update,
plane_assignment,
-@@ -1312,7 +1322,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
+@@ -1313,7 +1323,7 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
}
else
{
@@ -1089,7 +881,7 @@ index 341d54cc7..c739788ae 100644
}
case META_KMS_PLANE_TYPE_OVERLAY:
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
-@@ -1325,6 +1335,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
+@@ -1326,6 +1336,12 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
}
g_assert_not_reached ();
@@ -1103,10 +895,23 @@ index 341d54cc7..c739788ae 100644
static gboolean
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
-index d56636d55..b7a0ddd24 100644
+index da372383d..972873ac4 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
-@@ -1259,11 +1259,25 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
+@@ -1483,9 +1483,11 @@ meta_kms_impl_device_handle_update (MetaKmsImplDevice *impl_device,
+ meta_kms_update_merge_from (crtc_frame->pending_update, update);
+ meta_kms_update_free (update);
+ update = g_steal_pointer (&crtc_frame->pending_update);
+- disarm_crtc_frame_deadline_timer (crtc_frame);
+ }
+
++ if (crtc_frame->deadline.armed)
++ disarm_crtc_frame_deadline_timer (crtc_frame);
++
+ meta_kms_device_handle_flush (priv->device, latch_crtc);
+
+ feedback = do_process (impl_device, latch_crtc, update, flags);
+@@ -1848,6 +1850,16 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
return TRUE;
}
@@ -1123,8 +928,8 @@ index d56636d55..b7a0ddd24 100644
void
meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
{
-+ MetaKmsImplDevicePrivate *priv =
-+ meta_kms_impl_device_get_instance_private (impl_device);
+@@ -1855,6 +1867,8 @@ meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
+ meta_kms_impl_device_get_instance_private (impl_device);
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
+ g_list_foreach (priv->crtcs, release_buffers, NULL);
@@ -1132,32 +937,11 @@ index d56636d55..b7a0ddd24 100644
if (klass->prepare_shutdown)
klass->prepare_shutdown (impl_device);
-diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c
-index c1c29905c..09c2d8fad 100644
---- a/src/backends/native/meta-kms-page-flip.c
-+++ b/src/backends/native/meta-kms-page-flip.c
-@@ -25,6 +25,7 @@
- #include "backends/native/meta-kms-impl.h"
- #include "backends/native/meta-kms-private.h"
- #include "backends/native/meta-kms-update.h"
-+#include "backends/native/meta-kms-crtc.h"
-
- typedef struct _MetaKmsPageFlipClosure
- {
-@@ -150,6 +151,8 @@ meta_kms_page_flip_data_flipped (MetaKms *kms,
-
- meta_assert_not_in_kms_impl (kms);
-
-+ meta_swap_chain_swap_buffers (meta_kms_crtc_get_swap_chain (page_flip_data->crtc));
-+
- for (l = page_flip_data->closures; l; l = l->next)
- {
- MetaKmsPageFlipClosure *closure = l->data;
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
-index ceb298a80..02d9d0159 100644
+index 5189c5ab3..bb7349ecf 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
-@@ -183,6 +183,7 @@ static void
+@@ -190,6 +190,7 @@ static void
meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment)
{
g_clear_pointer (&plane_assignment->fb_damage, meta_kms_fb_damage_free);
@@ -1165,7 +949,7 @@ index ceb298a80..02d9d0159 100644
g_free (plane_assignment);
}
-@@ -265,7 +266,7 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
+@@ -292,7 +293,7 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
.update = update,
.crtc = crtc,
.plane = plane,
@@ -1175,27 +959,27 @@ index ceb298a80..02d9d0159 100644
.dst_rect = dst_rect,
.flags = flags,
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
-index d3a840b31..ce6fb4337 100644
+index ec009ec8c..c6708946e 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
-@@ -177,6 +177,8 @@ struct _MetaKms
+@@ -155,6 +155,8 @@ struct _MetaKms
+ int kernel_thread_inhibit_count;
- GList *pending_callbacks;
- guint callback_source_id;
+ MetaKmsCursorManager *cursor_manager;
+
+ gboolean shutting_down;
};
- G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
-@@ -599,6 +601,7 @@ static void
+ G_DEFINE_TYPE (MetaKms, meta_kms, META_TYPE_THREAD)
+@@ -433,6 +435,7 @@ static void
on_prepare_shutdown (MetaBackend *backend,
MetaKms *kms)
{
+ kms->shutting_down = TRUE;
meta_kms_run_impl_task_sync (kms, prepare_shutdown_in_impl, NULL, NULL);
- flush_callbacks (kms);
- }
-@@ -639,6 +642,12 @@ meta_kms_new (MetaBackend *backend,
+ meta_thread_flush_callbacks (META_THREAD (kms));
+
+@@ -487,6 +490,12 @@ meta_kms_new (MetaBackend *backend,
return kms;
}
@@ -1209,10 +993,10 @@ index d3a840b31..ce6fb4337 100644
meta_kms_finalize (GObject *object)
{
diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h
-index fe4fef1a0..88421ed28 100644
+index 743401406..f6b19520b 100644
--- a/src/backends/native/meta-kms.h
+++ b/src/backends/native/meta-kms.h
-@@ -51,6 +51,8 @@ MetaKmsDevice * meta_kms_create_device (MetaKms *kms,
+@@ -60,6 +60,8 @@ MetaKmsDevice * meta_kms_create_device (MetaKms *kms,
MetaKmsDeviceFlag flags,
GError **error);
@@ -1222,7 +1006,7 @@ index fe4fef1a0..88421ed28 100644
MetaKmsFlags flags,
GError **error);
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
-index 1ab117eb9..c507383e5 100644
+index 2388a44a2..14d727c55 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -72,7 +72,7 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
@@ -1249,11 +1033,13 @@ index 1ab117eb9..c507383e5 100644
} gbm;
#ifdef HAVE_EGL_DEVICE
-@@ -116,6 +121,14 @@ struct _MetaOnscreenNative
+@@ -116,6 +121,16 @@ struct _MetaOnscreenNative
gulong privacy_screen_changed_handler_id;
gulong color_space_changed_handler_id;
gulong hdr_metadata_changed_handler_id;
+
++ gboolean needs_flush;
++
+ unsigned int swaps_pending;
+
+ struct {
@@ -1264,7 +1050,7 @@ index 1ab117eb9..c507383e5 100644
};
G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
-@@ -123,40 +136,17 @@ G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
+@@ -123,40 +138,17 @@ G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
static GQuark blit_source_quark = 0;
@@ -1312,7 +1098,7 @@ index 1ab117eb9..c507383e5 100644
static void
maybe_update_frame_info (MetaCrtc *crtc,
-@@ -193,7 +183,7 @@ meta_onscreen_native_notify_frame_complete (CoglOnscreen *onscreen)
+@@ -193,7 +185,7 @@ meta_onscreen_native_notify_frame_complete (CoglOnscreen *onscreen)
info = cogl_onscreen_pop_head_frame_info (onscreen);
@@ -1321,16 +1107,17 @@ index 1ab117eb9..c507383e5 100644
_cogl_onscreen_notify_frame_sync (onscreen, info);
_cogl_onscreen_notify_complete (onscreen, info);
-@@ -228,7 +218,7 @@ notify_view_crtc_presented (MetaRendererView *view,
+@@ -228,7 +220,8 @@ notify_view_crtc_presented (MetaRendererView *view,
maybe_update_frame_info (crtc, frame_info, time_us, flags, sequence);
meta_onscreen_native_notify_frame_complete (onscreen);
- meta_onscreen_native_swap_drm_fb (onscreen);
++ meta_swap_chain_swap_buffers (meta_kms_crtc_get_swap_chain (kms_crtc));
+ try_post_latest_swap (onscreen);
}
- static int64_t
-@@ -284,15 +274,13 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
+ static void
+@@ -278,15 +271,13 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
CoglFramebuffer *framebuffer =
clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view));
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
@@ -1347,7 +1134,7 @@ index 1ab117eb9..c507383e5 100644
}
static void
-@@ -342,7 +330,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
+@@ -336,7 +327,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
meta_onscreen_native_notify_frame_complete (onscreen);
@@ -1356,7 +1143,7 @@ index 1ab117eb9..c507383e5 100644
}
static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
-@@ -403,18 +391,40 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data,
+@@ -397,18 +388,40 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data,
}
#endif /* HAVE_EGL_DEVICE */
@@ -1367,7 +1154,8 @@ index 1ab117eb9..c507383e5 100644
{
CoglFrameInfo *frame_info;
+ MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
-+
+
+- meta_onscreen_native_swap_drm_fb (onscreen);
+ /* Remember we can't compare stalled_fb because it's not used by
+ * META_RENDERER_NATIVE_MODE_EGL_DEVICE. So we judge stalled to be whenever
+ * swaps_pending > 1.
@@ -1376,8 +1164,7 @@ index 1ab117eb9..c507383e5 100644
+ return;
+
+ onscreen_native->swaps_pending--;
-
-- meta_onscreen_native_swap_drm_fb (onscreen);
++
+ g_clear_object (&onscreen_native->gbm.stalled_fb);
frame_info = cogl_onscreen_peek_tail_frame_info (onscreen);
@@ -1400,7 +1187,7 @@ index 1ab117eb9..c507383e5 100644
static void
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererView *view,
-@@ -431,7 +441,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
+@@ -425,7 +438,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaRendererNativeGpuData *renderer_gpu_data;
MetaGpuKms *gpu_kms;
@@ -1409,7 +1196,7 @@ index 1ab117eb9..c507383e5 100644
MetaKmsPlaneAssignment *plane_assignment;
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
-@@ -446,7 +456,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
+@@ -440,7 +453,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
@@ -1418,19 +1205,33 @@ index 1ab117eb9..c507383e5 100644
plane_assignment = meta_crtc_kms_assign_primary_plane (crtc_kms,
buffer,
-@@ -457,6 +467,11 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
- meta_kms_plane_assignment_set_fb_damage (plane_assignment,
- rectangles, n_rectangles);
- }
+@@ -596,6 +609,16 @@ import_shared_framebuffer (CoglOnscreen *onscreen,
+ return imported_buffer;
+ }
+
++static void
++reference_owning_gbm_surface (CoglOnscreen *onscreen,
++ MetaDrmBufferGbm *buffer_gbm)
++{
++ g_object_set_data_full (G_OBJECT (buffer_gbm),
++ "gbm_surface owner",
++ g_object_ref (onscreen),
++ (GDestroyNotify) g_object_unref);
++}
+
-+ g_object_set_data_full (G_OBJECT (buffer),
-+ "gbm_surface owner",
-+ g_object_ref (onscreen),
-+ (GDestroyNotify) g_object_unref);
- break;
- case META_RENDERER_NATIVE_MODE_SURFACELESS:
- g_assert_not_reached ();
-@@ -698,12 +713,17 @@ static MetaDrmBufferDumb *
+ static MetaDrmBuffer *
+ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
+ MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
+@@ -681,6 +704,8 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
+ return NULL;
+ }
+
++ reference_owning_gbm_surface (onscreen, buffer_gbm);
++
+ g_object_set_qdata_full (G_OBJECT (buffer_gbm),
+ blit_source_quark,
+ g_object_ref (primary_gpu_fb),
+@@ -693,12 +718,17 @@ static MetaDrmBufferDumb *
secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
{
MetaDrmBufferDumb *current_dumb_fb;
@@ -1452,7 +1253,7 @@ index 1ab117eb9..c507383e5 100644
}
static MetaDrmBuffer *
-@@ -1038,10 +1058,15 @@ on_swap_buffer_update_result (const MetaKmsFeedback *kms_feedback,
+@@ -1029,10 +1059,15 @@ swap_buffer_result_feedback (const MetaKmsFeedback *kms_feedback,
g_warning ("Page flip failed: %s", error->message);
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
@@ -1470,8 +1271,8 @@ index 1ab117eb9..c507383e5 100644
+ }
}
- static void
-@@ -1058,31 +1083,35 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+ static const MetaKmsResultListenerVtable swap_buffer_result_listener_vtable = {
+@@ -1053,30 +1088,35 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
@@ -1495,7 +1296,6 @@ index 1ab117eb9..c507383e5 100644
g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL;
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
-- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
+ size_t rectangles_size;
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
@@ -1517,7 +1317,15 @@ index 1ab117eb9..c507383e5 100644
secondary_gpu_fb =
update_secondary_gpu_state_pre_swap_buffers (onscreen,
rectangles,
-@@ -1138,7 +1167,15 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1113,6 +1153,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+ return;
+ }
+
++ reference_owning_gbm_surface (onscreen, buffer_gbm);
+ primary_gpu_fb = META_DRM_BUFFER (g_steal_pointer (&buffer_gbm));
+ break;
+ case META_RENDERER_NATIVE_MODE_SURFACELESS:
+@@ -1132,7 +1173,15 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
@@ -1534,7 +1342,7 @@ index 1ab117eb9..c507383e5 100644
if (onscreen_native->secondary_gpu_state)
g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb);
else
-@@ -1152,6 +1189,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1146,6 +1195,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
#endif
}
@@ -1544,7 +1352,7 @@ index 1ab117eb9..c507383e5 100644
/*
* If we changed EGL context, cogl will have the wrong idea about what is
* current, making it fail to set it when it needs to. Avoid that by making
-@@ -1161,12 +1201,82 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1155,12 +1207,83 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
if (egl_context_changed)
_cogl_winsys_egl_ensure_current (cogl_display);
@@ -1588,7 +1396,8 @@ index 1ab117eb9..c507383e5 100644
+ g_autoptr (ClutterFrame) frame = NULL;
+ MetaFrameNative *frame_native;
+
-+ if (onscreen_native->next_post.frame == NULL)
++ if (onscreen_native->next_post.frame == NULL ||
++ onscreen_native->view == NULL)
+ return;
+
+ if (meta_kms_is_shutting_down (kms))
@@ -1629,7 +1438,7 @@ index 1ab117eb9..c507383e5 100644
kms_update = meta_frame_native_ensure_kms_update (frame_native,
kms_device);
meta_kms_update_add_result_listener (kms_update,
-@@ -1179,15 +1289,13 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1175,15 +1298,13 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
onscreen_native->crtc,
kms_update,
META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
@@ -1647,7 +1456,7 @@ index 1ab117eb9..c507383e5 100644
return;
}
-@@ -1207,8 +1315,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1203,8 +1324,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
kms_update = meta_frame_native_steal_kms_update (frame_native);
meta_renderer_native_queue_mode_set_update (renderer_native,
kms_update);
@@ -1656,7 +1465,7 @@ index 1ab117eb9..c507383e5 100644
return;
}
else if (meta_renderer_native_has_pending_mode_set (renderer_native))
-@@ -1222,8 +1328,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1218,8 +1337,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
meta_frame_native_steal_kms_update (frame_native);
meta_renderer_native_post_mode_set_updates (renderer_native);
@@ -1665,7 +1474,7 @@ index 1ab117eb9..c507383e5 100644
return;
}
break;
-@@ -1239,8 +1343,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+@@ -1235,8 +1352,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
kms_update);
meta_renderer_native_post_mode_set_updates (renderer_native);
@@ -1674,15 +1483,15 @@ index 1ab117eb9..c507383e5 100644
return;
}
break;
-@@ -1256,7 +1358,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
- kms_feedback =
- meta_kms_device_process_update_sync (kms_device, kms_update,
- META_KMS_UPDATE_FLAG_NONE);
+@@ -1251,7 +1366,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
+ kms_update = meta_frame_native_steal_kms_update (frame_native);
+ meta_kms_device_post_update (kms_device, kms_update,
+ META_KMS_UPDATE_FLAG_NONE);
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
}
gboolean
-@@ -1301,6 +1402,7 @@ on_scanout_update_result (const MetaKmsFeedback *kms_feedback,
+@@ -1296,6 +1410,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
CoglOnscreen *onscreen = COGL_ONSCREEN (onscreen_native);
const GError *error;
CoglFrameInfo *frame_info;
@@ -1690,7 +1499,7 @@ index 1ab117eb9..c507383e5 100644
error = meta_kms_feedback_get_error (kms_feedback);
if (!error)
-@@ -1314,8 +1416,7 @@ on_scanout_update_result (const MetaKmsFeedback *kms_feedback,
+@@ -1309,8 +1424,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
g_warning ("Direct scanout page flip failed: %s", error->message);
@@ -1700,15 +1509,15 @@ index 1ab117eb9..c507383e5 100644
clutter_stage_view_add_redraw_clip (view, NULL);
clutter_stage_view_schedule_update_now (view);
}
-@@ -1324,7 +1425,6 @@ on_scanout_update_result (const MetaKmsFeedback *kms_feedback,
+@@ -1319,7 +1433,6 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
meta_onscreen_native_notify_frame_complete (onscreen);
- meta_onscreen_native_clear_next_fb (onscreen);
}
- static gboolean
-@@ -1375,6 +1475,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
+ static const MetaKmsResultListenerVtable scanout_result_listener_vtable = {
+@@ -1371,6 +1484,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
return FALSE;
}
@@ -1727,50 +1536,75 @@ index 1ab117eb9..c507383e5 100644
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
render_gpu);
-@@ -1414,6 +1526,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
+@@ -1385,6 +1510,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
kms_device = meta_kms_crtc_get_device (kms_crtc);
kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device);
+ g_set_object (&onscreen_native->gbm.direct_fb,
+ onscreen_native->gbm.next_fb);
meta_kms_update_add_result_listener (kms_update,
- on_scanout_update_result,
- onscreen_native);
-@@ -1558,7 +1672,20 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
+ &scanout_result_listener_vtable,
+ NULL,
+@@ -1430,12 +1557,6 @@ void
+ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen,
+ ClutterFrame *frame)
+ {
+- MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
+- MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
+- MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
+-
+- meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc),
+- kms_crtc);
+ }
+
+ void
+@@ -1555,22 +1676,79 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
MetaKmsUpdate *kms_update;
-- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
++ unsigned int frames_pending = cogl_onscreen_count_pending_frames (onscreen);
++ unsigned int swaps_pending = onscreen_native->swaps_pending;
++ unsigned int posts_pending = frames_pending - swaps_pending;
+
+- kms_update = meta_frame_native_steal_kms_update (frame_native);
+- if (!kms_update)
++ onscreen_native->needs_flush |= meta_kms_device_handle_flush (kms_device,
++ kms_crtc);
+
-+ if (meta_frame_native_has_kms_update (frame_native) &&
-+ cogl_onscreen_count_pending_frames (onscreen) > 0 &&
-+ onscreen_native->swaps_pending == 0)
++ if (!meta_frame_native_has_kms_update (frame_native))
+ {
+- if (meta_kms_device_handle_flush (kms_device, kms_crtc))
+- {
+- kms_update = meta_kms_update_new (kms_device);
+- meta_kms_update_set_flushing (kms_update, kms_crtc);
+- }
+- else
++ if (!onscreen_native->needs_flush || posts_pending)
+ {
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
+ return;
+ }
+ }
+
++ if (posts_pending && !swaps_pending)
+ {
-+ /* Posts are busy AND we have no swaps pending so just retry the same
-+ * frame later in try_post_latest_swap.
-+ */
++ g_return_if_fail (meta_frame_native_has_kms_update (frame_native));
+ g_warn_if_fail (onscreen_native->next_post.frame == NULL);
++
+ g_clear_pointer (&onscreen_native->next_post.frame, clutter_frame_unref);
+ onscreen_native->next_post.frame = clutter_frame_ref (frame);
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
+ return;
+ }
-
- kms_update = meta_frame_native_steal_kms_update (frame_native);
- if (!kms_update)
-@@ -1567,6 +1694,42 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
- return;
- }
-
-+ if (cogl_onscreen_count_pending_frames (onscreen) > 0)
++
++ kms_update = meta_frame_native_steal_kms_update (frame_native);
++
++ if (posts_pending && swaps_pending)
+ {
-+ /* Posts are busy AND we have swaps pending so best to merge our cursor
-+ * update into the pending swap.
-+ */
+ MetaFrameNative *older_frame_native;
+ MetaKmsUpdate *older_kms_update;
+
-+ g_return_if_fail (onscreen_native->swaps_pending > 0);
++ g_return_if_fail (kms_update);
+ g_return_if_fail (onscreen_native->next_post.frame != NULL);
+
+ older_frame_native =
@@ -1779,11 +1613,22 @@ index 1ab117eb9..c507383e5 100644
+ meta_frame_native_ensure_kms_update (older_frame_native, kms_device);
+ meta_kms_update_merge_from (older_kms_update, kms_update);
+ meta_kms_update_free (kms_update);
-+
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
+ return;
+ }
+
++ if (!kms_update)
++ {
++ kms_update = meta_kms_update_new (kms_device);
++ g_warn_if_fail (onscreen_native->needs_flush);
++ }
++
++ if (onscreen_native->needs_flush)
++ {
++ meta_kms_update_set_flushing (kms_update, kms_crtc);
++ onscreen_native->needs_flush = FALSE;
++ }
++
+ post_finish_frame (onscreen_native, kms_update);
+
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
@@ -1799,12 +1644,12 @@ index 1ab117eb9..c507383e5 100644
+ g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
+
meta_kms_update_add_result_listener (kms_update,
- on_finish_frame_update_result,
- onscreen_native);
-@@ -1587,7 +1750,17 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
- kms_feedback =
- meta_kms_device_process_update_sync (kms_device, kms_update,
- META_KMS_UPDATE_FLAG_NONE);
+ &finish_frame_result_listener_vtable,
+ NULL,
+@@ -1594,7 +1772,17 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
+ meta_kms_update_set_flushing (kms_update, kms_crtc);
+ meta_kms_device_post_update (kms_device, kms_update,
+ META_KMS_UPDATE_FLAG_NONE);
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
+}
+
@@ -1820,7 +1665,7 @@ index 1ab117eb9..c507383e5 100644
}
static gboolean
-@@ -2414,7 +2587,7 @@ meta_onscreen_native_dispose (GObject *object)
+@@ -2421,7 +2609,7 @@ meta_onscreen_native_dispose (GObject *object)
{
case META_RENDERER_NATIVE_MODE_GBM:
g_clear_object (&onscreen_native->gbm.next_fb);
@@ -1829,7 +1674,7 @@ index 1ab117eb9..c507383e5 100644
break;
case META_RENDERER_NATIVE_MODE_SURFACELESS:
g_assert_not_reached ();
-@@ -2448,6 +2621,10 @@ meta_onscreen_native_dispose (GObject *object)
+@@ -2455,6 +2643,10 @@ meta_onscreen_native_dispose (GObject *object)
g_clear_object (&onscreen_native->output);
g_clear_object (&onscreen_native->crtc);
@@ -1841,7 +1686,7 @@ index 1ab117eb9..c507383e5 100644
static void
diff --git a/src/backends/native/meta-onscreen-native.h b/src/backends/native/meta-onscreen-native.h
-index 05a9ecdb8..a33ee3857 100644
+index 91eb7b533..11bb5ba56 100644
--- a/src/backends/native/meta-onscreen-native.h
+++ b/src/backends/native/meta-onscreen-native.h
@@ -45,6 +45,8 @@ void meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
@@ -1854,10 +1699,28 @@ index 05a9ecdb8..a33ee3857 100644
MetaDrmBuffer *fb);
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
-index 4da361e2b..e5d995388 100644
+index 57cb20b7e..6acc09918 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
-@@ -708,12 +708,18 @@ static gboolean
+@@ -98,6 +98,7 @@ struct _MetaRendererNative
+
+ GList *detached_onscreens;
+ GList *lingering_onscreens;
++ GList *disabled_crtcs;
+ guint release_unused_gpus_idle_id;
+
+ GList *power_save_page_flip_onscreens;
+@@ -676,6 +677,9 @@ configure_disabled_crtcs (MetaKmsDevice *kms_device,
+
+ kms_update = ensure_mode_set_update (renderer_native, kms_device);
+ meta_kms_update_mode_set (kms_update, kms_crtc, NULL, NULL);
++
++ renderer_native->disabled_crtcs =
++ g_list_prepend (renderer_native->disabled_crtcs, kms_crtc);
+ }
+ }
+
+@@ -683,12 +687,18 @@ static gboolean
dummy_power_save_page_flip_cb (gpointer user_data)
{
MetaRendererNative *renderer_native = user_data;
@@ -1878,7 +1741,7 @@ index 4da361e2b..e5d995388 100644
renderer_native->power_save_page_flip_source_id = 0;
return G_SOURCE_REMOVE;
-@@ -725,6 +731,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na
+@@ -700,6 +710,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na
{
const unsigned int timeout_ms = 100;
@@ -1888,7 +1751,38 @@ index 4da361e2b..e5d995388 100644
if (!renderer_native->power_save_page_flip_source_id)
{
renderer_native->power_save_page_flip_source_id =
-@@ -1473,6 +1482,26 @@ detach_onscreens (MetaRenderer *renderer)
+@@ -810,6 +823,22 @@ clear_detached_onscreens (MetaRendererNative *renderer_native)
+ g_object_unref);
+ }
+
++static void
++clear_disabled_crtcs (MetaRendererNative *renderer_native)
++{
++ GList *l;
++
++ for (l = renderer_native->disabled_crtcs; l; l = l->next)
++ {
++ MetaKmsCrtc *kms_crtc = l->data;
++ MetaSwapChain *swap_chain = meta_kms_crtc_get_swap_chain (kms_crtc);
++
++ meta_swap_chain_release_buffers (swap_chain);
++ }
++
++ g_clear_list (&renderer_native->disabled_crtcs, NULL);
++}
++
+ static void
+ mode_sets_update_result_feedback (const MetaKmsFeedback *kms_feedback,
+ gpointer user_data)
+@@ -871,6 +900,7 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
+ post_mode_set_updates (renderer_native);
+
+ clear_detached_onscreens (renderer_native);
++ clear_disabled_crtcs (renderer_native);
+
+ meta_kms_notify_modes_set (kms);
+
+@@ -1493,6 +1523,26 @@ detach_onscreens (MetaRenderer *renderer)
}
}
@@ -1915,7 +1809,7 @@ index 4da361e2b..e5d995388 100644
static void
meta_renderer_native_rebuild_views (MetaRenderer *renderer)
{
-@@ -1483,6 +1512,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
+@@ -1503,6 +1553,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
MetaRendererClass *parent_renderer_class =
META_RENDERER_CLASS (meta_renderer_native_parent_class);
@@ -1923,6 +1817,14 @@ index 4da361e2b..e5d995388 100644
meta_kms_discard_pending_page_flips (kms);
g_hash_table_remove_all (renderer_native->mode_set_updates);
+@@ -2237,6 +2288,7 @@ meta_renderer_native_finalize (GObject *object)
+ g_clear_handle_id (&renderer_native->release_unused_gpus_idle_id,
+ g_source_remove);
+ clear_detached_onscreens (renderer_native);
++ clear_disabled_crtcs (renderer_native);
+
+ g_hash_table_destroy (renderer_native->gpu_datas);
+ g_clear_object (&renderer_native->gles3);
diff --git a/src/backends/native/meta-swap-chain.c b/src/backends/native/meta-swap-chain.c
new file mode 100644
index 000000000..c3bed569d
@@ -2133,23 +2035,23 @@ index 000000000..bad772b89
+
+#endif /* META_SWAP_CHAIN_H */
diff --git a/src/meson.build b/src/meson.build
-index 5e95e666f..5fc6b4e4a 100644
+index ca2ef166c..0038988bd 100644
--- a/src/meson.build
+++ b/src/meson.build
-@@ -820,6 +820,8 @@ if have_native_backend
+@@ -850,6 +850,8 @@ if have_native_backend
'backends/native/meta-seat-native.h',
'backends/native/meta-stage-native.c',
'backends/native/meta-stage-native.h',
+ 'backends/native/meta-swap-chain.c',
+ 'backends/native/meta-swap-chain.h',
- 'backends/native/meta-udev.c',
- 'backends/native/meta-udev.h',
- 'backends/native/meta-virtual-input-device-native.c',
+ 'backends/native/meta-thread-impl.c',
+ 'backends/native/meta-thread-impl.h',
+ 'backends/native/meta-thread-private.h',
diff --git a/src/tests/clutter/conform/event-delivery.c b/src/tests/clutter/conform/event-delivery.c
-index 0f3ca256c..0c9fdf77b 100644
+index 383ad0bae..3b259139a 100644
--- a/src/tests/clutter/conform/event-delivery.c
+++ b/src/tests/clutter/conform/event-delivery.c
-@@ -326,6 +326,7 @@ event_delivery_implicit_grab_cancelled (void)
+@@ -329,6 +329,7 @@ event_delivery_implicit_grab_cancelled (void)
n_child_1_leave_events = n_child_2_leave_events = n_stage_leave_events = 0;
n_action_sequences_cancelled = 0;
clutter_actor_destroy (child_1);
@@ -2158,10 +2060,10 @@ index 0f3ca256c..0c9fdf77b 100644
g_assert_cmpint (n_child_1_leave_events, ==, 0);
g_assert_cmpint (n_action_sequences_cancelled, ==, 1);
diff --git a/src/tests/native-kms-render.c b/src/tests/native-kms-render.c
-index 1557b764e..c482d07e0 100644
+index 31e74a9a4..259d315dc 100644
--- a/src/tests/native-kms-render.c
+++ b/src/tests/native-kms-render.c
-@@ -41,6 +41,8 @@
+@@ -39,6 +39,8 @@
#include "tests/meta-wayland-test-driver.h"
#include "tests/meta-wayland-test-utils.h"
@@ -2170,7 +2072,7 @@ index 1557b764e..c482d07e0 100644
typedef struct
{
int number_of_frames_left;
-@@ -48,12 +50,15 @@ typedef struct
+@@ -46,12 +48,15 @@ typedef struct
struct {
int n_paints;
@@ -2187,7 +2089,7 @@ index 1557b764e..c482d07e0 100644
gboolean scanout_sabotaged;
gboolean fallback_painted;
guint repaint_guard_id;
-@@ -103,7 +108,7 @@ meta_test_kms_render_basic (void)
+@@ -101,7 +106,7 @@ meta_test_kms_render_basic (void)
gulong handler_id;
test = (KmsRenderingTest) {
@@ -2196,7 +2098,7 @@ index 1557b764e..c482d07e0 100644
.loop = g_main_loop_new (NULL, FALSE),
};
handler_id = g_signal_connect (stage, "after-update",
-@@ -125,7 +130,6 @@ on_scanout_before_update (ClutterStage *stage,
+@@ -123,7 +128,6 @@ on_scanout_before_update (ClutterStage *stage,
KmsRenderingTest *test)
{
test->scanout.n_paints = 0;
@@ -2204,7 +2106,7 @@ index 1557b764e..c482d07e0 100644
}
static void
-@@ -136,6 +140,7 @@ on_scanout_before_paint (ClutterStage *stage,
+@@ -134,6 +138,7 @@ on_scanout_before_paint (ClutterStage *stage,
{
CoglScanout *scanout;
MetaDrmBuffer *buffer;
@@ -2212,7 +2114,7 @@ index 1557b764e..c482d07e0 100644
scanout = clutter_stage_view_peek_scanout (stage_view);
if (!scanout)
-@@ -143,8 +148,14 @@ on_scanout_before_paint (ClutterStage *stage,
+@@ -141,8 +146,14 @@ on_scanout_before_paint (ClutterStage *stage,
g_assert_true (META_IS_DRM_BUFFER (scanout));
buffer = META_DRM_BUFFER (scanout);
@@ -2229,7 +2131,7 @@ index 1557b764e..c482d07e0 100644
}
static void
-@@ -173,12 +184,12 @@ on_scanout_presented (ClutterStage *stage,
+@@ -171,12 +182,12 @@ on_scanout_presented (ClutterStage *stage,
MetaDeviceFile *device_file;
GError *error = NULL;
drmModeCrtc *drm_crtc;
@@ -2245,7 +2147,7 @@ index 1557b764e..c482d07e0 100644
device_pool = meta_backend_native_get_device_pool (backend_native);
-@@ -197,15 +208,41 @@ on_scanout_presented (ClutterStage *stage,
+@@ -195,15 +206,41 @@ on_scanout_presented (ClutterStage *stage,
drm_crtc = drmModeGetCrtc (meta_device_file_get_fd (device_file),
meta_kms_crtc_get_id (kms_crtc));
g_assert_nonnull (drm_crtc);
@@ -2291,7 +2193,7 @@ index 1557b764e..c482d07e0 100644
}
typedef enum
-@@ -244,7 +281,9 @@ meta_test_kms_render_client_scanout (void)
+@@ -242,7 +279,9 @@ meta_test_kms_render_client_scanout (void)
g_assert_nonnull (wayland_test_client);
test = (KmsRenderingTest) {
@@ -2301,7 +2203,7 @@ index 1557b764e..c482d07e0 100644
.wait_for_scanout = TRUE,
};
-@@ -270,7 +309,8 @@ meta_test_kms_render_client_scanout (void)
+@@ -268,7 +307,8 @@ meta_test_kms_render_client_scanout (void)
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
g_main_loop_run (test.loop);
@@ -2311,7 +2213,7 @@ index 1557b764e..c482d07e0 100644
g_debug ("Unmake fullscreen");
window = meta_find_window_from_title (test_context, "dma-buf-scanout-test");
-@@ -292,10 +332,15 @@ meta_test_kms_render_client_scanout (void)
+@@ -290,10 +330,15 @@ meta_test_kms_render_client_scanout (void)
g_assert_cmpint (buffer_rect.y, ==, 10);
test.wait_for_scanout = FALSE;
@@ -2328,7 +2230,7 @@ index 1557b764e..c482d07e0 100644
g_debug ("Moving back to 0, 0");
meta_window_move_frame (window, TRUE, 0, 0);
-@@ -307,10 +352,15 @@ meta_test_kms_render_client_scanout (void)
+@@ -305,10 +350,15 @@ meta_test_kms_render_client_scanout (void)
g_assert_cmpint (buffer_rect.y, ==, 0);
test.wait_for_scanout = TRUE;
@@ -2345,7 +2247,7 @@ index 1557b764e..c482d07e0 100644
g_signal_handler_disconnect (stage, before_update_handler_id);
g_signal_handler_disconnect (stage, before_paint_handler_id);
-@@ -360,6 +410,15 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
+@@ -362,6 +412,15 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
if (!scanout)
return;
@@ -2361,7 +2263,7 @@ index 1557b764e..c482d07e0 100644
g_assert_false (test->scanout_fallback.scanout_sabotaged);
if (is_atomic_mode_setting (kms_device))
-@@ -394,6 +453,15 @@ on_scanout_fallback_paint_view (ClutterStage *stage,
+@@ -399,6 +458,15 @@ on_scanout_fallback_paint_view (ClutterStage *stage,
g_clear_handle_id (&test->scanout_fallback.repaint_guard_id,
g_source_remove);
test->scanout_fallback.fallback_painted = TRUE;
@@ -2377,7 +2279,7 @@ index 1557b764e..c482d07e0 100644
}
}
-@@ -403,11 +471,11 @@ on_scanout_fallback_presented (ClutterStage *stage,
+@@ -408,11 +476,11 @@ on_scanout_fallback_presented (ClutterStage *stage,
ClutterFrameInfo *frame_info,
KmsRenderingTest *test)
{
@@ -2393,7 +2295,7 @@ index 1557b764e..c482d07e0 100644
}
static void
-@@ -436,6 +504,7 @@ meta_test_kms_render_client_scanout_fallback (void)
+@@ -441,6 +509,7 @@ meta_test_kms_render_client_scanout_fallback (void)
g_assert_nonnull (wayland_test_client);
test = (KmsRenderingTest) {