diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 2fe6bd10e..124f24cbd 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -254,6 +254,7 @@ swap_framebuffer (ClutterStageWindow *stage_window, ClutterStageCoglPrivate *priv = _clutter_stage_cogl_get_instance_private (stage_cogl); CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); clutter_stage_view_before_swap_buffer (view, swap_region); @@ -276,7 +277,8 @@ swap_framebuffer (ClutterStageWindow *stage_window, damage[i * 4 + 3] = rect.height; } - frame_info = cogl_frame_info_new (priv->global_frame_counter); + frame_info = + cogl_frame_info_new (cogl_context, priv->global_frame_counter); priv->global_frame_counter++; /* push on the screen */ @@ -688,6 +690,7 @@ clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl, ClutterStageCoglPrivate *priv = _clutter_stage_cogl_get_instance_private (stage_cogl); CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); CoglOnscreen *onscreen; CoglFrameInfo *frame_info; @@ -695,7 +698,7 @@ clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl, onscreen = COGL_ONSCREEN (framebuffer); - frame_info = cogl_frame_info_new (priv->global_frame_counter); + frame_info = cogl_frame_info_new (cogl_context, priv->global_frame_counter); if (!cogl_onscreen_direct_scanout (onscreen, scanout, @@ -748,9 +751,10 @@ clutter_stage_cogl_add_onscreen_frame_info (ClutterStageCogl *stage_cogl, ClutterStageCoglPrivate *priv = _clutter_stage_cogl_get_instance_private (stage_cogl); CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); + CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); CoglFrameInfo *frame_info; - frame_info = cogl_frame_info_new (priv->global_frame_counter); + frame_info = cogl_frame_info_new (cogl_context, priv->global_frame_counter); priv->global_frame_counter++; cogl_onscreen_add_frame_info (COGL_ONSCREEN (framebuffer), frame_info); diff --git a/cogl/cogl/cogl-frame-info-private.h b/cogl/cogl/cogl-frame-info-private.h index 81904f7a4..2a59288d1 100644 --- a/cogl/cogl/cogl-frame-info-private.h +++ b/cogl/cogl/cogl-frame-info-private.h @@ -33,6 +33,7 @@ #include "cogl-frame-info.h" #include "cogl-object-private.h" +#include "cogl-context.h" typedef enum _CoglFrameInfoFlag { @@ -62,6 +63,8 @@ struct _CoglFrameInfo { CoglObject _parent; + CoglContext *context; + int64_t frame_counter; int64_t presentation_time_us; /* CLOCK_MONOTONIC */ float refresh_rate; @@ -71,9 +74,14 @@ struct _CoglFrameInfo CoglFrameInfoFlag flags; unsigned int sequence; + + CoglTimestampQuery *timestamp_query; + int64_t gpu_time_before_buffer_swap_ns; + int64_t cpu_time_before_buffer_swap_us; }; COGL_EXPORT -CoglFrameInfo *cogl_frame_info_new (int64_t global_frame_counter); +CoglFrameInfo *cogl_frame_info_new (CoglContext *context, + int64_t global_frame_counter); #endif /* __COGL_FRAME_INFO_PRIVATE_H */ diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c index a31d91689..867740d97 100644 --- a/cogl/cogl/cogl-frame-info.c +++ b/cogl/cogl/cogl-frame-info.c @@ -32,6 +32,7 @@ #include "cogl-frame-info-private.h" #include "cogl-gtype-private.h" +#include "cogl-context-private.h" static void _cogl_frame_info_free (CoglFrameInfo *info); @@ -39,11 +40,13 @@ COGL_OBJECT_DEFINE (FrameInfo, frame_info); COGL_GTYPE_DEFINE_CLASS (FrameInfo, frame_info); CoglFrameInfo * -cogl_frame_info_new (int64_t global_frame_counter) +cogl_frame_info_new (CoglContext *context, + int64_t global_frame_counter) { CoglFrameInfo *info; info = g_new0 (CoglFrameInfo, 1); + info->context = context; info->global_frame_counter = global_frame_counter; return _cogl_frame_info_object_new (info); @@ -52,6 +55,9 @@ cogl_frame_info_new (int64_t global_frame_counter) static void _cogl_frame_info_free (CoglFrameInfo *info) { + if (info->timestamp_query) + cogl_context_free_timestamp_query (info->context, info->timestamp_query); + g_free (info); } @@ -114,3 +120,24 @@ cogl_frame_info_get_sequence (CoglFrameInfo *info) return info->sequence; } + +int64_t +cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info) +{ + int64_t gpu_time_rendering_done_ns; + + if (!info->timestamp_query) + return 0; + + gpu_time_rendering_done_ns = + cogl_context_timestamp_query_get_time_ns (info->context, + info->timestamp_query); + + return gpu_time_rendering_done_ns - info->gpu_time_before_buffer_swap_ns; +} + +int64_t +cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info) +{ + return info->cpu_time_before_buffer_swap_us; +} diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h index 7278a08ca..c0ff12bc1 100644 --- a/cogl/cogl/cogl-frame-info.h +++ b/cogl/cogl/cogl-frame-info.h @@ -150,6 +150,12 @@ gboolean cogl_frame_info_is_vsync (CoglFrameInfo *info); COGL_EXPORT unsigned int cogl_frame_info_get_sequence (CoglFrameInfo *info); +COGL_EXPORT +int64_t cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info); + +COGL_EXPORT +int64_t cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info); + G_END_DECLS #endif /* __COGL_FRAME_INFO_H */ diff --git a/src/backends/x11/nested/meta-stage-x11-nested.c b/src/backends/x11/nested/meta-stage-x11-nested.c index 7a6c14a09..b16486706 100644 --- a/src/backends/x11/nested/meta-stage-x11-nested.c +++ b/src/backends/x11/nested/meta-stage-x11-nested.c @@ -168,6 +168,7 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window, MetaRenderer *renderer = meta_backend_get_renderer (backend); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); + CoglContext *context = cogl_framebuffer_get_context (onscreen); GList *l; CoglFrameInfo *frame_info; @@ -195,7 +196,7 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window, draw_view (stage_nested, renderer_view, texture); } - frame_info = cogl_frame_info_new (0); + frame_info = cogl_frame_info_new (context, 0); cogl_onscreen_swap_buffers (stage_x11->onscreen, frame_info, frame); if (!clutter_frame_has_result (frame))