From a793b4eef58842173c15d3c9ad1c32f00e3fb0cb Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 23 Jun 2020 18:03:54 +0800 Subject: [PATCH] cogl: Add new 'sync-{primitive,frame}' options for COGL_DEBUG This allows profilers to trace the callers of whatever is spending the most time on the GPU, and to measure render times more accurately. Previously such information was hidden as it completed in the background (asynchronously) after we call swap buffers. Part-of: --- cogl/cogl/cogl-debug-options.h | 13 +++++++++++++ cogl/cogl/cogl-debug.c | 4 +++- cogl/cogl/cogl-debug.h | 2 ++ cogl/cogl/cogl-journal.c | 11 +++++++++-- cogl/cogl/cogl-onscreen.c | 6 ++++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cogl/cogl/cogl-debug-options.h b/cogl/cogl/cogl-debug-options.h index 25c70d766..8450becd1 100644 --- a/cogl/cogl/cogl-debug-options.h +++ b/cogl/cogl/cogl-debug-options.h @@ -171,3 +171,16 @@ OPT (PERFORMANCE, "performance", N_("Trace performance concerns"), N_("Tries to highlight sub-optimal Cogl usage.")) +OPT (SYNC_PRIMITIVE, + N_("Root Cause"), + "sync-primitive", + N_("Render primitives synchronously"), + N_("Call glFinish after rendering each primitive, so profilers can see " + "the call stack of what's incurring most of the render time.")) +OPT (SYNC_FRAME, + N_("Root Cause"), + "sync-frame", + N_("Render frames synchronously"), + N_("Call glFinish after rendering each frame, so profilers can measure " + "the total render time (as a portion of the stage update time) more " + "accurately.")) diff --git a/cogl/cogl/cogl-debug.c b/cogl/cogl/cogl-debug.c index 3898ee125..800f448df 100644 --- a/cogl/cogl/cogl-debug.c +++ b/cogl/cogl/cogl-debug.c @@ -80,7 +80,9 @@ static const GDebugKey cogl_behavioural_debug_keys[] = { { "wireframe", COGL_DEBUG_WIREFRAME}, { "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP}, { "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES}, - { "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL} + { "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL}, + { "sync-primitive", COGL_DEBUG_SYNC_PRIMITIVE }, + { "sync-frame", COGL_DEBUG_SYNC_FRAME}, }; static const int n_cogl_behavioural_debug_keys = G_N_ELEMENTS (cogl_behavioural_debug_keys); diff --git a/cogl/cogl/cogl-debug.h b/cogl/cogl/cogl-debug.h index 82a572b9c..d6bc358b5 100644 --- a/cogl/cogl/cogl-debug.h +++ b/cogl/cogl/cogl-debug.h @@ -71,6 +71,8 @@ typedef enum COGL_DEBUG_CLIPPING, COGL_DEBUG_WINSYS, COGL_DEBUG_PERFORMANCE, + COGL_DEBUG_SYNC_PRIMITIVE, + COGL_DEBUG_SYNC_FRAME, COGL_DEBUG_N_FLAGS } CoglDebugFlags; diff --git a/cogl/cogl/cogl-journal.c b/cogl/cogl/cogl-journal.c index b567530bd..4949232d3 100644 --- a/cogl/cogl/cogl-journal.c +++ b/cogl/cogl/cogl-journal.c @@ -1629,8 +1629,15 @@ _cogl_journal_log_quad (CoglJournal *journal, add_framebuffer_deps_cb, framebuffer); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING))) - _cogl_journal_flush (journal); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_PRIMITIVE))) + { + _cogl_journal_flush (journal); + cogl_framebuffer_finish (framebuffer); + } + else if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING))) + { + _cogl_journal_flush (journal); + } COGL_TIMER_STOP (_cogl_uprof_context, log_timer); } diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index 651f3a727..f6d21cf06 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -315,6 +315,9 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, _cogl_framebuffer_flush_journal (framebuffer); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) + cogl_framebuffer_finish (framebuffer); + winsys = _cogl_framebuffer_get_winsys (framebuffer); winsys->onscreen_swap_buffers_with_damage (onscreen, rectangles, n_rectangles, @@ -364,6 +367,9 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, _cogl_framebuffer_flush_journal (framebuffer); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) + cogl_framebuffer_finish (framebuffer); + winsys = _cogl_framebuffer_get_winsys (framebuffer); /* This should only be called if the winsys advertises