kms/crtc: Calculate CRTC deadline for VRR
Use a sufficiently low refresh rate to calculate the CRTC deadline when variable refresh rate is enabled. This is done to avoid cursor updates from driving the monitor refresh rate. It's not great solution and is sometimes not enough, but it avoids stutter in the main content as a result of cursor movement in most cases. The unfortunate downside of this approach is that cursor movement would usually only update with the main content and would not be smooth when the main content updates are not frequent enough. A better solution may use an approach similar to LFC (Low Framerate Compensation) to insert cursor-only updates between updates of the main content, but achieving adequate results with an approach of this nature requires more research and experimentation. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This commit is contained in:
parent
2a3fc9b830
commit
a74fbecbd6
@ -31,6 +31,8 @@
|
||||
#define DEADLINE_EVASION_US 800
|
||||
#define DEADLINE_EVASION_WITH_KMS_TOPIC_US 1000
|
||||
|
||||
#define MINIMUM_REFRESH_RATE 30.f
|
||||
|
||||
typedef struct _MetaKmsCrtcPropTable
|
||||
{
|
||||
MetaKmsProp props[META_KMS_CRTC_N_PROPS];
|
||||
@ -550,9 +552,6 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
int ret;
|
||||
int64_t next_presentation_us;
|
||||
int64_t next_deadline_us;
|
||||
drmModeModeInfo *drm_mode;
|
||||
int64_t vblank_duration_us;
|
||||
int64_t deadline_evasion_us;
|
||||
|
||||
if (!crtc->current_state.is_drm_mode_valid)
|
||||
{
|
||||
@ -578,30 +577,45 @@ meta_kms_crtc_determine_deadline (MetaKmsCrtc *crtc,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
drm_mode = &crtc->current_state.drm_mode;
|
||||
next_presentation_us =
|
||||
s2us (vblank.reply.tval_sec) + vblank.reply.tval_usec + 0.5 +
|
||||
G_USEC_PER_SEC / meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
|
||||
/*
|
||||
* 1
|
||||
* time per pixel = -----------------
|
||||
* Pixel clock (Hz)
|
||||
*
|
||||
* number of pixels = vdisplay * htotal
|
||||
*
|
||||
* time spent scanning out = time per pixel * number of pixels
|
||||
*
|
||||
*/
|
||||
|
||||
if (meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
deadline_evasion_us = DEADLINE_EVASION_WITH_KMS_TOPIC_US;
|
||||
if (crtc->current_state.vrr_enabled)
|
||||
{
|
||||
next_presentation_us = 0;
|
||||
next_deadline_us =
|
||||
s2us (vblank.reply.tval_sec) + vblank.reply.tval_usec + 0.5 +
|
||||
G_USEC_PER_SEC / MINIMUM_REFRESH_RATE;
|
||||
}
|
||||
else
|
||||
deadline_evasion_us = DEADLINE_EVASION_US;
|
||||
{
|
||||
drmModeModeInfo *drm_mode;
|
||||
int64_t vblank_duration_us;
|
||||
int64_t deadline_evasion_us;
|
||||
|
||||
vblank_duration_us = meta_calculate_drm_mode_vblank_duration_us (drm_mode);
|
||||
next_deadline_us = next_presentation_us - (vblank_duration_us +
|
||||
deadline_evasion_us);
|
||||
drm_mode = &crtc->current_state.drm_mode;
|
||||
|
||||
next_presentation_us =
|
||||
s2us (vblank.reply.tval_sec) + vblank.reply.tval_usec + 0.5 +
|
||||
G_USEC_PER_SEC / meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
|
||||
/*
|
||||
* 1
|
||||
* time per pixel = -----------------
|
||||
* Pixel clock (Hz)
|
||||
*
|
||||
* number of pixels = vdisplay * htotal
|
||||
*
|
||||
* time spent scanning out = time per pixel * number of pixels
|
||||
*
|
||||
*/
|
||||
|
||||
if (meta_is_topic_enabled (META_DEBUG_KMS))
|
||||
deadline_evasion_us = DEADLINE_EVASION_WITH_KMS_TOPIC_US;
|
||||
else
|
||||
deadline_evasion_us = DEADLINE_EVASION_US;
|
||||
|
||||
vblank_duration_us = meta_calculate_drm_mode_vblank_duration_us (drm_mode);
|
||||
next_deadline_us = next_presentation_us - (vblank_duration_us +
|
||||
deadline_evasion_us);
|
||||
}
|
||||
|
||||
*out_next_presentation_us = next_presentation_us;
|
||||
*out_next_deadline_us = next_deadline_us;
|
||||
|
Loading…
Reference in New Issue
Block a user