diff options
40 files changed, 378 insertions, 768 deletions
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index 8b96d02163..75695c1ad7 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -1,13 +1,9 @@ #include <benchmark/benchmark.h> -#include <mbgl/benchmark/util.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/renderer/async_renderer_frontend.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/storage/default_file_source.hpp> @@ -31,17 +27,14 @@ public: map.getStyle().addImage(std::make_unique<style::Image>("test-icon", decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0)); - mbgl::benchmark::render(map, view); + frontend.render(map); } util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view{ backend.getContext(), { 1000, 1000 } }; DefaultFileSource fileSource{ "benchmark/fixtures/api/cache.db", "." }; ThreadPool threadPool{ 4 }; - AsyncRendererFrontend rendererFrontend { std::make_unique<Renderer>(backend, 1, fileSource, threadPool), backend, view }; - Map map { rendererFrontend, MapObserver::nullObserver(), view.getSize(), 1, fileSource, threadPool, MapMode::Still }; + HeadlessFrontend frontend { { 1000, 1000 }, 1, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), 1, fileSource, threadPool, MapMode::Still }; ScreenBox box{{ 0, 0 }, { 1000, 1000 }}; }; @@ -51,7 +44,7 @@ static void API_queryRenderedFeaturesAll(::benchmark::State& state) { QueryBenchmark bench; while (state.KeepRunning()) { - bench.rendererFrontend.getRenderer()->queryRenderedFeatures(bench.box, {}); + bench.frontend.getRenderer()->queryRenderedFeatures(bench.box, {}); } } @@ -59,7 +52,7 @@ static void API_queryRenderedFeaturesLayerFromLowDensity(::benchmark::State& sta QueryBenchmark bench; while (state.KeepRunning()) { - bench.rendererFrontend.getRenderer()->queryRenderedFeatures(bench.box, {{{ "testlayer" }}, {}}); + bench.frontend.getRenderer()->queryRenderedFeatures(bench.box, {{{ "testlayer" }}, {}}); } } @@ -67,7 +60,7 @@ static void API_queryRenderedFeaturesLayerFromHighDensity(::benchmark::State& st QueryBenchmark bench; while (state.KeepRunning()) { - bench.rendererFrontend.getRenderer()->queryRenderedFeatures(bench.box, {{{"road-street" }}, {}}); + bench.frontend.getRenderer()->queryRenderedFeatures(bench.box, {{{"road-street" }}, {}}); } } diff --git a/benchmark/api/render.benchmark.cpp b/benchmark/api/render.benchmark.cpp index 90667d4ed4..9f1ea68e0b 100644 --- a/benchmark/api/render.benchmark.cpp +++ b/benchmark/api/render.benchmark.cpp @@ -1,14 +1,10 @@ #include <benchmark/benchmark.h> -#include <mbgl/benchmark/util.hpp> #include <mbgl/map/map.hpp> #include <mbgl/map/map_observer.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/renderer/async_renderer_frontend.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/storage/default_file_source.hpp> @@ -29,9 +25,6 @@ public: } util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 1000, 1000 } }; DefaultFileSource fileSource { "benchmark/fixtures/api/cache.db", "." }; ThreadPool threadPool { 4 }; }; @@ -47,25 +40,25 @@ static void prepare(Map& map, optional<std::string> json = {}) { static void API_renderStill_reuse_map(::benchmark::State& state) { RenderBenchmark bench; - AsyncRendererFrontend frontend { std::make_unique<Renderer>(bench.backend, 1, bench.fileSource, bench.threadPool), bench.backend, bench.view }; - Map map { frontend, MapObserver::nullObserver(), bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + HeadlessFrontend frontend { { 1000, 1000 }, 1, bench.fileSource, bench.threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; prepare(map); while (state.KeepRunning()) { - mbgl::benchmark::render(map, bench.view); + frontend.render(map); } } static void API_renderStill_reuse_map_switch_styles(::benchmark::State& state) { RenderBenchmark bench; - AsyncRendererFrontend frontend { std::make_unique<Renderer>(bench.backend, 1, bench.fileSource, bench.threadPool), bench.backend, bench.view }; - Map map { frontend, MapObserver::nullObserver(), bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + HeadlessFrontend frontend { { 1000, 1000 }, 1, bench.fileSource, bench.threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; while (state.KeepRunning()) { prepare(map, { "{}" }); - mbgl::benchmark::render(map, bench.view); + frontend.render(map); prepare(map); - mbgl::benchmark::render(map, bench.view); + frontend.render(map); } } @@ -73,10 +66,10 @@ static void API_renderStill_recreate_map(::benchmark::State& state) { RenderBenchmark bench; while (state.KeepRunning()) { - AsyncRendererFrontend frontend { std::make_unique<Renderer>(bench.backend, 1, bench.fileSource, bench.threadPool), bench.backend, bench.view }; - Map map { frontend, MapObserver::nullObserver(), bench.view.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; + HeadlessFrontend frontend { { 1000, 1000 }, 1, bench.fileSource, bench.threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), 1, bench.fileSource, bench.threadPool, MapMode::Still }; prepare(map); - mbgl::benchmark::render(map, bench.view); + frontend.render(map); } } diff --git a/benchmark/src/mbgl/benchmark/util.cpp b/benchmark/src/mbgl/benchmark/util.cpp deleted file mode 100644 index a56279886f..0000000000 --- a/benchmark/src/mbgl/benchmark/util.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <mbgl/benchmark/util.hpp> -#include <mbgl/gl/offscreen_view.hpp> - -#include <mbgl/map/map.hpp> -#include <mbgl/map/view.hpp> -#include <mbgl/util/image.hpp> -#include <mbgl/util/run_loop.hpp> - -namespace mbgl { -namespace benchmark { - -void render(Map& map, OffscreenView& view) { - PremultipliedImage result; - map.renderStill([&](std::exception_ptr) { - result = view.readStillImage(); - }); - - while (!result.valid()) { - util::RunLoop::Get()->runOnce(); - } -} - -} // namespace benchmark -} // namespace mbgl diff --git a/benchmark/src/mbgl/benchmark/util.hpp b/benchmark/src/mbgl/benchmark/util.hpp deleted file mode 100644 index 73acfb69d5..0000000000 --- a/benchmark/src/mbgl/benchmark/util.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace mbgl { - -class Map; -class OffscreenView; - -namespace benchmark { - -void render(Map&, OffscreenView&); - -} // namespace benchmark -} // namespace mbgl diff --git a/bin/render.cpp b/bin/render.cpp index 0214d3310c..444921ff2b 100644 --- a/bin/render.cpp +++ b/bin/render.cpp @@ -2,14 +2,10 @@ #include <mbgl/util/image.hpp> #include <mbgl/util/run_loop.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/style/style.hpp> -#include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/renderer/async_renderer_frontend.hpp> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" @@ -85,13 +81,9 @@ int main(int argc, char *argv[]) { fileSource.setAccessToken(std::string(token)); } - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view(backend.getContext(), { static_cast<uint32_t>(width * pixelRatio), - static_cast<uint32_t>(height * pixelRatio) }); ThreadPool threadPool(4); - AsyncRendererFrontend rendererFrontend(std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), backend, view); - Map map(rendererFrontend, MapObserver::nullObserver(), mbgl::Size { width, height }, pixelRatio, fileSource, threadPool, MapMode::Still); + HeadlessFrontend frontend({ width, height }, pixelRatio, fileSource, threadPool); + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still); if (style_path.find("://") == std::string::npos) { style_path = std::string("file://") + style_path; @@ -106,23 +98,14 @@ int main(int argc, char *argv[]) { map.setDebug(debug ? mbgl::MapDebugOptions::TileBorders | mbgl::MapDebugOptions::ParseStatus : mbgl::MapDebugOptions::NoDebug); } - map.renderStill([&](std::exception_ptr error) { - try { - if (error) { - std::rethrow_exception(error); - } - } catch(std::exception& e) { - std::cout << "Error: " << e.what() << std::endl; - exit(1); - } - + try { std::ofstream out(output, std::ios::binary); - out << encodePNG(view.readStillImage()); + out << encodePNG(frontend.render(map)); out.close(); - loop.stop(); - }); - - loop.run(); + } catch(std::exception& e) { + std::cout << "Error: " << e.what() << std::endl; + exit(1); + } return 0; } diff --git a/cmake/benchmark-files.cmake b/cmake/benchmark-files.cmake index d5364c3e58..f17d95941d 100644 --- a/cmake/benchmark-files.cmake +++ b/cmake/benchmark-files.cmake @@ -18,8 +18,6 @@ set(MBGL_BENCHMARK_FILES # src/mbgl/benchmark benchmark/src/mbgl/benchmark/benchmark.cpp - benchmark/src/mbgl/benchmark/util.cpp - benchmark/src/mbgl/benchmark/util.hpp # util benchmark/util/dtoa.benchmark.cpp diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index 6f8a7751e4..79e87a0b10 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -1,6 +1,4 @@ add_executable(mbgl-benchmark - platform/default/mbgl/renderer/async_renderer_frontend.cpp - platform/default/mbgl/renderer/async_renderer_frontend.hpp ${MBGL_BENCHMARK_FILES} ) diff --git a/cmake/node.cmake b/cmake/node.cmake index a17863407e..502edd8293 100644 --- a/cmake/node.cmake +++ b/cmake/node.cmake @@ -19,8 +19,6 @@ target_sources(mbgl-node PRIVATE platform/node/src/node_request.cpp PRIVATE platform/node/src/node_feature.hpp PRIVATE platform/node/src/node_feature.cpp - PRIVATE platform/node/src/node_renderer_frontend.hpp - PRIVATE platform/node/src/node_renderer_frontend.cpp PRIVATE platform/node/src/node_thread_pool.hpp PRIVATE platform/node/src/node_thread_pool.cpp PRIVATE platform/node/src/util/async_queue.hpp diff --git a/cmake/render.cmake b/cmake/render.cmake index 350350dc76..407e1ca8ef 100644 --- a/cmake/render.cmake +++ b/cmake/render.cmake @@ -1,6 +1,4 @@ add_executable(mbgl-render - platform/default/mbgl/renderer/async_renderer_frontend.cpp - platform/default/mbgl/renderer/async_renderer_frontend.hpp bin/render.cpp ) diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index 1bae959bb7..19412e6133 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -60,8 +60,6 @@ set(MBGL_TEST_FILES test/src/mbgl/test/stub_geometry_tile_feature.hpp test/src/mbgl/test/stub_layer_observer.hpp test/src/mbgl/test/stub_render_source_observer.hpp - test/src/mbgl/test/stub_renderer_frontend.cpp - test/src/mbgl/test/stub_renderer_frontend.hpp test/src/mbgl/test/stub_style_observer.hpp test/src/mbgl/test/stub_tile_observer.hpp test/src/mbgl/test/test.cpp diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 7b0c8d60f2..390e4842f4 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -308,10 +308,10 @@ macro(mbgl_platform_test) platform/android/src/test/main.jni.cpp # Headless view + platform/default/mbgl/gl/headless_frontend.cpp + platform/default/mbgl/gl/headless_frontend.hpp platform/default/mbgl/gl/headless_backend.cpp platform/default/mbgl/gl/headless_backend.hpp - platform/default/mbgl/gl/offscreen_view.cpp - platform/default/mbgl/gl/offscreen_view.hpp platform/linux/src/headless_backend_egl.cpp platform/linux/src/headless_display_egl.cpp diff --git a/platform/default/mbgl/gl/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp index 82660331fa..a854fe9731 100644 --- a/platform/default/mbgl/gl/headless_backend.cpp +++ b/platform/default/mbgl/gl/headless_backend.cpp @@ -9,10 +9,26 @@ namespace mbgl { -HeadlessBackend::HeadlessBackend() = default; +class HeadlessBackend::View { +public: + View(gl::Context& context, Size size) + : color(context.createRenderbuffer<gl::RenderbufferType::RGBA>(size)), + depthStencil(context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size)), + framebuffer(context.createFramebuffer(color, depthStencil)) { + } + + gl::Renderbuffer<gl::RenderbufferType::RGBA> color; + gl::Renderbuffer<gl::RenderbufferType::DepthStencil> depthStencil; + gl::Framebuffer framebuffer; +}; + +HeadlessBackend::HeadlessBackend(Size size_) + : size(size_) { +} HeadlessBackend::~HeadlessBackend() { BackendScope guard { *this }; + view.reset(); context.reset(); } @@ -36,8 +52,29 @@ void HeadlessBackend::deactivate() { active = false; } +void HeadlessBackend::bind() { + gl::Context& context_ = getContext(); + + if (!view) { + view = std::make_unique<View>(context_, size); + } + + context_.bindFramebuffer = view->framebuffer.framebuffer; + context_.scissorTest = false; + context_.viewport = { 0, 0, size }; +} + void HeadlessBackend::updateAssumedState() { // no-op } +void HeadlessBackend::setSize(Size size_) { + size = size_; + view.reset(); +} + +PremultipliedImage HeadlessBackend::readStillImage() { + return getContext().readFramebuffer<PremultipliedImage>(size); +} + } // namespace mbgl diff --git a/platform/default/mbgl/gl/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp index 5f39eb9f00..d845e9930c 100644 --- a/platform/default/mbgl/gl/headless_backend.hpp +++ b/platform/default/mbgl/gl/headless_backend.hpp @@ -1,5 +1,6 @@ #pragma once +#include <mbgl/map/view.hpp> #include <mbgl/renderer/renderer_backend.hpp> #include <memory> @@ -9,13 +10,17 @@ namespace mbgl { class HeadlessDisplay; -class HeadlessBackend : public RendererBackend { +class HeadlessBackend : public View, public RendererBackend { public: - HeadlessBackend(); + HeadlessBackend(Size = { 256, 256 }); ~HeadlessBackend() override; + void bind() override; void updateAssumedState() override; + void setSize(Size); + PremultipliedImage readStillImage(); + struct Impl { virtual ~Impl() = default; virtual void activateContext() = 0; @@ -37,7 +42,12 @@ private: std::shared_ptr<HeadlessDisplay> display; std::unique_ptr<Impl> impl; + Size size; + float pixelRatio; bool active = false; + + class View; + std::unique_ptr<View> view; }; } // namespace mbgl diff --git a/platform/default/mbgl/gl/headless_frontend.cpp b/platform/default/mbgl/gl/headless_frontend.cpp new file mode 100644 index 0000000000..3f34d8eeba --- /dev/null +++ b/platform/default/mbgl/gl/headless_frontend.cpp @@ -0,0 +1,86 @@ +#include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/renderer/renderer.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/util/run_loop.hpp> + +namespace mbgl { + +HeadlessFrontend::HeadlessFrontend(float pixelRatio_, FileSource& fileSource, Scheduler& scheduler) + : HeadlessFrontend({ 256, 256 }, pixelRatio_, fileSource, scheduler) { +} + +HeadlessFrontend::HeadlessFrontend(Size size_, float pixelRatio_, FileSource& fileSource, Scheduler& scheduler) + : size(size_), + pixelRatio(pixelRatio_), + backend({ static_cast<uint32_t>(size.width * pixelRatio), + static_cast<uint32_t>(size.height * pixelRatio) }), + asyncInvalidate([this] { + if (renderer && updateParameters) { + mbgl::BackendScope guard { backend }; + renderer->render(backend, *updateParameters); + } + }), + renderer(std::make_unique<Renderer>(backend, pixelRatio, fileSource, scheduler)) { +} + +HeadlessFrontend::~HeadlessFrontend() = default; + +void HeadlessFrontend::reset() { + assert(renderer); + renderer.reset(); +} + +void HeadlessFrontend::update(std::shared_ptr<UpdateParameters> updateParameters_) { + updateParameters = updateParameters_; + asyncInvalidate.send(); +} + +void HeadlessFrontend::setObserver(RendererObserver& observer_) { + assert(renderer); + renderer->setObserver(&observer_); +} + +Size HeadlessFrontend::getSize() const { + return size; +} + +Renderer* HeadlessFrontend::getRenderer() { + assert(renderer); + return renderer.get(); +} + +RendererBackend* HeadlessFrontend::getBackend() { + return &backend; +} + +void HeadlessFrontend::setSize(Size size_) { + if (size != size_) { + size = size_; + backend.setSize({ static_cast<uint32_t>(size_.width * pixelRatio), + static_cast<uint32_t>(size_.height * pixelRatio) }); + } +} + +PremultipliedImage HeadlessFrontend::readStillImage() { + return backend.readStillImage(); +} + +PremultipliedImage HeadlessFrontend::render(Map& map) { + PremultipliedImage result; + + map.renderStill([&](std::exception_ptr error) { + if (error) { + std::rethrow_exception(error); + } else { + result = backend.readStillImage(); + } + }); + + while (!result.valid()) { + util::RunLoop::Get()->runOnce(); + } + + return result; +} + +} // namespace mbgl diff --git a/platform/default/mbgl/gl/headless_frontend.hpp b/platform/default/mbgl/gl/headless_frontend.hpp new file mode 100644 index 0000000000..18d0d2527b --- /dev/null +++ b/platform/default/mbgl/gl/headless_frontend.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include <mbgl/renderer/renderer_frontend.hpp> +#include <mbgl/gl/headless_backend.hpp> +#include <mbgl/util/async_task.hpp> + +#include <memory> + +namespace mbgl { + +class FileSource; +class Scheduler; +class Renderer; +class RendererBackend; +class Map; + +class HeadlessFrontend : public RendererFrontend { +public: + HeadlessFrontend(float pixelRatio_, FileSource&, Scheduler&); + HeadlessFrontend(Size, float pixelRatio_, FileSource&, Scheduler&); + ~HeadlessFrontend() override; + + void reset() override; + void update(std::shared_ptr<UpdateParameters>) override; + void setObserver(RendererObserver&) override; + + Size getSize() const; + void setSize(Size); + + Renderer* getRenderer(); + RendererBackend* getBackend(); + + PremultipliedImage readStillImage(); + PremultipliedImage render(Map&); + +private: + Size size; + float pixelRatio; + + HeadlessBackend backend; + util::AsyncTask asyncInvalidate; + + std::unique_ptr<Renderer> renderer; + std::shared_ptr<UpdateParameters> updateParameters; +}; + +} // namespace mbgl diff --git a/platform/default/mbgl/gl/offscreen_view.cpp b/platform/default/mbgl/gl/offscreen_view.cpp deleted file mode 100644 index e7cf7cffe5..0000000000 --- a/platform/default/mbgl/gl/offscreen_view.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include <mbgl/gl/offscreen_view.hpp> -#include <mbgl/gl/context.hpp> -#include <mbgl/gl/framebuffer.hpp> -#include <mbgl/gl/renderbuffer.hpp> -#include <mbgl/util/optional.hpp> - -#include <cstring> -#include <cassert> - -namespace mbgl { - -class OffscreenView::Impl { -public: - Impl(gl::Context& context_, const Size size_) : context(context_), size(std::move(size_)) { - assert(!size.isEmpty()); - } - - void bind() { - if (!framebuffer) { - color = context.createRenderbuffer<gl::RenderbufferType::RGBA>(size); - depthStencil = context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size); - framebuffer = context.createFramebuffer(*color, *depthStencil); - } else { - context.bindFramebuffer = framebuffer->framebuffer; - } - - context.scissorTest = false; - context.viewport = { 0, 0, size }; - } - - PremultipliedImage readStillImage() { - return context.readFramebuffer<PremultipliedImage>(size); - } - - const Size& getSize() const { - return size; - } - -private: - gl::Context& context; - const Size size; - optional<gl::Framebuffer> framebuffer; - optional<gl::Renderbuffer<gl::RenderbufferType::RGBA>> color; - optional<gl::Renderbuffer<gl::RenderbufferType::DepthStencil>> depthStencil; -}; - -OffscreenView::OffscreenView(gl::Context& context, const Size size) - : impl(std::make_unique<Impl>(context, std::move(size))) { -} - -OffscreenView::~OffscreenView() = default; - -void OffscreenView::bind() { - impl->bind(); -} - -PremultipliedImage OffscreenView::readStillImage() { - return impl->readStillImage(); -} - -const Size& OffscreenView::getSize() const { - return impl->getSize(); -} - -} // namespace mbgl diff --git a/platform/default/mbgl/gl/offscreen_view.hpp b/platform/default/mbgl/gl/offscreen_view.hpp deleted file mode 100644 index eb888272e5..0000000000 --- a/platform/default/mbgl/gl/offscreen_view.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include <mbgl/map/view.hpp> -#include <mbgl/util/image.hpp> - -namespace mbgl { - -namespace gl { -class Context; -} // namespace gl - -class OffscreenView : public View { -public: - OffscreenView(gl::Context&, Size size = { 256, 256 }); - ~OffscreenView() override; - - void bind() override; - - PremultipliedImage readStillImage(); - - const Size& getSize() const; - -private: - class Impl; - const std::unique_ptr<Impl> impl; -}; - -} // namespace mbgl diff --git a/platform/default/mbgl/renderer/async_renderer_frontend.cpp b/platform/default/mbgl/renderer/async_renderer_frontend.cpp deleted file mode 100644 index 230d0bb820..0000000000 --- a/platform/default/mbgl/renderer/async_renderer_frontend.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "async_renderer_frontend.hpp" - -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/renderer/renderer.hpp> - -namespace mbgl { - -AsyncRendererFrontend::AsyncRendererFrontend(std::unique_ptr<Renderer> renderer_, RendererBackend& backend, View& view_) - : renderer(std::move(renderer_)) - , view(view_) - , asyncInvalidate([&] { - if (renderer && updateParameters) { - BackendScope guard { backend }; - renderer->render(view, *updateParameters); - } - }) { -} - -AsyncRendererFrontend::~AsyncRendererFrontend() = default; - -void AsyncRendererFrontend::reset() { - assert(renderer); - renderer.reset(); -} - -void AsyncRendererFrontend::update(std::shared_ptr<UpdateParameters> updateParameters_) { - updateParameters = updateParameters_; - asyncInvalidate.send(); -} - -void AsyncRendererFrontend::setObserver(RendererObserver& observer_) { - assert(renderer); - renderer->setObserver(&observer_); -} - -Renderer* AsyncRendererFrontend::getRenderer() { - assert(renderer); - return renderer.get(); -} - -} // namespace mbgl diff --git a/platform/default/mbgl/renderer/async_renderer_frontend.hpp b/platform/default/mbgl/renderer/async_renderer_frontend.hpp deleted file mode 100644 index e1b2f780cd..0000000000 --- a/platform/default/mbgl/renderer/async_renderer_frontend.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include <mbgl/map/view.hpp> -#include <mbgl/renderer/renderer_frontend.hpp> -#include <mbgl/util/async_task.hpp> - -#include <memory> -#include <vector> - -namespace mbgl { - -class Renderer; -class RendererBackend; - -// Default implementation for RendererFrontend -class AsyncRendererFrontend : public mbgl::RendererFrontend { -public: - AsyncRendererFrontend(std::unique_ptr<Renderer>, RendererBackend&, View&); - ~AsyncRendererFrontend() override; - - void reset() override; - - void update(std::shared_ptr<UpdateParameters> updateParameters_) override; - - void setObserver(RendererObserver& observer_) override; - - Renderer* getRenderer(); - -private: - std::unique_ptr<Renderer> renderer; - View& view; - std::shared_ptr<UpdateParameters> updateParameters; - util::AsyncTask asyncInvalidate; -}; - -} // namespace mbgl diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index efb31d2e00..7ea1dddef7 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -49,13 +49,13 @@ macro(mbgl_platform_core) PRIVATE platform/default/png_writer.cpp # Headless view + PRIVATE platform/default/mbgl/gl/headless_frontend.cpp + PRIVATE platform/default/mbgl/gl/headless_frontend.hpp PRIVATE platform/default/mbgl/gl/headless_backend.cpp PRIVATE platform/default/mbgl/gl/headless_backend.hpp PRIVATE platform/darwin/src/headless_backend_eagl.mm PRIVATE platform/default/mbgl/gl/headless_display.cpp PRIVATE platform/default/mbgl/gl/headless_display.hpp - PRIVATE platform/default/mbgl/gl/offscreen_view.cpp - PRIVATE platform/default/mbgl/gl/offscreen_view.hpp # Thread pool PRIVATE platform/default/mbgl/util/shared_thread_pool.cpp diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index 8fbfafb417..3aa1fdbbfc 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -80,11 +80,11 @@ macro(mbgl_platform_core) PRIVATE platform/default/webp_reader.cpp # Headless view + PRIVATE platform/default/mbgl/gl/headless_frontend.cpp + PRIVATE platform/default/mbgl/gl/headless_frontend.hpp PRIVATE platform/default/mbgl/gl/headless_backend.cpp PRIVATE platform/default/mbgl/gl/headless_backend.hpp PRIVATE platform/default/mbgl/gl/headless_display.hpp - PRIVATE platform/default/mbgl/gl/offscreen_view.cpp - PRIVATE platform/default/mbgl/gl/offscreen_view.hpp # Thread pool PRIVATE platform/default/mbgl/util/default_thread_pool.cpp diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index d037469bd0..86c54b612c 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -45,13 +45,13 @@ macro(mbgl_platform_core) PRIVATE platform/default/png_writer.cpp # Headless view + PRIVATE platform/default/mbgl/gl/headless_frontend.cpp + PRIVATE platform/default/mbgl/gl/headless_frontend.hpp PRIVATE platform/default/mbgl/gl/headless_backend.cpp PRIVATE platform/default/mbgl/gl/headless_backend.hpp PRIVATE platform/darwin/src/headless_backend_cgl.cpp PRIVATE platform/default/mbgl/gl/headless_display.hpp PRIVATE platform/darwin/src/headless_display_cgl.cpp - PRIVATE platform/default/mbgl/gl/offscreen_view.cpp - PRIVATE platform/default/mbgl/gl/offscreen_view.hpp # Thread pool PRIVATE platform/default/mbgl/util/shared_thread_pool.cpp diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 0b87a86210..7c7082bd09 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -3,11 +3,10 @@ #include "node_feature.hpp" #include "node_conversion.hpp" #include "node_geojson.hpp" -#include "node_renderer_frontend.hpp" #include <mbgl/util/exception.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/backend_scope.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/style/conversion/source.hpp> #include <mbgl/style/conversion/layer.hpp> #include <mbgl/style/conversion/filter.hpp> @@ -26,8 +25,7 @@ struct NodeMap::RenderOptions { double pitch = 0; double latitude = 0; double longitude = 0; - unsigned int width = 512; - unsigned int height = 512; + mbgl::Size size = { 512, 512 }; std::vector<std::string> classes; mbgl::MapDebugOptions debugOptions = mbgl::MapDebugOptions::NoDebug; }; @@ -38,8 +36,6 @@ static const char* releasedMessage() { return "Map resources have already been released"; } -NodeBackend::NodeBackend(): HeadlessBackend() {} - void NodeMapObserver::onDidFailLoadingMap(std::exception_ptr error) { std::rethrow_exception(error); } @@ -258,11 +254,11 @@ NodeMap::RenderOptions NodeMap::ParseOptions(v8::Local<v8::Object> obj) { } if (Nan::Has(obj, Nan::New("width").ToLocalChecked()).FromJust()) { - options.width = Nan::Get(obj, Nan::New("width").ToLocalChecked()).ToLocalChecked()->IntegerValue(); + options.size.width = Nan::Get(obj, Nan::New("width").ToLocalChecked()).ToLocalChecked()->IntegerValue(); } if (Nan::Has(obj, Nan::New("height").ToLocalChecked()).FromJust()) { - options.height = Nan::Get(obj, Nan::New("height").ToLocalChecked()).ToLocalChecked()->IntegerValue(); + options.size.height = Nan::Get(obj, Nan::New("height").ToLocalChecked()).ToLocalChecked()->IntegerValue(); } if (Nan::Has(obj, Nan::New("classes").ToLocalChecked()).FromJust()) { @@ -358,15 +354,8 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) { } void NodeMap::startRender(NodeMap::RenderOptions options) { - map->setSize({ options.width, options.height }); - - const mbgl::Size fbSize{ static_cast<uint32_t>(options.width * pixelRatio), - static_cast<uint32_t>(options.height * pixelRatio) }; - if (!view || view->getSize() != fbSize) { - view.reset(); - mbgl::BackendScope scope { backend }; - view = std::make_unique<mbgl::OffscreenView>(backend.getContext(), fbSize); - } + frontend->setSize(options.size); + map->setSize(options.size); if (map->getZoom() != options.zoom) { map->setZoom(options.zoom); @@ -395,7 +384,7 @@ void NodeMap::startRender(NodeMap::RenderOptions options) { uv_async_send(async); } else { assert(!image.data); - image = view->readStillImage(); + image = frontend->readStillImage(); uv_async_send(async); } }); @@ -525,9 +514,8 @@ void NodeMap::cancel() { // Reset map explicitly as it resets the renderer frontend map.reset(); - auto renderer = std::make_unique<mbgl::Renderer>(backend, pixelRatio, *this, threadpool); - rendererFrontend = std::make_unique<NodeRendererFrontend>(std::move(renderer), backend, [this] { return view.get(); }); - map = std::make_unique<mbgl::Map>(*rendererFrontend, mapObserver, mbgl::Size{ 256, 256 }, pixelRatio, + frontend = std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size{ 256, 256 }, pixelRatio, *this, threadpool); + map = std::make_unique<mbgl::Map>(*frontend, mapObserver, frontend->getSize(), pixelRatio, *this, threadpool, mbgl::MapMode::Still); // FIXME: Reload the style after recreating the map. We need to find @@ -882,11 +870,8 @@ void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>& info) { if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); nodeMap->map->dumpDebugLogs(); - - if (nodeMap->rendererFrontend) { - nodeMap->rendererFrontend->dumpDebugLogs(); - } - + nodeMap->frontend->getRenderer()->dumpDebugLogs(); + info.GetReturnValue().SetUndefined(); } @@ -948,7 +933,7 @@ void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>& auto pos0 = Nan::Get(posOrBox, 0).ToLocalChecked().As<v8::Array>(); auto pos1 = Nan::Get(posOrBox, 1).ToLocalChecked().As<v8::Array>(); - optional = nodeMap->rendererFrontend->queryRenderedFeatures(mbgl::ScreenBox { + optional = nodeMap->frontend->getRenderer()->queryRenderedFeatures(mbgl::ScreenBox { { Nan::Get(pos0, 0).ToLocalChecked()->NumberValue(), Nan::Get(pos0, 1).ToLocalChecked()->NumberValue() @@ -959,7 +944,7 @@ void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>& }, queryOptions); } else { - optional = nodeMap->rendererFrontend->queryRenderedFeatures(mbgl::ScreenCoordinate { + optional = nodeMap->frontend->getRenderer()->queryRenderedFeatures(mbgl::ScreenCoordinate { Nan::Get(posOrBox, 0).ToLocalChecked()->NumberValue(), Nan::Get(posOrBox, 1).ToLocalChecked()->NumberValue() }, queryOptions); @@ -985,10 +970,10 @@ NodeMap::NodeMap(v8::Local<v8::Object> options) : 1.0; }()) , mapObserver(NodeMapObserver()) - , rendererFrontend(std::make_unique<NodeRendererFrontend>(std::make_unique<mbgl::Renderer>(backend, pixelRatio, *this, threadpool), backend, [this] { return view.get(); })) - , map(std::make_unique<mbgl::Map>(*rendererFrontend, + , frontend(std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size { 256, 256 }, pixelRatio, *this, threadpool)) + , map(std::make_unique<mbgl::Map>(*frontend, mapObserver, - mbgl::Size { 256, 256 }, + frontend->getSize(), pixelRatio, *this, threadpool, diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index 08a3dcaa79..7bd3b99bea 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -4,8 +4,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/storage/file_source.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> +#include <mbgl/util/image.hpp> #include <exception> @@ -15,15 +14,13 @@ #include <nan.h> #pragma GCC diagnostic pop +namespace mbgl { +class Map; +class HeadlessFrontend; +} // namespace mbgl + namespace node_mbgl { - -class NodeRendererFrontend; -class NodeBackend : public mbgl::HeadlessBackend { -public: - NodeBackend(); -}; - class NodeMapObserver : public mbgl::MapObserver { void onDidFailLoadingMap(std::exception_ptr) override; }; @@ -73,11 +70,9 @@ public: std::unique_ptr<mbgl::AsyncRequest> request(const mbgl::Resource&, mbgl::FileSource::Callback); const float pixelRatio; - NodeBackend backend; - std::unique_ptr<mbgl::OffscreenView> view; NodeThreadPool threadpool; NodeMapObserver mapObserver; - std::unique_ptr<NodeRendererFrontend> rendererFrontend; + std::unique_ptr<mbgl::HeadlessFrontend> frontend; std::unique_ptr<mbgl::Map> map; std::exception_ptr error; diff --git a/platform/node/src/node_renderer_frontend.cpp b/platform/node/src/node_renderer_frontend.cpp deleted file mode 100644 index 5ebb92717b..0000000000 --- a/platform/node/src/node_renderer_frontend.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "node_renderer_frontend.hpp" - -#include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/renderer_backend.hpp> -#include <mbgl/renderer/backend_scope.hpp> - -namespace node_mbgl { - -NodeRendererFrontend::NodeRendererFrontend(std::unique_ptr<mbgl::Renderer> renderer_, mbgl::RendererBackend& backend_, ViewAccessorFunction getView) - : renderer(std::move(renderer_)) - , asyncInvalidate([&, getView] { - if (renderer && updateParameters) { - mbgl::BackendScope guard { backend_ }; - renderer->render(*getView(), *updateParameters); - } - }) { -} - -NodeRendererFrontend::~NodeRendererFrontend() = default; - -void NodeRendererFrontend::reset() { - assert(renderer); - renderer.reset(); -} - -void NodeRendererFrontend::setObserver(mbgl::RendererObserver& observer_) { - assert(renderer); - renderer->setObserver(&observer_); -} - -void NodeRendererFrontend::update(std::shared_ptr<mbgl::UpdateParameters> updateParameters_) { - updateParameters = updateParameters_; - asyncInvalidate.send(); -} - -std::vector<mbgl::Feature> NodeRendererFrontend::queryRenderedFeatures(const mbgl::ScreenBox& box, - const mbgl::RenderedQueryOptions& options) const { - assert(renderer); - return renderer->queryRenderedFeatures(box, options); -} - -std::vector<mbgl::Feature> NodeRendererFrontend::queryRenderedFeatures(const mbgl::ScreenCoordinate& point, - const mbgl::RenderedQueryOptions& options) const { - assert(renderer); - return renderer->queryRenderedFeatures(point, options); -} - -void NodeRendererFrontend::dumpDebugLogs() { - assert(renderer); - return renderer->dumpDebugLogs(); -} - -} // namespace node_mbgl diff --git a/platform/node/src/node_renderer_frontend.hpp b/platform/node/src/node_renderer_frontend.hpp deleted file mode 100644 index c70291317b..0000000000 --- a/platform/node/src/node_renderer_frontend.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include <mbgl/renderer/renderer_frontend.hpp> -#include <mbgl/renderer/query.hpp> -#include <mbgl/util/async_task.hpp> -#include <mbgl/util/feature.hpp> -#include <mbgl/util/geo.hpp> - -#include <functional> -#include <memory> - -namespace mbgl { - class Renderer; - class RendererBackend; - class View; -} // namespace mbgl - -namespace node_mbgl { - -class NodeRendererFrontend : public mbgl::RendererFrontend { -public: - using ViewAccessorFunction = std::function<mbgl::View* ()>; - NodeRendererFrontend(std::unique_ptr<mbgl::Renderer>, mbgl::RendererBackend&, ViewAccessorFunction); - - ~NodeRendererFrontend(); - - void reset() override; - - void setObserver(mbgl::RendererObserver&) override; - - void update(std::shared_ptr<mbgl::UpdateParameters>) override; - - // Feature querying - std::vector<mbgl::Feature> queryRenderedFeatures(const mbgl::ScreenCoordinate&, - const mbgl::RenderedQueryOptions& options = {}) const; - std::vector<mbgl::Feature> queryRenderedFeatures(const mbgl::ScreenBox&, - const mbgl::RenderedQueryOptions& = {}) const; - - void dumpDebugLogs(); - -private: - std::unique_ptr<mbgl::Renderer> renderer; - std::shared_ptr<mbgl::UpdateParameters> updateParameters; - mbgl::util::AsyncTask asyncInvalidate; -}; - -} // namespace node_mbgl diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake index 0f2bab0516..732fb1de28 100644 --- a/platform/qt/config.cmake +++ b/platform/qt/config.cmake @@ -52,12 +52,12 @@ endmacro() macro(mbgl_platform_test) target_sources(mbgl-test + PRIVATE platform/default/mbgl/gl/headless_frontend.cpp + PRIVATE platform/default/mbgl/gl/headless_frontend.hpp PRIVATE platform/default/mbgl/gl/headless_backend.cpp PRIVATE platform/default/mbgl/gl/headless_backend.hpp PRIVATE platform/default/mbgl/gl/headless_display.cpp PRIVATE platform/default/mbgl/gl/headless_display.hpp - PRIVATE platform/default/mbgl/gl/offscreen_view.cpp - PRIVATE platform/default/mbgl/gl/offscreen_view.hpp PRIVATE platform/qt/test/headless_backend_qt.cpp PRIVATE platform/qt/test/main.cpp PRIVATE platform/qt/test/qmapboxgl.cpp diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 878ef90831..d6476f9a3e 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -6,14 +6,11 @@ #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/color.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> +#include <mbgl/gl/headless_frontend.hpp> using namespace mbgl; @@ -30,19 +27,16 @@ std::unique_ptr<style::Image> namedMarker(const std::string& name) { class AnnotationTest { public: util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), view }; - Map map { rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still }; void checkRendering(const char * name) { test::checkImage(std::string("test/fixtures/annotations/") + name, - test::render(map, view), 0.0002, 0.1); + frontend.render(map), 0.0002, 0.1); } }; @@ -160,7 +154,7 @@ TEST(Annotations, AddMultiple) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.addAnnotation(SymbolAnnotation { Point<double> { 10, 0 }, "default_marker" }); test.checkRendering("add_multiple"); @@ -170,7 +164,7 @@ TEST(Annotations, NonImmediateAdd) { AnnotationTest test; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.frontend.render(test.map); Polygon<double> polygon = { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }; FillAnnotation annotation { polygon }; @@ -188,7 +182,7 @@ TEST(Annotations, UpdateSymbolAnnotationGeometry) { test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" }); test.checkRendering("update_point"); @@ -202,7 +196,7 @@ TEST(Annotations, UpdateSymbolAnnotationIcon) { test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point<double> { 0, 0 }, "flipped_marker" }); test.checkRendering("update_icon"); @@ -218,7 +212,7 @@ TEST(Annotations, UpdateLineAnnotationGeometry) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = LineString<double> {{ { 0, 0 }, { -45, -45 } }}; test.map.updateAnnotation(line, annotation); @@ -235,7 +229,7 @@ TEST(Annotations, UpdateLineAnnotationStyle) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); annotation.width = { 2 }; @@ -252,7 +246,7 @@ TEST(Annotations, UpdateFillAnnotationGeometry) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = Polygon<double> { {{ { 0, 0 }, { 0, 45 }, { 45, 0 } }} }; test.map.updateAnnotation(fill, annotation); @@ -269,7 +263,7 @@ TEST(Annotations, UpdateFillAnnotationStyle) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); test.map.updateAnnotation(fill, annotation); @@ -283,7 +277,7 @@ TEST(Annotations, RemovePoint) { test.map.addAnnotationImage(namedMarker("default_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(point); test.checkRendering("remove_point"); @@ -300,7 +294,7 @@ TEST(Annotations, RemoveShape) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID shape = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(shape); test.checkRendering("remove_shape"); @@ -312,7 +306,7 @@ TEST(Annotations, ImmediateRemoveShape) { test.map.removeAnnotation(test.map.addAnnotation(LineAnnotation { LineString<double>() })); test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.frontend.render(test.map); } TEST(Annotations, SwitchStyle) { @@ -322,7 +316,7 @@ TEST(Annotations, SwitchStyle) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.checkRendering("switch_style"); @@ -335,7 +329,7 @@ TEST(Annotations, ReaddImage) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.addAnnotationImage(std::make_unique<style::Image>("default_marker", namedImage("flipped_marker"), 1.0)); test.checkRendering("readd_image"); @@ -349,14 +343,14 @@ TEST(Annotations, QueryRenderedFeatures) { test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 50 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features.size(), 1u); EXPECT_TRUE(!!features[0].id); EXPECT_EQ(*features[0].id, uint64_t(0)); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); EXPECT_EQ(features2.size(), 1u); EXPECT_TRUE(!!features2[0].id); EXPECT_EQ(*features2[0].id, uint64_t(1)); @@ -365,7 +359,7 @@ TEST(Annotations, QueryRenderedFeatures) { TEST(Annotations, QueryFractionalZoomLevels) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); @@ -381,8 +375,8 @@ TEST(Annotations, QueryFractionalZoomLevels) { test.map.setLatLngZoom({ 5, 5 }, 0); for (uint16_t zoomSteps = 10; zoomSteps <= 20; ++zoomSteps) { test.map.setZoom(zoomSteps / 10.0); - test::render(test.map, test.view); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box); + test.frontend.render(test.map); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box); // Filter out repeated features. // See 'edge-cases/null-island' query-test for reference. @@ -397,7 +391,7 @@ TEST(Annotations, QueryFractionalZoomLevels) { TEST(Annotations, VisibleFeatures) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); @@ -413,9 +407,9 @@ TEST(Annotations, VisibleFeatures) { // Change bearing *after* adding annotations causes them to be reordered. test.map.setBearing(45); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box, {}); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {}); auto sortID = [](const Feature& lhs, const Feature& rhs) { return lhs.id < rhs.id; }; auto sameID = [](const Feature& lhs, const Feature& rhs) { return lhs.id == rhs.id; }; std::sort(features.begin(), features.end(), sortID); @@ -424,8 +418,8 @@ TEST(Annotations, VisibleFeatures) { test.map.setBearing(0); test.map.setZoom(4); - test::render(test.map, test.view); - features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box); + test.frontend.render(test.map); + features = test.frontend.getRenderer()->queryRenderedFeatures(box); std::sort(features.begin(), features.end(), sortID); features.erase(std::unique(features.begin(), features.end(), sameID), features.end()); EXPECT_EQ(features.size(), ids.size()); diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp index 9f53b763be..690c1548e5 100644 --- a/test/api/api_misuse.test.cpp +++ b/test/api/api_misuse.test.cpp @@ -4,11 +4,8 @@ #include <mbgl/map/map.hpp> #include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/storage/online_file_source.hpp> -#include <mbgl/renderer/renderer.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/util/exception.hpp> #include <mbgl/util/run_loop.hpp> @@ -24,16 +21,12 @@ TEST(API, RenderWithoutCallback) { util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 128, 512 } }; StubFileSource fileSource; ThreadPool threadPool(4); float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), view }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; - auto map = std::make_unique<Map>(rendererFrontend, MapObserver::nullObserver(), view.getSize(), + auto map = std::make_unique<Map>(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still); map->renderStill(nullptr); diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 972485338f..1c514aeca2 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -2,16 +2,12 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> -#include <mbgl/renderer/renderer.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/run_loop.hpp> @@ -89,14 +85,11 @@ public: TEST(CustomLayer, Basic) { util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); ThreadPool threadPool(4); float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), view }; - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still); map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); map.setLatLngZoom({ 37.8, -122.5 }, 10); @@ -117,6 +110,5 @@ TEST(CustomLayer, Basic) { layer->setFillColor(Color{ 1.0, 1.0, 0.0, 1.0 }); map.getStyle().addLayer(std::move(layer)); - test::checkImage("test/fixtures/custom_layer/basic", test::render(map, view), 0.0006, 0.1); - + test::checkImage("test/fixtures/custom_layer/basic", frontend.render(map), 0.0006, 0.1); } diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index a5224222cb..3f3825eb72 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -1,7 +1,4 @@ #include <mbgl/map/map.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/test/stub_file_source.hpp> #include <mbgl/test/util.hpp> @@ -12,7 +9,7 @@ #include <mbgl/style/image.hpp> #include <mbgl/style/source.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> +#include <mbgl/gl/headless_frontend.hpp> using namespace mbgl; using namespace mbgl::style; @@ -26,19 +23,15 @@ public: map.getStyle().addImage(std::make_unique<style::Image>("test-icon", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); - test::render(map, view); + frontend.render(map); } util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), view }; - Map map { rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still }; }; @@ -47,10 +40,10 @@ public: TEST(Query, QueryRenderedFeatures) { QueryTest test; - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features1.size(), 4u); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); EXPECT_EQ(features2.size(), 0u); } @@ -59,16 +52,16 @@ TEST(Query, QueryRenderedFeaturesFilterLayer) { auto zz = test.map.pixelForLatLng({ 0, 0 }); - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); EXPECT_EQ(features1.size(), 1u); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); EXPECT_EQ(features2.size(), 2u); - auto features3 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); EXPECT_EQ(features3.size(), 0u); - auto features4 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); + auto features4 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); EXPECT_EQ(features4.size(), 1u); } @@ -78,22 +71,22 @@ TEST(Query, QueryRenderedFeaturesFilter) { auto zz = test.map.pixelForLatLng({ 0, 0 }); const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } TEST(Query, QuerySourceFeatures) { QueryTest test; - auto features1 = test.rendererFrontend.getRenderer()->querySourceFeatures("source3"); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source3"); EXPECT_EQ(features1.size(), 1u); } @@ -101,15 +94,15 @@ TEST(Query, QuerySourceFeaturesOptionValidation) { QueryTest test; // GeoJSONSource, doesn't require a layer id - auto features = test.rendererFrontend.getRenderer()->querySourceFeatures("source3"); + auto features = test.frontend.getRenderer()->querySourceFeatures("source3"); ASSERT_EQ(features.size(), 1u); // VectorSource, requires a layer id - features = test.rendererFrontend.getRenderer()->querySourceFeatures("source5"); + features = test.frontend.getRenderer()->querySourceFeatures("source5"); ASSERT_EQ(features.size(), 0u); // RasterSource, not supported - features = test.rendererFrontend.getRenderer()->querySourceFeatures("source6"); + features = test.frontend.getRenderer()->querySourceFeatures("source6"); ASSERT_EQ(features.size(), 0u); } @@ -117,15 +110,15 @@ TEST(Query, QuerySourceFeaturesFilter) { QueryTest test; const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp index 30699718b3..8046927c54 100644 --- a/test/gl/object.test.cpp +++ b/test/gl/object.test.cpp @@ -2,8 +2,6 @@ #include <mbgl/renderer/backend_scope.hpp> #include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> - #include <mbgl/gl/context.hpp> #include <memory> @@ -47,9 +45,8 @@ TEST(GLObject, Value) { } TEST(GLObject, Store) { - HeadlessBackend backend; + HeadlessBackend backend { { 256, 256 } }; BackendScope scope { backend }; - OffscreenView view(backend.getContext()); gl::Context context; EXPECT_TRUE(context.empty()); diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 3e8f8696e1..95d652f2af 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -4,16 +4,12 @@ #include <mbgl/test/fixture_log_observer.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/headless_display.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/storage/network_status.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/online_file_source.hpp> -#include <mbgl/renderer/renderer.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> @@ -21,7 +17,6 @@ #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/layers/background_layer.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> #include <mbgl/util/color.hpp> using namespace mbgl; @@ -53,30 +48,33 @@ public: didFinishLoadingStyleCallback(); } } - + + void onDidFinishRenderingFrame(RenderMode mode) final { + if (didFinishRenderingFrame) { + didFinishRenderingFrame(mode); + } + } + std::function<void()> onWillStartLoadingMapCallback; std::function<void()> onDidFinishLoadingMapCallback; std::function<void()> didFailLoadingMapCallback; std::function<void()> didFinishLoadingStyleCallback; + std::function<void(RenderMode)> didFinishRenderingFrame; }; template <class FileSource = StubFileSource> class MapTest { public: util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; FileSource fileSource; ThreadPool threadPool { 4 }; StubMapObserver observer; - StubRendererFrontend rendererFrontend; + HeadlessFrontend frontend; Map map; MapTest(float pixelRatio = 1, MapMode mode = MapMode::Still) - : rendererFrontend( - std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), view) - , map(rendererFrontend, observer, view.getSize(), pixelRatio, fileSource, threadPool, mode) { + : frontend(pixelRatio, fileSource, threadPool) + , map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, mode) { } template <typename T = FileSource> @@ -84,10 +82,8 @@ public: float pixelRatio = 1, MapMode mode = MapMode::Still, typename std::enable_if<std::is_same<T, DefaultFileSource>::value>::type* = 0) : fileSource { cachePath, assetRoot } - , rendererFrontend( - std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), - view) - , map(rendererFrontend, observer, view.getSize(), pixelRatio, fileSource, threadPool, mode) { + , frontend(pixelRatio, fileSource, threadPool) + , map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, mode) { } }; @@ -157,7 +153,7 @@ TEST(Map, Offline) { test.map.getStyle().loadURL(prefix + "style.json"); test::checkImage("test/fixtures/map/offline", - test::render(test.map, test.view), + test.frontend.render(test.map), 0.0015, 0.1); @@ -296,7 +292,7 @@ TEST(Map, StyleExpiredWithRender) { test.fileSource.respond(Resource::Style, response); EXPECT_EQ(1u, test.fileSource.requests.size()); - test::render(test.map, test.view); + test.frontend.render(test.map); EXPECT_EQ(1u, test.fileSource.requests.size()); test.fileSource.respond(Resource::Style, response); @@ -406,16 +402,18 @@ TEST(Map, AddLayer) { layer->setBackgroundColor({ { 1, 0, 0, 1 } }); test.map.getStyle().addLayer(std::move(layer)); - test::checkImage("test/fixtures/map/add_layer", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/add_layer", test.frontend.render(test.map)); } TEST(Map, WithoutVAOExtension) { MapTest<DefaultFileSource> test { ":memory:", "test/fixtures/api/assets" }; - test.backend.getContext().disableVAOExtension = true; + + BackendScope scope { *test.frontend.getBackend() }; + test.frontend.getBackend()->getContext().disableVAOExtension = true; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); - test::checkImage("test/fixtures/map/no_vao", test::render(test.map, test.view), 0.002); + test::checkImage("test/fixtures/map/no_vao", test.frontend.render(test.map), 0.002); } TEST(Map, RemoveLayer) { @@ -428,7 +426,7 @@ TEST(Map, RemoveLayer) { test.map.getStyle().addLayer(std::move(layer)); test.map.getStyle().removeLayer("background"); - test::checkImage("test/fixtures/map/remove_layer", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/remove_layer", test.frontend.render(test.map)); } TEST(Map, DisabledSources) { @@ -486,9 +484,9 @@ TEST(Map, DisabledSources) { } )STYLE"); - test::checkImage("test/fixtures/map/disabled_layers/first", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/disabled_layers/first", test.frontend.render(test.map)); test.map.setZoom(0.5); - test::checkImage("test/fixtures/map/disabled_layers/second", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/disabled_layers/second", test.frontend.render(test.map)); } TEST(Map, DontLoadUnneededTiles) { @@ -533,16 +531,13 @@ TEST(Map, DontLoadUnneededTiles) { const double z = double(zoom) / 10; tiles.clear(); test.map.setZoom(z); - test::render(test.map, test.view); + test.frontend.render(test.map); EXPECT_EQ(referenceTiles[z], tiles) << "zoom level " << z; } } TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) { util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; ThreadPool threadPool { 4 }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); float pixelRatio { 1 }; @@ -551,39 +546,26 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) { util::Timer emergencyShutoff; emergencyShutoff.start(10s, 0s, [&] { - util::RunLoop::Get()->stop(); + runLoop.stop(); FAIL() << "Did not stop rendering"; }); util::Timer timer; - std::function<bool()> isLoaded; - - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(backend, pixelRatio, fileSource, threadPool), - [&](StubRendererFrontend& bridge) { - if (isLoaded()) { - // Abort the test after 1 second after the map loading fully. Note that a "fully loaded - // map" doesn't mean that we won't render anymore: we could still render fade in/fade - // out or other animations. - // If we are continuing to render indefinitely, the emergency shutoff above will trigger - // and the test will fail since the regular time will be constantly reset. - timer.start(1s, 0s, [&] { - util::RunLoop::Get()->stop(); - }); - } - - bridge.render(view); - } - }; - - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, - threadPool, MapMode::Continuous); + HeadlessFrontend frontend(pixelRatio, fileSource, threadPool); - isLoaded = [&] { - return map.isFullyLoaded(); + StubMapObserver observer; + observer.didFinishRenderingFrame = [&] (MapObserver::RenderMode) { + // Start a timer that ends the test one second from now. If we are continuing to render + // indefinitely, the timer will be constantly restarted and never trigger. Instead, the + // emergency shutoff above will trigger, failing the test. + timer.start(1s, 0s, [&] { + runLoop.stop(); + }); }; + Map map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Continuous); map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); - util::RunLoop::Get()->run(); + + runLoop.run(); } diff --git a/test/map/prefetch.test.cpp b/test/map/prefetch.test.cpp index 436bdc3b63..5c9a22d1bf 100644 --- a/test/map/prefetch.test.cpp +++ b/test/map/prefetch.test.cpp @@ -1,18 +1,14 @@ #include <mbgl/test/util.hpp> #include <mbgl/test/stub_file_source.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/backend_scope.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/style/style.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> #include <algorithm> #include <string> @@ -24,14 +20,10 @@ using namespace std::literals::string_literals; TEST(Map, PrefetchTiles) { util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope(backend); - OffscreenView view(backend.getContext(), { 512, 512 }); ThreadPool threadPool(4); StubFileSource fileSource; - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(backend, 1, fileSource, threadPool), view }; - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), 1, fileSource, threadPool, MapMode::Still); + HeadlessFrontend frontend { { 512, 512 }, 1, fileSource, threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), 1, fileSource, threadPool, MapMode::Still); std::vector<int> tiles; @@ -65,7 +57,7 @@ TEST(Map, PrefetchTiles) { map.setLatLngZoom({ 40.726989, -73.992857 }, zoom); // Manhattan // Should always render the ideal tiles (i.e. a green map) - test::checkImage("test/fixtures/map/prefetch", test::render(map, view)); + test::checkImage("test/fixtures/map/prefetch", frontend.render(map)); ASSERT_TRUE(std::is_permutation(tiles.begin(), tiles.end(), expected.begin())); ASSERT_FALSE(tiles.empty()); diff --git a/test/src/mbgl/test/stub_renderer_frontend.cpp b/test/src/mbgl/test/stub_renderer_frontend.cpp deleted file mode 100644 index 7edcfd397e..0000000000 --- a/test/src/mbgl/test/stub_renderer_frontend.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include <mbgl/test/stub_renderer_frontend.hpp> - -#include <mbgl/map/view.hpp> -#include <mbgl/renderer/renderer.hpp> - -namespace mbgl { - -StubRendererFrontend::StubRendererFrontend(std::unique_ptr<Renderer> renderer_, InvalidateCallback invalidate) - : renderer(std::move(renderer_)) - , asyncInvalidate([this, invalidate=std::move(invalidate)]() { - invalidate(*this); - }) { -} - -StubRendererFrontend::StubRendererFrontend(std::unique_ptr<Renderer> renderer_, View& view) - : renderer(std::move(renderer_)) - , asyncInvalidate([&]() { - this->render(view); - }) { -} - -StubRendererFrontend::~StubRendererFrontend() { - reset(); -} - -void StubRendererFrontend::reset() { - if (renderer) { - renderer.reset(); - } -} - -void StubRendererFrontend::setObserver(RendererObserver& observer) { - if (!renderer) return; - renderer->setObserver(&observer); -} - -void StubRendererFrontend::update(std::shared_ptr<UpdateParameters> params) { - updateParameters = std::move(params); - asyncInvalidate.send(); -} - -void StubRendererFrontend::render(View& view) { - if (!updateParameters || !renderer) return; - renderer->render(view, *updateParameters); -} - -Renderer* StubRendererFrontend::getRenderer() { - return renderer.get(); -} - -} // namespace mbgl - diff --git a/test/src/mbgl/test/stub_renderer_frontend.hpp b/test/src/mbgl/test/stub_renderer_frontend.hpp deleted file mode 100644 index f6dd1d0472..0000000000 --- a/test/src/mbgl/test/stub_renderer_frontend.hpp +++ /dev/null @@ -1,44 +0,0 @@ - -#pragma once - -#include <mbgl/renderer/renderer_frontend.hpp> -#include <mbgl/util/async_task.hpp> -#include <mbgl/util/geo.hpp> -#include <mbgl/util/feature.hpp> -#include <mbgl/renderer/query.hpp> - -#include <functional> -#include <memory> - -namespace mbgl { - -class Renderer; -class View; - -class StubRendererFrontend : public RendererFrontend { -public: - // Calls the provided callback when it's time to render - using InvalidateCallback = std::function<void (StubRendererFrontend&)>; - StubRendererFrontend(std::unique_ptr<Renderer>, InvalidateCallback); - - // Will render async - StubRendererFrontend(std::unique_ptr<Renderer>, View&); - - ~StubRendererFrontend() override; - - void reset() override; - - void setObserver(RendererObserver&) override; - - void update(std::shared_ptr<UpdateParameters>) override; - void render(View& view); - - Renderer* getRenderer(); - -private: - std::unique_ptr<Renderer> renderer; - std::shared_ptr<UpdateParameters> updateParameters; - util::AsyncTask asyncInvalidate; -}; - -} // namespace mbgl diff --git a/test/src/mbgl/test/util.cpp b/test/src/mbgl/test/util.cpp index 0b1034e315..028a0a9d51 100644 --- a/test/src/mbgl/test/util.cpp +++ b/test/src/mbgl/test/util.cpp @@ -1,12 +1,8 @@ #include <mbgl/test/util.hpp> -#include <mbgl/map/map.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> -#include <mbgl/util/chrono.hpp> -#include <mbgl/util/run_loop.hpp> #include <mapbox/pixelmatch.hpp> @@ -98,19 +94,6 @@ Server::~Server() { } } -PremultipliedImage render(Map& map, OffscreenView& view) { - PremultipliedImage result; - map.renderStill([&](std::exception_ptr) { - result = view.readStillImage(); - }); - - while (!result.valid()) { - util::RunLoop::Get()->runOnce(); - } - - return result; -} - void checkImage(const std::string& base, const PremultipliedImage& actual, double imageThreshold, diff --git a/test/src/mbgl/test/util.hpp b/test/src/mbgl/test/util.hpp index 9c015f1641..7a8d78897e 100644 --- a/test/src/mbgl/test/util.hpp +++ b/test/src/mbgl/test/util.hpp @@ -54,11 +54,6 @@ #include <gtest/gtest.h> namespace mbgl { - -class Map; -class OffscreenView; -class HeadlessDisplay; - namespace test { class Server { @@ -70,8 +65,6 @@ private: int fd = -1; }; -PremultipliedImage render(Map&, OffscreenView&); - void checkImage(const std::string& base, const PremultipliedImage& actual, double imageThreshold = 0, diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp index ad7982ce57..54763cd9db 100644 --- a/test/util/memory.test.cpp +++ b/test/util/memory.test.cpp @@ -3,15 +3,11 @@ #include <mbgl/test/util.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/renderer/backend_scope.hpp> -#include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/style/style.hpp> -#include <mbgl/renderer/renderer.hpp> -#include <mbgl/test/stub_renderer_frontend.hpp> #include <algorithm> #include <iostream> @@ -38,9 +34,6 @@ public: } util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 512, 512 } }; StubFileSource fileSource; ThreadPool threadPool { 4 }; @@ -77,30 +70,25 @@ TEST(Memory, Vector) { MemoryTest test; float ratio { 2 }; - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, + HeadlessFrontend frontend { { 256, 256 }, ratio, test.fileSource, test.threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), ratio, test.fileSource, test.threadPool, MapMode::Still); map.setZoom(16); // more map features map.getStyle().loadURL("mapbox://streets"); - test::render(map, test.view); + frontend.render(map); } TEST(Memory, Raster) { MemoryTest test; float ratio { 2 }; - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, + HeadlessFrontend frontend { { 256, 256 }, ratio, test.fileSource, test.threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), ratio, test.fileSource, test.threadPool, MapMode::Still); map.getStyle().loadURL("mapbox://satellite"); - test::render(map, test.view); + frontend.render(map); } /** @@ -127,57 +115,47 @@ TEST(Memory, Footprint) { if (!shouldRunFootprint()) { return; } - + MemoryTest test; - float ratio { 2 }; - auto renderMap = [&](Map& map, const char* style){ - map.setZoom(16); - map.getStyle().loadURL(style); - test::render(map, test.view); + class FrontendAndMap { + public: + FrontendAndMap(MemoryTest& test_, const char* style) + : frontend(Size{ 256, 256 }, 2, test_.fileSource, test_.threadPool) + , map(frontend, MapObserver::nullObserver(), frontend.getSize(), 2, test_.fileSource, test_.threadPool, MapMode::Still) { + map.setZoom(16); + map.getStyle().loadURL(style); + frontend.render(map); + } + + HeadlessFrontend frontend; + Map map; }; // Warm up buffers and cache. for (unsigned i = 0; i < 10; ++i) { - StubRendererFrontend rendererFrontend { - std::make_unique<Renderer>(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(map, "mapbox://streets"); - renderMap(map, "mapbox://satellite"); - }; + FrontendAndMap(test, "mapbox://streets"); + FrontendAndMap(test, "mapbox://satellite"); + } // Process close callbacks, mostly needed by // libuv runloop. test.runLoop.runOnce(); - std::vector<std::pair<std::unique_ptr<Map>, std::unique_ptr<RendererFrontend>>> maps; + std::vector<std::unique_ptr<FrontendAndMap>> maps; unsigned runs = 15; long vectorInitialRSS = mbgl::test::getCurrentRSS(); for (unsigned i = 0; i < runs; ++i) { - auto frontend = std::make_unique<StubRendererFrontend>( - std::make_unique<Renderer>(test.backend, ratio, test.fileSource, test.threadPool), test.view); - auto vector = std::make_unique<Map>(*frontend, MapObserver::nullObserver(), - Size{ 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(*vector, "mapbox://streets"); - maps.push_back({std::move(vector), std::move(frontend)}); - }; + maps.emplace_back(std::make_unique<FrontendAndMap>(test, "mapbox://streets")); + } double vectorFootprint = (mbgl::test::getCurrentRSS() - vectorInitialRSS) / double(runs); long rasterInitialRSS = mbgl::test::getCurrentRSS(); for (unsigned i = 0; i < runs; ++i) { - auto frontend = std::make_unique<StubRendererFrontend>( - std::make_unique<Renderer>(test.backend, ratio, test.fileSource, test.threadPool), test.view); - auto raster = std::make_unique<Map>(*frontend, MapObserver::nullObserver(), - Size{ 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(*raster, "mapbox://satellite"); - maps.push_back({std::move(raster), std::move(frontend)}); - }; + maps.emplace_back(std::make_unique<FrontendAndMap>(test, "mapbox://satellite")); + } double rasterFootprint = (mbgl::test::getCurrentRSS() - rasterInitialRSS) / double(runs); diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp index d4efd75689..09c940c4c3 100644 --- a/test/util/offscreen_texture.test.cpp +++ b/test/util/offscreen_texture.test.cpp @@ -3,7 +3,6 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gl/headless_backend.hpp> -#include <mbgl/gl/offscreen_view.hpp> #include <mbgl/renderer/backend_scope.hpp> #include <mbgl/util/offscreen_texture.hpp> @@ -11,20 +10,19 @@ using namespace mbgl; TEST(OffscreenTexture, EmptyRed) { - HeadlessBackend backend; + HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; - OffscreenView view(backend.getContext(), { 512, 256 }); - // Scissor test shouldn't leak after OffscreenView::bind(). + // Scissor test shouldn't leak after HeadlessBackend::bind(). MBGL_CHECK_ERROR(glScissor(64, 64, 128, 128)); backend.getContext().scissorTest.setCurrentValue(true); - view.bind(); + backend.bind(); MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f)); MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); - auto image = view.readStillImage(); + auto image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/empty-red", image, 0, 0); } @@ -74,7 +72,7 @@ struct Buffer { TEST(OffscreenTexture, RenderToTexture) { - HeadlessBackend backend; + HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; auto& context = backend.getContext(); @@ -124,8 +122,7 @@ void main() { Buffer triangleBuffer({ 0, 0.5, 0.5, -0.5, -0.5, -0.5 }); Buffer viewportBuffer({ -1, -1, 1, -1, -1, 1, 1, 1 }); - OffscreenView view(context, { 512, 256 }); - view.bind(); + backend.bind(); // First, draw red to the bound FBO. context.clear(Color::red(), {}, {}); @@ -153,9 +150,9 @@ void main() { test::checkImage("test/fixtures/offscreen_texture/render-to-texture", image, 0, 0); // Now reset the FBO back to normal and retrieve the original (restored) framebuffer. - view.bind(); + backend.bind(); - image = view.readStillImage(); + image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0); // Now, composite the Framebuffer texture we've rendered to onto the main FBO. @@ -168,6 +165,6 @@ void main() { glVertexAttribPointer(compositeShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr)); MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - image = view.readStillImage(); + image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/render-to-fbo-composited", image, 0, 0.1); } |