Use signals instead of onscreen framebuffer frame callbacks
CoglFrameInfo is a frame info container associated with a single onscreen framebuffer. The clutter stage will eventually support drawing a stage frame with multiple onscreen framebuffers, thus needs its own frame info container. This patch introduces a new stage signal 'presented' and a accompaning ClutterFrameInfo and adapts the stage windows and past onscreen frame callbacks users to use the signal and new info container. https://bugzilla.gnome.org/show_bug.cgi?id=768976
This commit is contained in:
parent
92341e7c30
commit
28a898a22f
@ -37,11 +37,6 @@ void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
|
|||||||
CLUTTER_AVAILABLE_IN_MUTTER
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
gboolean _clutter_get_sync_to_vblank (void);
|
gboolean _clutter_get_sync_to_vblank (void);
|
||||||
|
|
||||||
CLUTTER_AVAILABLE_IN_MUTTER
|
|
||||||
CoglFrameClosure *clutter_stage_add_frame_callback (ClutterStage *stage,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
CLUTTER_AVAILABLE_IN_MUTTER
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
|
int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
|
||||||
|
|
||||||
|
@ -125,6 +125,10 @@ gboolean _clutter_stage_update_state (ClutterStage *stag
|
|||||||
void _clutter_stage_set_scale_factor (ClutterStage *stage,
|
void _clutter_stage_set_scale_factor (ClutterStage *stage,
|
||||||
int factor);
|
int factor);
|
||||||
|
|
||||||
|
void _clutter_stage_presented (ClutterStage *stage,
|
||||||
|
CoglFrameEvent frame_event,
|
||||||
|
ClutterFrameInfo *frame_info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
|
||||||
|
@ -338,25 +338,6 @@ _clutter_stage_window_get_views (ClutterStageWindow *window)
|
|||||||
return iface->get_views (window);
|
return iface->get_views (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglFrameClosure *
|
|
||||||
_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
|
||||||
|
|
||||||
return iface->set_frame_callback (window, callback, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_clutter_stage_window_remove_frame_callback (ClutterStageWindow *window,
|
|
||||||
CoglFrameClosure *closure)
|
|
||||||
{
|
|
||||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
|
||||||
|
|
||||||
iface->remove_frame_callback (window, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_stage_window_finish_frame (ClutterStageWindow *window)
|
_clutter_stage_window_finish_frame (ClutterStageWindow *window)
|
||||||
{
|
{
|
||||||
|
@ -87,11 +87,6 @@ struct _ClutterStageWindowIface
|
|||||||
int factor);
|
int factor);
|
||||||
int (* get_scale_factor) (ClutterStageWindow *stage_window);
|
int (* get_scale_factor) (ClutterStageWindow *stage_window);
|
||||||
GList *(* get_views) (ClutterStageWindow *stage_window);
|
GList *(* get_views) (ClutterStageWindow *stage_window);
|
||||||
CoglFrameClosure *(* set_frame_callback) (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data);
|
|
||||||
void (* remove_frame_callback) (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameClosure *closure);
|
|
||||||
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
||||||
void (* finish_frame) (ClutterStageWindow *stage_window);
|
void (* finish_frame) (ClutterStageWindow *stage_window);
|
||||||
};
|
};
|
||||||
@ -151,13 +146,6 @@ int _clutter_stage_window_get_scale_factor (ClutterStageWin
|
|||||||
|
|
||||||
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
|
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
|
||||||
|
|
||||||
CoglFrameClosure *_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
void _clutter_stage_window_remove_frame_callback (ClutterStageWindow *stage_winow,
|
|
||||||
CoglFrameClosure *closure);
|
|
||||||
|
|
||||||
void _clutter_stage_window_finish_frame (ClutterStageWindow *window);
|
void _clutter_stage_window_finish_frame (ClutterStageWindow *window);
|
||||||
|
|
||||||
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
|
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
|
||||||
|
@ -190,6 +190,7 @@ enum
|
|||||||
DEACTIVATE,
|
DEACTIVATE,
|
||||||
DELETE_EVENT,
|
DELETE_EVENT,
|
||||||
AFTER_PAINT,
|
AFTER_PAINT,
|
||||||
|
PRESENTED,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -2167,6 +2168,21 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 0);
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterStage::presented: (skip)
|
||||||
|
* @stage: the stage that received the event
|
||||||
|
* @frame_event: a #CoglFrameEvent
|
||||||
|
* @frame_info: a #ClutterFrameInfo
|
||||||
|
*/
|
||||||
|
stage_signals[PRESENTED] =
|
||||||
|
g_signal_new (I_("presented"),
|
||||||
|
G_TYPE_FROM_CLASS (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 2,
|
||||||
|
G_TYPE_INT, G_TYPE_POINTER);
|
||||||
|
|
||||||
klass->fullscreen = clutter_stage_real_fullscreen;
|
klass->fullscreen = clutter_stage_real_fullscreen;
|
||||||
klass->activate = clutter_stage_real_activate;
|
klass->activate = clutter_stage_real_activate;
|
||||||
klass->deactivate = clutter_stage_real_deactivate;
|
klass->deactivate = clutter_stage_real_deactivate;
|
||||||
@ -4628,19 +4644,6 @@ _clutter_stage_set_scale_factor (ClutterStage *stage,
|
|||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglFrameClosure *
|
|
||||||
clutter_stage_add_frame_callback (ClutterStage *stage,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterStageWindow *stage_window;
|
|
||||||
|
|
||||||
stage_window = _clutter_stage_get_window (stage);
|
|
||||||
return _clutter_stage_window_set_frame_callback (stage_window,
|
|
||||||
callback,
|
|
||||||
user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
clutter_stage_get_frame_counter (ClutterStage *stage)
|
clutter_stage_get_frame_counter (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
@ -4649,3 +4652,12 @@ clutter_stage_get_frame_counter (ClutterStage *stage)
|
|||||||
stage_window = _clutter_stage_get_window (stage);
|
stage_window = _clutter_stage_get_window (stage);
|
||||||
return _clutter_stage_window_get_frame_counter (stage_window);
|
return _clutter_stage_window_get_frame_counter (stage_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_stage_presented (ClutterStage *stage,
|
||||||
|
CoglFrameEvent frame_event,
|
||||||
|
ClutterFrameInfo *frame_info)
|
||||||
|
{
|
||||||
|
g_signal_emit (stage, stage_signals[PRESENTED], 0,
|
||||||
|
(int) frame_event, frame_info);
|
||||||
|
}
|
||||||
|
@ -135,6 +135,16 @@ struct _ClutterFog
|
|||||||
gfloat z_far;
|
gfloat z_far;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterFrameInfo: (skip)
|
||||||
|
*/
|
||||||
|
struct _ClutterFrameInfo
|
||||||
|
{
|
||||||
|
int64_t frame_counter;
|
||||||
|
int64_t presentation_time;
|
||||||
|
float refresh_rate;
|
||||||
|
};
|
||||||
|
|
||||||
CLUTTER_AVAILABLE_IN_ALL
|
CLUTTER_AVAILABLE_IN_ALL
|
||||||
GType clutter_perspective_get_type (void) G_GNUC_CONST;
|
GType clutter_perspective_get_type (void) G_GNUC_CONST;
|
||||||
CLUTTER_DEPRECATED_IN_1_10
|
CLUTTER_DEPRECATED_IN_1_10
|
||||||
|
@ -51,6 +51,7 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _ClutterActor ClutterActor;
|
typedef struct _ClutterActor ClutterActor;
|
||||||
|
|
||||||
typedef struct _ClutterStage ClutterStage;
|
typedef struct _ClutterStage ClutterStage;
|
||||||
|
typedef struct _ClutterFrameInfo ClutterFrameInfo;
|
||||||
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
||||||
typedef struct _ClutterChildMeta ClutterChildMeta;
|
typedef struct _ClutterChildMeta ClutterChildMeta;
|
||||||
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
|
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
|
||||||
|
@ -81,24 +81,15 @@ clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
|
|||||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
|
CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
|
||||||
|
|
||||||
if (stage_cogl->frame_closure != NULL)
|
|
||||||
{
|
|
||||||
_clutter_stage_window_remove_frame_callback (stage_window,
|
|
||||||
stage_cogl->frame_closure);
|
|
||||||
stage_cogl->frame_closure = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
frame_cb (CoglOnscreen *onscreen,
|
_clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
|
||||||
CoglFrameEvent event,
|
CoglFrameEvent frame_event,
|
||||||
CoglFrameInfo *info,
|
ClutterFrameInfo *frame_info)
|
||||||
void *user_data)
|
|
||||||
{
|
{
|
||||||
ClutterStageCogl *stage_cogl = user_data;
|
|
||||||
|
|
||||||
if (event == COGL_FRAME_EVENT_SYNC)
|
if (frame_event == COGL_FRAME_EVENT_SYNC)
|
||||||
{
|
{
|
||||||
/* Early versions of the swap_event implementation in Mesa
|
/* Early versions of the swap_event implementation in Mesa
|
||||||
* deliver BufferSwapComplete event when not selected for,
|
* deliver BufferSwapComplete event when not selected for,
|
||||||
@ -112,13 +103,14 @@ frame_cb (CoglOnscreen *onscreen,
|
|||||||
if (stage_cogl->pending_swaps > 0)
|
if (stage_cogl->pending_swaps > 0)
|
||||||
stage_cogl->pending_swaps--;
|
stage_cogl->pending_swaps--;
|
||||||
}
|
}
|
||||||
else if (event == COGL_FRAME_EVENT_COMPLETE)
|
else if (frame_event == COGL_FRAME_EVENT_COMPLETE)
|
||||||
{
|
{
|
||||||
gint64 presentation_time_cogl = cogl_frame_info_get_presentation_time (info);
|
gint64 presentation_time_cogl = frame_info->presentation_time;
|
||||||
|
|
||||||
if (presentation_time_cogl != 0)
|
if (presentation_time_cogl != 0)
|
||||||
{
|
{
|
||||||
CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
|
ClutterBackend *backend = stage_cogl->backend;
|
||||||
|
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
||||||
gint64 current_time_cogl = cogl_get_clock_time (context);
|
gint64 current_time_cogl = cogl_get_clock_time (context);
|
||||||
gint64 now = g_get_monotonic_time ();
|
gint64 now = g_get_monotonic_time ();
|
||||||
|
|
||||||
@ -126,8 +118,10 @@ frame_cb (CoglOnscreen *onscreen,
|
|||||||
now + (presentation_time_cogl - current_time_cogl) / 1000;
|
now + (presentation_time_cogl - current_time_cogl) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
stage_cogl->refresh_rate = cogl_frame_info_get_refresh_rate (info);
|
stage_cogl->refresh_rate = frame_info->refresh_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -148,10 +142,6 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
stage_cogl->frame_closure =
|
|
||||||
_clutter_stage_window_set_frame_callback (stage_window,
|
|
||||||
frame_cb, stage_window);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ struct _ClutterStageCogl
|
|||||||
float refresh_rate;
|
float refresh_rate;
|
||||||
int pending_swaps;
|
int pending_swaps;
|
||||||
|
|
||||||
CoglFrameClosure *frame_closure;
|
|
||||||
|
|
||||||
gint64 last_presentation_time;
|
gint64 last_presentation_time;
|
||||||
gint64 update_time;
|
gint64 update_time;
|
||||||
|
|
||||||
@ -78,6 +76,11 @@ struct _ClutterStageCoglClass
|
|||||||
CLUTTER_AVAILABLE_IN_MUTTER
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
GType _clutter_stage_cogl_get_type (void) G_GNUC_CONST;
|
GType _clutter_stage_cogl_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
CLUTTER_AVAILABLE_IN_MUTTER
|
||||||
|
void _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
|
||||||
|
CoglFrameEvent frame_event,
|
||||||
|
ClutterFrameInfo *frame_info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_STAGE_COGL_H__ */
|
#endif /* __CLUTTER_STAGE_COGL_H__ */
|
||||||
|
@ -443,6 +443,13 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
|||||||
if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen))
|
if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen))
|
||||||
_clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
|
_clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
|
||||||
|
|
||||||
|
if (stage_x11->frame_closure)
|
||||||
|
{
|
||||||
|
cogl_onscreen_remove_frame_callback (stage_x11->onscreen,
|
||||||
|
stage_x11->frame_closure);
|
||||||
|
stage_x11->frame_closure = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||||
|
|
||||||
g_list_free (stage_x11->legacy_views);
|
g_list_free (stage_x11->legacy_views);
|
||||||
@ -604,6 +611,23 @@ stage_events_device_added (ClutterDeviceManager *device_manager,
|
|||||||
stage_cogl->wrapper);
|
stage_cogl->wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
frame_cb (CoglOnscreen *onscreen,
|
||||||
|
CoglFrameEvent frame_event,
|
||||||
|
CoglFrameInfo *frame_info,
|
||||||
|
void *user_data)
|
||||||
|
|
||||||
|
{
|
||||||
|
ClutterStageCogl *stage_cogl = user_data;
|
||||||
|
ClutterFrameInfo clutter_frame_info = {
|
||||||
|
.frame_counter = cogl_frame_info_get_frame_counter (frame_info),
|
||||||
|
.presentation_time = cogl_frame_info_get_presentation_time (frame_info),
|
||||||
|
.refresh_rate = cogl_frame_info_get_refresh_rate (frame_info)
|
||||||
|
};
|
||||||
|
|
||||||
|
_clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
@ -628,6 +652,14 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
|||||||
|
|
||||||
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
||||||
|
|
||||||
|
cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
|
||||||
|
_clutter_get_sync_to_vblank ());
|
||||||
|
stage_x11->frame_closure =
|
||||||
|
cogl_onscreen_add_frame_callback (stage_x11->onscreen,
|
||||||
|
frame_cb,
|
||||||
|
stage_cogl,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (stage_x11->legacy_view)
|
if (stage_x11->legacy_view)
|
||||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||||
"framebuffer", stage_x11->onscreen,
|
"framebuffer", stage_x11->onscreen,
|
||||||
@ -929,31 +961,6 @@ clutter_stage_x11_get_views (ClutterStageWindow *stage_window)
|
|||||||
return stage_x11->legacy_views;
|
return stage_x11->legacy_views;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglFrameClosure *
|
|
||||||
clutter_stage_x11_set_frame_callback (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
|
||||||
|
|
||||||
cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
|
|
||||||
_clutter_get_sync_to_vblank ());
|
|
||||||
|
|
||||||
return cogl_onscreen_add_frame_callback (stage_x11->onscreen,
|
|
||||||
callback,
|
|
||||||
user_data,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_stage_x11_remove_frame_callback (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameClosure *closure)
|
|
||||||
{
|
|
||||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
|
||||||
|
|
||||||
cogl_onscreen_remove_frame_callback (stage_x11->onscreen, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window)
|
clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
@ -1037,8 +1044,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
|
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
|
||||||
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
|
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
|
||||||
iface->get_views = clutter_stage_x11_get_views;
|
iface->get_views = clutter_stage_x11_get_views;
|
||||||
iface->set_frame_callback = clutter_stage_x11_set_frame_callback;
|
|
||||||
iface->remove_frame_callback = clutter_stage_x11_remove_frame_callback;
|
|
||||||
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
|
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,8 @@ struct _ClutterStageX11
|
|||||||
ClutterStageView *legacy_view;
|
ClutterStageView *legacy_view;
|
||||||
GList *legacy_views;
|
GList *legacy_views;
|
||||||
|
|
||||||
|
CoglFrameClosure *frame_closure;
|
||||||
|
|
||||||
gchar *title;
|
gchar *title;
|
||||||
|
|
||||||
guint clipped_redraws_cool_off;
|
guint clipped_redraws_cool_off;
|
||||||
|
@ -42,6 +42,8 @@ struct _CoglFrameInfo
|
|||||||
int64_t presentation_time;
|
int64_t presentation_time;
|
||||||
float refresh_rate;
|
float refresh_rate;
|
||||||
|
|
||||||
|
int64_t global_frame_counter;
|
||||||
|
|
||||||
CoglOutput *output;
|
CoglOutput *output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,3 +79,9 @@ cogl_frame_info_get_output (CoglFrameInfo *info)
|
|||||||
{
|
{
|
||||||
return info->output;
|
return info->output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
|
||||||
|
{
|
||||||
|
return info->global_frame_counter;
|
||||||
|
}
|
||||||
|
@ -143,6 +143,11 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
|
|||||||
CoglOutput *
|
CoglOutput *
|
||||||
cogl_frame_info_get_output (CoglFrameInfo *info);
|
cogl_frame_info_get_output (CoglFrameInfo *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_frame_info_get_global_frame_counter: (skip)
|
||||||
|
*/
|
||||||
|
int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_FRAME_INFO_H */
|
#endif /* __COGL_FRAME_INFO_H */
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <cogl/cogl-texture.h>
|
#include <cogl/cogl-texture.h>
|
||||||
#include <cogl/cogl-meta-texture.h>
|
#include <cogl/cogl-meta-texture.h>
|
||||||
#include <cogl/cogl-error-private.h>
|
#include <cogl/cogl-error-private.h>
|
||||||
|
#include <cogl/cogl-frame-info-private.h>
|
||||||
#include <cogl/cogl-renderer-private.h>
|
#include <cogl/cogl-renderer-private.h>
|
||||||
#include <cogl/winsys/cogl-winsys-egl-private.h>
|
#include <cogl/winsys/cogl-winsys-egl-private.h>
|
||||||
#include <cogl/winsys/cogl-winsys-private.h>
|
#include <cogl/winsys/cogl-winsys-private.h>
|
||||||
|
@ -36,6 +36,7 @@ struct _MetaStageNative
|
|||||||
ClutterStageCogl parent;
|
ClutterStageCogl parent;
|
||||||
|
|
||||||
CoglOnscreen *pending_onscreen;
|
CoglOnscreen *pending_onscreen;
|
||||||
|
CoglClosure *frame_closure;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
||||||
@ -136,6 +137,16 @@ meta_stage_native_unrealize (ClutterStageWindow *stage_window)
|
|||||||
|
|
||||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||||
|
|
||||||
|
if (stage_native->frame_closure)
|
||||||
|
{
|
||||||
|
CoglOnscreen *onscreen;
|
||||||
|
|
||||||
|
onscreen = get_legacy_onscreen (stage_native);
|
||||||
|
cogl_onscreen_remove_frame_callback (onscreen,
|
||||||
|
stage_native->frame_closure);
|
||||||
|
stage_native->frame_closure = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_clear_pointer (&stage_native->pending_onscreen, cogl_object_unref);
|
g_clear_pointer (&stage_native->pending_onscreen, cogl_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +179,23 @@ meta_stage_native_get_geometry (ClutterStageWindow *stage_window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
frame_cb (CoglOnscreen *onscreen,
|
||||||
|
CoglFrameEvent frame_event,
|
||||||
|
CoglFrameInfo *frame_info,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
MetaStageNative *stage_native = user_data;
|
||||||
|
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_native);
|
||||||
|
ClutterFrameInfo clutter_frame_info = {
|
||||||
|
.frame_counter = cogl_frame_info_get_frame_counter (frame_info),
|
||||||
|
.refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
|
||||||
|
.presentation_time = cogl_frame_info_get_presentation_time (frame_info)
|
||||||
|
};
|
||||||
|
|
||||||
|
_clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
@ -179,6 +207,7 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
|
|||||||
MetaRendererView *legacy_view;
|
MetaRendererView *legacy_view;
|
||||||
cairo_rectangle_int_t view_layout = { 0 };
|
cairo_rectangle_int_t view_layout = { 0 };
|
||||||
CoglFramebuffer *framebuffer;
|
CoglFramebuffer *framebuffer;
|
||||||
|
CoglOnscreen *onscreen;
|
||||||
|
|
||||||
legacy_view = get_legacy_view (renderer);
|
legacy_view = get_legacy_view (renderer);
|
||||||
if (legacy_view)
|
if (legacy_view)
|
||||||
@ -196,6 +225,16 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
|
|||||||
"framebuffer", framebuffer,
|
"framebuffer", framebuffer,
|
||||||
NULL);
|
NULL);
|
||||||
meta_renderer_set_legacy_view (renderer, legacy_view);
|
meta_renderer_set_legacy_view (renderer, legacy_view);
|
||||||
|
|
||||||
|
onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
|
cogl_onscreen_set_swap_throttled (onscreen,
|
||||||
|
_clutter_get_sync_to_vblank ());
|
||||||
|
|
||||||
|
stage_native->frame_closure =
|
||||||
|
cogl_onscreen_add_frame_callback (onscreen,
|
||||||
|
frame_cb,
|
||||||
|
stage_native,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
@ -208,36 +247,6 @@ meta_stage_native_get_views (ClutterStageWindow *stage_window)
|
|||||||
return meta_renderer_get_views (renderer);
|
return meta_renderer_get_views (renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglClosure *
|
|
||||||
meta_stage_native_set_frame_callback (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameCallback callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
|
||||||
CoglOnscreen *legacy_onscreen;
|
|
||||||
|
|
||||||
legacy_onscreen = get_legacy_onscreen (stage_native);
|
|
||||||
cogl_onscreen_set_swap_throttled (legacy_onscreen,
|
|
||||||
_clutter_get_sync_to_vblank ());
|
|
||||||
|
|
||||||
return cogl_onscreen_add_frame_callback (legacy_onscreen,
|
|
||||||
callback,
|
|
||||||
user_data,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_stage_native_remove_frame_callback (ClutterStageWindow *stage_window,
|
|
||||||
CoglFrameClosure *closure)
|
|
||||||
{
|
|
||||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
|
||||||
CoglOnscreen *legacy_onscreen;
|
|
||||||
|
|
||||||
legacy_onscreen = get_legacy_onscreen (stage_native);
|
|
||||||
|
|
||||||
cogl_onscreen_remove_frame_callback (legacy_onscreen, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window)
|
meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
@ -269,7 +278,5 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
|
iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
|
||||||
iface->get_geometry = meta_stage_native_get_geometry;
|
iface->get_geometry = meta_stage_native_get_geometry;
|
||||||
iface->get_views = meta_stage_native_get_views;
|
iface->get_views = meta_stage_native_get_views;
|
||||||
iface->set_frame_callback = meta_stage_native_set_frame_callback;
|
|
||||||
iface->remove_frame_callback = meta_stage_native_remove_frame_callback;
|
|
||||||
iface->get_frame_counter = meta_stage_native_get_frame_counter;
|
iface->get_frame_counter = meta_stage_native_get_frame_counter;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ struct _MetaCompositor
|
|||||||
GList *windows;
|
GList *windows;
|
||||||
Window output;
|
Window output;
|
||||||
|
|
||||||
CoglFrameClosure *frame_closure;
|
|
||||||
CoglContext *context;
|
CoglContext *context;
|
||||||
|
|
||||||
/* Used for unredirecting fullscreen windows */
|
/* Used for unredirecting fullscreen windows */
|
||||||
|
@ -83,6 +83,12 @@
|
|||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_presented (ClutterStage *stage,
|
||||||
|
CoglFrameEvent event,
|
||||||
|
ClutterFrameInfo *frame_info,
|
||||||
|
MetaCompositor *compositor);
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_modal (MetaDisplay *display)
|
is_modal (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -475,6 +481,10 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
|
|
||||||
compositor->stage = meta_backend_get_stage (backend);
|
compositor->stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
|
g_signal_connect (compositor->stage, "presented",
|
||||||
|
G_CALLBACK (on_presented),
|
||||||
|
compositor);
|
||||||
|
|
||||||
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
||||||
* when benchmarking drawing performance, connects to ::after-paint
|
* when benchmarking drawing performance, connects to ::after-paint
|
||||||
* and calls glFinish(). The timing information from that will be
|
* and calls glFinish(). The timing information from that will be
|
||||||
@ -998,17 +1008,16 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
frame_callback (CoglOnscreen *onscreen,
|
on_presented (ClutterStage *stage,
|
||||||
CoglFrameEvent event,
|
CoglFrameEvent event,
|
||||||
CoglFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
void *user_data)
|
MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
MetaCompositor *compositor = user_data;
|
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
if (event == COGL_FRAME_EVENT_COMPLETE)
|
if (event == COGL_FRAME_EVENT_COMPLETE)
|
||||||
{
|
{
|
||||||
gint64 presentation_time_cogl = cogl_frame_info_get_presentation_time (frame_info);
|
gint64 presentation_time_cogl = frame_info->presentation_time;
|
||||||
gint64 presentation_time;
|
gint64 presentation_time;
|
||||||
|
|
||||||
if (presentation_time_cogl != 0)
|
if (presentation_time_cogl != 0)
|
||||||
@ -1045,14 +1054,6 @@ meta_pre_paint_func (gpointer data)
|
|||||||
MetaWindowActor *top_window;
|
MetaWindowActor *top_window;
|
||||||
MetaCompositor *compositor = data;
|
MetaCompositor *compositor = data;
|
||||||
|
|
||||||
if (!compositor->frame_closure)
|
|
||||||
{
|
|
||||||
compositor->frame_closure =
|
|
||||||
clutter_stage_add_frame_callback (CLUTTER_STAGE (compositor->stage),
|
|
||||||
frame_callback,
|
|
||||||
compositor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (compositor->windows == NULL)
|
if (compositor->windows == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ void meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
|||||||
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
||||||
void meta_window_actor_post_paint (MetaWindowActor *self);
|
void meta_window_actor_post_paint (MetaWindowActor *self);
|
||||||
void meta_window_actor_frame_complete (MetaWindowActor *self,
|
void meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||||
CoglFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
gint64 presentation_time);
|
gint64 presentation_time);
|
||||||
|
|
||||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
||||||
|
@ -2029,13 +2029,13 @@ do_send_frame_timings (MetaWindowActor *self,
|
|||||||
static void
|
static void
|
||||||
send_frame_timings (MetaWindowActor *self,
|
send_frame_timings (MetaWindowActor *self,
|
||||||
FrameData *frame,
|
FrameData *frame,
|
||||||
CoglFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
gint64 presentation_time)
|
gint64 presentation_time)
|
||||||
{
|
{
|
||||||
float refresh_rate;
|
float refresh_rate;
|
||||||
int refresh_interval;
|
int refresh_interval;
|
||||||
|
|
||||||
refresh_rate = cogl_frame_info_get_refresh_rate (frame_info);
|
refresh_rate = frame_info->refresh_rate;
|
||||||
/* 0.0 is a flag for not known, but sanity-check against other odd numbers */
|
/* 0.0 is a flag for not known, but sanity-check against other odd numbers */
|
||||||
if (refresh_rate >= 1.0)
|
if (refresh_rate >= 1.0)
|
||||||
refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
|
refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
|
||||||
@ -2046,9 +2046,9 @@ send_frame_timings (MetaWindowActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_actor_frame_complete (MetaWindowActor *self,
|
meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||||
CoglFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
gint64 presentation_time)
|
gint64 presentation_time)
|
||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
GList *l;
|
GList *l;
|
||||||
@ -2060,7 +2060,7 @@ meta_window_actor_frame_complete (MetaWindowActor *self,
|
|||||||
{
|
{
|
||||||
GList *l_next = l->next;
|
GList *l_next = l->next;
|
||||||
FrameData *frame = l->data;
|
FrameData *frame = l->data;
|
||||||
gint64 frame_counter = cogl_frame_info_get_frame_counter (frame_info);
|
gint64 frame_counter = frame_info->frame_counter;
|
||||||
|
|
||||||
if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter)
|
if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user