diff options
54 files changed, 662 insertions, 408 deletions
diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index 4ef6890cef..a4d9c30477 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -5,6 +5,9 @@ add_executable(mbgl-glfw target_sources(mbgl-glfw PRIVATE platform/glfw/glfw_view.hpp PRIVATE platform/glfw/glfw_view.cpp + PRIVATE platform/glfw/glfw_backend.hpp + PRIVATE platform/glfw/glfw_gl_backend.hpp + PRIVATE platform/glfw/glfw_gl_backend.cpp PRIVATE platform/glfw/glfw_renderer_frontend.hpp PRIVATE platform/glfw/glfw_renderer_frontend.cpp PRIVATE platform/glfw/settings_json.hpp diff --git a/include/mbgl/gfx/backend_scope.hpp b/include/mbgl/gfx/backend_scope.hpp index b92334ae0f..ae42123e97 100644 --- a/include/mbgl/gfx/backend_scope.hpp +++ b/include/mbgl/gfx/backend_scope.hpp @@ -1,11 +1,10 @@ #pragma once namespace mbgl { +namespace gfx { class RendererBackend; -namespace gfx { - class BackendScope { public: // There are two types of scopes: Creating an "Implicit" scope tells Mapbox GL that the diff --git a/include/mbgl/gfx/renderer_backend.hpp b/include/mbgl/gfx/renderer_backend.hpp new file mode 100644 index 0000000000..032c7021da --- /dev/null +++ b/include/mbgl/gfx/renderer_backend.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include <mbgl/util/util.hpp> + +#include <memory> +#include <mutex> + +namespace mbgl { +namespace gfx { + +class Context; +class Renderable; +class BackendScope; + +// TODO: Rename to "Device" +class RendererBackend { +protected: + explicit RendererBackend(); + +public: + virtual ~RendererBackend(); + RendererBackend(const RendererBackend&) = delete; + RendererBackend& operator=(const RendererBackend&) = delete; + + // Returns the device's context. + Context& getContext(); + + // Returns a reference to the default surface that should be rendered on. + virtual Renderable& getDefaultRenderable() = 0; + +protected: + virtual std::unique_ptr<Context> createContext() = 0; + + // Called when the backend's GL context needs to be made active or inactive. These are called, + // as a matched pair, exclusively through BackendScope, in two situations: + // + // 1. When releasing GL resources during Renderer destruction + // (Including calling CustomLayerHost::deinitialize during RenderCustomLayer destruction) + // 2. When renderering through Renderer::render() + // (Including calling CustomLayerHost::initialize for newly added custom layers and + // CustomLayerHost::deinitialize on layer removal) + virtual void activate() = 0; + virtual void deactivate() = 0; + +protected: + std::unique_ptr<Context> context; + std::once_flag initialized; + + friend class BackendScope; +}; + +MBGL_CONSTEXPR bool operator==(const RendererBackend& a, const RendererBackend& b) { + return &a == &b; +} + +} // namespace gfx +} // namespace mbgl diff --git a/include/mbgl/gl/renderer_backend.hpp b/include/mbgl/gl/renderer_backend.hpp new file mode 100644 index 0000000000..7ef8759477 --- /dev/null +++ b/include/mbgl/gl/renderer_backend.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include <mbgl/gfx/renderer_backend.hpp> +#include <mbgl/util/image.hpp> +#include <mbgl/util/size.hpp> +#include <mbgl/util/util.hpp> + +namespace mbgl { +namespace gl { + +class Context; +using ProcAddress = void (*)(); +using FramebufferID = uint32_t; + +class RendererBackend : public gfx::RendererBackend { +public: + RendererBackend(); + ~RendererBackend() override; + + // Returns the backend's context which manages OpenGL state. + Context& getGLContext(); + + // Called prior to rendering to update the internally assumed OpenGL state. + virtual void updateAssumedState() = 0; + +protected: + std::unique_ptr<gfx::Context> createContext() override; + + // Called with the name of an OpenGL extension that should be loaded. RendererBackend implementations + // must call the API-specific version that obtains the function pointer for this function, + // or a null pointer if unsupported/unavailable. + virtual ProcAddress getExtensionFunctionPointer(const char*) = 0; + + // Reads the color pixel data from the currently bound framebuffer. + PremultipliedImage readFramebuffer(const Size&); + + // A constant to signal that a framebuffer is bound, but with an unknown ID. + static constexpr const FramebufferID ImplicitFramebufferBinding = + std::numeric_limits<FramebufferID>::max(); + + // Tells the renderer that OpenGL state has already been set by the windowing toolkit. + // It sets the internal assumed state to the supplied values. + void assumeFramebufferBinding(FramebufferID fbo); + void assumeViewport(int32_t x, int32_t y, const Size&); + void assumeScissorTest(bool); + + // Returns true when assumed framebuffer binding hasn't changed from the implicit binding. + bool implicitFramebufferBound(); + +public: + // Triggers an OpenGL state update if the internal assumed state doesn't match the + // supplied values. + void setFramebufferBinding(FramebufferID fbo); + void setViewport(int32_t x, int32_t y, const Size&); + void setScissorTest(bool); +}; + +} // namespace gl +} // namespace mbgl diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp index 0bed4cdaa8..aa06210804 100644 --- a/include/mbgl/renderer/renderer.hpp +++ b/include/mbgl/renderer/renderer.hpp @@ -13,16 +13,19 @@ namespace mbgl { -class RendererBackend; class RendererObserver; class RenderedQueryOptions; class Scheduler; class SourceQueryOptions; class UpdateParameters; +namespace gfx { +class RendererBackend; +} // namespace gfx + class Renderer { public: - Renderer(RendererBackend&, float pixelRatio_, Scheduler&, + Renderer(gfx::RendererBackend&, float pixelRatio_, Scheduler&, GLContextMode = GLContextMode::Unique, const optional<std::string> programCacheDir = {}, const optional<std::string> localFontFamily = {}); diff --git a/include/mbgl/renderer/renderer_backend.hpp b/include/mbgl/renderer/renderer_backend.hpp deleted file mode 100644 index f75d00ebb3..0000000000 --- a/include/mbgl/renderer/renderer_backend.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include <mbgl/gfx/backend_scope.hpp> -#include <mbgl/util/image.hpp> -#include <mbgl/util/size.hpp> -#include <mbgl/util/util.hpp> - -#include <memory> -#include <mutex> - -namespace mbgl { - -namespace gl { -class Context; -using ProcAddress = void (*)(); -using FramebufferID = uint32_t; -} // namespace gl - -// The RendererBackend is used by the Renderer to facilitate -// the actual rendering. -class RendererBackend { -public: - RendererBackend(); - virtual ~RendererBackend(); - - // Returns the backend's context which manages OpenGL state. - gl::Context& getContext(); - - // Called prior to rendering to update the internally assumed OpenGL state. - virtual void updateAssumedState() = 0; - - // Called when this backend is used for rendering. Implementations should ensure that a renderable - // object is bound and glClear/glDraw* calls can be done. They should also make sure that - // calling .bind() repeatedly is a no-op and that the appropriate gl::Context values are - // set to the current state. - virtual void bind() = 0; - - virtual Size getFramebufferSize() const = 0; - -protected: - // Called with the name of an OpenGL extension that should be loaded. RendererBackend implementations - // must call the API-specific version that obtains the function pointer for this function, - // or a null pointer if unsupported/unavailable. - virtual gl::ProcAddress getExtensionFunctionPointer(const char*) = 0; - - // Called when the backend's GL context needs to be made active or inactive. These are called, - // as a matched pair, exclusively through BackendScope, in two situations: - // - // 1. When releasing GL resources during Renderer destruction - // (Including calling CustomLayerHost::deinitialize during RenderCustomLayer destruction) - // 2. When renderering through Renderer::render() - // (Including calling CustomLayerHost::initialize for newly added custom layers and - // CustomLayerHost::deinitialize on layer removal) - virtual void activate() = 0; - virtual void deactivate() = 0; - - // Reads the color pixel data from the currently bound framebuffer. - PremultipliedImage readFramebuffer(const Size&) const; - - // A constant to signal that a framebuffer is bound, but with an unknown ID. - static constexpr const gl::FramebufferID ImplicitFramebufferBinding = - std::numeric_limits<gl::FramebufferID>::max(); - - // Tells the renderer that OpenGL state has already been set by the windowing toolkit. - // It sets the internal assumed state to the supplied values. - void assumeFramebufferBinding(gl::FramebufferID fbo); - void assumeViewport(int32_t x, int32_t y, const Size&); - void assumeScissorTest(bool); - - // Returns true when assumed framebuffer binding hasn't changed from the implicit binding. - bool implicitFramebufferBound(); - - // Triggers an OpenGL state update if the internal assumed state doesn't match the - // supplied values. - void setFramebufferBinding(gl::FramebufferID fbo); - void setViewport(int32_t x, int32_t y, const Size&); - void setScissorTest(bool); - -protected: - std::unique_ptr<gl::Context> context; - -private: - std::once_flag initialized; - - friend class gfx::BackendScope; -}; - -MBGL_CONSTEXPR bool operator==(const RendererBackend& a, const RendererBackend& b) { - return &a == &b; -} - -} // namespace mbgl diff --git a/platform/android/src/android_renderer_backend.cpp b/platform/android/src/android_renderer_backend.cpp index 52a9a93170..09c9e85ad5 100755 --- a/platform/android/src/android_renderer_backend.cpp +++ b/platform/android/src/android_renderer_backend.cpp @@ -1,6 +1,8 @@ #include "android_renderer_backend.hpp" +#include <mbgl/gfx/backend_scope.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <EGL/egl.h> @@ -9,18 +11,27 @@ namespace mbgl { namespace android { -/** - * From mbgl::View - */ -void AndroidRendererBackend::bind() { - assert(gfx::BackendScope::exists()); - setFramebufferBinding(0); - setViewport(0, 0, getFramebufferSize()); +class AndroidGLRenderableResource final : public mbgl::gl::RenderableResource { +public: + AndroidGLRenderableResource(AndroidRendererBackend& backend_) : backend(backend_) { + } + + void bind() override { + assert(gfx::BackendScope::exists()); + backend.setFramebufferBinding(0); + backend.setViewport(0, 0, backend.getSize()); + } + +private: + AndroidRendererBackend& backend; +}; + +AndroidRendererBackend::AndroidRendererBackend() + : mbgl::gfx::Renderable({ 64, 64 }, std::make_unique<AndroidGLRenderableResource>(*this)) { } -/** - * From mbgl::RendererBackend. - */ +AndroidRendererBackend::~AndroidRendererBackend() = default; + gl::ProcAddress AndroidRendererBackend::getExtensionFunctionPointer(const char* name) { assert(gfx::BackendScope::exists()); return eglGetProcAddress(name); @@ -28,34 +39,26 @@ gl::ProcAddress AndroidRendererBackend::getExtensionFunctionPointer(const char* void AndroidRendererBackend::updateViewPort() { assert(gfx::BackendScope::exists()); - setViewport(0, 0, getFramebufferSize()); + setViewport(0, 0, size); } void AndroidRendererBackend::resizeFramebuffer(int width, int height) { - fbWidth = width; - fbHeight = height; + size = { static_cast<uint32_t>(width), static_cast<uint32_t>(height) }; } -PremultipliedImage AndroidRendererBackend::readFramebuffer() const { +PremultipliedImage AndroidRendererBackend::readFramebuffer() { assert(gfx::BackendScope::exists()); - return RendererBackend::readFramebuffer(getFramebufferSize()); -} - -mbgl::Size AndroidRendererBackend::getFramebufferSize() const { - return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) }; + return gl::RendererBackend::readFramebuffer(size); } -/** - * From mbgl::RendererBackend. - */ void AndroidRendererBackend::updateAssumedState() { assumeFramebufferBinding(0); - assumeViewport(0, 0, getFramebufferSize()); + assumeViewport(0, 0, size); } void AndroidRendererBackend::markContextLost() { if (context) { - context->setCleanupOnDestruction(false); + getGLContext().setCleanupOnDestruction(false); } } diff --git a/platform/android/src/android_renderer_backend.hpp b/platform/android/src/android_renderer_backend.hpp index d2c100dcc1..f06f38e688 100755 --- a/platform/android/src/android_renderer_backend.hpp +++ b/platform/android/src/android_renderer_backend.hpp @@ -1,40 +1,42 @@ #pragma once -#include <mbgl/renderer/renderer_backend.hpp> +#include <mbgl/gfx/renderable.hpp> +#include <mbgl/gl/renderer_backend.hpp> namespace mbgl { namespace android { -class AndroidRendererBackend : public RendererBackend { +class AndroidRendererBackend : public gl::RendererBackend, public mbgl::gfx::Renderable { public: + AndroidRendererBackend(); + ~AndroidRendererBackend() override; - // mbgl::RendererBackend // - void bind() override; - void updateAssumedState() override; - mbgl::Size getFramebufferSize() const override; + void updateViewPort(); - // Ensures the current context is not - // cleaned up when destroyed + // Ensures the current context is not cleaned up when destroyed void markContextLost(); - void updateViewPort(); - void resizeFramebuffer(int width, int height); - PremultipliedImage readFramebuffer() const; - -protected: - // mbgl::RendererBackend // - gl::ProcAddress getExtensionFunctionPointer(const char*) override; - void activate() override {}; - void deactivate() override {}; + PremultipliedImage readFramebuffer(); + // mbgl::gfx::RendererBackend implementation +public: + mbgl::gfx::Renderable& getDefaultRenderable() override { + return *this; + } -private: - - // Minimum texture size according to OpenGL ES 2.0 specification. - int fbWidth = 64; - int fbHeight = 64; - +protected: + void activate() override { + // no-op + } + void deactivate() override { + // no-op + } + + // mbgl::gl::RendererBackend implementation +protected: + mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) override; + void updateAssumedState() override; }; } // namespace android diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp index f0273cee50..7fefa457b1 100644 --- a/platform/android/src/map_renderer.cpp +++ b/platform/android/src/map_renderer.cpp @@ -1,6 +1,7 @@ #include "map_renderer.hpp" #include <mbgl/renderer/renderer.hpp> +#include <mbgl/gfx/backend_scope.hpp> #include <mbgl/util/shared_thread_pool.hpp> #include <mbgl/util/run_loop.hpp> @@ -159,6 +160,9 @@ void MapRenderer::onSurfaceCreated(JNIEnv&) { // Lock as the initialization can come from the main thread or the GL thread first std::lock_guard<std::mutex> lock(initialisationMutex); + // The GL context is already active if get a new surface. + gfx::BackendScope backendGuard { *backend, gfx::BackendScope::ScopeType::Implicit }; + // The android system will have already destroyed the underlying // GL resources if this is not the first initialization and an // attempt to clean them up will fail diff --git a/platform/darwin/src/MGLRendererFrontend.h b/platform/darwin/src/MGLRendererFrontend.h index 5e6a051bbb..ead6ad2660 100644 --- a/platform/darwin/src/MGLRendererFrontend.h +++ b/platform/darwin/src/MGLRendererFrontend.h @@ -1,7 +1,7 @@ #include <mbgl/gfx/backend_scope.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/renderer/renderer_frontend.hpp> +#include <mbgl/gl/renderer_backend.hpp> #include <mbgl/util/async_task.hpp> #include <mbgl/util/optional.hpp> @@ -13,7 +13,7 @@ class MGLRenderFrontend : public mbgl::RendererFrontend { public: - MGLRenderFrontend(std::unique_ptr<mbgl::Renderer> renderer_, MGLMapView* nativeView_, mbgl::RendererBackend& mbglBackend_, bool async = false) + MGLRenderFrontend(std::unique_ptr<mbgl::Renderer> renderer_, MGLMapView* nativeView_, mbgl::gl::RendererBackend& mbglBackend_, bool async = false) : renderer(std::move(renderer_)) , nativeView(nativeView_) , mbglBackend(mbglBackend_) { @@ -69,7 +69,7 @@ public: private: std::unique_ptr<mbgl::Renderer> renderer; __weak MGLMapView *nativeView = nullptr; - mbgl::RendererBackend& mbglBackend; + mbgl::gl::RendererBackend& mbglBackend; std::shared_ptr<mbgl::UpdateParameters> updateParameters; mbgl::optional<mbgl::util::AsyncTask> asyncInvalidate; }; diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp index 46a5beb870..a21bcad9d0 100644 --- a/platform/darwin/src/headless_backend_cgl.cpp +++ b/platform/darwin/src/headless_backend_cgl.cpp @@ -8,6 +8,7 @@ #include <stdexcept> namespace mbgl { +namespace gl { // This class provides a singleton that contains information about the pixel format used for // instantiating new headless rendering contexts. @@ -125,4 +126,5 @@ void HeadlessBackend::createImpl() { impl = std::make_unique<CGLBackendImpl>(); } +} // namespace gl } // namespace mbgl diff --git a/platform/darwin/src/headless_backend_eagl.mm b/platform/darwin/src/headless_backend_eagl.mm index 050fa62c78..4ccc485313 100644 --- a/platform/darwin/src/headless_backend_eagl.mm +++ b/platform/darwin/src/headless_backend_eagl.mm @@ -5,6 +5,7 @@ #include <stdexcept> namespace mbgl { +namespace gl { class EAGLBackendImpl : public HeadlessBackend::Impl { public: @@ -50,4 +51,5 @@ void HeadlessBackend::createImpl() { impl = std::make_unique<EAGLBackendImpl>(); } +} // namespace gl } // namespace mbgl diff --git a/platform/default/include/mbgl/gl/headless_backend.hpp b/platform/default/include/mbgl/gl/headless_backend.hpp index 7757037533..9135c269be 100644 --- a/platform/default/include/mbgl/gl/headless_backend.hpp +++ b/platform/default/include/mbgl/gl/headless_backend.hpp @@ -1,19 +1,22 @@ #pragma once -#include <mbgl/renderer/renderer_backend.hpp> +#include <mbgl/gfx/renderable.hpp> +#include <mbgl/gl/renderer_backend.hpp> #include <memory> #include <functional> namespace mbgl { +namespace gl { -class HeadlessBackend : public RendererBackend { +class HeadlessBackend final : public gl::RendererBackend, public gfx::Renderable { public: HeadlessBackend(Size = { 256, 256 }); ~HeadlessBackend() override; - void bind() override; - Size getFramebufferSize() const override; + gfx::Renderable& getDefaultRenderable() override; + + Size getFramebufferSize() const; void updateAssumedState() override; void setSize(Size); @@ -39,12 +42,9 @@ private: private: std::unique_ptr<Impl> impl; - Size size; float pixelRatio; bool active = false; - - class View; - std::unique_ptr<View> view; }; +} // namespace gl } // namespace mbgl diff --git a/platform/default/include/mbgl/gl/headless_frontend.hpp b/platform/default/include/mbgl/gl/headless_frontend.hpp index ca3230a809..2e9378bf8f 100644 --- a/platform/default/include/mbgl/gl/headless_frontend.hpp +++ b/platform/default/include/mbgl/gl/headless_frontend.hpp @@ -13,10 +13,13 @@ namespace mbgl { class Scheduler; class Renderer; -class RendererBackend; class Map; class TransformState; +namespace gfx { +class RendererBackend; +} // namespace gfx + class HeadlessFrontend : public RendererFrontend { public: HeadlessFrontend(float pixelRatio_, Scheduler&, const optional<std::string> programCacheDir = {}, GLContextMode mode = GLContextMode::Unique, const optional<std::string> localFontFamily = {}); @@ -31,7 +34,7 @@ public: void setSize(Size); Renderer* getRenderer(); - RendererBackend* getBackend(); + gfx::RendererBackend* getBackend(); CameraOptions getCameraOptions(); bool hasImage(const std::string&); @@ -50,7 +53,7 @@ private: Size size; float pixelRatio; - HeadlessBackend backend; + gl::HeadlessBackend backend; util::AsyncTask asyncInvalidate; std::unique_ptr<Renderer> renderer; diff --git a/platform/default/src/mbgl/gl/headless_backend.cpp b/platform/default/src/mbgl/gl/headless_backend.cpp index 4d05be1675..cbf451d80b 100644 --- a/platform/default/src/mbgl/gl/headless_backend.cpp +++ b/platform/default/src/mbgl/gl/headless_backend.cpp @@ -1,4 +1,5 @@ #include <mbgl/gl/headless_backend.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gfx/backend_scope.hpp> @@ -7,27 +8,38 @@ #include <type_traits> namespace mbgl { +namespace gl { -class HeadlessBackend::View { +class HeadlessRenderableResource final : public gl::RenderableResource { public: - View(gl::Context& context, Size size_) - : color(context.createRenderbuffer<gfx::RenderbufferPixelType::RGBA>(size_)), + HeadlessRenderableResource(gl::Context& context_, Size size_) + : context(context_), + color(context.createRenderbuffer<gfx::RenderbufferPixelType::RGBA>(size_)), depthStencil(context.createRenderbuffer<gfx::RenderbufferPixelType::DepthStencil>(size_)), framebuffer(context.createFramebuffer(color, depthStencil)) { } + void bind() override { + context.bindFramebuffer = framebuffer.framebuffer; + context.scissorTest = false; + context.viewport = { 0, 0, framebuffer.size }; + } + + gl::Context& context; gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA> color; gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil> depthStencil; gl::Framebuffer framebuffer; }; HeadlessBackend::HeadlessBackend(Size size_) - : size(size_) { + : mbgl::gfx::Renderable(size_, nullptr) { } HeadlessBackend::~HeadlessBackend() { gfx::BackendScope guard { *this }; - view.reset(); + resource.reset(); + // Explicitly reset the context so that it is destructed and cleaned up before we destruct + // the impl object. context.reset(); } @@ -53,16 +65,11 @@ void HeadlessBackend::deactivate() { active = false; } -void HeadlessBackend::bind() { - gl::Context& context_ = getContext(); - - if (!view) { - view = std::make_unique<View>(context_, size); +gfx::Renderable& HeadlessBackend::getDefaultRenderable() { + if (!resource) { + resource = std::make_unique<HeadlessRenderableResource>(static_cast<gl::Context&>(getContext()), size); } - - context_.bindFramebuffer = view->framebuffer.framebuffer; - context_.scissorTest = false; - context_.viewport = { 0, 0, size }; + return *this; } Size HeadlessBackend::getFramebufferSize() const { @@ -75,11 +82,12 @@ void HeadlessBackend::updateAssumedState() { void HeadlessBackend::setSize(Size size_) { size = size_; - view.reset(); + resource.reset(); } PremultipliedImage HeadlessBackend::readStillImage() { - return getContext().readFramebuffer<PremultipliedImage>(size); + return static_cast<gl::Context&>(getContext()).readFramebuffer<PremultipliedImage>(size); } +} // namespace gl } // namespace mbgl diff --git a/platform/default/src/mbgl/gl/headless_frontend.cpp b/platform/default/src/mbgl/gl/headless_frontend.cpp index 3c8188c8a3..406c197904 100644 --- a/platform/default/src/mbgl/gl/headless_frontend.cpp +++ b/platform/default/src/mbgl/gl/headless_frontend.cpp @@ -1,4 +1,5 @@ #include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/gfx/backend_scope.hpp> #include <mbgl/renderer/renderer.hpp> #include <mbgl/renderer/renderer_state.hpp> #include <mbgl/renderer/update_parameters.hpp> @@ -58,7 +59,7 @@ Renderer* HeadlessFrontend::getRenderer() { return renderer.get(); } -RendererBackend* HeadlessFrontend::getBackend() { +gfx::RendererBackend* HeadlessFrontend::getBackend() { return &backend; } diff --git a/platform/glfw/glfw_backend.hpp b/platform/glfw/glfw_backend.hpp new file mode 100644 index 0000000000..1a2c89ac7a --- /dev/null +++ b/platform/glfw/glfw_backend.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include <mbgl/util/size.hpp> + +namespace mbgl { +namespace gfx { +class RendererBackend; +} // namespace gfx +} // namespace mbgl + +class GLFWBackend { +public: + explicit GLFWBackend() = default; + GLFWBackend(const GLFWBackend&) = delete; + GLFWBackend& operator=(const GLFWBackend&) = delete; + virtual ~GLFWBackend() = default; + + virtual mbgl::gfx::RendererBackend& getRendererBackend() = 0; + virtual mbgl::Size getSize() const = 0; + virtual void setSize(mbgl::Size) = 0; +}; diff --git a/platform/glfw/glfw_gl_backend.cpp b/platform/glfw/glfw_gl_backend.cpp new file mode 100644 index 0000000000..b61e2775d5 --- /dev/null +++ b/platform/glfw/glfw_gl_backend.cpp @@ -0,0 +1,58 @@ +#include "glfw_gl_backend.hpp" + +#include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gl/renderable_resource.hpp> + +#include <GLFW/glfw3.h> + +class GLFWGLRenderableResource final : public mbgl::gl::RenderableResource { +public: + GLFWGLRenderableResource(GLFWGLBackend& backend_) : backend(backend_) { + } + + void bind() override { + backend.setFramebufferBinding(0); + backend.setViewport(0, 0, backend.getSize()); + } + +private: + GLFWGLBackend& backend; +}; + +GLFWGLBackend::GLFWGLBackend(GLFWwindow* window_) + : mbgl::gfx::Renderable( + [window_] { + int fbWidth, fbHeight; + glfwGetFramebufferSize(window_, &fbWidth, &fbHeight); + return mbgl::Size{ static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) }; + }(), + std::make_unique<GLFWGLRenderableResource>(*this)), + window(window_) { +} + +GLFWGLBackend::~GLFWGLBackend() = default; + +void GLFWGLBackend::activate() { + glfwMakeContextCurrent(window); +} + +void GLFWGLBackend::deactivate() { + glfwMakeContextCurrent(nullptr); +} + +mbgl::gl::ProcAddress GLFWGLBackend::getExtensionFunctionPointer(const char* name) { + return glfwGetProcAddress(name); +} + +void GLFWGLBackend::updateAssumedState() { + assumeFramebufferBinding(0); + assumeViewport(0, 0, size); +} + +mbgl::Size GLFWGLBackend::getSize() const { + return size; +} + +void GLFWGLBackend::setSize(const mbgl::Size newSize) { + size = newSize; +} diff --git a/platform/glfw/glfw_gl_backend.hpp b/platform/glfw/glfw_gl_backend.hpp new file mode 100644 index 0000000000..ba4f6fa788 --- /dev/null +++ b/platform/glfw/glfw_gl_backend.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "glfw_backend.hpp" + +#include <mbgl/gfx/renderable.hpp> +#include <mbgl/gl/renderer_backend.hpp> + +struct GLFWwindow; + +class GLFWGLBackend final : public GLFWBackend, + public mbgl::gl::RendererBackend, + public mbgl::gfx::Renderable { +public: + GLFWGLBackend(GLFWwindow*); + ~GLFWGLBackend() override; + + // GLFWRendererBackend implementation +public: + mbgl::gfx::RendererBackend& getRendererBackend() override { + return *this; + } + mbgl::Size getSize() const override; + void setSize(mbgl::Size) override; + + // mbgl::gfx::RendererBackend implementation +public: + mbgl::gfx::Renderable& getDefaultRenderable() override { + return *this; + } + +protected: + void activate() override; + void deactivate() override; + + // mbgl::gl::RendererBackend implementation +protected: + mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) override; + void updateAssumedState() override; + +private: + GLFWwindow* window; +}; diff --git a/platform/glfw/glfw_renderer_frontend.cpp b/platform/glfw/glfw_renderer_frontend.cpp index 82efbcdfb1..b8478a49f8 100644 --- a/platform/glfw/glfw_renderer_frontend.cpp +++ b/platform/glfw/glfw_renderer_frontend.cpp @@ -31,7 +31,7 @@ void GLFWRendererFrontend::render() { if (!updateParameters) return; - mbgl::gfx::BackendScope guard { glfwView, mbgl::gfx::BackendScope::ScopeType::Implicit }; + mbgl::gfx::BackendScope guard { glfwView.getRendererBackend(), mbgl::gfx::BackendScope::ScopeType::Implicit }; // onStyleImageMissing might be called during a render. The user implemented method // could trigger a call to MGLRenderFrontend#update which overwrites `updateParameters`. diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 483ca14559..2772ed0773 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -1,4 +1,5 @@ #include "glfw_view.hpp" +#include "glfw_gl_backend.hpp" #include "glfw_renderer_frontend.hpp" #include "ny_route.hpp" @@ -105,8 +106,10 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_) glfwSetKeyCallback(window, onKey); glfwGetWindowSize(window, &width, &height); - glfwGetFramebufferSize(window, &fbWidth, &fbHeight); - pixelRatio = static_cast<float>(fbWidth) / width; + + backend = std::make_unique<GLFWGLBackend>(window); + + pixelRatio = static_cast<float>(backend->getSize().width) / width; glfwMakeContextCurrent(nullptr); @@ -158,14 +161,8 @@ void GLFWView::setRenderFrontend(GLFWRendererFrontend* rendererFrontend_) { rendererFrontend = rendererFrontend_; } -void GLFWView::updateAssumedState() { - assumeFramebufferBinding(0); - assumeViewport(0, 0, getFramebufferSize()); -} - -void GLFWView::bind() { - setFramebufferBinding(0); - setViewport(0, 0, getFramebufferSize()); +mbgl::gfx::RendererBackend& GLFWView::getRendererBackend() { + return backend->getRendererBackend(); } void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { @@ -499,11 +496,7 @@ void GLFWView::onWindowResize(GLFWwindow *window, int width, int height) { void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) { auto *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window)); - view->fbWidth = width; - view->fbHeight = height; - - mbgl::gfx::BackendScope scope { *view, mbgl::gfx::BackendScope::ScopeType::Implicit }; - view->bind(); + view->backend->setSize({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) }); // This is only triggered when the framebuffer is resized, but not the window. It can // happen when you move the window between screens with a different pixel ratio. @@ -578,7 +571,7 @@ void GLFWView::run() { updateAnimatedAnnotations(); - activate(); + mbgl::gfx::BackendScope scope { backend->getRendererBackend() }; rendererFrontend->render(); @@ -608,22 +601,6 @@ mbgl::Size GLFWView::getSize() const { return { static_cast<uint32_t>(width), static_cast<uint32_t>(height) }; } -mbgl::Size GLFWView::getFramebufferSize() const { - return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) }; -} - -mbgl::gl::ProcAddress GLFWView::getExtensionFunctionPointer(const char* name) { - return glfwGetProcAddress(name); -} - -void GLFWView::activate() { - glfwMakeContextCurrent(window); -} - -void GLFWView::deactivate() { - glfwMakeContextCurrent(nullptr); -} - void GLFWView::invalidate() { dirty = true; glfwPostEmptyEvent(); diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp index d5acf697f7..9b580f80cc 100644 --- a/platform/glfw/glfw_view.hpp +++ b/platform/glfw/glfw_view.hpp @@ -1,15 +1,21 @@ #pragma once #include <mbgl/map/map.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/timer.hpp> #include <mbgl/util/geometry.hpp> struct GLFWwindow; +class GLFWBackend; class GLFWRendererFrontend; -class GLFWView : public mbgl::RendererBackend, public mbgl::MapObserver { +namespace mbgl { +namespace gfx { +class RendererBackend; +} // namespace gfx +} // namespace mbgl + +class GLFWView : public mbgl::MapObserver { public: GLFWView(bool fullscreen = false, bool benchmark = false); ~GLFWView() override; @@ -20,6 +26,8 @@ public: void setRenderFrontend(GLFWRendererFrontend*); + mbgl::gfx::RendererBackend& getRendererBackend(); + // Callback called when the user presses the key mapped to style change. // The expected action is to set a new style, different to the current one. void setChangeStyleCallback(std::function<void()> callback); @@ -41,20 +49,12 @@ public: void invalidate(); mbgl::Size getSize() const; - mbgl::Size getFramebufferSize() const override; - - // mbgl::RendererBackend implementation - void bind() override; - void updateAssumedState() override; // mbgl::MapObserver implementation void onDidFinishLoadingStyle() override; protected: // mbgl::Backend implementation - mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) override; - void activate() override; - void deactivate() override; private: // Window callbacks @@ -95,6 +95,7 @@ private: mbgl::Map* map = nullptr; GLFWRendererFrontend* rendererFrontend = nullptr; + std::unique_ptr<GLFWBackend> backend; bool fullscreen = false; const bool benchmark = false; @@ -110,8 +111,6 @@ private: int width = 1024; int height = 768; - int fbWidth; - int fbHeight; float pixelRatio; double lastX = 0, lastY = 0; diff --git a/platform/glfw/main.cpp b/platform/glfw/main.cpp index fb7c2b4ffb..0a4ace6a19 100644 --- a/platform/glfw/main.cpp +++ b/platform/glfw/main.cpp @@ -109,9 +109,9 @@ int main(int argc, char *argv[]) { } mbgl::ThreadPool threadPool(4); - GLFWRendererFrontend rendererFrontend { std::make_unique<mbgl::Renderer>(backend, view->getPixelRatio(), threadPool), backend }; + GLFWRendererFrontend rendererFrontend { std::make_unique<mbgl::Renderer>(view->getRendererBackend(), view->getPixelRatio(), threadPool), *view }; - mbgl::Map map(rendererFrontend, backend, threadPool, + mbgl::Map map(rendererFrontend, *view, threadPool, mbgl::MapOptions().withSize(view->getSize()).withPixelRatio(view->getPixelRatio()), resourceOptions); backend.setMap(&map); diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index f78b2d150c..4cbe839179 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -19,7 +19,8 @@ #include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/renderer/mode.hpp> #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/renderer_backend.hpp> +#import <mbgl/gl/renderer_backend.hpp> +#import <mbgl/gl/renderable_resource.hpp> #include <mbgl/math/wrap.hpp> #include <mbgl/util/exception.hpp> #include <mbgl/util/geo.hpp> @@ -6719,10 +6720,26 @@ public: return _annotationViewReuseQueueByIdentifier[identifier]; } -class MBGLView : public mbgl::RendererBackend, public mbgl::MapObserver -{ +class MBGLView; + +class MBGLMapViewRenderable final : public mbgl::gl::RenderableResource { +public: + MBGLMapViewRenderable(MBGLView& backend_) : backend(backend_) { + } + + void bind() override; + +private: + MBGLView& backend; +}; + +class MBGLView : public mbgl::gl::RendererBackend, + public mbgl::gfx::Renderable, + public mbgl::MapObserver { public: - MBGLView(MGLMapView* nativeView_) : nativeView(nativeView_) { + MBGLView(MGLMapView* nativeView_) : mbgl::gfx::Renderable( + nativeView_.framebufferSize, + std::make_unique<MBGLMapViewRenderable>(*this)), nativeView(nativeView_) { } /// This function is called before we start rendering, when iOS invokes our rendering method. @@ -6733,7 +6750,7 @@ public: assumeViewport(0, 0, nativeView.framebufferSize); } - void bind() override { + void restoreFramebufferBinding() { if (!implicitFramebufferBound()) { // Something modified our state, and we need to bind the original drawable again. // Doing this also sets the viewport to the full framebuffer. @@ -6747,10 +6764,6 @@ public: } } - mbgl::Size getFramebufferSize() const override { - return nativeView.framebufferSize; - } - void onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) override { bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated; [nativeView cameraWillChangeAnimated:animated]; @@ -6855,6 +6868,10 @@ public: return reinterpret_cast<mbgl::gl::ProcAddress>(symbol); } + mbgl::gfx::Renderable& getDefaultRenderable() override { + return *this; + } + void activate() override { if (activationCount++) @@ -6876,11 +6893,15 @@ public: } private: - __weak MGLMapView *nativeView = nullptr; + __weak MGLMapView* nativeView = nullptr; NSUInteger activationCount = 0; }; +void MBGLMapViewRenderable::bind() { + backend.restoreFramebufferBinding(); +} + @end #pragma mark - IBAdditions methods diff --git a/platform/linux/src/headless_backend_egl.cpp b/platform/linux/src/headless_backend_egl.cpp index d72fbbfdea..21db012510 100644 --- a/platform/linux/src/headless_backend_egl.cpp +++ b/platform/linux/src/headless_backend_egl.cpp @@ -8,6 +8,7 @@ #include <cassert> namespace mbgl { +namespace gl { // This class provides a singleton that contains information about the configuration used for // instantiating new headless rendering contexts. @@ -142,4 +143,5 @@ void HeadlessBackend::createImpl() { impl = std::make_unique<EGLBackendImpl>(); } +} // namespace gl } // namespace mbgl diff --git a/platform/linux/src/headless_backend_glx.cpp b/platform/linux/src/headless_backend_glx.cpp index 27af98e70a..4045d6635e 100644 --- a/platform/linux/src/headless_backend_glx.cpp +++ b/platform/linux/src/headless_backend_glx.cpp @@ -7,6 +7,7 @@ #include <GL/glx.h> namespace mbgl { +namespace gl { // This class provides a singleton that contains information about the configuration used for // instantiating new headless rendering contexts. @@ -127,4 +128,5 @@ void HeadlessBackend::createImpl() { impl = std::make_unique<GLXBackendImpl>(); } +} // namespace gl } // namespace mbgl diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index cb0cd7fa00..589d866782 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -34,7 +34,8 @@ #import <mbgl/util/default_thread_pool.hpp> #import <mbgl/style/image.hpp> #import <mbgl/renderer/renderer.hpp> -#import <mbgl/renderer/renderer_backend.hpp> +#import <mbgl/gl/renderer_backend.hpp> +#import <mbgl/gl/renderable_resource.hpp> #import <mbgl/storage/network_status.hpp> #import <mbgl/storage/resource_options.hpp> #import <mbgl/math/wrap.hpp> @@ -3041,10 +3042,27 @@ public: _mbglMap->setDebug(options); } +class MGLMapViewImpl; + +class MGLMapViewRenderable final : public mbgl::gl::RenderableResource { +public: + MGLMapViewRenderable(MGLMapViewImpl& backend_) : backend(backend_) { + } + + void bind() override; + +private: + MGLMapViewImpl& backend; +}; + /// Adapter responsible for bridging calls from mbgl to MGLMapView and Cocoa. -class MGLMapViewImpl : public mbgl::RendererBackend, public mbgl::MapObserver { +class MGLMapViewImpl : public mbgl::gl::RendererBackend, + public mbgl::gfx::Renderable, + public mbgl::MapObserver { public: - MGLMapViewImpl(MGLMapView *nativeView_) : nativeView(nativeView_) {} + MGLMapViewImpl(MGLMapView *nativeView_) : mbgl::gfx::Renderable( + nativeView_.framebufferSize, + std::make_unique<MGLMapViewRenderable>(*this)), nativeView(nativeView_) {} void onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) override { bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated; @@ -3141,6 +3159,10 @@ public: return reinterpret_cast<mbgl::gl::ProcAddress>(symbol); } + mbgl::gfx::Renderable& getDefaultRenderable() override { + return *this; + } + void activate() override { if (activationCount++) { return; @@ -3164,15 +3186,11 @@ public: assumeViewport(0, 0, nativeView.framebufferSize); } - void bind() override { + void restoreFramebufferBinding() { setFramebufferBinding(fbo); setViewport(0, 0, nativeView.framebufferSize); } - mbgl::Size getFramebufferSize() const override { - return nativeView.framebufferSize; - } - mbgl::PremultipliedImage readStillImage() { return readFramebuffer(nativeView.framebufferSize); } @@ -3188,4 +3206,8 @@ private: NSUInteger activationCount = 0; }; +void MGLMapViewRenderable::bind() { + backend.restoreFramebufferBinding(); +} + @end diff --git a/platform/qt/src/headless_backend_qt.cpp b/platform/qt/src/headless_backend_qt.cpp index 3702fdf14a..1d62afabff 100644 --- a/platform/qt/src/headless_backend_qt.cpp +++ b/platform/qt/src/headless_backend_qt.cpp @@ -6,21 +6,22 @@ #include <cassert> namespace mbgl { +namespace gl { -class QtBackendImpl : public HeadlessBackend::Impl { +class QtBackendImpl final : public HeadlessBackend::Impl { public: - ~QtBackendImpl() final = default; + ~QtBackendImpl() = default; - gl::ProcAddress getExtensionFunctionPointer(const char* name) final { + gl::ProcAddress getExtensionFunctionPointer(const char* name) { QOpenGLContext* thisContext = QOpenGLContext::currentContext(); return thisContext->getProcAddress(name); } - void activateContext() final { + void activateContext() { widget.makeCurrent(); } - void deactivateContext() final { + void deactivateContext() { widget.doneCurrent(); } @@ -33,4 +34,5 @@ void HeadlessBackend::createImpl() { impl = std::make_unique<QtBackendImpl>(); } +} // namespace gl } // namespace mbgl diff --git a/platform/qt/src/qmapboxgl_map_renderer.cpp b/platform/qt/src/qmapboxgl_map_renderer.cpp index 6b4103eabf..d10df50149 100644 --- a/platform/qt/src/qmapboxgl_map_renderer.cpp +++ b/platform/qt/src/qmapboxgl_map_renderer.cpp @@ -1,6 +1,8 @@ #include "qmapboxgl_map_renderer.hpp" #include "qmapboxgl_scheduler.hpp" +#include <mbgl/gfx/backend_scope.hpp> + #include <QThreadStorage> #include <QtGlobal> diff --git a/platform/qt/src/qmapboxgl_map_renderer.hpp b/platform/qt/src/qmapboxgl_map_renderer.hpp index d771a416da..7db0da99fa 100644 --- a/platform/qt/src/qmapboxgl_map_renderer.hpp +++ b/platform/qt/src/qmapboxgl_map_renderer.hpp @@ -4,7 +4,6 @@ #include "qmapboxgl_renderer_backend.hpp" #include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/renderer/renderer_observer.hpp> #include <mbgl/util/shared_thread_pool.hpp> #include <mbgl/util/util.hpp> diff --git a/platform/qt/src/qmapboxgl_renderer_backend.cpp b/platform/qt/src/qmapboxgl_renderer_backend.cpp index ac12981279..2a9706eb48 100644 --- a/platform/qt/src/qmapboxgl_renderer_backend.cpp +++ b/platform/qt/src/qmapboxgl_renderer_backend.cpp @@ -1,39 +1,51 @@ #include "qmapboxgl_renderer_backend.hpp" +#include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gl/renderable_resource.hpp> + #include <QOpenGLContext> #include <QtGlobal> -void QMapboxGLRendererBackend::updateAssumedState() -{ - assumeFramebufferBinding(ImplicitFramebufferBinding); - assumeViewport(0, 0, m_size); +class QMapboxGLRenderableResource final : public mbgl::gl::RenderableResource { +public: + QMapboxGLRenderableResource(QMapboxGLRendererBackend& backend_) : backend(backend_) { + } + + void bind() override { + assert(mbgl::gfx::BackendScope::exists()); + backend.restoreFramebufferBinding(); + backend.setViewport(0, 0, backend.getSize()); + } + +private: + QMapboxGLRendererBackend& backend; +}; + +QMapboxGLRendererBackend::QMapboxGLRendererBackend() + : mbgl::gfx::Renderable({ 0, 0 }, std::make_unique<QMapboxGLRenderableResource>(*this)) { } -void QMapboxGLRendererBackend::bind() -{ - assert(mbgl::gfx::BackendScope::exists()); +QMapboxGLRendererBackend::~QMapboxGLRendererBackend() = default; - setFramebufferBinding(m_fbo); - setViewport(0, 0, m_size); +void QMapboxGLRendererBackend::updateAssumedState() { + assumeFramebufferBinding(ImplicitFramebufferBinding); + assumeViewport(0, 0, size); } -mbgl::Size QMapboxGLRendererBackend::getFramebufferSize() const -{ - return m_size; +void QMapboxGLRendererBackend::restoreFramebufferBinding() { + setFramebufferBinding(m_fbo); } -void QMapboxGLRendererBackend::updateFramebuffer(quint32 fbo, const mbgl::Size &size) -{ +void QMapboxGLRendererBackend::updateFramebuffer(quint32 fbo, const mbgl::Size& newSize) { m_fbo = fbo; - m_size = size; + size = newSize; } /*! Initializes an OpenGL extension function such as Vertex Array Objects (VAOs), required by Mapbox GL Native engine. */ -mbgl::gl::ProcAddress QMapboxGLRendererBackend::getExtensionFunctionPointer(const char* name) -{ +mbgl::gl::ProcAddress QMapboxGLRendererBackend::getExtensionFunctionPointer(const char* name) { QOpenGLContext* thisContext = QOpenGLContext::currentContext(); return thisContext->getProcAddress(name); } diff --git a/platform/qt/src/qmapboxgl_renderer_backend.hpp b/platform/qt/src/qmapboxgl_renderer_backend.hpp index 476b3502c1..8d015f500d 100644 --- a/platform/qt/src/qmapboxgl_renderer_backend.hpp +++ b/platform/qt/src/qmapboxgl_renderer_backend.hpp @@ -2,32 +2,37 @@ #include "qmapboxgl.hpp" -#include <mbgl/renderer/renderer_backend.hpp> +#include <mbgl/gfx/renderable.hpp> +#include <mbgl/gl/renderer_backend.hpp> #include <mbgl/util/shared_thread_pool.hpp> -class QMapboxGLRendererBackend : public mbgl::RendererBackend -{ +class QMapboxGLRendererBackend final : public mbgl::gl::RendererBackend, + public mbgl::gfx::Renderable { public: - QMapboxGLRendererBackend() = default; - virtual ~QMapboxGLRendererBackend() = default; + QMapboxGLRendererBackend(); + ~QMapboxGLRendererBackend() override; - // mbgl::RendererBackend implementation - void updateAssumedState() final; - void bind() final; - mbgl::Size getFramebufferSize() const final; + void updateFramebuffer(quint32 fbo, const mbgl::Size&); + void restoreFramebufferBinding(); - void updateFramebuffer(quint32 fbo, const mbgl::Size &); + // mbgl::gfx::RendererBackend implementation +public: + mbgl::gfx::Renderable& getDefaultRenderable() override { + return *this; + } protected: - mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) final; - // No-op, implicit mode. - void activate() final {} - void deactivate() final {} + void activate() override {} + void deactivate() override {} + + // mbgl::gl::RendererBackend implementation +protected: + mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) override; + void updateAssumedState() override; private: quint32 m_fbo = 0; - mbgl::Size m_size = { 0, 0 }; Q_DISABLE_COPY(QMapboxGLRendererBackend) }; diff --git a/platform/qt/src/qt_geojson.cpp b/platform/qt/src/qt_geojson.cpp index cd808f016c..48d78abfe0 100644 --- a/platform/qt/src/qt_geojson.cpp +++ b/platform/qt/src/qt_geojson.cpp @@ -3,6 +3,8 @@ #include <mbgl/util/geometry.hpp> #include <mbgl/util/feature.hpp> +#pragma clang diagnostic ignored "-Wenum-compare-switch" + namespace QMapbox { mbgl::Point<double> asMapboxGLPoint(const QMapbox::Coordinate &coordinate) { diff --git a/src/core-files.json b/src/core-files.json index 9d3cbddd7f..23ccc6d631 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -17,6 +17,7 @@ "src/mbgl/geometry/feature_index.cpp", "src/mbgl/geometry/line_atlas.cpp", "src/mbgl/gfx/attribute.cpp", + "src/mbgl/gfx/renderer_backend.cpp", "src/mbgl/gl/attribute.cpp", "src/mbgl/gl/binary_program.cpp", "src/mbgl/gl/command_encoder.cpp", @@ -25,6 +26,7 @@ "src/mbgl/gl/enum.cpp", "src/mbgl/gl/object.cpp", "src/mbgl/gl/offscreen_texture.cpp", + "src/mbgl/gl/renderer_backend.cpp", "src/mbgl/gl/texture.cpp", "src/mbgl/gl/uniform.cpp", "src/mbgl/gl/value.cpp", @@ -130,7 +132,6 @@ "src/mbgl/renderer/render_static_data.cpp", "src/mbgl/renderer/render_tile.cpp", "src/mbgl/renderer/renderer.cpp", - "src/mbgl/renderer/renderer_backend.cpp", "src/mbgl/renderer/renderer_impl.cpp", "src/mbgl/renderer/renderer_state.cpp", "src/mbgl/renderer/sources/render_custom_geometry_source.cpp", @@ -323,7 +324,9 @@ "mbgl/annotation/annotation.hpp": "include/mbgl/annotation/annotation.hpp", "mbgl/gfx/backend_scope.hpp": "include/mbgl/gfx/backend_scope.hpp", "mbgl/gfx/renderable.hpp": "include/mbgl/gfx/renderable.hpp", + "mbgl/gfx/renderer_backend.hpp": "include/mbgl/gfx/renderer_backend.hpp", "mbgl/gl/renderable_resource.hpp": "include/mbgl/gl/renderable_resource.hpp", + "mbgl/gl/renderer_backend.hpp": "include/mbgl/gl/renderer_backend.hpp", "mbgl/layermanager/background_layer_factory.hpp": "include/mbgl/layermanager/background_layer_factory.hpp", "mbgl/layermanager/circle_layer_factory.hpp": "include/mbgl/layermanager/circle_layer_factory.hpp", "mbgl/layermanager/custom_layer_factory.hpp": "include/mbgl/layermanager/custom_layer_factory.hpp", @@ -352,7 +355,6 @@ "mbgl/renderer/mode.hpp": "include/mbgl/renderer/mode.hpp", "mbgl/renderer/query.hpp": "include/mbgl/renderer/query.hpp", "mbgl/renderer/renderer.hpp": "include/mbgl/renderer/renderer.hpp", - "mbgl/renderer/renderer_backend.hpp": "include/mbgl/renderer/renderer_backend.hpp", "mbgl/renderer/renderer_frontend.hpp": "include/mbgl/renderer/renderer_frontend.hpp", "mbgl/renderer/renderer_observer.hpp": "include/mbgl/renderer/renderer_observer.hpp", "mbgl/renderer/renderer_state.hpp": "include/mbgl/renderer/renderer_state.hpp", diff --git a/src/mbgl/gfx/renderer_backend.cpp b/src/mbgl/gfx/renderer_backend.cpp new file mode 100644 index 0000000000..f0336f8b60 --- /dev/null +++ b/src/mbgl/gfx/renderer_backend.cpp @@ -0,0 +1,22 @@ +#include <mbgl/gfx/renderer_backend.hpp> +#include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gfx/context.hpp> + +namespace mbgl { +namespace gfx { + +RendererBackend::RendererBackend() = default; + +RendererBackend::~RendererBackend() = default; + +gfx::Context& RendererBackend::getContext() { + assert(BackendScope::exists()); + std::call_once(initialized, [this] { + context = createContext(); + }); + assert(context); + return *context; +} + +} // namespace gfx +} // namespace mbgl diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index d33ae067f6..458bf9b649 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -1,5 +1,6 @@ #include <mbgl/gl/context.hpp> #include <mbgl/gl/enum.hpp> +#include <mbgl/gl/renderer_backend.hpp> #include <mbgl/gl/vertex_buffer_resource.hpp> #include <mbgl/gl/index_buffer_resource.hpp> #include <mbgl/gl/texture_resource.hpp> @@ -53,12 +54,12 @@ static_assert(underlying_type(UniformDataType::SamplerCube) == GL_SAMPLER_CUBE, static_assert(std::is_same<BinaryProgramFormat, GLenum>::value, "OpenGL type mismatch"); -Context::Context() +Context::Context(RendererBackend& backend_) : gfx::Context(gfx::ContextType::OpenGL, [] { GLint value; MBGL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value)); return value; - }()) { + }()), backend(backend_) { } Context::~Context() { @@ -701,6 +702,7 @@ void Context::setColorMode(const gfx::ColorMode& color) { } std::unique_ptr<gfx::CommandEncoder> Context::createCommandEncoder() { + backend.updateAssumedState(); return std::make_unique<gl::CommandEncoder>(*this); } diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 2fb1d242ce..0fad92f3df 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -27,6 +27,7 @@ namespace gl { constexpr size_t TextureMax = 64; using ProcAddress = void (*)(); +class RendererBackend; namespace extension { class VertexArray; @@ -36,7 +37,7 @@ class ProgramBinary; class Context final : public gfx::Context { public: - Context(); + Context(RendererBackend&); ~Context() override; Context(const Context&) = delete; Context& operator=(const Context& other) = delete; @@ -136,6 +137,7 @@ public: } private: + RendererBackend& backend; bool cleanupOnDestruction = true; std::unique_ptr<extension::Debugging> debugging; diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp new file mode 100644 index 0000000000..ed3f38193f --- /dev/null +++ b/src/mbgl/gl/renderer_backend.cpp @@ -0,0 +1,71 @@ +#include <mbgl/gl/renderer_backend.hpp> +#include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/extension.hpp> + +#include <cassert> + +namespace mbgl { +namespace gl { + +RendererBackend::RendererBackend() = default; + +std::unique_ptr<gfx::Context> RendererBackend::createContext() { + auto result = std::make_unique<gl::Context>(*this); + result->enableDebugging(); + result->initializeExtensions( + std::bind(&RendererBackend::getExtensionFunctionPointer, this, std::placeholders::_1)); + // Needs move to placate GCC 4.9 + return std::move(result); +} + +gl::Context& RendererBackend::getGLContext() { + return static_cast<gl::Context&>(getContext()); +} + +PremultipliedImage RendererBackend::readFramebuffer(const Size& size) { + return getGLContext().readFramebuffer<PremultipliedImage>(size); +} + +void RendererBackend::assumeFramebufferBinding(const gl::FramebufferID fbo) { + getGLContext().bindFramebuffer.setCurrentValue(fbo); + if (fbo != ImplicitFramebufferBinding) { + assert(gl::value::BindFramebuffer::Get() == getGLContext().bindFramebuffer.getCurrentValue()); + } +} + +void RendererBackend::assumeViewport(int32_t x, int32_t y, const Size& size) { + getGLContext().viewport.setCurrentValue({ x, y, size }); + assert(gl::value::Viewport::Get() == getGLContext().viewport.getCurrentValue()); +} + +void RendererBackend::assumeScissorTest(bool enabled) { + getGLContext().scissorTest.setCurrentValue(enabled); + assert(gl::value::ScissorTest::Get() == getGLContext().scissorTest.getCurrentValue()); +} + +bool RendererBackend::implicitFramebufferBound() { + return getGLContext().bindFramebuffer.getCurrentValue() == ImplicitFramebufferBinding; +} + +void RendererBackend::setFramebufferBinding(const gl::FramebufferID fbo) { + getGLContext().bindFramebuffer = fbo; + if (fbo != ImplicitFramebufferBinding) { + assert(gl::value::BindFramebuffer::Get() == getGLContext().bindFramebuffer.getCurrentValue()); + } +} + +void RendererBackend::setViewport(int32_t x, int32_t y, const Size& size) { + getGLContext().viewport = { x, y, size }; + assert(gl::value::Viewport::Get() == getGLContext().viewport.getCurrentValue()); +} + +void RendererBackend::setScissorTest(bool enabled) { + getGLContext().scissorTest = enabled; + assert(gl::value::ScissorTest::Get() == getGLContext().scissorTest.getCurrentValue()); +} + +RendererBackend::~RendererBackend() = default; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/renderer/backend_scope.cpp b/src/mbgl/renderer/backend_scope.cpp index e4988a37c2..f3d7871473 100644 --- a/src/mbgl/renderer/backend_scope.cpp +++ b/src/mbgl/renderer/backend_scope.cpp @@ -1,5 +1,5 @@ -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/gfx/backend_scope.hpp> +#include <mbgl/gfx/renderer_backend.hpp> #include <mbgl/util/thread_local.hpp> #include <cassert> diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index 240aef84ce..0b99460e76 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -1,12 +1,13 @@ #include <mbgl/renderer/layers/render_custom_layer.hpp> #include <mbgl/renderer/paint_parameters.hpp> -#include <mbgl/renderer/renderer_backend.hpp> +#include <mbgl/gfx/renderer_backend.hpp> #include <mbgl/gfx/backend_scope.hpp> #include <mbgl/renderer/bucket.hpp> #include <mbgl/platform/gl_functions.hpp> #include <mbgl/style/layers/custom_layer_impl.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/util/mat4.hpp> namespace mbgl { @@ -86,7 +87,7 @@ void RenderCustomLayer::render(PaintParameters& paintParameters, RenderSource*) // Reset the view back to our original one, just in case the CustomLayer changed // the viewport or Framebuffer. - paintParameters.backend.bind(); + paintParameters.backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); glContext.setDirtyState(); } diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index d7c59570c1..720d2ff2f8 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -4,7 +4,6 @@ #include <mbgl/renderer/paint_parameters.hpp> #include <mbgl/renderer/image_manager.hpp> #include <mbgl/renderer/render_static_data.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/programs/programs.hpp> #include <mbgl/programs/fill_extrusion_program.hpp> #include <mbgl/tile/tile.hpp> @@ -13,6 +12,7 @@ #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> #include <mbgl/tile/geometry_tile.hpp> +#include <mbgl/gfx/renderer_backend.hpp> #include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gl/renderable_resource.hpp> diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index d2ff5841ec..3e44f7bfb0 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -8,8 +8,10 @@ #include <mbgl/tile/tile.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/geometry/feature_index.hpp> +#include <mbgl/gfx/renderer_backend.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> +#include <mbgl/gfx/context.hpp> +#include <mbgl/gfx/renderable.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> #include <mbgl/tile/geometry_tile.hpp> @@ -63,9 +65,6 @@ bool RenderFillLayer::hasCrossfade() const { } void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { - // TODO: remove cast - gl::Context& glContext = static_cast<gl::Context&>(parameters.context); - if (unevaluated.get<FillPattern>().isUndefined()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); @@ -89,7 +88,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { evaluated.get<FillTranslateAnchor>(), parameters.state) ), - uniforms::world::Value( glContext.viewport.getCurrentValue().size ), + uniforms::world::Value( parameters.backend.getDefaultRenderable().getSize() ), }, paintPropertyBinders, evaluated, @@ -174,7 +173,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(), parameters.state), - glContext.viewport.getCurrentValue().size, + parameters.backend.getDefaultRenderable().getSize(), geometryTile.iconAtlasTexture->size, crossfade, tile.id, diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index 3458c47da0..c162beaf61 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -9,7 +9,7 @@ namespace mbgl { PaintParameters::PaintParameters(gfx::Context& context_, float pixelRatio_, GLContextMode contextMode_, - RendererBackend& backend_, + gfx::RendererBackend& backend_, const UpdateParameters& updateParameters, const EvaluatedLight& evaluatedLight_, RenderStaticData& staticData_, diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index e553028f90..1329a14404 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -15,7 +15,6 @@ namespace mbgl { -class RendererBackend; class UpdateParameters; class RenderStaticData; class Programs; @@ -26,6 +25,7 @@ class UnwrappedTileID; namespace gfx { class Context; +class RendererBackend; class CommandEncoder; } // namespace gfx @@ -34,7 +34,7 @@ public: PaintParameters(gfx::Context&, float pixelRatio, GLContextMode, - RendererBackend&, + gfx::RendererBackend&, const UpdateParameters&, const EvaluatedLight&, RenderStaticData&, @@ -44,7 +44,7 @@ public: ~PaintParameters(); gfx::Context& context; - RendererBackend& backend; + gfx::RendererBackend& backend; const std::unique_ptr<gfx::CommandEncoder> encoder; const TransformState& state; diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index a345ed6e12..b70d25dd86 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -7,7 +7,7 @@ namespace mbgl { -Renderer::Renderer(RendererBackend& backend, +Renderer::Renderer(gfx::RendererBackend& backend, float pixelRatio_, Scheduler& scheduler_, GLContextMode contextMode_, diff --git a/src/mbgl/renderer/renderer_backend.cpp b/src/mbgl/renderer/renderer_backend.cpp deleted file mode 100644 index 24249e06a4..0000000000 --- a/src/mbgl/renderer/renderer_backend.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include <mbgl/renderer/renderer_backend.hpp> -#include <mbgl/gfx/backend_scope.hpp> -#include <mbgl/gl/context.hpp> -#include <mbgl/gl/extension.hpp> - -#include <cassert> - -namespace mbgl { - -RendererBackend::RendererBackend() = default; - -gl::Context& RendererBackend::getContext() { - assert(gfx::BackendScope::exists()); - std::call_once(initialized, [this] { - context = std::make_unique<gl::Context>(); - context->enableDebugging(); - context->initializeExtensions( - std::bind(&RendererBackend::getExtensionFunctionPointer, this, std::placeholders::_1)); - }); - return *context; -} - -PremultipliedImage RendererBackend::readFramebuffer(const Size& size) const { - assert(context); - return context->readFramebuffer<PremultipliedImage>(size); -} - -void RendererBackend::assumeFramebufferBinding(const gl::FramebufferID fbo) { - getContext().bindFramebuffer.setCurrentValue(fbo); - if (fbo != ImplicitFramebufferBinding) { - assert(gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); - } -} - -void RendererBackend::assumeViewport(int32_t x, int32_t y, const Size& size) { - getContext().viewport.setCurrentValue({ x, y, size }); - assert(gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); -} - -void RendererBackend::assumeScissorTest(bool enabled) { - getContext().scissorTest.setCurrentValue(enabled); - assert(gl::value::ScissorTest::Get() == getContext().scissorTest.getCurrentValue()); -} - -bool RendererBackend::implicitFramebufferBound() { - return getContext().bindFramebuffer.getCurrentValue() == ImplicitFramebufferBinding; -} - -void RendererBackend::setFramebufferBinding(const gl::FramebufferID fbo) { - getContext().bindFramebuffer = fbo; - if (fbo != ImplicitFramebufferBinding) { - assert(gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); - } -} - -void RendererBackend::setViewport(int32_t x, int32_t y, const Size& size) { - getContext().viewport = { x, y, size }; - assert(gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); -} - -void RendererBackend::setScissorTest(bool enabled) { - getContext().scissorTest = enabled; - assert(gl::value::ScissorTest::Get() == getContext().scissorTest.getCurrentValue()); -} - -RendererBackend::~RendererBackend() = default; - -} // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 3a85928cc3..f5f87fc7fd 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -1,7 +1,6 @@ #include <mbgl/annotation/annotation_manager.hpp> #include <mbgl/layermanager/layer_manager.hpp> #include <mbgl/renderer/renderer_impl.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/renderer/renderer_observer.hpp> #include <mbgl/renderer/render_source.hpp> #include <mbgl/renderer/render_layer.hpp> @@ -16,7 +15,10 @@ #include <mbgl/renderer/query.hpp> #include <mbgl/gfx/backend_scope.hpp> #include <mbgl/renderer/image_manager.hpp> +#include <mbgl/gfx/renderer_backend.hpp> +#include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/geometry/line_atlas.hpp> #include <mbgl/style/source_impl.hpp> #include <mbgl/style/transition_options.hpp> @@ -35,7 +37,7 @@ static RendererObserver& nullObserver() { return observer; } -Renderer::Impl::Impl(RendererBackend& backend_, +Renderer::Impl::Impl(gfx::RendererBackend& backend_, float pixelRatio_, Scheduler& scheduler_, GLContextMode contextMode_, @@ -307,8 +309,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { observer->onWillStartRenderingFrame(); - backend.updateAssumedState(); - // Set render tiles to the render items. for (auto& renderItem : renderItems) { if (!renderItem.source) { @@ -364,7 +364,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } } - // TODO: remove cast gl::Context& glContext = static_cast<gl::Context&>(parameters.context); @@ -392,7 +391,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { // Renders any 3D layers bottom-to-top to unique FBOs with texture attachments, but share the same // depth rbo between them. if (parameters.staticData.has3D) { - parameters.staticData.backendSize = parameters.backend.getFramebufferSize(); + parameters.staticData.backendSize = parameters.backend.getDefaultRenderable().getSize(); const auto debugGroup(parameters.encoder->createDebugGroup("3d")); parameters.pass = RenderPass::Pass3D; @@ -420,7 +419,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { { using namespace gl::value; - parameters.backend.bind(); + parameters.backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); if (parameters.debugOptions & MapDebugOptions::Overdraw) { glContext.clear(Color::black(), ClearDepth::Default, ClearStencil::Default); } else if (parameters.contextMode == GLContextMode::Shared) { @@ -600,7 +599,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { void Renderer::Impl::flush() { assert(gfx::BackendScope::exists()); - backend.getContext().flush(); + gl::Context& glContext = static_cast<gl::Context&>(backend.getContext()); + glContext.flush(); } std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const { diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 624b4c273c..c8ee939e7a 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -20,7 +20,6 @@ namespace mbgl { -class RendererBackend; class RendererObserver; class RenderSource; class RenderLayer; @@ -34,11 +33,15 @@ class ImageManager; class LineAtlas; class CrossTileSymbolIndex; +namespace gfx { +class RendererBackend; +} // namespace gfx + class Renderer::Impl : public GlyphManagerObserver, public ImageManagerObserver, public RenderSourceObserver{ public: - Impl(RendererBackend&, float pixelRatio_, Scheduler&, GLContextMode, + Impl(gfx::RendererBackend&, float pixelRatio_, Scheduler&, GLContextMode, const optional<std::string> programCacheDir, const optional<std::string> localFontFamily_); ~Impl() final; @@ -95,7 +98,7 @@ private: friend class Renderer; - RendererBackend& backend; + gfx::RendererBackend& backend; Scheduler& scheduler; RendererObserver* observer; diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 48cdc1c0f5..277d988f9e 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -43,10 +43,10 @@ PropertyMap properties; } // namespace TEST(Buckets, CircleBucket) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; - gl::Context context; + gl::Context context{ backend }; CircleBucket bucket { { {0, 0, 0}, MapMode::Static, 1.0, nullptr }, {} }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); @@ -62,11 +62,11 @@ TEST(Buckets, CircleBucket) { } TEST(Buckets, FillBucket) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; style::Properties<>::PossiblyEvaluated layout; - gl::Context context; + gl::Context context{ backend }; FillBucket bucket { layout, {}, 5.0f, 1}; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); @@ -81,11 +81,11 @@ TEST(Buckets, FillBucket) { } TEST(Buckets, LineBucket) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; style::LineLayoutProperties::PossiblyEvaluated layout; - gl::Context context; + gl::Context context{ backend }; LineBucket bucket { layout, {}, 10.0f, 1 }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); @@ -105,7 +105,7 @@ TEST(Buckets, LineBucket) { } TEST(Buckets, SymbolBucket) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; style::SymbolLayoutProperties::PossiblyEvaluated layout; @@ -115,7 +115,7 @@ TEST(Buckets, SymbolBucket) { std::string bucketLeaderID = "test"; std::vector<SymbolInstance> symbolInstances; - gl::Context context; + gl::Context context{ backend }; SymbolBucket bucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), 1.0f }; ASSERT_FALSE(bucket.hasIconData()); ASSERT_FALSE(bucket.hasTextData()); @@ -139,10 +139,10 @@ TEST(Buckets, SymbolBucket) { } TEST(Buckets, RasterBucket) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; - gl::Context context; + gl::Context context{ backend }; PremultipliedImage rgba({ 1, 1 }); // RasterBucket::hasData() is always true. diff --git a/test/gl/context.test.cpp b/test/gl/context.test.cpp index 14f7cd3a13..4e41af55d1 100644 --- a/test/gl/context.test.cpp +++ b/test/gl/context.test.cpp @@ -8,6 +8,7 @@ #include <mbgl/gfx/backend_scope.hpp> #include <mbgl/gl/defines.hpp> #include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/storage/resource_options.hpp> #include <mbgl/style/style.hpp> #include <mbgl/style/layers/custom_layer.hpp> @@ -104,8 +105,8 @@ TEST(GLContextMode, Shared) { { // Custom rendering outside of GL Native render loop. - frontend.getBackend()->bind(); gfx::BackendScope scope { *frontend.getBackend() }; + frontend.getBackend()->getDefaultRenderable().getResource<gl::RenderableResource>().bind(); Shader paintShader(vertexShaderSource, fragmentShaderSource); Buffer triangleBuffer({ 0, 0.5, 0.5, -0.5, -0.5, -0.5 }); diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp index 5441c4c335..2e53b12a80 100644 --- a/test/gl/object.test.cpp +++ b/test/gl/object.test.cpp @@ -45,10 +45,10 @@ TEST(GLObject, Value) { } TEST(GLObject, Store) { - HeadlessBackend backend { { 256, 256 } }; + gl::HeadlessBackend backend { { 256, 256 } }; gfx::BackendScope scope { backend }; - gl::Context context; + gl::Context context{ backend }; EXPECT_TRUE(context.empty()); gl::UniqueTexture texture = context.createUniqueTexture(); diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 41275df7f0..a2d36b2ca2 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -614,8 +614,8 @@ TEST(Map, AddLayer) { TEST(Map, WithoutVAOExtension) { MapTest<DefaultFileSource> test { ":memory:", "test/fixtures/api/assets" }; - test.frontend.getBackend()->getContext().disableVAOExtension = true; gfx::BackendScope scope { *test.frontend.getBackend() }; + static_cast<gl::Context&>(test.frontend.getBackend()->getContext()).disableVAOExtension = true; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); diff --git a/test/renderer/backend_scope.test.cpp b/test/renderer/backend_scope.test.cpp index e78c895ac8..f5c43a34a1 100644 --- a/test/renderer/backend_scope.test.cpp +++ b/test/renderer/backend_scope.test.cpp @@ -1,21 +1,14 @@ #include <mbgl/test/util.hpp> -#include <mbgl/renderer/renderer_backend.hpp> +#include <mbgl/gl/renderer_backend.hpp> #include <mbgl/gfx/backend_scope.hpp> #include <functional> using namespace mbgl; -class StubRendererBackend: public RendererBackend { +class StubRendererBackend: public gl::RendererBackend { public: - void bind() override { - } - - mbgl::Size getFramebufferSize() const override { - return mbgl::Size{}; - } - void activate() override { if (activateFunction) activateFunction(); } @@ -29,7 +22,13 @@ public: } gl::ProcAddress getExtensionFunctionPointer(const char*) override { - return {}; + abort(); + return nullptr; + } + + gfx::Renderable& getDefaultRenderable() override { + abort(); + return reinterpret_cast<gfx::Renderable&>(*this); } std::function<void ()> activateFunction; diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp index 91bae66ce3..ef10984364 100644 --- a/test/util/offscreen_texture.test.cpp +++ b/test/util/offscreen_texture.test.cpp @@ -14,14 +14,14 @@ using namespace mbgl; using namespace mbgl::platform; TEST(OffscreenTexture, EmptyRed) { - HeadlessBackend backend({ 512, 256 }); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; - // Scissor test shouldn't leak after HeadlessBackend::bind(). + // Scissor test shouldn't leak after gl::HeadlessBackend::bind(). MBGL_CHECK_ERROR(glScissor(64, 64, 128, 128)); - backend.getContext().scissorTest.setCurrentValue(true); + static_cast<gl::Context&>(backend.getContext()).scissorTest.setCurrentValue(true); - backend.bind(); + backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f)); MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); @@ -76,9 +76,9 @@ struct Buffer { TEST(OffscreenTexture, RenderToTexture) { - HeadlessBackend backend({ 512, 256 }); - auto& context = backend.getContext(); + gl::HeadlessBackend backend({ 512, 256 }); gfx::BackendScope scope { backend }; + auto& context = static_cast<gl::Context&>(backend.getContext()); MBGL_CHECK_ERROR(glEnable(GL_BLEND)); MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); @@ -126,7 +126,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 }); - backend.bind(); + backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); // First, draw red to the bound FBO. context.clear(Color::red(), {}, {}); @@ -154,7 +154,7 @@ 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. - backend.bind(); + backend.getDefaultRenderable().getResource<gl::RenderableResource>().bind(); image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0); |