From 86fb027bda56d5e7f6945e88ee7350129c1a2b4d Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Wed, 18 Oct 2023 17:41:10 +0300 Subject: [PATCH 1/9] Benchmark app frame time improvements. --- include/mbgl/map/map_observer.hpp | 3 +- include/mbgl/renderer/renderer_observer.hpp | 2 +- .../default/src/mbgl/map/map_snapshotter.cpp | 12 +++-- platform/ios/app/MBXViewController.m | 4 +- .../ios/benchmark/MBXBenchViewController.mm | 52 +++++++++++++------ platform/ios/src/MLNMapView+Impl.mm | 2 +- platform/ios/src/MLNMapView+Metal.mm | 2 +- platform/ios/src/MLNMapView+OpenGL.mm | 5 ++ platform/ios/src/MLNMapView.mm | 7 +-- platform/ios/src/MLNMapViewDelegate.h | 3 +- platform/ios/src/MLNMapView_Private.h | 3 +- .../MLNMapViewDelegateIntegrationTests.swift | 2 +- src/mbgl/map/map_impl.cpp | 5 +- src/mbgl/map/map_impl.hpp | 2 +- src/mbgl/renderer/renderer_impl.cpp | 8 ++- 15 files changed, 75 insertions(+), 37 deletions(-) diff --git a/include/mbgl/map/map_observer.hpp b/include/mbgl/map/map_observer.hpp index 0ebed53d1f0..6f29a0b2d68 100644 --- a/include/mbgl/map/map_observer.hpp +++ b/include/mbgl/map/map_observer.hpp @@ -42,7 +42,8 @@ class MapObserver { RenderMode mode; bool needsRepaint; // In continous mode, shows that there are ongoig transitions. bool placementChanged; - double frameTime; + double frameEncodingTime; + double frameRenderingTime; }; virtual void onCameraWillChange(CameraChangeMode) {} diff --git a/include/mbgl/renderer/renderer_observer.hpp b/include/mbgl/renderer/renderer_observer.hpp index 990c03081e2..99763bfd5d9 100644 --- a/include/mbgl/renderer/renderer_observer.hpp +++ b/include/mbgl/renderer/renderer_observer.hpp @@ -36,7 +36,7 @@ class RendererObserver { virtual void onDidFinishRenderingFrame(RenderMode, bool /*repaint*/, bool /*placementChanged*/) {} /// End of frame, booleans flags that a repaint is required and that placement changed. - virtual void onDidFinishRenderingFrame(RenderMode mode, bool repaint, bool placementChanged, double /*frameTime*/) { + virtual void onDidFinishRenderingFrame(RenderMode mode, bool repaint, bool placementChanged, double /*frameEncodingTime*/, double /*frameRenderingTime*/) { onDidFinishRenderingFrame(mode, repaint, placementChanged); } diff --git a/platform/default/src/mbgl/map/map_snapshotter.cpp b/platform/default/src/mbgl/map/map_snapshotter.cpp index eab4baa1ef1..039cdf5ec04 100644 --- a/platform/default/src/mbgl/map/map_snapshotter.cpp +++ b/platform/default/src/mbgl/map/map_snapshotter.cpp @@ -39,9 +39,10 @@ class ForwardingRendererObserver final : public RendererObserver { void onDidFinishRenderingFrame(RenderMode mode, bool repaintNeeded, bool placementChanged, - double frameTime) override { - void (RendererObserver::*f)(RenderMode, bool, bool, double) = &RendererObserver::onDidFinishRenderingFrame; - delegate.invoke(f, mode, repaintNeeded, placementChanged, frameTime); + double frameEncodingTime, + double frameRenderingTime) override { + void (RendererObserver::*f)(RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; + delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } void onStyleImageMissing(const std::string& image, const StyleImageMissingCallback& cb) override { @@ -84,11 +85,12 @@ class SnapshotterRenderer final : public RendererObserver { void onDidFinishRenderingFrame(RenderMode mode, bool repaintNeeded, bool placementChanged, - double frameTime) override { + double frameEncodingTime, + double frameRenderingTime) override { if (mode == RenderMode::Full && hasPendingStillImageRequest) { stillImage = frontend.readStillImage(); } - rendererObserver->onDidFinishRenderingFrame(mode, repaintNeeded, placementChanged, frameTime); + rendererObserver->onDidFinishRenderingFrame(mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } void onStyleImageMissing(const std::string& id, const StyleImageMissingCallback& done) override { diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 66b702c58a2..697c484f7d4 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -2451,9 +2451,9 @@ - (void)updateHUD { return features; } -- (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(BOOL)fullyRendered frameTime:(double)frameTime { +- (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(BOOL)fullyRendered frameEncodingTime:(double)frameEncodingTime frameRenderingTime:(double)frameRenderingTime { if (self.frameTimeGraphEnabled) { - [self.frameTimeGraphView updatePathWithFrameDuration:frameTime]; + [self.frameTimeGraphView updatePathWithFrameDuration:frameEncodingTime]; } } diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 43309d325c9..08c3f27d7b6 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -110,9 +110,11 @@ - (void)redirectLogToDocuments: (NSString*) fileName size_t idx = 0; enum class State { None, WaitingForAssets, WarmingUp, Benchmarking } state = State::None; int frames = 0; -double totalFrameTime = 0; +double totalFrameEncodingTime = 0; +double totalFrameRenderingTime = 0; std::chrono::steady_clock::time_point started; -std::vector > result; +std::vector > resultEncodingTime; +std::vector > resultRenderingTime; static const int warmupDuration = 20; // frames static const int benchmarkDuration = 200; // frames @@ -133,19 +135,31 @@ - (void)startBenchmarkIteration } else { // Do nothing. The benchmark is completed. NSLog(@"Benchmark completed."); - NSLog(@"Result:"); - double totalFrameTime = 0; + + NSLog(@"Result Encoding:"); size_t colWidth = 0; - for (const auto& row : result) { + for (const auto& row : resultEncodingTime) { colWidth = std::max(row.first.size(), colWidth); } - for (const auto& row : result) { + + double totalFrameEncodingTime = 0; + for (const auto& row : resultEncodingTime) { + NSLog(@"| %-*s | %4.1f ms | %4.1f fps |", int(colWidth), row.first.c_str(), 1e3 * row.second, 1.0 / row.second); + totalFrameEncodingTime += row.second; + } + + NSLog(@"Average frame encoding time: %4.1f ms", totalFrameEncodingTime * 1e3 / resultEncodingTime.size()); + NSLog(@"Average Encoding FPS: %4.1f", resultEncodingTime.size() / totalFrameEncodingTime); + + NSLog(@"Result Rendering:"); + double totalFrameRenderingTime = 0; + for (const auto& row : resultRenderingTime) { NSLog(@"| %-*s | %4.1f ms | %4.1f fps |", int(colWidth), row.first.c_str(), 1e3 * row.second, 1.0 / row.second); - totalFrameTime += row.second; + totalFrameRenderingTime += row.second; } - NSLog(@"Average frame time: %4.1f ms", totalFrameTime * 1e3 / result.size()); - NSLog(@"Average FPS: %4.1f", result.size() / totalFrameTime); + NSLog(@"Average frame rendering time: %4.1f ms", totalFrameRenderingTime * 1e3 / resultRenderingTime.size()); + NSLog(@"Average Rendering FPS: %4.1f", resultRenderingTime.size() / totalFrameRenderingTime); // NSLog(@"Total uploads: %zu", mbgl::uploadCount); // NSLog(@"Total uploads with dirty vattr: %zu", mbgl::uploadVertextAttrsDirty); @@ -174,12 +188,14 @@ - (void)startBenchmarkIteration - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(__unused BOOL)fullyRendered - frameTime:(double)frameTime + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime { if (state == State::Benchmarking) { frames++; - totalFrameTime += frameTime; + totalFrameEncodingTime += frameEncodingTime; + totalFrameRenderingTime += frameRenderingTime; if (frames >= benchmarkDuration) { state = State::None; @@ -187,10 +203,13 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView // Report FPS const auto duration = std::chrono::duration_cast(std::chrono::steady_clock::now() - started).count(); const auto wallClockFPS = double(frames * 1e6) / duration; - const auto frameTime = static_cast(totalFrameTime) / frames; - const auto potentialFPS = 1.0 / frameTime; - result.emplace_back(mbgl::bench::locations[idx].name, frameTime); - NSLog(@"- Frame time: %.1f ms, FPS: %.1f (%.1f sync FPS)", frameTime * 1e3, potentialFPS, wallClockFPS); + const auto frameEncodingTime = static_cast(totalFrameEncodingTime) / frames; + const auto frameRenderingTime = static_cast(totalFrameRenderingTime) / frames; + const auto potentialEncondingFPS = 1.0 / frameEncodingTime; + const auto potentialRenderingFPS = 1.0 / frameRenderingTime; + resultEncodingTime.emplace_back(mbgl::bench::locations[idx].name, frameEncodingTime); + resultRenderingTime.emplace_back(mbgl::bench::locations[idx].name, frameRenderingTime); + NSLog(@"- Frame encoding time: %.1f ms, Encoding FPS: %.1f | Frame rendering time: %.1f ms, Rendering FPS: %.1f (%.1f sync FPS)", frameEncodingTime * 1e3, potentialEncondingFPS, frameRenderingTime * 1e3, potentialRenderingFPS, wallClockFPS); // Start benchmarking the next location. idx++; @@ -207,7 +226,8 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView if (frames >= warmupDuration) { frames = 0; - totalFrameTime = 0; + totalFrameEncodingTime = 0; + totalFrameRenderingTime = 0; state = State::Benchmarking; started = std::chrono::steady_clock::now(); NSLog(@"- Benchmarking for %d frames...", benchmarkDuration); diff --git a/platform/ios/src/MLNMapView+Impl.mm b/platform/ios/src/MLNMapView+Impl.mm index 21d47a21cd7..901a542f714 100644 --- a/platform/ios/src/MLNMapView+Impl.mm +++ b/platform/ios/src/MLNMapView+Impl.mm @@ -81,7 +81,7 @@ void MLNMapViewImpl::onDidFinishRenderingFrame(mbgl::MapObserver::RenderFrameStatus status) { bool fullyRendered = status.mode == mbgl::MapObserver::RenderMode::Full; - [mapView mapViewDidFinishRenderingFrameFullyRendered:fullyRendered frameTime:status.frameTime]; + [mapView mapViewDidFinishRenderingFrameFullyRendered:fullyRendered frameEncodingTime:status.frameEncodingTime frameRenderingTime:status.frameRenderingTime]; } void MLNMapViewImpl::onWillStartRenderingMap() { diff --git a/platform/ios/src/MLNMapView+Metal.mm b/platform/ios/src/MLNMapView+Metal.mm index d8614c920b3..7e683906257 100644 --- a/platform/ios/src/MLNMapView+Metal.mm +++ b/platform/ios/src/MLNMapView+Metal.mm @@ -83,7 +83,7 @@ void swap() override { // Un-comment for synchronous, which can help troubleshoot rendering problems, // particularly those related to resource tracking and multiple queued buffers. - //[commandBuffer waitUntilCompleted]; + [commandBuffer waitUntilCompleted]; commandBuffer = nil; commandBufferPtr.reset(); diff --git a/platform/ios/src/MLNMapView+OpenGL.mm b/platform/ios/src/MLNMapView+OpenGL.mm index b8c4d008ec0..8ab98ee485a 100644 --- a/platform/ios/src/MLNMapView+OpenGL.mm +++ b/platform/ios/src/MLNMapView+OpenGL.mm @@ -2,6 +2,7 @@ #import "MLNLoggingConfiguration_Private.h" #import "MLNMapView+OpenGL.h" +#include #include #import @@ -48,6 +49,10 @@ CGFloat contentScaleFactor() { void bind() override { backend.restoreFramebufferBinding(); } + + void swap() override { + static_cast(backend.getContext()).finish(); + } mbgl::Size framebufferSize() { assert(glView); diff --git a/platform/ios/src/MLNMapView.mm b/platform/ios/src/MLNMapView.mm index 939c4db6a5c..ef0e4ff6fd7 100644 --- a/platform/ios/src/MLNMapView.mm +++ b/platform/ios/src/MLNMapView.mm @@ -6813,7 +6813,8 @@ - (void)mapViewWillStartRenderingFrame { } - (void)mapViewDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered - frameTime:(double)frameTime { + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime { if (!_mbglMap) { return; @@ -6825,9 +6826,9 @@ - (void)mapViewDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered [self.style didChangeValueForKey:@"layers"]; } - if ([self.delegate respondsToSelector:@selector(mapViewDidFinishRenderingFrame:fullyRendered:frameTime:)]) + if ([self.delegate respondsToSelector:@selector(mapViewDidFinishRenderingFrame:fullyRendered:frameEncodingTime:frameRenderingTime:)]) { - [self.delegate mapViewDidFinishRenderingFrame:self fullyRendered:fullyRendered frameTime:frameTime]; + [self.delegate mapViewDidFinishRenderingFrame:self fullyRendered:fullyRendered frameEncodingTime:frameEncodingTime frameRenderingTime:frameRenderingTime]; } else if ([self.delegate respondsToSelector:@selector(mapViewDidFinishRenderingFrame:fullyRendered:)]) { diff --git a/platform/ios/src/MLNMapViewDelegate.h b/platform/ios/src/MLNMapViewDelegate.h index 451cd06ccbf..ca48aab711e 100644 --- a/platform/ios/src/MLNMapViewDelegate.h +++ b/platform/ios/src/MLNMapViewDelegate.h @@ -254,7 +254,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView fullyRendered:(BOOL)fullyRendered - frameTime:(double)frameTime; + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime; /** Tells the delegate that the map view is entering an idle state, and no more diff --git a/platform/ios/src/MLNMapView_Private.h b/platform/ios/src/MLNMapView_Private.h index 90343b6df9a..de090836777 100644 --- a/platform/ios/src/MLNMapView_Private.h +++ b/platform/ios/src/MLNMapView_Private.h @@ -38,7 +38,8 @@ FOUNDATION_EXTERN MLN_EXPORT MLNExceptionName const _Nonnull MLNUnderlyingMapUna - (void)mapViewDidFailLoadingMapWithError:(nonnull NSError *)error; - (void)mapViewWillStartRenderingFrame; - (void)mapViewDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered - frameTime:(double)frameTime; + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime; - (void)mapViewWillStartRenderingMap; - (void)mapViewDidFinishRenderingMapFullyRendered:(BOOL)fullyRendered; - (void)mapViewDidBecomeIdle; diff --git a/platform/ios/test/MLNMapViewDelegateIntegrationTests.swift b/platform/ios/test/MLNMapViewDelegateIntegrationTests.swift index 4192598fb9e..3742db89fa7 100644 --- a/platform/ios/test/MLNMapViewDelegateIntegrationTests.swift +++ b/platform/ios/test/MLNMapViewDelegateIntegrationTests.swift @@ -61,7 +61,7 @@ extension MLNMapViewDelegateIntegrationTests: MLNMapViewDelegate { func mapViewDidFinishRenderingFrame(_ mapView: MLNMapView, fullyRendered: Bool) {} - func mapViewDidFinishRenderingFrame(_ mapView: MLNMapView, fullyRendered: Bool, frameTime: Double) {} + func mapViewDidFinishRenderingFrame(_ mapView: MLNMapView, fullyRendered: Bool, frameEncodingTime: Double, frameRenderingTime: Double) {} func mapView(_ mapView: MLNMapView, shapeAnnotationIsEnabled annotation: MLNShape) -> Bool { return false } diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index 9f901c3a505..c8863153d69 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -131,12 +131,13 @@ void Map::Impl::onWillStartRenderingFrame() { void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode, bool needsRepaint, bool placemenChanged, - double frameTime) { + double frameEncodingTime, + double frameRenderingTime) { rendererFullyLoaded = renderMode == RenderMode::Full; if (mode == MapMode::Continuous) { observer.onDidFinishRenderingFrame( - {MapObserver::RenderMode(renderMode), needsRepaint, placemenChanged, frameTime}); + {MapObserver::RenderMode(renderMode), needsRepaint, placemenChanged, frameEncodingTime, frameRenderingTime}); if (needsRepaint || transform.inTransition()) { onUpdate(); diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index 025d0f9d6f2..2d7794f5dad 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -45,7 +45,7 @@ class Map::Impl final : public style::Observer, public RendererObserver { void onInvalidate() final; void onResourceError(std::exception_ptr) final; void onWillStartRenderingFrame() final; - void onDidFinishRenderingFrame(RenderMode, bool, bool, double) final; + void onDidFinishRenderingFrame(RenderMode, bool, bool, double, double) final; void onWillStartRenderingMap() final; void onDidFinishRenderingMap() final; void onStyleImageMissing(const std::string&, const std::function&) final; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index ece37357228..e5410a98da6 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -382,16 +382,22 @@ void Renderer::Impl::render(const RenderTree& renderTree, // Ends the RenderPass parameters.renderPass.reset(); + + const auto startRendering = util::MonotonicTimer::now().count(); parameters.encoder->present(parameters.backend.getDefaultRenderable()); + const auto renderingTime = util::MonotonicTimer::now().count() - startRendering; // CommandEncoder destructor submits render commands. parameters.encoder.reset(); + + const auto encodingTime = renderTree.getElapsedTime() - renderingTime; observer->onDidFinishRenderingFrame( renderTreeParameters.loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial, renderTreeParameters.needsRepaint, renderTreeParameters.placementChanged, - renderTree.getElapsedTime()); + encodingTime, + renderingTime); if (!renderTreeParameters.loaded) { renderState = RenderState::Partial; From b31c123fe09e0a90ba4090fe80db9709775419a1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:41:57 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- include/mbgl/renderer/renderer_observer.hpp | 6 +++++- platform/default/src/mbgl/map/map_snapshotter.cpp | 6 ++++-- src/mbgl/map/map_impl.cpp | 7 +++++-- src/mbgl/renderer/renderer_impl.cpp | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/mbgl/renderer/renderer_observer.hpp b/include/mbgl/renderer/renderer_observer.hpp index 99763bfd5d9..29968d896ba 100644 --- a/include/mbgl/renderer/renderer_observer.hpp +++ b/include/mbgl/renderer/renderer_observer.hpp @@ -36,7 +36,11 @@ class RendererObserver { virtual void onDidFinishRenderingFrame(RenderMode, bool /*repaint*/, bool /*placementChanged*/) {} /// End of frame, booleans flags that a repaint is required and that placement changed. - virtual void onDidFinishRenderingFrame(RenderMode mode, bool repaint, bool placementChanged, double /*frameEncodingTime*/, double /*frameRenderingTime*/) { + virtual void onDidFinishRenderingFrame(RenderMode mode, + bool repaint, + bool placementChanged, + double /*frameEncodingTime*/, + double /*frameRenderingTime*/) { onDidFinishRenderingFrame(mode, repaint, placementChanged); } diff --git a/platform/default/src/mbgl/map/map_snapshotter.cpp b/platform/default/src/mbgl/map/map_snapshotter.cpp index 039cdf5ec04..56da5d787c4 100644 --- a/platform/default/src/mbgl/map/map_snapshotter.cpp +++ b/platform/default/src/mbgl/map/map_snapshotter.cpp @@ -41,7 +41,8 @@ class ForwardingRendererObserver final : public RendererObserver { bool placementChanged, double frameEncodingTime, double frameRenderingTime) override { - void (RendererObserver::*f)(RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; + void (RendererObserver::*f)( + RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } @@ -90,7 +91,8 @@ class SnapshotterRenderer final : public RendererObserver { if (mode == RenderMode::Full && hasPendingStillImageRequest) { stillImage = frontend.readStillImage(); } - rendererObserver->onDidFinishRenderingFrame(mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); + rendererObserver->onDidFinishRenderingFrame( + mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } void onStyleImageMissing(const std::string& id, const StyleImageMissingCallback& done) override { diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index c8863153d69..789adc8e3b8 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -136,8 +136,11 @@ void Map::Impl::onDidFinishRenderingFrame(RenderMode renderMode, rendererFullyLoaded = renderMode == RenderMode::Full; if (mode == MapMode::Continuous) { - observer.onDidFinishRenderingFrame( - {MapObserver::RenderMode(renderMode), needsRepaint, placemenChanged, frameEncodingTime, frameRenderingTime}); + observer.onDidFinishRenderingFrame({MapObserver::RenderMode(renderMode), + needsRepaint, + placemenChanged, + frameEncodingTime, + frameRenderingTime}); if (needsRepaint || transform.inTransition()) { onUpdate(); diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index e5410a98da6..e1f65a2b8da 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -382,14 +382,14 @@ void Renderer::Impl::render(const RenderTree& renderTree, // Ends the RenderPass parameters.renderPass.reset(); - + const auto startRendering = util::MonotonicTimer::now().count(); parameters.encoder->present(parameters.backend.getDefaultRenderable()); const auto renderingTime = util::MonotonicTimer::now().count() - startRendering; // CommandEncoder destructor submits render commands. parameters.encoder.reset(); - + const auto encodingTime = renderTree.getElapsedTime() - renderingTime; observer->onDidFinishRenderingFrame( From 3e632905406de0b60479b5e6546fca2443e93b96 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Wed, 18 Oct 2023 19:41:39 +0300 Subject: [PATCH 3/9] Removed the possible fps results. --- .../ios/benchmark/MBXBenchViewController.mm | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 08c3f27d7b6..10febe66db3 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -113,8 +113,7 @@ - (void)redirectLogToDocuments: (NSString*) fileName double totalFrameEncodingTime = 0; double totalFrameRenderingTime = 0; std::chrono::steady_clock::time_point started; -std::vector > resultEncodingTime; -std::vector > resultRenderingTime; +std::vector> > result; static const int warmupDuration = 20; // frames static const int benchmarkDuration = 200; // frames @@ -136,30 +135,22 @@ - (void)startBenchmarkIteration // Do nothing. The benchmark is completed. NSLog(@"Benchmark completed."); - NSLog(@"Result Encoding:"); + NSLog(@"Result:"); size_t colWidth = 0; - for (const auto& row : resultEncodingTime) { + for (const auto& row : result) { colWidth = std::max(row.first.size(), colWidth); } double totalFrameEncodingTime = 0; - for (const auto& row : resultEncodingTime) { - NSLog(@"| %-*s | %4.1f ms | %4.1f fps |", int(colWidth), row.first.c_str(), 1e3 * row.second, 1.0 / row.second); - totalFrameEncodingTime += row.second; - } - - NSLog(@"Average frame encoding time: %4.1f ms", totalFrameEncodingTime * 1e3 / resultEncodingTime.size()); - NSLog(@"Average Encoding FPS: %4.1f", resultEncodingTime.size() / totalFrameEncodingTime); - - NSLog(@"Result Rendering:"); double totalFrameRenderingTime = 0; - for (const auto& row : resultRenderingTime) { - NSLog(@"| %-*s | %4.1f ms | %4.1f fps |", int(colWidth), row.first.c_str(), 1e3 * row.second, 1.0 / row.second); - totalFrameRenderingTime += row.second; + for (const auto& row : result) { + NSLog(@"| %-*s | %4.1f ms | %4.1f ms |", int(colWidth), row.first.c_str(), 1e3 * row.second.first, 1e3 * row.second.second); + totalFrameEncodingTime += row.second.first; + totalFrameRenderingTime += row.second.second; } - NSLog(@"Average frame rendering time: %4.1f ms", totalFrameRenderingTime * 1e3 / resultRenderingTime.size()); - NSLog(@"Average Rendering FPS: %4.1f", resultRenderingTime.size() / totalFrameRenderingTime); + NSLog(@"Average frame encoding time: %4.1f ms", totalFrameEncodingTime * 1e3 / result.size()); + NSLog(@"Average frame rendering time: %4.1f ms", totalFrameRenderingTime * 1e3 / result.size()); // NSLog(@"Total uploads: %zu", mbgl::uploadCount); // NSLog(@"Total uploads with dirty vattr: %zu", mbgl::uploadVertextAttrsDirty); @@ -205,11 +196,8 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView const auto wallClockFPS = double(frames * 1e6) / duration; const auto frameEncodingTime = static_cast(totalFrameEncodingTime) / frames; const auto frameRenderingTime = static_cast(totalFrameRenderingTime) / frames; - const auto potentialEncondingFPS = 1.0 / frameEncodingTime; - const auto potentialRenderingFPS = 1.0 / frameRenderingTime; - resultEncodingTime.emplace_back(mbgl::bench::locations[idx].name, frameEncodingTime); - resultRenderingTime.emplace_back(mbgl::bench::locations[idx].name, frameRenderingTime); - NSLog(@"- Frame encoding time: %.1f ms, Encoding FPS: %.1f | Frame rendering time: %.1f ms, Rendering FPS: %.1f (%.1f sync FPS)", frameEncodingTime * 1e3, potentialEncondingFPS, frameRenderingTime * 1e3, potentialRenderingFPS, wallClockFPS); + result.emplace_back(mbgl::bench::locations[idx].name, std::make_pair(frameEncodingTime, frameRenderingTime)); + NSLog(@"- Frame encoding time: %.1f ms, Frame rendering time: %.1f ms (%.1f sync FPS)", frameEncodingTime * 1e3, frameRenderingTime * 1e3, wallClockFPS); // Start benchmarking the next location. idx++; From 07069bcb4023c459f05d31c20dffd88a3188738e Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Mon, 23 Oct 2023 21:51:45 +0300 Subject: [PATCH 4/9] Subsctracted bind drawable waiting time. --- platform/ios/benchmark/MBXBenchViewController.mm | 12 +++++++++--- src/mbgl/renderer/renderer_impl.cpp | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 10febe66db3..ef6211bfb34 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -203,7 +203,9 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView idx++; [self startBenchmarkIteration]; } else { - [mapView setNeedsRerender]; + dispatch_async(dispatch_get_main_queue(), ^{ + [mapView setNeedsRerender]; + }); } return; } @@ -220,7 +222,9 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView started = std::chrono::steady_clock::now(); NSLog(@"- Benchmarking for %d frames...", benchmarkDuration); } - [mapView setNeedsRerender]; + dispatch_async(dispatch_get_main_queue(), ^{ + [mapView setNeedsRerender]; + }); return; } @@ -232,7 +236,9 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView state = State::WarmingUp; [self.mapView didReceiveMemoryWarning]; NSLog(@"- Warming up for %d frames...", warmupDuration); - [mapView setNeedsRerender]; + dispatch_async(dispatch_get_main_queue(), ^{ + [mapView setNeedsRerender]; + }); } return; } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index e1f65a2b8da..9e6b03b39e5 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -358,7 +358,9 @@ void Renderer::Impl::render(const RenderTree& renderTree, drawable3DPass(); } drawableTargetsPass(); + const auto startClear = util::MonotonicTimer::now().count(); commonClearPass(); + const auto clearTime = util::MonotonicTimer::now().count() - startClear; drawableOpaquePass(); drawableTranslucentPass(); drawableDebugOverlays(); @@ -390,7 +392,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, // CommandEncoder destructor submits render commands. parameters.encoder.reset(); - const auto encodingTime = renderTree.getElapsedTime() - renderingTime; + const auto encodingTime = renderTree.getElapsedTime() - clearTime - renderingTime; observer->onDidFinishRenderingFrame( renderTreeParameters.loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial, From d34151c37d649b71842608dd497a41f814df71cf Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 2 Nov 2023 20:46:07 +0100 Subject: [PATCH 5/9] Refactored benchmark app to use headless frontend for an accurate measurement of the frame time. --- platform/BUILD.bazel | 2 +- .../include/mbgl/gfx/headless_frontend.hpp | 5 +- .../src/mbgl/gfx/headless_frontend.cpp | 42 +++-- platform/ios/benchmark/BUILD.bazel | 4 +- ...chAppDelegate.m => MBXBenchAppDelegate.mm} | 0 .../ios/benchmark/MBXBenchViewController.mm | 177 +++++++++++++----- platform/ios/benchmark/{main.m => main.mm} | 0 platform/ios/src/MLNMapView+Metal.mm | 2 +- platform/ios/src/MLNMapView+OpenGL.mm | 5 - src/mbgl/renderer/renderer_impl.cpp | 4 +- 10 files changed, 169 insertions(+), 72 deletions(-) rename platform/ios/benchmark/{MBXBenchAppDelegate.m => MBXBenchAppDelegate.mm} (100%) rename platform/ios/benchmark/{main.m => main.mm} (100%) diff --git a/platform/BUILD.bazel b/platform/BUILD.bazel index 71ae8fe7976..284e461d7b3 100644 --- a/platform/BUILD.bazel +++ b/platform/BUILD.bazel @@ -232,7 +232,7 @@ objc_library( objc_library( name = "ios-benchapp", - copts = MAPLIBRE_FLAGS, + copts = CPP_FLAGS + MAPLIBRE_FLAGS, srcs = ["//platform/ios/benchmark:ios_benchmark_srcs"], hdrs = ["//platform/ios/benchmark:ios_benchmark_hdrs"], includes = [ diff --git a/platform/default/include/mbgl/gfx/headless_frontend.hpp b/platform/default/include/mbgl/gfx/headless_frontend.hpp index 1e1f1c14030..ff961ffc1d1 100644 --- a/platform/default/include/mbgl/gfx/headless_frontend.hpp +++ b/platform/default/include/mbgl/gfx/headless_frontend.hpp @@ -31,7 +31,8 @@ class HeadlessFrontend : public RendererFrontend { float pixelRatio_, gfx::HeadlessBackend::SwapBehaviour swapBehavior = gfx::HeadlessBackend::SwapBehaviour::NoFlush, gfx::ContextMode mode = gfx::ContextMode::Unique, - const std::optional& localFontFamily = std::nullopt); + const std::optional& localFontFamily = std::nullopt, + bool invalidateOnUpdate_ = true); ~HeadlessFrontend() override; void reset() override; @@ -56,6 +57,7 @@ class HeadlessFrontend : public RendererFrontend { PremultipliedImage readStillImage(); RenderResult render(Map&); void renderOnce(Map&); + void renderFrame(); std::optional getTransformState() const; @@ -66,6 +68,7 @@ class HeadlessFrontend : public RendererFrontend { std::atomic frameTime; std::unique_ptr backend; util::AsyncTask asyncInvalidate; + bool invalidateOnUpdate; std::unique_ptr renderer; std::shared_ptr updateParameters; diff --git a/platform/default/src/mbgl/gfx/headless_frontend.cpp b/platform/default/src/mbgl/gfx/headless_frontend.cpp index a2a03a5e625..9d9834a5683 100644 --- a/platform/default/src/mbgl/gfx/headless_frontend.cpp +++ b/platform/default/src/mbgl/gfx/headless_frontend.cpp @@ -21,7 +21,8 @@ HeadlessFrontend::HeadlessFrontend(Size size_, float pixelRatio_, gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode, - const std::optional& localFontFamily) + const std::optional& localFontFamily, + bool invalidateOnUpdate_) : size(size_), pixelRatio(pixelRatio_), frameTime(0), @@ -30,22 +31,9 @@ HeadlessFrontend::HeadlessFrontend(Size size_, swapBehavior, contextMode)), asyncInvalidate([this] { - if (renderer && updateParameters) { - auto startTime = mbgl::util::MonotonicTimer::now(); - gfx::BackendScope guard{*getBackend()}; - - // onStyleImageMissing might be called during a render. The user - // implemented method could trigger a call to - // MLNRenderFrontend#update which overwrites `updateParameters`. - // Copy the shared pointer here so that the parameters aren't - // destroyed while `render(...)` is still using them. - auto updateParameters_ = updateParameters; - renderer->render(updateParameters_); - - auto endTime = mbgl::util::MonotonicTimer::now(); - frameTime = (endTime - startTime).count(); - } + renderFrame(); }), + invalidateOnUpdate(invalidateOnUpdate_), renderer(std::make_unique(*getBackend(), pixelRatio, localFontFamily)) {} HeadlessFrontend::~HeadlessFrontend() = default; @@ -57,7 +45,9 @@ void HeadlessFrontend::reset() { void HeadlessFrontend::update(std::shared_ptr updateParameters_) { updateParameters = updateParameters_; - asyncInvalidate.send(); + if (invalidateOnUpdate) { + asyncInvalidate.send(); + } } void HeadlessFrontend::setObserver(RendererObserver& observer_) { @@ -169,6 +159,24 @@ void HeadlessFrontend::renderOnce(Map&) { util::RunLoop::Get()->runOnce(); } +void HeadlessFrontend::renderFrame() { + if (renderer && updateParameters) { + auto startTime = mbgl::util::MonotonicTimer::now(); + gfx::BackendScope guard{*getBackend()}; + + // onStyleImageMissing might be called during a render. The user + // implemented method could trigger a call to + // MLNRenderFrontend#update which overwrites `updateParameters`. + // Copy the shared pointer here so that the parameters aren't + // destroyed while `render(...)` is still using them. + auto updateParameters_ = updateParameters; + renderer->render(updateParameters_); + + auto endTime = mbgl::util::MonotonicTimer::now(); + frameTime = (endTime - startTime).count(); + } +} + std::optional HeadlessFrontend::getTransformState() const { if (updateParameters) { return updateParameters->transformState; diff --git a/platform/ios/benchmark/BUILD.bazel b/platform/ios/benchmark/BUILD.bazel index 5094e7566a6..af5d09d07bb 100644 --- a/platform/ios/benchmark/BUILD.bazel +++ b/platform/ios/benchmark/BUILD.bazel @@ -3,8 +3,8 @@ load("//platform/ios/bazel:macros.bzl", "info_plist") filegroup( name = "ios_benchmark_srcs", srcs = [ - "main.m", - "MBXBenchAppDelegate.m", + "main.mm", + "MBXBenchAppDelegate.mm", "MBXBenchViewController.mm", "locations.cpp", ], diff --git a/platform/ios/benchmark/MBXBenchAppDelegate.m b/platform/ios/benchmark/MBXBenchAppDelegate.mm similarity index 100% rename from platform/ios/benchmark/MBXBenchAppDelegate.m rename to platform/ios/benchmark/MBXBenchAppDelegate.mm diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index ef6211bfb34..0b0b7414c9d 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -1,15 +1,52 @@ #import "MBXBenchViewController.h" #import "MBXBenchAppDelegate.h" #import "MLNMapView_Private.h" -#import "MLNMapViewDelegate.h" +#import "MLNOfflineStorage_Private.h" +#import "MLNSettings_Private.h" #include "locations.hpp" #include -@interface MBXBenchViewController () +#include +#include +#include +#include -@property (nonatomic) MLNMapView *mapView; +@protocol BenchMapDelegate +- (void)mapDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime; +@end + + +class BenchMapObserver : public mbgl::MapObserver { +public: + BenchMapObserver() = delete; + BenchMapObserver(id mapDelegate_) : mapDelegate(mapDelegate_) {} + virtual ~BenchMapObserver() = default; + + void onDidFinishRenderingFrame(RenderFrameStatus status) override final { + //NSLog(@"Frame encoding time: %4.1f ms", status.frameEncodingTime * 1e3); + //NSLog(@"Frame rendering time: %4.1f ms", status.frameRenderingTime * 1e3); + + bool fullyRendered = status.mode == mbgl::MapObserver::RenderMode::Full; + [mapDelegate mapDidFinishRenderingFrameFullyRendered:fullyRendered + frameEncodingTime:status.frameEncodingTime + frameRenderingTime:status.frameRenderingTime]; + } + +protected: + __weak id mapDelegate = nullptr; +}; + +@interface MBXBenchViewController () { + std::unique_ptr observer; + std::unique_ptr frontend; + std::unique_ptr map; +} + +@property (nonatomic) UIImageView *imageView; @end @@ -32,6 +69,15 @@ + (void)initialize - (void)viewDidLoad { [super viewDidLoad]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + #ifdef LOG_TO_DOCUMENTS_DIR + [self setAndRedirectLogFileToDocuments]; + #endif // Use a local style and local assets if they’ve been downloaded. NSURL *tile = [[NSBundle mainBundle] URLForResource:@"11" withExtension:@"pbf" subdirectory:@"tiles/tiles/v3/5/7"]; @@ -42,28 +88,50 @@ - (void)viewDidLoad constexpr auto styleIndex = 0; NSURL *url = [NSURL URLWithString:tile ? @"asset://styles/streets.json" : [NSString stringWithCString:styles[styleIndex].c_str() encoding:NSUTF8StringEncoding]]; NSLog(@"Using style URL: \"%@\"", [url absoluteString]); - - self.mapView = [[MLNMapView alloc] initWithFrame:self.view.bounds styleURL:url]; - self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.mapView.delegate = self; - self.mapView.opaque = YES; - self.mapView.zoomEnabled = NO; - self.mapView.scrollEnabled = NO; - self.mapView.rotateEnabled = NO; - self.mapView.userInteractionEnabled = YES; - self.mapView.preferredFramesPerSecond = MLNMapViewPreferredFramesPerSecondMaximum; - - [self.view addSubview:self.mapView]; -} -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; + self.imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view addSubview:self.imageView]; + + mbgl::Size viewSize = { static_cast(self.view.bounds.size.width), + static_cast(self.view.bounds.size.height) }; + auto pixelRatio = [[UIScreen mainScreen] scale]; + + observer = std::make_unique(self); + frontend = std::make_unique( + viewSize, + pixelRatio, + mbgl::gfx::HeadlessBackend::SwapBehaviour::Flush, + mbgl::gfx::ContextMode::Unique, + /* localFontFamily */ std::nullopt, + /* invalidateOnUpdate */ false + ); + + mbgl::MapOptions mapOptions; + mapOptions.withMapMode(mbgl::MapMode::Continuous) + .withSize(viewSize) + .withPixelRatio(pixelRatio) + .withConstrainMode(mbgl::ConstrainMode::None) + .withViewportMode(mbgl::ViewportMode::Default) + .withCrossSourceCollisions(true); + + mbgl::TileServerOptions* tileServerOptions = [[MLNSettings sharedSettings] tileServerOptionsInternal]; + mbgl::ResourceOptions resourceOptions; + resourceOptions.withCachePath(MLNOfflineStorage.sharedOfflineStorage.databasePath.UTF8String) + .withAssetPath([NSBundle mainBundle].resourceURL.path.UTF8String) + .withTileServerOptions(*tileServerOptions); + mbgl::ClientOptions clientOptions; + + auto apiKey = [[MLNSettings sharedSettings] apiKey]; + if (apiKey) { + resourceOptions.withApiKey([apiKey UTF8String]); + } + + map = std::make_unique(*frontend, *observer, mapOptions, resourceOptions, clientOptions); + map->setSize(viewSize); + map->setDebug(mbgl::MapDebugOptions::NoDebug); + map->getStyle().loadURL([url.absoluteString UTF8String]); - #ifdef LOG_TO_DOCUMENTS_DIR - [self setAndRedirectLogFileToDocuments]; - #endif - [self startBenchmarkIteration]; } @@ -122,15 +190,48 @@ - (void)redirectLogToDocuments: (NSString*) fileName extern std::size_t uploadCount, uploadBuildCount, uploadVertextAttrsDirty, uploadInvalidSegments; } +- (void)renderFrame +{ + frontend->renderFrame(); + + auto image = frontend->readStillImage(); + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef bitmapContext = CGBitmapContextCreate( + image.data.get(), + image.size.width, + image.size.height, + 8, + 4 * image.size.width, + colorSpace, + kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault + ); + CFRelease(colorSpace); + CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); + CGContextRelease(bitmapContext); + + self.imageView.image = [UIImage imageWithCGImage:cgImage]; + CGImageRelease(cgImage); +} + - (void)startBenchmarkIteration { if (mbgl::bench::locations.size() > idx) { const auto& location = mbgl::bench::locations[idx]; - [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(location.latitude, location.longitude) zoomLevel:location.zoom animated:NO]; - self.mapView.direction = location.bearing; + + mbgl::CameraOptions cameraOptions; + cameraOptions.center = mbgl::LatLng(location.latitude, location.longitude); + cameraOptions.zoom = location.zoom; + cameraOptions.bearing = location.bearing; + map->jumpTo(cameraOptions); + state = State::WaitingForAssets; NSLog(@"Benchmarking \"%s\"", location.name.c_str()); NSLog(@"- Loading assets..."); + + dispatch_async(dispatch_get_main_queue(), ^{ + [self renderFrame]; + }); } else { // Do nothing. The benchmark is completed. NSLog(@"Benchmark completed."); @@ -170,17 +271,12 @@ - (void)startBenchmarkIteration { [app performSelector:@selector(suspend)]; } - else if ([app respondsToSelector:@selector(terminate)]) - { - [app performSelector:@selector(terminate)]; - } } } -- (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView - fullyRendered:(__unused BOOL)fullyRendered - frameEncodingTime:(double)frameEncodingTime - frameRenderingTime:(double)frameRenderingTime +- (void)mapDidFinishRenderingFrameFullyRendered:(__unused BOOL)fullyRendered + frameEncodingTime:(double)frameEncodingTime + frameRenderingTime:(double)frameRenderingTime { if (state == State::Benchmarking) { @@ -204,12 +300,11 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView [self startBenchmarkIteration]; } else { dispatch_async(dispatch_get_main_queue(), ^{ - [mapView setNeedsRerender]; + [self renderFrame]; }); } return; } - else if (state == State::WarmingUp) { frames++; @@ -223,23 +318,21 @@ - (void)mapViewDidFinishRenderingFrame:(MLNMapView *)mapView NSLog(@"- Benchmarking for %d frames...", benchmarkDuration); } dispatch_async(dispatch_get_main_queue(), ^{ - [mapView setNeedsRerender]; + [self renderFrame]; }); return; } - else if (state == State::WaitingForAssets) { - if ([mapView isFullyLoaded]) + if (map->isFullyLoaded()) { // Start the benchmarking timer. state = State::WarmingUp; - [self.mapView didReceiveMemoryWarning]; NSLog(@"- Warming up for %d frames...", warmupDuration); - dispatch_async(dispatch_get_main_queue(), ^{ - [mapView setNeedsRerender]; - }); } + dispatch_async(dispatch_get_main_queue(), ^{ + [self renderFrame]; + }); return; } } diff --git a/platform/ios/benchmark/main.m b/platform/ios/benchmark/main.mm similarity index 100% rename from platform/ios/benchmark/main.m rename to platform/ios/benchmark/main.mm diff --git a/platform/ios/src/MLNMapView+Metal.mm b/platform/ios/src/MLNMapView+Metal.mm index ebd548c3945..c9635b6df00 100644 --- a/platform/ios/src/MLNMapView+Metal.mm +++ b/platform/ios/src/MLNMapView+Metal.mm @@ -82,7 +82,7 @@ void swap() override { // Un-comment for synchronous, which can help troubleshoot rendering problems, // particularly those related to resource tracking and multiple queued buffers. - [commandBuffer waitUntilCompleted]; + //[commandBuffer waitUntilCompleted]; commandBuffer = nil; commandBufferPtr.reset(); diff --git a/platform/ios/src/MLNMapView+OpenGL.mm b/platform/ios/src/MLNMapView+OpenGL.mm index 8ab98ee485a..b8c4d008ec0 100644 --- a/platform/ios/src/MLNMapView+OpenGL.mm +++ b/platform/ios/src/MLNMapView+OpenGL.mm @@ -2,7 +2,6 @@ #import "MLNLoggingConfiguration_Private.h" #import "MLNMapView+OpenGL.h" -#include #include #import @@ -49,10 +48,6 @@ CGFloat contentScaleFactor() { void bind() override { backend.restoreFramebufferBinding(); } - - void swap() override { - static_cast(backend.getContext()).finish(); - } mbgl::Size framebufferSize() { assert(glView); diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 9e6b03b39e5..e1f65a2b8da 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -358,9 +358,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, drawable3DPass(); } drawableTargetsPass(); - const auto startClear = util::MonotonicTimer::now().count(); commonClearPass(); - const auto clearTime = util::MonotonicTimer::now().count() - startClear; drawableOpaquePass(); drawableTranslucentPass(); drawableDebugOverlays(); @@ -392,7 +390,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, // CommandEncoder destructor submits render commands. parameters.encoder.reset(); - const auto encodingTime = renderTree.getElapsedTime() - clearTime - renderingTime; + const auto encodingTime = renderTree.getElapsedTime() - renderingTime; observer->onDidFinishRenderingFrame( renderTreeParameters.loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial, From 204c16d1d96ebe5f0f86b0347b8086e83a174838 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:47:26 +0000 Subject: [PATCH 6/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- platform/default/src/mbgl/gfx/headless_frontend.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/default/src/mbgl/gfx/headless_frontend.cpp b/platform/default/src/mbgl/gfx/headless_frontend.cpp index 9d9834a5683..8efe4cb5bab 100644 --- a/platform/default/src/mbgl/gfx/headless_frontend.cpp +++ b/platform/default/src/mbgl/gfx/headless_frontend.cpp @@ -30,9 +30,7 @@ HeadlessFrontend::HeadlessFrontend(Size size_, {static_cast(size.width * pixelRatio), static_cast(size.height * pixelRatio)}, swapBehavior, contextMode)), - asyncInvalidate([this] { - renderFrame(); - }), + asyncInvalidate([this] { renderFrame(); }), invalidateOnUpdate(invalidateOnUpdate_), renderer(std::make_unique(*getBackend(), pixelRatio, localFontFamily)) {} From e4132bfc3808c3bca2669617526e61c81f053709 Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 2 Nov 2023 20:58:23 +0100 Subject: [PATCH 7/9] Fixed qt platform. --- platform/qt/src/utils/renderer_observer.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/qt/src/utils/renderer_observer.hpp b/platform/qt/src/utils/renderer_observer.hpp index 785c3ce8a06..f226910fbe2 100644 --- a/platform/qt/src/utils/renderer_observer.hpp +++ b/platform/qt/src/utils/renderer_observer.hpp @@ -33,10 +33,11 @@ class RendererObserver : public mbgl::RendererObserver { void onDidFinishRenderingFrame(RenderMode mode, bool repaintNeeded, bool placementChanged, - double frameTime) override { + double frameEncodingTime, + double frameRenderingTime) override { void (mbgl::RendererObserver::*f)( - RenderMode, bool, bool, double) = &mbgl::RendererObserver::onDidFinishRenderingFrame; - delegate.invoke(f, mode, repaintNeeded, placementChanged, frameTime); + RenderMode, bool, bool, double, double) = &mbgl::RendererObserver::onDidFinishRenderingFrame; + delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } void onDidFinishRenderingMap() final { delegate.invoke(&mbgl::RendererObserver::onDidFinishRenderingMap); } From f81597f72123314214c59200a69bbc4329e7d19e Mon Sep 17 00:00:00 2001 From: Alex Cristici Date: Thu, 2 Nov 2023 21:26:17 +0100 Subject: [PATCH 8/9] Fixed Android platform and OpenGL rendering. --- .../src/cpp/android_renderer_frontend.cpp | 7 ++++--- platform/ios/benchmark/MBXBenchViewController.mm | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp index 840e4404aac..9df86bc3fd5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp @@ -34,9 +34,10 @@ class ForwardingRendererObserver : public RendererObserver { void onDidFinishRenderingFrame(RenderMode mode, bool repaintNeeded, bool placementChanged, - double frameTime) override { - void (RendererObserver::*f)(RenderMode, bool, bool, double) = &RendererObserver::onDidFinishRenderingFrame; - delegate.invoke(f, mode, repaintNeeded, placementChanged, frameTime); + double frameEncodingTime, + double frameRenderingTime) override { + void (RendererObserver::*f)(RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; + delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); } void onDidFinishRenderingMap() override { delegate.invoke(&RendererObserver::onDidFinishRenderingMap); } diff --git a/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/benchmark/MBXBenchViewController.mm index 0b0b7414c9d..b01be05c24f 100644 --- a/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/benchmark/MBXBenchViewController.mm @@ -192,6 +192,8 @@ - (void)redirectLogToDocuments: (NSString*) fileName - (void)renderFrame { + mbgl::gfx::BackendScope guard{*(frontend->getBackend())}; + frontend->renderFrame(); auto image = frontend->readStillImage(); From 54776e14107a3f117205c1d1ac49b82e8144e859 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:26:40 +0000 Subject: [PATCH 9/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp index 9df86bc3fd5..481e8122151 100644 --- a/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp +++ b/platform/android/MapboxGLAndroidSDK/src/cpp/android_renderer_frontend.cpp @@ -36,7 +36,8 @@ class ForwardingRendererObserver : public RendererObserver { bool placementChanged, double frameEncodingTime, double frameRenderingTime) override { - void (RendererObserver::*f)(RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; + void (RendererObserver::*f)( + RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame; delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime); }