diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/android/core-files.json | 1 | ||||
-rw-r--r-- | platform/default/include/mbgl/gfx/headless_backend.hpp | 10 | ||||
-rw-r--r-- | platform/default/include/mbgl/gfx/headless_frontend.hpp | 8 | ||||
-rw-r--r-- | platform/default/include/mbgl/gl/headless_backend.hpp | 7 | ||||
-rw-r--r-- | platform/default/src/mbgl/gfx/headless_frontend.cpp | 61 | ||||
-rw-r--r-- | platform/default/src/mbgl/gl/headless_backend.cpp | 32 | ||||
-rw-r--r-- | platform/default/src/mbgl/map/map_snapshotter.cpp | 4 | ||||
-rw-r--r-- | platform/default/src/mbgl/util/monotonic_timer.cpp | 24 | ||||
-rw-r--r-- | platform/ios/core-files.json | 1 | ||||
-rw-r--r-- | platform/linux/config.cmake | 1 | ||||
-rw-r--r-- | platform/macos/core-files.json | 1 |
11 files changed, 107 insertions, 43 deletions
diff --git a/platform/android/core-files.json b/platform/android/core-files.json index d536247154..e21a586e29 100644 --- a/platform/android/core-files.json +++ b/platform/android/core-files.json @@ -93,6 +93,7 @@ "platform/default/src/mbgl/map/map_snapshotter.cpp", "platform/default/src/mbgl/text/bidi.cpp", "platform/default/src/mbgl/util/compression.cpp", + "platform/default/src/mbgl/util/monotonic_timer.cpp", "platform/default/src/mbgl/util/png_writer.cpp", "platform/default/src/mbgl/util/thread_local.cpp", "platform/default/src/mbgl/util/utf.cpp", diff --git a/platform/default/include/mbgl/gfx/headless_backend.hpp b/platform/default/include/mbgl/gfx/headless_backend.hpp index 325422323a..5167e6a465 100644 --- a/platform/default/include/mbgl/gfx/headless_backend.hpp +++ b/platform/default/include/mbgl/gfx/headless_backend.hpp @@ -15,11 +15,13 @@ namespace gfx { // of readStillImage. class HeadlessBackend : public gfx::Renderable { public: + enum class SwapBehaviour { NoFlush, Flush }; + // Factory. - static std::unique_ptr<HeadlessBackend> - Create(const Size size = { 256, 256 }, - const gfx::ContextMode contextMode = gfx::ContextMode::Unique) { - return Backend::Create<HeadlessBackend, Size, gfx::ContextMode>(size, contextMode); + static std::unique_ptr<HeadlessBackend> Create(const Size size = {256, 256}, + SwapBehaviour swapBehavior = SwapBehaviour::NoFlush, + const gfx::ContextMode contextMode = gfx::ContextMode::Unique) { + return Backend::Create<HeadlessBackend, Size, SwapBehaviour, gfx::ContextMode>(size, swapBehavior, contextMode); } virtual PremultipliedImage readStillImage() = 0; diff --git a/platform/default/include/mbgl/gfx/headless_frontend.hpp b/platform/default/include/mbgl/gfx/headless_frontend.hpp index 8f7a7bf202..353452123d 100644 --- a/platform/default/include/mbgl/gfx/headless_frontend.hpp +++ b/platform/default/include/mbgl/gfx/headless_frontend.hpp @@ -1,11 +1,12 @@ #pragma once +#include <mbgl/gfx/headless_backend.hpp> #include <mbgl/map/camera.hpp> #include <mbgl/renderer/renderer_frontend.hpp> -#include <mbgl/gfx/headless_backend.hpp> #include <mbgl/util/async_task.hpp> #include <mbgl/util/optional.hpp> +#include <atomic> #include <memory> namespace mbgl { @@ -17,10 +18,12 @@ class TransformState; class HeadlessFrontend : public RendererFrontend { public: HeadlessFrontend(float pixelRatio_, + gfx::HeadlessBackend::SwapBehaviour swapBehviour = gfx::HeadlessBackend::SwapBehaviour::NoFlush, gfx::ContextMode mode = gfx::ContextMode::Unique, const optional<std::string> localFontFamily = {}); HeadlessFrontend(Size, float pixelRatio_, + gfx::HeadlessBackend::SwapBehaviour swapBehviour = gfx::HeadlessBackend::SwapBehaviour::NoFlush, gfx::ContextMode mode = gfx::ContextMode::Unique, const optional<std::string> localFontFamily = {}); ~HeadlessFrontend() override; @@ -29,6 +32,7 @@ public: void update(std::shared_ptr<UpdateParameters>) override; void setObserver(RendererObserver&) override; + double getFrameTime() const; Size getSize() const; void setSize(Size); @@ -45,6 +49,7 @@ public: PremultipliedImage readStillImage(); PremultipliedImage render(Map&); + void renderOnce(Map&); optional<TransformState> getTransformState() const; @@ -52,6 +57,7 @@ private: Size size; float pixelRatio; + std::atomic<double> frameTime; std::unique_ptr<gfx::HeadlessBackend> backend; util::AsyncTask asyncInvalidate; diff --git a/platform/default/include/mbgl/gl/headless_backend.hpp b/platform/default/include/mbgl/gl/headless_backend.hpp index 8aefb5ff6c..b77f1b756f 100644 --- a/platform/default/include/mbgl/gl/headless_backend.hpp +++ b/platform/default/include/mbgl/gl/headless_backend.hpp @@ -10,13 +10,17 @@ namespace gl { class HeadlessBackend final : public gl::RendererBackend, public gfx::HeadlessBackend { public: - HeadlessBackend(Size = { 256, 256 }, gfx::ContextMode = gfx::ContextMode::Unique); + HeadlessBackend(Size = {256, 256}, + SwapBehaviour = SwapBehaviour::NoFlush, + gfx::ContextMode = gfx::ContextMode::Unique); ~HeadlessBackend() override; void updateAssumedState() override; gfx::Renderable& getDefaultRenderable() override; PremultipliedImage readStillImage() override; RendererBackend* getRendererBackend() override; + void swap(); + class Impl { public: virtual ~Impl() = default; @@ -37,6 +41,7 @@ private: private: std::unique_ptr<Impl> impl; bool active = false; + SwapBehaviour swapBehaviour = SwapBehaviour::NoFlush; }; } // namespace gl diff --git a/platform/default/src/mbgl/gfx/headless_frontend.cpp b/platform/default/src/mbgl/gfx/headless_frontend.cpp index 287567adbd..87d09911a2 100644 --- a/platform/default/src/mbgl/gfx/headless_frontend.cpp +++ b/platform/default/src/mbgl/gfx/headless_frontend.cpp @@ -1,43 +1,50 @@ -#include <mbgl/gfx/headless_frontend.hpp> #include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/map/transform_state.hpp> #include <mbgl/renderer/renderer.hpp> #include <mbgl/renderer/renderer_state.hpp> #include <mbgl/renderer/update_parameters.hpp> -#include <mbgl/map/map.hpp> -#include <mbgl/map/transform_state.hpp> +#include <mbgl/util/monotonic_timer.hpp> #include <mbgl/util/run_loop.hpp> namespace mbgl { HeadlessFrontend::HeadlessFrontend(float pixelRatio_, + gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode, const optional<std::string> localFontFamily) - : HeadlessFrontend( - { 256, 256 }, pixelRatio_, contextMode, localFontFamily) { -} + : HeadlessFrontend({256, 256}, pixelRatio_, swapBehavior, contextMode, localFontFamily) {} HeadlessFrontend::HeadlessFrontend(Size size_, float pixelRatio_, + gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode, const optional<std::string> localFontFamily) : size(size_), pixelRatio(pixelRatio_), - backend(gfx::HeadlessBackend::Create({ static_cast<uint32_t>(size.width * pixelRatio), - static_cast<uint32_t>(size.height * pixelRatio) }, contextMode)), - asyncInvalidate([this] { - if (renderer && updateParameters) { - gfx::BackendScope guard { *getBackend() }; - - // onStyleImageMissing might be called during a render. The user implemented method - // could trigger a call to MGLRenderFrontend#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_); - } - }), - renderer(std::make_unique<Renderer>(*getBackend(), pixelRatio, localFontFamily)) { -} + frameTime(0), + backend(gfx::HeadlessBackend::Create( + {static_cast<uint32_t>(size.width * pixelRatio), static_cast<uint32_t>(size.height * pixelRatio)}, + 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 MGLRenderFrontend#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(); + } + }), + renderer(std::make_unique<Renderer>(*getBackend(), pixelRatio, localFontFamily)) {} HeadlessFrontend::~HeadlessFrontend() = default; @@ -56,6 +63,10 @@ void HeadlessFrontend::setObserver(RendererObserver& observer_) { renderer->setObserver(&observer_); } +double HeadlessFrontend::getFrameTime() const { + return frameTime; +} + Size HeadlessFrontend::getSize() const { return size; } @@ -147,10 +158,14 @@ PremultipliedImage HeadlessFrontend::render(Map& map) { if (error) { std::rethrow_exception(error); } - + return result; } +void HeadlessFrontend::renderOnce(Map&) { + util::RunLoop::Get()->runOnce(); +} + optional<TransformState> HeadlessFrontend::getTransformState() const { if (updateParameters) { return updateParameters->transformState; diff --git a/platform/default/src/mbgl/gl/headless_backend.cpp b/platform/default/src/mbgl/gl/headless_backend.cpp index 732e4babae..697c560f76 100644 --- a/platform/default/src/mbgl/gl/headless_backend.cpp +++ b/platform/default/src/mbgl/gl/headless_backend.cpp @@ -12,12 +12,12 @@ namespace gl { class HeadlessRenderableResource final : public gl::RenderableResource { public: - HeadlessRenderableResource(gl::Context& context_, Size size_) - : context(context_), + HeadlessRenderableResource(HeadlessBackend& backend_, gl::Context& context_, Size size_) + : backend(backend_), + context(context_), color(context.createRenderbuffer<gfx::RenderbufferPixelType::RGBA>(size_)), depthStencil(context.createRenderbuffer<gfx::RenderbufferPixelType::DepthStencil>(size_)), - framebuffer(context.createFramebuffer(color, depthStencil)) { - } + framebuffer(context.createFramebuffer(color, depthStencil)) {} void bind() override { context.bindFramebuffer = framebuffer.framebuffer; @@ -25,18 +25,22 @@ public: context.viewport = { 0, 0, framebuffer.size }; } + void swap() override { backend.swap(); } + + HeadlessBackend& backend; gl::Context& context; gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA> color; gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil> depthStencil; gl::Framebuffer framebuffer; }; -HeadlessBackend::HeadlessBackend(const Size size_, const gfx::ContextMode contextMode_) - : mbgl::gl::RendererBackend(contextMode_), mbgl::gfx::HeadlessBackend(size_) { -} +HeadlessBackend::HeadlessBackend(const Size size_, + gfx::HeadlessBackend::SwapBehaviour swapBehaviour_, + const gfx::ContextMode contextMode_) + : mbgl::gl::RendererBackend(contextMode_), mbgl::gfx::HeadlessBackend(size_), swapBehaviour(swapBehaviour_) {} HeadlessBackend::~HeadlessBackend() { - gfx::BackendScope guard { *this }; + gfx::BackendScope guard{*this}; resource.reset(); // Explicitly reset the context so that it is destructed and cleaned up before we destruct // the impl object. @@ -67,11 +71,15 @@ void HeadlessBackend::deactivate() { gfx::Renderable& HeadlessBackend::getDefaultRenderable() { if (!resource) { - resource = std::make_unique<HeadlessRenderableResource>(static_cast<gl::Context&>(getContext()), size); + resource = std::make_unique<HeadlessRenderableResource>(*this, static_cast<gl::Context&>(getContext()), size); } return *this; } +void HeadlessBackend::swap() { + if (swapBehaviour == SwapBehaviour::Flush) static_cast<gl::Context&>(getContext()).finish(); +} + void HeadlessBackend::updateAssumedState() { // no-op } @@ -89,9 +97,9 @@ RendererBackend* HeadlessBackend::getRendererBackend() { namespace gfx { template <> -std::unique_ptr<gfx::HeadlessBackend> -Backend::Create<gfx::Backend::Type::OpenGL>(const Size size, const gfx::ContextMode contextMode) { - return std::make_unique<gl::HeadlessBackend>(size, contextMode); +std::unique_ptr<gfx::HeadlessBackend> Backend::Create<gfx::Backend::Type::OpenGL>( + const Size size, gfx::HeadlessBackend::SwapBehaviour swapBehavior, const gfx::ContextMode contextMode) { + return std::make_unique<gl::HeadlessBackend>(size, swapBehavior, contextMode); } } // namespace gfx diff --git a/platform/default/src/mbgl/map/map_snapshotter.cpp b/platform/default/src/mbgl/map/map_snapshotter.cpp index 5f4060e3f0..705a791af9 100644 --- a/platform/default/src/mbgl/map/map_snapshotter.cpp +++ b/platform/default/src/mbgl/map/map_snapshotter.cpp @@ -51,8 +51,8 @@ MapSnapshotter::Impl::Impl(const std::pair<bool, std::string> style, const optional<LatLngBounds> region, const optional<std::string> localFontFamily, const ResourceOptions& resourceOptions) - : frontend( - size, pixelRatio, gfx::ContextMode::Unique, localFontFamily), + : frontend( + size, pixelRatio, gfx::HeadlessBackend::SwapBehaviour::NoFlush, gfx::ContextMode::Unique, localFontFamily), map(frontend, MapObserver::nullObserver(), MapOptions().withMapMode(MapMode::Static).withSize(size).withPixelRatio(pixelRatio), diff --git a/platform/default/src/mbgl/util/monotonic_timer.cpp b/platform/default/src/mbgl/util/monotonic_timer.cpp new file mode 100644 index 0000000000..43c2ce6717 --- /dev/null +++ b/platform/default/src/mbgl/util/monotonic_timer.cpp @@ -0,0 +1,24 @@ +#include <assert.h> +#include <chrono> +#include <mbgl/util/monotonic_timer.hpp> + +namespace mbgl { +namespace util { + +// Prefer high resolution timer if it is monotonic +template <typename T, std::enable_if_t<std::chrono::high_resolution_clock::is_steady, T>* = nullptr> +static T sample() { + return std::chrono::duration_cast<T>(std::chrono::high_resolution_clock::now().time_since_epoch()); +} + +template <typename T, std::enable_if_t<!std::chrono::high_resolution_clock::is_steady, T>* = nullptr> +static T sample() { + return std::chrono::duration_cast<T>(std::chrono::steady_clock::now().time_since_epoch()); +} + +std::chrono::duration<double> MonotonicTimer::now() { + return sample<std::chrono::duration<double>>(); +} + +} // namespace util +} // namespace mbgl
\ No newline at end of file diff --git a/platform/ios/core-files.json b/platform/ios/core-files.json index 7c916b027b..08cf1b5946 100644 --- a/platform/ios/core-files.json +++ b/platform/ios/core-files.json @@ -17,6 +17,7 @@ "platform/default/src/mbgl/map/map_snapshotter.cpp", "platform/default/src/mbgl/text/bidi.cpp", "platform/default/src/mbgl/util/compression.cpp", + "platform/default/src/mbgl/util/monotonic_timer.cpp", "platform/default/src/mbgl/util/png_writer.cpp", "platform/default/src/mbgl/util/thread_local.cpp", "platform/default/src/mbgl/util/utf.cpp" diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 26de2430ce..39ae7c6d52 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -52,6 +52,7 @@ macro(mbgl_platform_core) PRIVATE platform/default/src/mbgl/layermanager/layer_manager.cpp PRIVATE platform/default/src/mbgl/util/compression.cpp PRIVATE platform/default/src/mbgl/util/logging_stderr.cpp + PRIVATE platform/default/src/mbgl/util/monotonic_timer.cpp PRIVATE platform/default/src/mbgl/util/string_stdlib.cpp PRIVATE platform/default/src/mbgl/util/thread.cpp PRIVATE platform/default/src/mbgl/util/thread_local.cpp diff --git a/platform/macos/core-files.json b/platform/macos/core-files.json index b0536c4863..5fde52876a 100644 --- a/platform/macos/core-files.json +++ b/platform/macos/core-files.json @@ -16,6 +16,7 @@ "platform/default/src/mbgl/map/map_snapshotter.cpp", "platform/default/src/mbgl/text/bidi.cpp", "platform/default/src/mbgl/util/compression.cpp", + "platform/default/src/mbgl/util/monotonic_timer.cpp", "platform/default/src/mbgl/util/png_writer.cpp", "platform/default/src/mbgl/util/thread_local.cpp", "platform/default/src/mbgl/util/utf.cpp" |