summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2019-04-01 16:56:24 +0200
committerKonstantin Käfer <mail@kkaefer.com>2019-04-05 11:49:17 +0200
commit66c020034e8260e5e071481e68ab61cd264723ba (patch)
treeb5263772d72175474d91ce2daa9dc037b99fab0d
parenta782a6d15b80dd83105604f3f779f6c83ba222e5 (diff)
downloadqtlocation-mapboxgl-66c020034e8260e5e071481e68ab61cd264723ba.tar.gz
[core] refactor RendererBackend
-rw-r--r--cmake/glfw.cmake3
-rw-r--r--include/mbgl/gfx/backend_scope.hpp3
-rw-r--r--include/mbgl/gfx/renderer_backend.hpp57
-rw-r--r--include/mbgl/gl/renderer_backend.hpp59
-rw-r--r--include/mbgl/renderer/renderer.hpp7
-rw-r--r--include/mbgl/renderer/renderer_backend.hpp92
-rwxr-xr-xplatform/android/src/android_renderer_backend.cpp51
-rwxr-xr-xplatform/android/src/android_renderer_backend.hpp48
-rw-r--r--platform/android/src/map_renderer.cpp4
-rw-r--r--platform/darwin/src/MGLRendererFrontend.h6
-rw-r--r--platform/darwin/src/headless_backend_cgl.cpp2
-rw-r--r--platform/darwin/src/headless_backend_eagl.mm2
-rw-r--r--platform/default/include/mbgl/gl/headless_backend.hpp16
-rw-r--r--platform/default/include/mbgl/gl/headless_frontend.hpp9
-rw-r--r--platform/default/src/mbgl/gl/headless_backend.cpp40
-rw-r--r--platform/default/src/mbgl/gl/headless_frontend.cpp3
-rw-r--r--platform/glfw/glfw_backend.hpp21
-rw-r--r--platform/glfw/glfw_gl_backend.cpp58
-rw-r--r--platform/glfw/glfw_gl_backend.hpp42
-rw-r--r--platform/glfw/glfw_renderer_frontend.cpp2
-rw-r--r--platform/glfw/glfw_view.cpp41
-rw-r--r--platform/glfw/glfw_view.hpp23
-rw-r--r--platform/glfw/main.cpp4
-rw-r--r--platform/ios/src/MGLMapView.mm41
-rw-r--r--platform/linux/src/headless_backend_egl.cpp2
-rw-r--r--platform/linux/src/headless_backend_glx.cpp2
-rw-r--r--platform/macos/src/MGLMapView.mm38
-rw-r--r--platform/qt/src/headless_backend_qt.cpp12
-rw-r--r--platform/qt/src/qmapboxgl_map_renderer.cpp2
-rw-r--r--platform/qt/src/qmapboxgl_map_renderer.hpp1
-rw-r--r--platform/qt/src/qmapboxgl_renderer_backend.cpp46
-rw-r--r--platform/qt/src/qmapboxgl_renderer_backend.hpp35
-rw-r--r--platform/qt/src/qt_geojson.cpp2
-rw-r--r--src/core-files.json6
-rw-r--r--src/mbgl/gfx/renderer_backend.cpp22
-rw-r--r--src/mbgl/gl/context.cpp6
-rw-r--r--src/mbgl/gl/context.hpp4
-rw-r--r--src/mbgl/gl/renderer_backend.cpp71
-rw-r--r--src/mbgl/renderer/backend_scope.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_custom_layer.cpp5
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp11
-rw-r--r--src/mbgl/renderer/paint_parameters.cpp2
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp6
-rw-r--r--src/mbgl/renderer/renderer.cpp2
-rw-r--r--src/mbgl/renderer/renderer_backend.cpp68
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp16
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp9
-rw-r--r--test/gl/bucket.test.cpp20
-rw-r--r--test/gl/context.test.cpp3
-rw-r--r--test/gl/object.test.cpp4
-rw-r--r--test/map/map.test.cpp2
-rw-r--r--test/renderer/backend_scope.test.cpp19
-rw-r--r--test/util/offscreen_texture.test.cpp16
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);