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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-10-10 00:52:11 +02:00 committed by Marge Bot
parent 1c20ba4c32
commit 487ea0dd95
9 changed files with 123 additions and 13 deletions

View File

@ -791,19 +791,27 @@ frame_cb (CoglOnscreen *onscreen,
void *user_data) void *user_data)
{ {
ClutterStageView *view = user_data; ClutterStageView *view = user_data;
ClutterFrameInfo clutter_frame_info;
if (frame_event == COGL_FRAME_EVENT_SYNC) if (frame_event == COGL_FRAME_EVENT_SYNC)
return; return;
if (cogl_frame_info_get_is_symbolic (frame_info))
{
clutter_stage_view_notify_ready (view);
}
else
{
ClutterFrameInfo clutter_frame_info;
clutter_frame_info = (ClutterFrameInfo) { clutter_frame_info = (ClutterFrameInfo) {
.frame_counter = cogl_frame_info_get_global_frame_counter (frame_info), .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info),
.refresh_rate = cogl_frame_info_get_refresh_rate (frame_info), .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
.presentation_time = ns2us (cogl_frame_info_get_presentation_time (frame_info)), .presentation_time =
ns2us (cogl_frame_info_get_presentation_time (frame_info)),
}; };
clutter_stage_view_notify_presented (view, &clutter_frame_info); clutter_stage_view_notify_presented (view, &clutter_frame_info);
} }
}
static void static void
clutter_stage_view_cogl_dispose (GObject *object) clutter_stage_view_cogl_dispose (GObject *object)

View File

@ -34,6 +34,12 @@
#include "cogl-frame-info.h" #include "cogl-frame-info.h"
#include "cogl-object-private.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 struct _CoglFrameInfo
{ {
CoglObject _parent; CoglObject _parent;
@ -43,6 +49,8 @@ struct _CoglFrameInfo
float refresh_rate; float refresh_rate;
int64_t global_frame_counter; int64_t global_frame_counter;
CoglFrameInfoFlag flags;
}; };
COGL_EXPORT COGL_EXPORT

View File

@ -64,12 +64,16 @@ cogl_frame_info_get_frame_counter (CoglFrameInfo *info)
int64_t int64_t
cogl_frame_info_get_presentation_time (CoglFrameInfo *info) cogl_frame_info_get_presentation_time (CoglFrameInfo *info)
{ {
g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC));
return info->presentation_time; return info->presentation_time;
} }
float float
cogl_frame_info_get_refresh_rate (CoglFrameInfo *info) cogl_frame_info_get_refresh_rate (CoglFrameInfo *info)
{ {
g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC));
return info->refresh_rate; return info->refresh_rate;
} }
@ -78,3 +82,9 @@ cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
{ {
return info->global_frame_counter; return info->global_frame_counter;
} }
gboolean
cogl_frame_info_get_is_symbolic (CoglFrameInfo *info)
{
return !!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC);
}

View File

@ -137,6 +137,9 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
COGL_EXPORT COGL_EXPORT
int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info); 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 G_END_DECLS
#endif /* __COGL_FRAME_INFO_H */ #endif /* __COGL_FRAME_INFO_H */

View File

@ -761,6 +761,27 @@ mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
return TRUE; 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 static gboolean
dispatch_page_flip (MetaKmsImplDevice *impl_device, dispatch_page_flip (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
@ -780,10 +801,30 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
plane_assignment = meta_kms_update_get_primary_plane_assignment (update, plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
crtc); crtc);
fd = meta_kms_impl_device_get_fd (impl_device);
meta_kms_update_get_custom_page_flip_func (update, meta_kms_update_get_custom_page_flip_func (update,
&custom_page_flip_func, &custom_page_flip_func,
&custom_page_flip_user_data); &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) if (custom_page_flip_func)
{ {
meta_topic (META_DEBUG_KMS, meta_topic (META_DEBUG_KMS,

View File

@ -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, void meta_kms_page_flip_data_take_error (MetaKmsPageFlipData *page_flip_data,
GError *error); GError *error);
void meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data);
#endif /* META_KMS_PAGE_FLIP_H */ #endif /* META_KMS_PAGE_FLIP_H */

View File

@ -44,6 +44,8 @@ struct _MetaKmsPageFlipData
unsigned int sec; unsigned int sec;
unsigned int usec; unsigned int usec;
gboolean is_symbolic;
GError *error; GError *error;
}; };
@ -125,6 +127,13 @@ meta_kms_page_flip_data_flipped (MetaKms *kms,
{ {
MetaKmsPageFlipClosure *closure = l->data; MetaKmsPageFlipClosure *closure = l->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, closure->vtable->flipped (page_flip_data->crtc,
page_flip_data->sequence, page_flip_data->sequence,
page_flip_data->sec, page_flip_data->sec,
@ -132,6 +141,7 @@ meta_kms_page_flip_data_flipped (MetaKms *kms,
closure->user_data); closure->user_data);
} }
} }
}
static MetaKms * static MetaKms *
meta_kms_from_impl_device (MetaKmsImplDevice *impl_device) meta_kms_from_impl_device (MetaKmsImplDevice *impl_device)
@ -156,6 +166,12 @@ meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data
page_flip_data->usec = usec; page_flip_data->usec = usec;
} }
void
meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data)
{
page_flip_data->is_symbolic = TRUE;
}
void void
meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
{ {

View File

@ -51,6 +51,9 @@ struct _MetaKmsPageFlipListenerVtable
unsigned int tv_usec, unsigned int tv_usec,
gpointer user_data); gpointer user_data);
void (* ready) (MetaKmsCrtc *crtc,
gpointer user_data);
void (* mode_set_fallback) (MetaKmsCrtc *crtc, void (* mode_set_fallback) (MetaKmsCrtc *crtc,
gpointer user_data); gpointer user_data);

View File

@ -1110,6 +1110,24 @@ page_flip_feedback_flipped (MetaKmsCrtc *kms_crtc,
g_object_unref (view); 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 static void
page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc, page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc,
gpointer user_data) gpointer user_data)
@ -1162,6 +1180,7 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc,
static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
.flipped = page_flip_feedback_flipped, .flipped = page_flip_feedback_flipped,
.ready = page_flip_feedback_ready,
.mode_set_fallback = page_flip_feedback_mode_set_fallback, .mode_set_fallback = page_flip_feedback_mode_set_fallback,
.discarded = page_flip_feedback_discarded, .discarded = page_flip_feedback_discarded,
}; };