mirror of
https://github.com/brl/mutter.git
synced 2025-06-14 01:09:30 +00:00
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:
@ -36,6 +36,7 @@ struct _MetaStageNative
|
||||
ClutterStageCogl parent;
|
||||
|
||||
CoglOnscreen *pending_onscreen;
|
||||
CoglClosure *frame_closure;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@ -179,6 +207,7 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
MetaRendererView *legacy_view;
|
||||
cairo_rectangle_int_t view_layout = { 0 };
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglOnscreen *onscreen;
|
||||
|
||||
legacy_view = get_legacy_view (renderer);
|
||||
if (legacy_view)
|
||||
@ -196,6 +225,16 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
"framebuffer", framebuffer,
|
||||
NULL);
|
||||
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 *
|
||||
@ -208,36 +247,6 @@ meta_stage_native_get_views (ClutterStageWindow *stage_window)
|
||||
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
|
||||
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->get_geometry = meta_stage_native_get_geometry;
|
||||
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;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ struct _MetaCompositor
|
||||
GList *windows;
|
||||
Window output;
|
||||
|
||||
CoglFrameClosure *frame_closure;
|
||||
CoglContext *context;
|
||||
|
||||
/* Used for unredirecting fullscreen windows */
|
||||
|
@ -83,6 +83,12 @@
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
on_presented (ClutterStage *stage,
|
||||
CoglFrameEvent event,
|
||||
ClutterFrameInfo *frame_info,
|
||||
MetaCompositor *compositor);
|
||||
|
||||
static gboolean
|
||||
is_modal (MetaDisplay *display)
|
||||
{
|
||||
@ -475,6 +481,10 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
|
||||
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,
|
||||
* when benchmarking drawing performance, connects to ::after-paint
|
||||
* and calls glFinish(). The timing information from that will be
|
||||
@ -998,17 +1008,16 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (CoglOnscreen *onscreen,
|
||||
CoglFrameEvent event,
|
||||
CoglFrameInfo *frame_info,
|
||||
void *user_data)
|
||||
on_presented (ClutterStage *stage,
|
||||
CoglFrameEvent event,
|
||||
ClutterFrameInfo *frame_info,
|
||||
MetaCompositor *compositor)
|
||||
{
|
||||
MetaCompositor *compositor = user_data;
|
||||
GList *l;
|
||||
|
||||
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;
|
||||
|
||||
if (presentation_time_cogl != 0)
|
||||
@ -1045,14 +1054,6 @@ meta_pre_paint_func (gpointer data)
|
||||
MetaWindowActor *top_window;
|
||||
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)
|
||||
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_post_paint (MetaWindowActor *self);
|
||||
void meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
CoglFrameInfo *frame_info,
|
||||
ClutterFrameInfo *frame_info,
|
||||
gint64 presentation_time);
|
||||
|
||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
||||
|
@ -2029,13 +2029,13 @@ do_send_frame_timings (MetaWindowActor *self,
|
||||
static void
|
||||
send_frame_timings (MetaWindowActor *self,
|
||||
FrameData *frame,
|
||||
CoglFrameInfo *frame_info,
|
||||
ClutterFrameInfo *frame_info,
|
||||
gint64 presentation_time)
|
||||
{
|
||||
float refresh_rate;
|
||||
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 */
|
||||
if (refresh_rate >= 1.0)
|
||||
refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
|
||||
@ -2046,9 +2046,9 @@ send_frame_timings (MetaWindowActor *self,
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
CoglFrameInfo *frame_info,
|
||||
gint64 presentation_time)
|
||||
meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
ClutterFrameInfo *frame_info,
|
||||
gint64 presentation_time)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
GList *l;
|
||||
@ -2060,7 +2060,7 @@ meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
{
|
||||
GList *l_next = l->next;
|
||||
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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user