mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
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:
parent
1c20ba4c32
commit
487ea0dd95
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user