summaryrefslogtreecommitdiff
path: root/src/compositor/compositor.c
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2012-11-12 14:11:08 -0500
committerOwen W. Taylor <otaylor@fishsoup.net>2013-01-30 15:47:52 -0500
commit3ae070720d6227f0b99afd52a16072856a5a8e80 (patch)
treee06e12b7a969f92e122f463916b3a8710662ce60 /src/compositor/compositor.c
parent4b332640ebc7432a23010488e7a100de71100c7f (diff)
downloadmutter-3ae070720d6227f0b99afd52a16072856a5a8e80.tar.gz
Send _NET_WM_FRAME_TIMINGS messages
We previously had timestamp information stubbed out in _NET_WM_FRAME_DRAWN. Instead of this, add a high-resolution timestamp in _NET_WM_FRAME_DRAWN then send a _NET_WM_FRAME_TIMINGS message after when we have complete frame timing information, representing the "presentation time" of the frame as an offset from the timestamp in _NET_WM_FRAME_DRAWN. To provide maximum space in the messages,_NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS are not done as WM_PROTOCOLS messages but have their own message types. https://bugzilla.gnome.org/show_bug.cgi?id=685463
Diffstat (limited to 'src/compositor/compositor.c')
-rw-r--r--src/compositor/compositor.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 6174e4262..aacbbc30f 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -550,7 +550,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
G_CALLBACK (after_stage_paint), info);
/* Wait 6-ms after vblank before starting to draw next frame */
- clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), 2);
+ clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY);
meta_screen_get_size (screen, &width, &height);
clutter_actor_realize (info->stage);
@@ -1206,12 +1206,54 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
}
static void
+frame_callback (CoglOnscreen *onscreen,
+ CoglFrameEvent event,
+ CoglFrameInfo *frame_info,
+ void *user_data)
+{
+ MetaCompScreen *info = 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;
+
+ if (presentation_time_cogl != 0)
+ {
+ CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
+ gint64 current_time_cogl = cogl_get_clock_time (context);
+ gint64 now = g_get_monotonic_time ();
+
+ presentation_time =
+ now + (presentation_time_cogl - current_time_cogl) / 1000;
+ }
+ else
+ {
+ presentation_time = 0;
+ }
+
+ for (l = info->windows; l; l = l->next)
+ meta_window_actor_frame_complete (l->data, frame_info, presentation_time);
+ }
+}
+
+static void
pre_paint_windows (MetaCompScreen *info)
{
GList *l;
MetaWindowActor *top_window;
MetaWindowActor *expected_unredirected_window = NULL;
+ if (info->onscreen == NULL)
+ {
+ info->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ());
+ info->frame_closure = cogl_onscreen_add_frame_callback (info->onscreen,
+ frame_callback,
+ info,
+ NULL);
+ }
+
if (info->windows == NULL)
return;