From 6f33547d757fb1394d1e643cdc226ae30b2edbc6 Mon Sep 17 00:00:00 2001 From: Gali Nelle Date: Sun, 9 Feb 2020 17:09:01 +0200 Subject: Add tracing entry points in the rendering pipeline This also includes a default tracing implementation that does not require hooking into a platform instrumentation, but simply stores timestamps into an array that can be dumped into a json file. Among possible use cases, dumping such metrics to file in CI to detect regressions of specific stages of the pipeline. --- CMakeLists.txt | 2 + include/mbgl/perf/runtime_metrics.hpp | 201 +++++++++++++++++++++ include/mbgl/perf/trace_data.in | 34 ++++ include/mbgl/util/chrono.hpp | 5 + platform/glfw/glfw_renderer_frontend.cpp | 11 +- platform/glfw/glfw_renderer_frontend.hpp | 2 + platform/glfw/glfw_view.cpp | 17 ++ src/mbgl/gl/render_custom_layer.cpp | 3 + .../renderer/layers/render_background_layer.cpp | 4 +- src/mbgl/renderer/layers/render_circle_layer.cpp | 4 +- .../layers/render_fill_extrusion_layer.cpp | 4 +- src/mbgl/renderer/layers/render_fill_layer.cpp | 3 + src/mbgl/renderer/layers/render_heatmap_layer.cpp | 4 +- .../renderer/layers/render_hillshade_layer.cpp | 5 +- src/mbgl/renderer/layers/render_line_layer.cpp | 4 +- src/mbgl/renderer/layers/render_raster_layer.cpp | 3 + src/mbgl/renderer/layers/render_symbol_layer.cpp | 4 +- src/mbgl/renderer/render_orchestrator.cpp | 7 +- src/mbgl/renderer/renderer.cpp | 13 +- src/mbgl/renderer/renderer_impl.cpp | 27 +++ src/mbgl/renderer/sources/render_image_source.cpp | 4 +- src/mbgl/renderer/sources/render_tile_source.cpp | 3 + 22 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 include/mbgl/perf/runtime_metrics.hpp create mode 100644 include/mbgl/perf/trace_data.in diff --git a/CMakeLists.txt b/CMakeLists.txt index e16dd9da05..bf1838c8dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -262,6 +262,8 @@ add_library( ${PROJECT_SOURCE_DIR}/include/mbgl/util/work_request.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/util/work_task.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/util/work_task_impl.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/perf/runtime_metrics.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/perf/trace_data.in ${PROJECT_SOURCE_DIR}/src/csscolorparser/csscolorparser.cpp ${PROJECT_SOURCE_DIR}/src/csscolorparser/csscolorparser.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/actor/mailbox.cpp diff --git a/include/mbgl/perf/runtime_metrics.hpp b/include/mbgl/perf/runtime_metrics.hpp new file mode 100644 index 0000000000..73c2c7cf46 --- /dev/null +++ b/include/mbgl/perf/runtime_metrics.hpp @@ -0,0 +1,201 @@ +#pragma once + +#define MBGL_COLLECT_RUNTIME_METRICS + +#ifndef MBGL_COLLECT_RUNTIME_METRICS +#define MBGL_TRACE_RENDERER_BEGIN(range, ...) +#define MBGL_TRACE_RENDERER_END(range, ...) +#define MBGL_TRACE_RENDERER_BEGINRECORD(range, ...) +#define MBGL_TRACE_RENDERER_ENDRECORD(range, ...) +#define MBGL_IF_TRACING(x) +#else +#include +#include +#include +#include + +#define MBGL_IF_TRACING(x) x + +//#define MBGL_TRACER_USE_MUTEX +#ifndef MBGL_TRACER_USE_MUTEX +#define LOCK_RENDERER(t) +#define UNLOCK_RENDERER(t) +#define RENDERER_LOCKER() +#else +#define LOCK_RENDERER(t) t.frame_mutex.lock(); +#define UNLOCK_RENDERER(t) t.frame_mutex.unlock(); +#define RENDERER_LOCKER() std::unique_lock locker(frame_mutex); +#endif + +// First argument intended to be rangeName +#define RANGE_NAME(X, ...) X +#define MBGL_TRACE_RENDERER_BEGIN(...) { \ + mbgl::util::Tracer &t = mbgl::util::Tracer::get(); \ + LOCK_RENDERER(t); \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).scope = t.currentScope; \ + t.currentScope += 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).begin = mbgl::util::Tracer::nanoseconds(); \ + UNLOCK_RENDERER(t); \ + } +#define MBGL_TRACE_RENDERER_END(...) { \ + mbgl::util::Tracer &t = mbgl::util::Tracer::get(); \ + LOCK_RENDERER(t); \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).end = mbgl::util::Tracer::nanoseconds(); \ + t.currentScope -= 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).totalCalls += 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).totalMs += t.frameTrace.RANGE_NAME(__VA_ARGS__).end - t.frameTrace.RANGE_NAME(__VA_ARGS__).begin; \ + UNLOCK_RENDERER(t); \ + } +#define MBGL_TRACE_RENDERER_BEGINRECORD(...) { \ + mbgl::util::Tracer &t = mbgl::util::Tracer::get(); \ + LOCK_RENDERER(t); \ + t.frameTraceReset(t.frameTrace); \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).scope = t.currentScope; \ + t.currentScope += 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).begin = mbgl::util::Tracer::nanoseconds(); \ + UNLOCK_RENDERER(t); \ + } +#define MBGL_TRACE_RENDERER_ENDRECORD(...) { \ + mbgl::util::Tracer &t = mbgl::util::Tracer::get(); \ + LOCK_RENDERER(t); \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).end = mbgl::util::Tracer::nanoseconds(); \ + t.currentScope -= 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).totalCalls += 1; \ + t.frameTrace.RANGE_NAME(__VA_ARGS__).totalMs += t.frameTrace.RANGE_NAME(__VA_ARGS__).end - t.frameTrace.RANGE_NAME(__VA_ARGS__).begin; \ + if (t.collectData) t.frameList.push_back(t.frameTrace); \ + UNLOCK_RENDERER(t); } + +#define MBGL_TRACE_APPSTART(...) { mbgl::util::Tracer::get().appStart = mbgl::util::Tracer::nanoseconds(); } + +#define NS2MS(x) ((x) * 0.000001) + +namespace mbgl { +namespace util { + +struct TraceInterval { + unsigned char scope = 0; // overwritten by each range + uint64_t begin = 0u; // overwritten by each range + uint64_t end = 0u; // overwritten by each range + uint64_t totalMs = 0u; + uint64_t totalCalls = 0u; +}; + +#define STRUCT_BEGIN(name) struct name { +#define STRUCT_END() }; +#define STRUCT_MEMBER_UINT64_RANGE(name, store_range, store_counter) TraceInterval name; +#include +#undef STRUCT_BEGIN +#undef STRUCT_END +#undef STRUCT_MEMBER_UINT64_RANGE + +// Instrumentation-less tracing implementation, possibly requiring mutexing +class Tracer +{ +public: + static uint64_t nanoseconds() { + return Clock::now().time_since_epoch().count(); + } + static Tracer& get() { + static Tracer i; // Guaranteed to be destroyed. + // Instantiated on first use. + return i; + } +private: + Tracer() {} + +public: + Tracer(Tracer const&) = delete; + void operator=(Tracer const&) = delete; + bool collectData = false; + + + std::mutex frame_mutex; + std::vector frameList; + mbgl::util::FrameTrace frameTrace; + unsigned int currentScope = 0u; + unsigned int appStart = 0u; + +/* frameTraceReset */ +#define STRUCT_BEGIN(name) static void frameTraceReset(name &data) { data = name(); // clear it by assigning to a new struct +#define STRUCT_END() }; +#define STRUCT_MEMBER_UINT64_RANGE(name, store_range, store_counter) +#include +#undef STRUCT_BEGIN +#undef STRUCT_END +#undef STRUCT_MEMBER_UINT64_RANGE + +/* framesToJson */ +#define STRUCT_BEGIN(name) \ +static std::string frameToJson(const name &data) { \ + std::string res; \ + res += "{\n"; +// The following assumes that one of { store_range, store_counter } is true. +#define STRUCT_MEMBER_UINT64_RANGE(name, store_range, store_counter) \ +res += std::string("\"") + std::string(#name) + std::string("\" : { "); \ +if (store_range) { \ + res += std::string("\"scope\" : ") + std::to_string(data.name.scope) + std::string(" , ") \ + + std::string("\"begin\" : ") + std::to_string(data.name.begin) + std::string(" , ") \ + + std::string("\"end\" : ") + std::to_string(data.name.end); } \ +if (store_counter) { if (store_range) res += std::string(","); \ + res += std::string("\"totalMs\" : ") + std::to_string(data.name.totalMs) + std::string(" , ") \ + + std::string("\"totalCalls\" : ") + std::to_string(data.name.totalCalls); \ +} \ +res += std::string(" },"); +#define STRUCT_END() \ + res.pop_back(); res += "}"; \ + return res; \ +}; +#include +#undef STRUCT_BEGIN +#undef STRUCT_END +#undef STRUCT_MEMBER_UINT64_RANGE + + inline bool isCollectingData() const { + return collectData; + } + inline void setCollectData(bool enabled) { + collectData = enabled; + } + + inline std::string framesJson(bool steal = false) const { + LOCK_RENDERER(*this); + std::vector frameList_; + if (steal) + frameList_ = std::move(frameList); + else + frameList_ = frameList; + UNLOCK_RENDERER(*this); + + std::string res; + res += "[\n"; + for (const auto &f: frameList) + res += frameToJson(f) + std::string(","); + res.pop_back(); + res += "]\n"; + return res; + } + + inline std::string dumpAll(bool steal = false) const { + std::string res; + res += "{\n"; + // meta + res += "\"global\": {\n"; + + res += "}\n"; + + // frames + res += ", \"frames\": "; + res += framesJson(steal); + + res += "}\n"; + return res; + } + + inline void clearFrames() { + RENDERER_LOCKER(); + frameList.clear(); + } +}; +} // namespace util +} // namespace mbgl +#endif diff --git a/include/mbgl/perf/trace_data.in b/include/mbgl/perf/trace_data.in new file mode 100644 index 0000000000..b2288fa9e7 --- /dev/null +++ b/include/mbgl/perf/trace_data.in @@ -0,0 +1,34 @@ +STRUCT_BEGIN(FrameTrace) + +STRUCT_MEMBER_UINT64_RANGE(update, true, false) // Before attaching render target +STRUCT_MEMBER_UINT64_RANGE(attach, true, false) +STRUCT_MEMBER_UINT64_RANGE(render, true, false) +STRUCT_MEMBER_UINT64_RANGE(orchestrate, true, false) // Before orchestration +STRUCT_MEMBER_UINT64_RANGE(prepare, true, false) // Before prepare -- This and below are not present IF (!isMapModeContinuous && !renderTreeParameters->loaded) +STRUCT_MEMBER_UINT64_RANGE(renderimpl, true, false) // Before Impl::render +STRUCT_MEMBER_UINT64_RANGE(waitrenderable, true, false) // Before wait on renderable +STRUCT_MEMBER_UINT64_RANGE(upload, true, false) // Before UPLOAD PASS +STRUCT_MEMBER_UINT64_RANGE(draw, true, false) +STRUCT_MEMBER_UINT64_RANGE(extrusions, true, false) // Before 3D pass (extrusions) +STRUCT_MEMBER_UINT64_RANGE(clear, true, false) // 1st draw stage +STRUCT_MEMBER_UINT64_RANGE(opaque, true, false) // 2 opaque should only have layer render items +STRUCT_MEMBER_UINT64_RANGE(translucent, true, false) // 3 same here +STRUCT_MEMBER_UINT64_RANGE(debug, true, false) // 4 debug only renders sourceRenderItems +STRUCT_MEMBER_UINT64_RANGE(flushencoder, true, false) // 5 --- + +STRUCT_MEMBER_UINT64_RANGE(imagesourcerenderdata, false, true) +STRUCT_MEMBER_UINT64_RANGE(layerrenderitem, false, true) +STRUCT_MEMBER_UINT64_RANGE(tilesourcerenderitem, false, true) + +STRUCT_MEMBER_UINT64_RANGE(fill_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(extrusion_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(line_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(circle_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(heatmap_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(background_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(raster_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(symbol_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(hillshade_layer, false, true) +STRUCT_MEMBER_UINT64_RANGE(custom_layer, false, true) + +STRUCT_END() diff --git a/include/mbgl/util/chrono.hpp b/include/mbgl/util/chrono.hpp index 723cd131e3..2b16e74b32 100644 --- a/include/mbgl/util/chrono.hpp +++ b/include/mbgl/util/chrono.hpp @@ -9,6 +9,7 @@ using Clock = std::chrono::steady_clock; using Seconds = std::chrono::seconds; using Milliseconds = std::chrono::milliseconds; +using Nanoseconds = std::chrono::nanoseconds; using TimePoint = Clock::time_point; using Duration = Clock::duration; @@ -22,6 +23,10 @@ inline Timestamp now() { return std::chrono::time_point_cast(std::chrono::system_clock::now()); } +inline uint64_t now_ns() { + return Clock::now().time_since_epoch().count(); +} + // Returns the RFC1123 formatted date. E.g. "Tue, 04 Nov 2014 02:13:24 GMT" std::string rfc1123(Timestamp); diff --git a/platform/glfw/glfw_renderer_frontend.cpp b/platform/glfw/glfw_renderer_frontend.cpp index 46f1309901..0c180985b8 100644 --- a/platform/glfw/glfw_renderer_frontend.cpp +++ b/platform/glfw/glfw_renderer_frontend.cpp @@ -2,6 +2,7 @@ #include #include +#include GLFWRendererFrontend::GLFWRendererFrontend(std::unique_ptr renderer_, GLFWView& glfwView_) : glfwView(glfwView_) @@ -30,7 +31,8 @@ void GLFWRendererFrontend::render() { assert(renderer); if (!updateParameters) return; - + MBGL_TRACE_RENDERER_BEGINRECORD(update); + MBGL_TRACE_RENDERER_BEGIN(attach); mbgl::gfx::BackendScope guard { glfwView.getRendererBackend(), mbgl::gfx::BackendScope::ScopeType::Implicit }; // onStyleImageMissing might be called during a render. The user implemented method @@ -38,10 +40,17 @@ void GLFWRendererFrontend::render() { // Copy the shared pointer here so that the parameters aren't destroyed while `render(...)` is // still using them. auto updateParameters_ = updateParameters; + MBGL_TRACE_RENDERER_END(attach); renderer->render(updateParameters_); + MBGL_TRACE_RENDERER_ENDRECORD(update); } mbgl::Renderer* GLFWRendererFrontend::getRenderer() { assert(renderer); return renderer.get(); } + +void GLFWRendererFrontend::setRecordFrame(bool enabled) +{ + recordFrames = enabled; +} diff --git a/platform/glfw/glfw_renderer_frontend.hpp b/platform/glfw/glfw_renderer_frontend.hpp index c992fe20fe..966f30d69a 100644 --- a/platform/glfw/glfw_renderer_frontend.hpp +++ b/platform/glfw/glfw_renderer_frontend.hpp @@ -21,9 +21,11 @@ public: void render(); mbgl::Renderer* getRenderer(); + void setRecordFrame(bool enabled); private: GLFWView& glfwView; std::unique_ptr renderer; std::shared_ptr updateParameters; + bool recordFrames = false; }; diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 3d10f2c654..1c042983aa 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -23,11 +23,16 @@ #include #include #include +#include #include #include #include +#include +#include +#include + #if MBGL_USE_GLES2 #define GLFW_INCLUDE_ES2 #endif // MBGL_USE_GLES2 @@ -234,6 +239,18 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, case GLFW_KEY_K: view->addRandomCustomPointAnnotations(1); break; + case GLFW_KEY_H: + MBGL_IF_TRACING(if (mbgl::util::Tracer::get().isCollectingData()) { \ + mbgl::util::Tracer::get().setCollectData(false); \ + std::string json = mbgl::util::Tracer::get().dumpAll(true); \ + printf("%s\n", json.c_str()); \ + std::ofstream out("/tmp/mbgl_glfw_trace.json"); \ + out << json; \ + out.close(); \ + } else { \ + mbgl::util::Tracer::get().setCollectData(true); \ + }) + break; case GLFW_KEY_L: view->addRandomLineAnnotations(1); break; diff --git a/src/mbgl/gl/render_custom_layer.cpp b/src/mbgl/gl/render_custom_layer.cpp index bb12ec1fcf..a41c5a499b 100644 --- a/src/mbgl/gl/render_custom_layer.cpp +++ b/src/mbgl/gl/render_custom_layer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace mbgl { @@ -59,6 +60,7 @@ void RenderCustomLayer::prepare(const LayerPrepareParameters&) { } void RenderCustomLayer::render(PaintParameters& paintParameters) { + MBGL_TRACE_RENDERER_BEGIN(custom_layer); if (host != impl(baseImpl).host) { //If the context changed, deinitialize the previous one before initializing the new one. if (host && !contextDestroyed) { @@ -99,6 +101,7 @@ void RenderCustomLayer::render(PaintParameters& paintParameters) { // the viewport or Framebuffer. paintParameters.backend.getDefaultRenderable().getResource().bind(); glContext.setDirtyState(); + MBGL_TRACE_RENDERER_END(custom_layer); } } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 694addcc97..bea7b1fa6f 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace mbgl { @@ -65,7 +66,7 @@ bool RenderBackgroundLayer::hasCrossfade() const { void RenderBackgroundLayer::render(PaintParameters& parameters) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. - + MBGL_TRACE_RENDERER_BEGIN(background_layer); const Properties<>::PossiblyEvaluated properties; const BackgroundProgram::Binders paintAttributeData(properties, 0); @@ -152,6 +153,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters) { ); } } + MBGL_TRACE_RENDERER_END(background_layer); } optional RenderBackgroundLayer::getSolidBackground() const { diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index b88a026e11..c870c34b0b 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace mbgl { @@ -63,7 +64,7 @@ void RenderCircleLayer::render(PaintParameters& parameters) { if (parameters.pass == RenderPass::Opaque) { return; } - + MBGL_TRACE_RENDERER_BEGIN(circle_layer); for (const RenderTile& tile : *renderTiles) { const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass); if (!renderData) { @@ -122,6 +123,7 @@ void RenderCircleLayer::render(PaintParameters& parameters) { getID() ); } + MBGL_TRACE_RENDERER_END(circle_layer); } GeometryCoordinate projectPoint(const GeometryCoordinate& p, const mat4& posMatrix, const Size& size) { diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index af0bc788d0..df3bab4d92 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace mbgl { @@ -71,7 +72,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) { if (parameters.pass != RenderPass::Translucent) { return; } - + MBGL_TRACE_RENDERER_BEGIN(extrusion_layer); const auto& evaluated = static_cast(*evaluatedProperties).evaluated; const auto& crossfade = static_cast(*evaluatedProperties).crossfade; if (evaluatedProperties->renderPasses == mbgl::underlying_type(RenderPass::None)) { @@ -224,6 +225,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) { // to prevent the second draw in cases where we have coincident polygons. drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass(), "color"); } + MBGL_TRACE_RENDERER_END(extrusion_layer); } bool RenderFillExtrusionLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeometry, diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index bbfcef7aba..788415cc16 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace mbgl { @@ -75,6 +76,7 @@ bool RenderFillLayer::hasCrossfade() const { void RenderFillLayer::render(PaintParameters& parameters) { assert(renderTiles); + MBGL_TRACE_RENDERER_BEGIN(fill_layer); if (unevaluated.get().isUndefined()) { parameters.renderTileClippingMasks(renderTiles); for (const RenderTile& tile : *renderTiles) { @@ -248,6 +250,7 @@ void RenderFillLayer::render(PaintParameters& parameters) { } } } + MBGL_TRACE_RENDERER_END(fill_layer); } bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeometry, diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 797aedd297..8a4f53463f 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace mbgl { @@ -72,7 +73,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters) { if (parameters.pass == RenderPass::Opaque) { return; } - + MBGL_TRACE_RENDERER_BEGIN(heatmap_layer); if (parameters.pass == RenderPass::Pass3D) { const auto& viewportSize = parameters.staticData.backendSize; const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; @@ -196,6 +197,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters) { getID() ); } + MBGL_TRACE_RENDERER_END(heatmap_layer); } void RenderHeatmapLayer::updateColorRamp() { diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index b570d9c4c9..5549072319 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace mbgl { @@ -79,6 +80,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) { assert(renderTiles); if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return; + MBGL_TRACE_RENDERER_BEGIN(hillshade_layer); const auto& evaluated = static_cast(*evaluatedProperties).evaluated; auto draw = [&] (const mat4& matrix, const auto& vertexBuffer, @@ -221,9 +223,8 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) { }); } } - - } + MBGL_TRACE_RENDERER_END(hillshade_layer); } } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 588cf6286c..7e0f2a89a7 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace mbgl { @@ -95,7 +96,7 @@ void RenderLineLayer::render(PaintParameters& parameters) { if (parameters.pass == RenderPass::Opaque) { return; } - + MBGL_TRACE_RENDERER_BEGIN(line_layer); parameters.renderTileClippingMasks(renderTiles); for (const RenderTile& tile : *renderTiles) { @@ -217,6 +218,7 @@ void RenderLineLayer::render(PaintParameters& parameters) { LineProgram::TextureBindings{}); } } + MBGL_TRACE_RENDERER_END(line_layer); } namespace { diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index 8a1a8a6c28..79cca99903 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace mbgl { @@ -90,6 +91,7 @@ void RenderRasterLayer::render(PaintParameters& parameters) { if (parameters.pass != RenderPass::Translucent || (!renderTiles && !imageData)) { return; } + MBGL_TRACE_RENDERER_BEGIN(raster_layer); const auto& evaluated = static_cast(*evaluatedProperties).evaluated; RasterProgram::Binders paintAttributeData{ evaluated, 0 }; @@ -199,6 +201,7 @@ void RenderRasterLayer::render(PaintParameters& parameters) { } } } + MBGL_TRACE_RENDERER_END(raster_layer); } } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 17376fd864..d41e76fb28 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -345,7 +346,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { if (parameters.pass == RenderPass::Opaque) { return; } - + MBGL_TRACE_RENDERER_BEGIN(symbol_layer); const bool sortFeaturesByKey = !impl(baseImpl).layout.get().isUndefined(); std::multiset renderableSegments; @@ -540,6 +541,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters) { } } } + MBGL_TRACE_RENDERER_END(symbol_layer); } // static diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index c771bd100b..6b002eb22b 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace mbgl { @@ -49,7 +50,11 @@ public: private: bool hasRenderPass(RenderPass pass) const override { return layer.get().hasRenderPass(pass); } void upload(gfx::UploadPass& pass) const override { layer.get().upload(pass); } - void render(PaintParameters& parameters) const override { layer.get().render(parameters); } + void render(PaintParameters& parameters) const override { + MBGL_TRACE_RENDERER_BEGIN(layerrenderitem); + layer.get().render(parameters); + MBGL_TRACE_RENDERER_END(layerrenderitem); + } const std::string& getName() const override { return layer.get().getID(); } uint32_t index; diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index 5afbbbd47e..af507ba823 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace mbgl { @@ -25,12 +26,22 @@ void Renderer::setObserver(RendererObserver* observer) { impl->orchestrator.setObserver(observer); } -void Renderer::render(const std::shared_ptr& updateParameters) { +void Renderer::render(const std::shared_ptr& updateParameters) { // ToDo: Change th assert(updateParameters); + MBGL_TRACE_RENDERER_BEGIN(render); + MBGL_TRACE_RENDERER_BEGIN(orchestrate); if (auto renderTree = impl->orchestrator.createRenderTree(updateParameters)) { + MBGL_TRACE_RENDERER_END(orchestrate) + MBGL_TRACE_RENDERER_BEGIN(prepare); renderTree->prepare(); + MBGL_TRACE_RENDERER_END(prepare) + MBGL_TRACE_RENDERER_BEGIN(renderimpl) impl->render(*renderTree); + MBGL_TRACE_RENDERER_END(renderimpl) + } else { + MBGL_TRACE_RENDERER_END(orchestrate) } + MBGL_TRACE_RENDERER_END(render); } std::vector Renderer::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const { diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 113840d059..a06b9bd435 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace mbgl { @@ -43,6 +44,8 @@ void Renderer::Impl::setObserver(RendererObserver* observer_) { } void Renderer::Impl::render(const RenderTree& renderTree) { + MBGL_TRACE_RENDERER_BEGIN(waitrenderable); + if (renderState == RenderState::Never) { observer->onWillStartRenderingMap(); } @@ -79,6 +82,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { const auto& sourceRenderItems = renderTree.getSourceRenderItems(); const auto& layerRenderItems = renderTree.getLayerRenderItems(); + MBGL_TRACE_RENDERER_END(waitrenderable); + MBGL_TRACE_RENDERER_BEGIN(upload); + // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { @@ -96,6 +102,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) { renderTree.getPatternAtlas().upload(*uploadPass); } + MBGL_TRACE_RENDERER_END(upload) + MBGL_TRACE_RENDERER_BEGIN(draw); + MBGL_TRACE_RENDERER_BEGIN(extrusions); + // - 3D PASS ------------------------------------------------------------------------------------- // Renders any 3D layers bottom-to-top to unique FBOs with texture attachments, but share the same // depth rbo between them. @@ -123,6 +133,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } + MBGL_TRACE_RENDERER_END(extrusions) + MBGL_TRACE_RENDERER_BEGIN(clear); + // - CLEAR ------------------------------------------------------------------------------------- // Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any // tiles whatsoever. @@ -136,6 +149,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { parameters.renderPass = parameters.encoder->createRenderPass("main buffer", { parameters.backend.getDefaultRenderable(), color, 1, 0 }); } + MBGL_TRACE_RENDERER_END(clear) + MBGL_TRACE_RENDERER_BEGIN(opaque); + // Actually render the layers parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; @@ -157,6 +173,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } + MBGL_TRACE_RENDERER_END(opaque) + MBGL_TRACE_RENDERER_BEGIN(translucent); + // - TRANSLUCENT PASS -------------------------------------------------------------------------- // Make a second pass, rendering translucent objects. This time, we render bottom-to-top. { @@ -174,6 +193,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } + MBGL_TRACE_RENDERER_END(translucent) + MBGL_TRACE_RENDERER_BEGIN(debug); + // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { @@ -188,6 +210,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } + MBGL_TRACE_RENDERER_END(debug) + MBGL_TRACE_RENDERER_BEGIN(flushencoder); + #if not defined(NDEBUG) if (parameters.debugOptions & MapDebugOptions::StencilClip) { // Render tile clip boundaries, using stencil buffer to calculate fill color. @@ -220,6 +245,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) { renderState = RenderState::Fully; observer->onDidFinishRenderingMap(); } + MBGL_TRACE_RENDERER_END(flushencoder) + MBGL_TRACE_RENDERER_END(draw) } void Renderer::Impl::reduceMemoryUse() { diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 6d197df9db..d00f2794a3 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace mbgl { @@ -29,7 +30,7 @@ void ImageSourceRenderData::render(PaintParameters& parameters) const { if (!bucket || !(parameters.debugOptions & MapDebugOptions::TileBorders)) { return; } - + MBGL_TRACE_RENDERER_BEGIN(imagesourcerenderdata); static const style::Properties<>::PossiblyEvaluated properties {}; static const DebugProgram::Binders paintAttributeData(properties, 0); @@ -64,6 +65,7 @@ void ImageSourceRenderData::render(PaintParameters& parameters) const { "image" ); } + MBGL_TRACE_RENDERER_END(imagesourcerenderdata); } RenderImageSource::RenderImageSource(Immutable impl_) diff --git a/src/mbgl/renderer/sources/render_tile_source.cpp b/src/mbgl/renderer/sources/render_tile_source.cpp index 221f976c50..d02752aea5 100644 --- a/src/mbgl/renderer/sources/render_tile_source.cpp +++ b/src/mbgl/renderer/sources/render_tile_source.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace mbgl { @@ -37,9 +38,11 @@ void TileSourceRenderItem::upload(gfx::UploadPass& parameters) const { } void TileSourceRenderItem::render(PaintParameters& parameters) const { + MBGL_TRACE_RENDERER_BEGIN(tilesourcerenderitem); for (auto& tile : *renderTiles) { tile.finishRender(parameters); } + MBGL_TRACE_RENDERER_END(tilesourcerenderitem); } RenderTileSource::RenderTileSource(Immutable impl_) -- cgit v1.2.1