From 487ea0dd95f64ffc12a82fbd15724eda5e4ddb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 10 Oct 2020 00:52:11 +0200 Subject: [PATCH] kms: Add symbolic page flips and cogl frame infos This makes it possible to post a symbolic page flip and frame callback, meant to be used by immediate symbolic page flip reply when emulating cursor plane changes using legacy drmMode* functions. Part-of: --- clutter/clutter/cogl/clutter-stage-cogl.c | 22 +++++++--- cogl/cogl/cogl-frame-info-private.h | 8 ++++ cogl/cogl/cogl-frame-info.c | 10 +++++ cogl/cogl/cogl-frame-info.h | 3 ++ .../native/meta-kms-impl-device-simple.c | 43 ++++++++++++++++++- .../native/meta-kms-page-flip-private.h | 2 + src/backends/native/meta-kms-page-flip.c | 26 ++++++++--- src/backends/native/meta-kms-update.h | 3 ++ src/backends/native/meta-renderer-native.c | 19 ++++++++ 9 files changed, 123 insertions(+), 13 deletions(-) diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 646a0f8e7..90f428ec8 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -791,18 +791,26 @@ frame_cb (CoglOnscreen *onscreen, void *user_data) { ClutterStageView *view = user_data; - ClutterFrameInfo clutter_frame_info; if (frame_event == COGL_FRAME_EVENT_SYNC) return; - clutter_frame_info = (ClutterFrameInfo) { - .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info), - .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info), - .presentation_time = ns2us (cogl_frame_info_get_presentation_time (frame_info)), - }; + if (cogl_frame_info_get_is_symbolic (frame_info)) + { + clutter_stage_view_notify_ready (view); + } + else + { + ClutterFrameInfo clutter_frame_info; - clutter_stage_view_notify_presented (view, &clutter_frame_info); + clutter_frame_info = (ClutterFrameInfo) { + .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info), + .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info), + .presentation_time = + ns2us (cogl_frame_info_get_presentation_time (frame_info)), + }; + clutter_stage_view_notify_presented (view, &clutter_frame_info); + } } static void diff --git a/cogl/cogl/cogl-frame-info-private.h b/cogl/cogl/cogl-frame-info-private.h index 13d856175..1c8fdc5cf 100644 --- a/cogl/cogl/cogl-frame-info-private.h +++ b/cogl/cogl/cogl-frame-info-private.h @@ -34,6 +34,12 @@ #include "cogl-frame-info.h" #include "cogl-object-private.h" +typedef enum _CoglFrameInfoFlag +{ + COGL_FRAME_INFO_FLAG_NONE = 0, + COGL_FRAME_INFO_FLAG_SYMBOLIC = 1 << 0, +} CoglFrameInfoFlag; + struct _CoglFrameInfo { CoglObject _parent; @@ -43,6 +49,8 @@ struct _CoglFrameInfo float refresh_rate; int64_t global_frame_counter; + + CoglFrameInfoFlag flags; }; COGL_EXPORT diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c index b5da21110..9d3420c02 100644 --- a/cogl/cogl/cogl-frame-info.c +++ b/cogl/cogl/cogl-frame-info.c @@ -64,12 +64,16 @@ cogl_frame_info_get_frame_counter (CoglFrameInfo *info) int64_t cogl_frame_info_get_presentation_time (CoglFrameInfo *info) { + g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); + return info->presentation_time; } float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info) { + g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); + return info->refresh_rate; } @@ -78,3 +82,9 @@ cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info) { return info->global_frame_counter; } + +gboolean +cogl_frame_info_get_is_symbolic (CoglFrameInfo *info) +{ + return !!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC); +} diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h index 2204bafdb..e2f9ff3bd 100644 --- a/cogl/cogl/cogl-frame-info.h +++ b/cogl/cogl/cogl-frame-info.h @@ -137,6 +137,9 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info); COGL_EXPORT int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info); +COGL_EXPORT +gboolean cogl_frame_info_get_is_symbolic (CoglFrameInfo *info); + G_END_DECLS #endif /* __COGL_FRAME_INFO_H */ diff --git a/src/backends/native/meta-kms-impl-device-simple.c b/src/backends/native/meta-kms-impl-device-simple.c index c9824539a..a045f8df6 100644 --- a/src/backends/native/meta-kms-impl-device-simple.c +++ b/src/backends/native/meta-kms-impl-device-simple.c @@ -761,6 +761,27 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple, return TRUE; } +static gboolean +symbolic_page_flip_idle (gpointer user_data) +{ + MetaKmsPageFlipData *page_flip_data = user_data; + MetaKmsImplDevice *impl_device; + MetaKmsCrtc *crtc; + + impl_device = meta_kms_page_flip_data_get_impl_device (page_flip_data); + crtc = meta_kms_page_flip_data_get_crtc (page_flip_data); + + meta_topic (META_DEBUG_KMS, + "[simple] Handling symbolic page flip callback from %s, data: %p, CRTC: %u", + meta_kms_impl_device_get_path (impl_device), + page_flip_data, + meta_kms_crtc_get_id (crtc)); + + meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data); + + return G_SOURCE_REMOVE; +} + static gboolean dispatch_page_flip (MetaKmsImplDevice *impl_device, MetaKmsUpdate *update, @@ -780,10 +801,30 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device, plane_assignment = meta_kms_update_get_primary_plane_assignment (update, crtc); - fd = meta_kms_impl_device_get_fd (impl_device); meta_kms_update_get_custom_page_flip_func (update, &custom_page_flip_func, &custom_page_flip_user_data); + + if (!plane_assignment && !custom_page_flip_func) + { + MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device); + MetaKms *kms = meta_kms_device_get_kms (device); + GSource *source; + + meta_kms_page_flip_data_make_symbolic (page_flip_data); + + source = meta_kms_add_source_in_impl (kms, + symbolic_page_flip_idle, + page_flip_data, + NULL); + + g_source_set_ready_time (source, 0); + g_source_unref (source); + + return TRUE; + } + + fd = meta_kms_impl_device_get_fd (impl_device); if (custom_page_flip_func) { meta_topic (META_DEBUG_KMS, diff --git a/src/backends/native/meta-kms-page-flip-private.h b/src/backends/native/meta-kms-page-flip-private.h index 50c95ae1c..1aed388f8 100644 --- a/src/backends/native/meta-kms-page-flip-private.h +++ b/src/backends/native/meta-kms-page-flip-private.h @@ -58,4 +58,6 @@ void meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_dat void meta_kms_page_flip_data_take_error (MetaKmsPageFlipData *page_flip_data, GError *error); +void meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data); + #endif /* META_KMS_PAGE_FLIP_H */ diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c index eaf6db51b..9f9f95ec2 100644 --- a/src/backends/native/meta-kms-page-flip.c +++ b/src/backends/native/meta-kms-page-flip.c @@ -44,6 +44,8 @@ struct _MetaKmsPageFlipData unsigned int sec; unsigned int usec; + gboolean is_symbolic; + GError *error; }; @@ -125,11 +127,19 @@ meta_kms_page_flip_data_flipped (MetaKms *kms, { MetaKmsPageFlipClosure *closure = l->data; - closure->vtable->flipped (page_flip_data->crtc, - page_flip_data->sequence, - page_flip_data->sec, - page_flip_data->usec, - closure->user_data); + if (page_flip_data->is_symbolic) + { + closure->vtable->ready (page_flip_data->crtc, + closure->user_data); + } + else + { + closure->vtable->flipped (page_flip_data->crtc, + page_flip_data->sequence, + page_flip_data->sec, + page_flip_data->usec, + closure->user_data); + } } } @@ -156,6 +166,12 @@ meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data page_flip_data->usec = usec; } +void +meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data) +{ + page_flip_data->is_symbolic = TRUE; +} + void meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) { diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index aa3cbb11d..2274b3791 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -51,6 +51,9 @@ struct _MetaKmsPageFlipListenerVtable unsigned int tv_usec, gpointer user_data); + void (* ready) (MetaKmsCrtc *crtc, + gpointer user_data); + void (* mode_set_fallback) (MetaKmsCrtc *crtc, gpointer user_data); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index a14749f56..9efee2c1f 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1110,6 +1110,24 @@ page_flip_feedback_flipped (MetaKmsCrtc *kms_crtc, g_object_unref (view); } +static void +page_flip_feedback_ready (MetaKmsCrtc *kms_crtc, + gpointer user_data) +{ + MetaRendererView *view = user_data; + CoglFramebuffer *framebuffer = + clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view)); + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + CoglFrameInfo *frame_info; + + frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); + frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; + + meta_onscreen_native_notify_frame_complete (onscreen); + + g_object_unref (view); +} + static void page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc, gpointer user_data) @@ -1162,6 +1180,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { .flipped = page_flip_feedback_flipped, + .ready = page_flip_feedback_ready, .mode_set_fallback = page_flip_feedback_mode_set_fallback, .discarded = page_flip_feedback_discarded, };