diff options
author | Owen W. Taylor <otaylor@fishsoup.net> | 2012-11-12 14:11:08 -0500 |
---|---|---|
committer | Owen W. Taylor <otaylor@fishsoup.net> | 2013-01-30 15:47:52 -0500 |
commit | 3ae070720d6227f0b99afd52a16072856a5a8e80 (patch) | |
tree | e06e12b7a969f92e122f463916b3a8710662ce60 /src/compositor/compositor.c | |
parent | 4b332640ebc7432a23010488e7a100de71100c7f (diff) | |
download | mutter-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.c | 44 |
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; |