onscreen/native: Mark GPU rendering duration as valid if supported

Since commit e30eb78891 `ClutterFrameClock` assumes that a valid CPU time
implies timestamp query support, which is also checked in
`cogl_onscreen_egl_swap_buffers_with_damage()`.

Unconditionally setting the CPU time on direct scanout meant that the
compositing path would be stuck on the last (direct scanout optimized)
result on GL implementations without timestamp query support since.

be0aa2976e (clutter/frame-clock: Avoid rapidly toggling dynamic max render time)

Fix that by explicitly marking the gpu rendering duration as valid when
querying the GPU timestamps is supported and check for it ClutterFrameClock.

Fixes: 56580ea7c9 ("backends/native: Assume zero rendering time for direct scanout buffers")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3655>
This commit is contained in:
Robert Mader 2024-03-09 11:37:18 +01:00
parent e2b42cdfd9
commit aaae07f9dd
8 changed files with 20 additions and 1 deletions

View File

@ -361,7 +361,8 @@ clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
frame_clock->got_measurements_last_frame = FALSE; 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_info->has_valid_gpu_rendering_duration)
{ {
int64_t dispatch_to_swap_us, swap_to_rendering_done_us, swap_to_flip_us; int64_t dispatch_to_swap_us, swap_to_rendering_done_us, swap_to_flip_us;

View File

@ -127,6 +127,7 @@ struct _ClutterFrameInfo
unsigned int sequence; unsigned int sequence;
gboolean has_valid_gpu_rendering_duration;
int64_t gpu_rendering_duration_ns; int64_t gpu_rendering_duration_ns;
int64_t cpu_time_before_buffer_swap_us; int64_t cpu_time_before_buffer_swap_us;
}; };

View File

@ -74,6 +74,7 @@ struct _CoglFrameInfo
unsigned int sequence; unsigned int sequence;
CoglTimestampQuery *timestamp_query; CoglTimestampQuery *timestamp_query;
gboolean has_valid_gpu_rendering_duration;
int64_t gpu_time_before_buffer_swap_ns; int64_t gpu_time_before_buffer_swap_ns;
int64_t cpu_time_before_buffer_swap_us; int64_t cpu_time_before_buffer_swap_us;

View File

@ -132,6 +132,12 @@ cogl_frame_info_get_sequence (CoglFrameInfo *info)
return info->sequence; return info->sequence;
} }
gboolean
cogl_frame_info_has_valid_gpu_rendering_duration (CoglFrameInfo *info)
{
return info->has_valid_gpu_rendering_duration;
}
int64_t int64_t
cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info) cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info)
{ {

View File

@ -127,6 +127,9 @@ gboolean cogl_frame_info_is_vsync (CoglFrameInfo *info);
COGL_EXPORT COGL_EXPORT
unsigned int cogl_frame_info_get_sequence (CoglFrameInfo *info); unsigned int cogl_frame_info_get_sequence (CoglFrameInfo *info);
COGL_EXPORT
gboolean cogl_frame_info_has_valid_gpu_rendering_duration (CoglFrameInfo *info);
COGL_EXPORT COGL_EXPORT
int64_t cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info); int64_t cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info);

View File

@ -318,6 +318,8 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
/* Set up a timestamp query for when all rendering will be finished. */ /* Set up a timestamp query for when all rendering will be finished. */
info->timestamp_query = info->timestamp_query =
cogl_framebuffer_create_timestamp_query (COGL_FRAMEBUFFER (onscreen)); cogl_framebuffer_create_timestamp_query (COGL_FRAMEBUFFER (onscreen));
info->has_valid_gpu_rendering_duration = TRUE;
} }
if (n_rectangles && priv->pf_eglSwapBuffersWithDamage) if (n_rectangles && priv->pf_eglSwapBuffersWithDamage)

View File

@ -77,6 +77,8 @@ frame_cb (CoglOnscreen *onscreen,
cogl_frame_info_get_presentation_time_us (frame_info), cogl_frame_info_get_presentation_time_us (frame_info),
.flags = flags, .flags = flags,
.sequence = cogl_frame_info_get_sequence (frame_info), .sequence = cogl_frame_info_get_sequence (frame_info),
.has_valid_gpu_rendering_duration =
cogl_frame_info_has_valid_gpu_rendering_duration (frame_info),
.gpu_rendering_duration_ns = .gpu_rendering_duration_ns =
cogl_frame_info_get_rendering_duration_ns (frame_info), cogl_frame_info_get_rendering_duration_ns (frame_info),
.cpu_time_before_buffer_swap_us = .cpu_time_before_buffer_swap_us =

View File

@ -1631,6 +1631,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time ();
if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_TIMESTAMP_QUERY))
frame_info->has_valid_gpu_rendering_duration = TRUE;
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
kms_device = meta_kms_crtc_get_device (kms_crtc); kms_device = meta_kms_crtc_get_device (kms_crtc);
kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device);