onscreen/native: Only set a VRR update if the CRTC supports the property

This also gets rid of the MetaFrameSyncMode enum and instead issues a
VRR update when the requested state differs from the CRTC state.

Fixes: fee33299 ("onscreen/native: Allow requesting frame synchronization")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3646>
This commit is contained in:
Sebastian Wick 2024-03-08 17:53:08 +01:00 committed by Marge Bot
parent 51811ec7b3
commit a50bc0ff7d

View File

@ -83,13 +83,6 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
MetaSharedFramebufferImportStatus import_status; MetaSharedFramebufferImportStatus import_status;
} MetaOnscreenNativeSecondaryGpuState; } MetaOnscreenNativeSecondaryGpuState;
typedef enum _MetaFrameSyncMode
{
META_FRAME_SYNC_MODE_INIT,
META_FRAME_SYNC_MODE_ENABLED,
META_FRAME_SYNC_MODE_DISABLED,
} MetaFrameSyncMode;
struct _MetaOnscreenNative struct _MetaOnscreenNative
{ {
CoglOnscreenEgl parent; CoglOnscreenEgl parent;
@ -117,8 +110,8 @@ struct _MetaOnscreenNative
} egl; } egl;
#endif #endif
MetaFrameSyncMode requested_frame_sync_mode; gboolean frame_sync_requested;
MetaFrameSyncMode frame_sync_mode; gboolean frame_sync_enabled;
MetaRendererView *view; MetaRendererView *view;
@ -1683,76 +1676,49 @@ void
meta_onscreen_native_request_frame_sync (MetaOnscreenNative *onscreen_native, meta_onscreen_native_request_frame_sync (MetaOnscreenNative *onscreen_native,
gboolean enabled) gboolean enabled)
{ {
onscreen_native->requested_frame_sync_mode = onscreen_native->frame_sync_requested = enabled;
enabled
? META_FRAME_SYNC_MODE_ENABLED
: META_FRAME_SYNC_MODE_DISABLED;
} }
gboolean gboolean
meta_onscreen_native_is_frame_sync_enabled (MetaOnscreenNative *onscreen_native) meta_onscreen_native_is_frame_sync_enabled (MetaOnscreenNative *onscreen_native)
{ {
return onscreen_native->frame_sync_mode == META_FRAME_SYNC_MODE_ENABLED; return onscreen_native->frame_sync_enabled;
} }
static void static void
update_frame_sync_mode (MetaOnscreenNative *onscreen_native, maybe_update_frame_sync (MetaOnscreenNative *onscreen_native,
ClutterFrame *frame, ClutterFrame *frame)
MetaFrameSyncMode sync_mode)
{ {
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc); MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
MetaFrameNative *frame_native; MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
MetaKmsCrtc *kms_crtc; MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
MetaKmsDevice *kms_device; const MetaKmsCrtcState *crtc_state =
meta_kms_crtc_get_current_state (kms_crtc);
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (onscreen_native->view);
ClutterFrameClock *frame_clock =
clutter_stage_view_get_frame_clock (stage_view);
ClutterFrameClockMode frame_clock_mode;
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
ClutterFrameClock *frame_clock; gboolean frame_sync_enabled = FALSE;
frame_native = meta_frame_native_from_frame (frame); if (meta_output_is_vrr_enabled (onscreen_native->output))
frame_sync_enabled = onscreen_native->frame_sync_requested;
frame_clock = if (frame_sync_enabled != onscreen_native->frame_sync_enabled)
clutter_stage_view_get_frame_clock (CLUTTER_STAGE_VIEW (onscreen_native->view));
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
kms_device = meta_kms_crtc_get_device (kms_crtc);
kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device);
switch (sync_mode)
{ {
case META_FRAME_SYNC_MODE_ENABLED: frame_clock_mode = frame_sync_enabled ? CLUTTER_FRAME_CLOCK_MODE_VARIABLE :
clutter_frame_clock_set_mode (frame_clock, CLUTTER_FRAME_CLOCK_MODE_FIXED;
CLUTTER_FRAME_CLOCK_MODE_VARIABLE); clutter_frame_clock_set_mode (frame_clock, frame_clock_mode);
meta_kms_update_set_vrr (kms_update, onscreen_native->frame_sync_enabled = frame_sync_enabled;
kms_crtc,
TRUE);
break;
case META_FRAME_SYNC_MODE_DISABLED:
clutter_frame_clock_set_mode (frame_clock,
CLUTTER_FRAME_CLOCK_MODE_FIXED);
meta_kms_update_set_vrr (kms_update,
kms_crtc,
FALSE);
break;
case META_FRAME_SYNC_MODE_INIT:
g_assert_not_reached ();
} }
onscreen_native->frame_sync_mode = sync_mode; if (crtc_state->vrr.supported &&
} frame_sync_enabled != crtc_state->vrr.enabled)
{
static void kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device);
maybe_update_frame_sync_mode (MetaOnscreenNative *onscreen_native, meta_kms_update_set_vrr (kms_update, kms_crtc, frame_sync_enabled);
ClutterFrame *frame) }
{
MetaFrameSyncMode sync_mode = onscreen_native->requested_frame_sync_mode;
if (!meta_output_is_vrr_enabled (onscreen_native->output))
sync_mode = META_FRAME_SYNC_MODE_DISABLED;
if (G_LIKELY (sync_mode == onscreen_native->frame_sync_mode))
return;
update_frame_sync_mode (onscreen_native, frame, sync_mode);
} }
void void
@ -1765,7 +1731,7 @@ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen,
meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc), meta_kms_device_await_flush (meta_kms_crtc_get_device (kms_crtc),
kms_crtc); kms_crtc);
maybe_update_frame_sync_mode (onscreen_native, frame); maybe_update_frame_sync (onscreen_native, frame);
} }
void void
@ -2864,8 +2830,6 @@ meta_onscreen_native_dispose (GObject *object)
static void static void
meta_onscreen_native_init (MetaOnscreenNative *onscreen_native) meta_onscreen_native_init (MetaOnscreenNative *onscreen_native)
{ {
onscreen_native->requested_frame_sync_mode = META_FRAME_SYNC_MODE_DISABLED;
onscreen_native->frame_sync_mode = META_FRAME_SYNC_MODE_INIT;
} }
static void static void