diff options
-rw-r--r-- | cmake/benchmark.cmake | 1 | ||||
-rw-r--r-- | cmake/core.cmake | 2 | ||||
-rw-r--r-- | cmake/glfw.cmake | 2 | ||||
-rw-r--r-- | cmake/test.cmake | 1 | ||||
-rw-r--r-- | include/mbgl/map/backend.hpp | 26 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 18 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.hpp | 2 | ||||
-rw-r--r-- | platform/default/mbgl/gl/headless_backend.cpp | 4 | ||||
-rw-r--r-- | platform/default/mbgl/gl/headless_backend.hpp | 2 | ||||
-rw-r--r-- | platform/glfw/glfw_view.cpp | 15 | ||||
-rw-r--r-- | platform/glfw/glfw_view.hpp | 2 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 20 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView.mm | 23 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl.cpp | 14 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_p.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/backend.cpp | 32 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 4 |
17 files changed, 103 insertions, 67 deletions
diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index c3b5c93937..c298d8ee28 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -7,7 +7,6 @@ target_compile_options(mbgl-benchmark ) target_include_directories(mbgl-benchmark - PRIVATE include PRIVATE src PRIVATE benchmark/include PRIVATE benchmark/src diff --git a/cmake/core.cmake b/cmake/core.cmake index 723139e368..a687b020dc 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -9,7 +9,7 @@ target_compile_options(mbgl-core target_include_directories(mbgl-core PUBLIC include - PUBLIC src # TODO: make private + PRIVATE src ) target_add_mason_package(mbgl-core PUBLIC geometry) diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake index cdde92bbf2..ba6ba92e9f 100644 --- a/cmake/glfw.cmake +++ b/cmake/glfw.cmake @@ -16,8 +16,6 @@ target_compile_options(mbgl-glfw ) target_include_directories(mbgl-glfw - PRIVATE include - PRIVATE src # TODO: eliminate PRIVATE platform/default ) diff --git a/cmake/test.cmake b/cmake/test.cmake index 16b7d630e2..5e77de2448 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -15,7 +15,6 @@ target_compile_options(mbgl-test set_source_files_properties(test/src/mbgl/test/util.cpp PROPERTIES COMPILE_FLAGS -DNODE_EXECUTABLE="${NodeJS_EXECUTABLE}") target_include_directories(mbgl-test - PRIVATE include PRIVATE src PRIVATE test/include PRIVATE test/src diff --git a/include/mbgl/map/backend.hpp b/include/mbgl/map/backend.hpp index 876c19261b..884c4b5256 100644 --- a/include/mbgl/map/backend.hpp +++ b/include/mbgl/map/backend.hpp @@ -1,6 +1,8 @@ #pragma once #include <mbgl/map/map_observer.hpp> +#include <mbgl/util/image.hpp> +#include <mbgl/util/size.hpp> #include <memory> #include <mutex> @@ -10,6 +12,7 @@ namespace mbgl { namespace gl { class Context; using ProcAddress = void (*)(); +using FramebufferID = uint32_t; } // namespace gl class BackendScope; @@ -22,6 +25,9 @@ public: // 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 the map needs to be rendered; the backend should call Map::render() at some point // in the near future. (Not called for Map::renderStill() mode.) virtual void invalidate() = 0; @@ -45,6 +51,26 @@ protected: 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 assumeViewportSize(const Size&); + + // 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 setViewportSize(const Size&); + protected: std::unique_ptr<gl::Context> context; diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index eeb4620c2e..4547eeff21 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -14,7 +14,6 @@ #include <jni/jni.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/map/backend_scope.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/event.hpp> @@ -100,8 +99,8 @@ NativeMapView::~NativeMapView() { * From mbgl::View */ void NativeMapView::bind() { - getContext().bindFramebuffer = 0; - getContext().viewport = { 0, 0, getFramebufferSize() }; + setFramebufferBinding(0); + setViewportSize(getFramebufferSize()); } /** @@ -284,18 +283,17 @@ void NativeMapView::render(jni::JNIEnv& env) { BackendScope guard(*this); if (framebufferSizeChanged) { - getContext().viewport = { 0, 0, getFramebufferSize() }; + setViewportSize(getFramebufferSize()); framebufferSizeChanged = false; } - updateViewBinding(); map->render(*this); if(snapshot){ snapshot = false; // take snapshot - auto image = getContext().readFramebuffer<mbgl::PremultipliedImage>(getFramebufferSize()); + auto image = readFramebuffer(getFramebufferSize()); auto bitmap = Bitmap::CreateBitmap(env, std::move(image)); // invoke Mapview#OnSnapshotReady @@ -1421,11 +1419,9 @@ mbgl::Size NativeMapView::getFramebufferSize() const { return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) }; } -void NativeMapView::updateViewBinding() { - getContext().bindFramebuffer.setCurrentValue(0); - assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); - getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() }); - assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); +void NativeMapView::updateAssumedState() { + assumeFramebufferBinding(0); + assumeViewportSize(getFramebufferSize()); } void NativeMapView::updateFps() { diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index af8c7dd660..4651ed81e7 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -58,6 +58,7 @@ public: // mbgl::Backend // + void updateAssumedState() override; void invalidate() override; // Deprecated // @@ -281,7 +282,6 @@ private: EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs); - void updateViewBinding(); mbgl::Size getFramebufferSize() const; void updateFps(); diff --git a/platform/default/mbgl/gl/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp index 798c8fe680..d2fbf4e4c7 100644 --- a/platform/default/mbgl/gl/headless_backend.cpp +++ b/platform/default/mbgl/gl/headless_backend.cpp @@ -41,6 +41,10 @@ void HeadlessBackend::deactivate() { active = false; } +void HeadlessBackend::updateAssumedState() { + // no-op +} + void HeadlessBackend::invalidate() { assert(false); } diff --git a/platform/default/mbgl/gl/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp index 7e1749a253..77b56856ae 100644 --- a/platform/default/mbgl/gl/headless_backend.hpp +++ b/platform/default/mbgl/gl/headless_backend.hpp @@ -15,6 +15,8 @@ public: HeadlessBackend(std::shared_ptr<HeadlessDisplay>); ~HeadlessBackend() override; + void updateAssumedState() override; + void invalidate() override; struct Impl { diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index b8cf285bdd..e833478795 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -3,8 +3,6 @@ #include <mbgl/annotation/annotation.hpp> #include <mbgl/sprite/sprite_image.hpp> #include <mbgl/style/transition_options.hpp> -#include <mbgl/gl/gl.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/util/platform.hpp> #include <mbgl/util/string.hpp> @@ -129,16 +127,14 @@ void GLFWView::setMap(mbgl::Map *map_) { map->addAnnotationIcon("default_marker", makeSpriteImage(22, 22, 1)); } -void GLFWView::updateViewBinding() { - getContext().bindFramebuffer.setCurrentValue(0); - assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); - getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() }); - assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); +void GLFWView::updateAssumedState() { + assumeFramebufferBinding(0); + assumeViewportSize(getFramebufferSize()); } void GLFWView::bind() { - getContext().bindFramebuffer = 0; - getContext().viewport = { 0, 0, getFramebufferSize() }; + setFramebufferBinding(0); + setViewportSize(getFramebufferSize()); } void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { @@ -459,7 +455,6 @@ void GLFWView::run() { activate(); mbgl::BackendScope scope { *this, mbgl::BackendScope::ScopeType::Implicit }; - updateViewBinding(); map->render(*this); glfwSwapBuffers(window); diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp index 55f795cd34..1cadae2e0f 100644 --- a/platform/glfw/glfw_view.hpp +++ b/platform/glfw/glfw_view.hpp @@ -38,13 +38,13 @@ public: void run(); // mbgl::View implementation - void updateViewBinding(); void bind() override; mbgl::Size getSize() const; mbgl::Size getFramebufferSize() const; // mbgl::Backend implementation void invalidate() override; + void updateAssumedState() override; protected: // mbgl::Backend implementation diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index e8bc1b4b2a..9bad58801f 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1,7 +1,6 @@ #import "MGLMapView_Private.h" #include <mbgl/util/logging.hpp> -#include <mbgl/gl/context.hpp> #import <GLKit/GLKit.h> #import <OpenGLES/EAGL.h> @@ -869,7 +868,6 @@ public: // The OpenGL implementation automatically enables the OpenGL context for us. mbgl::BackendScope scope { *_mbglView, mbgl::BackendScope::ScopeType::Implicit }; - _mbglView->updateViewBinding(); _mbglMap->render(*_mbglView); [self updateUserLocationAnnotationView]; @@ -5322,31 +5320,25 @@ public: MBGLView(MGLMapView* nativeView_) : nativeView(nativeView_) { } - mbgl::gl::value::Viewport::Type getViewport() const { - return { 0, 0, nativeView.framebufferSize }; - } - /// This function is called before we start rendering, when iOS invokes our rendering method. /// iOS already sets the correct framebuffer and viewport for us, so we need to update the /// context state with the anticipated values. - void updateViewBinding() { - // We are using 0 as the placeholder value for the GLKView's framebuffer. - getContext().bindFramebuffer.setCurrentValue(0); - getContext().viewport.setCurrentValue(getViewport()); - assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); + void updateAssumedState() override { + assumeFramebufferBinding(ImplicitFramebufferBinding); + assumeViewportSize(nativeView.framebufferSize); } void bind() override { - if (getContext().bindFramebuffer != 0) { + 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. // Note that in reality, iOS does not use the Framebuffer 0 (it's typically 1), and we // only use this is a placeholder value. [nativeView.glView bindDrawable]; - updateViewBinding(); + updateAssumedState(); } else { // Our framebuffer is still bound, but the viewport might have changed. - getContext().viewport = getViewport(); + setViewportSize(nativeView.framebufferSize); } } diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 45ac7c5357..3bf3909c8e 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -26,9 +26,9 @@ #import <mbgl/map/camera.hpp> #import <mbgl/storage/reachability.h> #import <mbgl/util/default_thread_pool.hpp> -#import <mbgl/gl/context.hpp> #import <mbgl/map/backend.hpp> #import <mbgl/map/backend_scope.hpp> +#import <mbgl/gl/gl.hpp> #import <mbgl/sprite/sprite_image.hpp> #import <mbgl/storage/default_file_source.hpp> #import <mbgl/storage/network_status.hpp> @@ -770,7 +770,6 @@ public: // The OpenGL implementation automatically enables the OpenGL context for us. mbgl::BackendScope scope { *_mbglView, mbgl::BackendScope::ScopeType::Implicit }; - _mbglView->updateViewBinding(); _mbglMap->render(*_mbglView); if (_isPrinting) { @@ -2866,25 +2865,19 @@ public: [NSOpenGLContext clearCurrentContext]; } - mbgl::gl::value::Viewport::Type getViewport() const { - return { 0, 0, nativeView.framebufferSize }; - } - - void updateViewBinding() { - fbo = mbgl::gl::value::BindFramebuffer::Get(); - getContext().bindFramebuffer.setCurrentValue(fbo); - getContext().viewport.setCurrentValue(getViewport()); - auto actualViewport = mbgl::gl::value::Viewport::Get(); - assert(actualViewport == getContext().viewport.getCurrentValue()); + void updateAssumedState() override { + MBGL_CHECK_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo)); + assumeFramebufferBinding(fbo); + assumeViewportSize(nativeView.framebufferSize); } void bind() override { - getContext().bindFramebuffer = fbo; - getContext().viewport = getViewport(); + setFramebufferBinding(fbo); + setViewportSize(nativeView.framebufferSize); } mbgl::PremultipliedImage readStillImage() { - return getContext().readFramebuffer<mbgl::PremultipliedImage>(nativeView.framebufferSize); + return readFramebuffer(nativeView.framebufferSize); } private: diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 5776502a5b..1499def75d 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -7,7 +7,6 @@ #include <mbgl/annotation/annotation.hpp> #include <mbgl/map/camera.hpp> #include <mbgl/map/map.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/map/backend_scope.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/layer.hpp> @@ -1500,7 +1499,6 @@ void QMapboxGL::render() mbgl::BackendScope scope { *d_ptr, mbgl::BackendScope::ScopeType::Implicit }; d_ptr->dirty = false; - d_ptr->updateViewBinding(); d_ptr->mapObj->render(*d_ptr); } @@ -1575,16 +1573,14 @@ mbgl::Size QMapboxGLPrivate::framebufferSize() const { return { static_cast<uint32_t>(fbSize.width()), static_cast<uint32_t>(fbSize.height()) }; } -void QMapboxGLPrivate::updateViewBinding() { - getContext().bindFramebuffer.setCurrentValue(fbObject); - assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); - getContext().viewport.setCurrentValue({ 0, 0, framebufferSize() }); - assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); +void QMapboxGLPrivate::updateAssumedState() { + assumeFramebufferBinding(fbObject); + assumeViewportSize(framebufferSize()); } void QMapboxGLPrivate::bind() { - getContext().bindFramebuffer = fbObject; - getContext().viewport = { 0, 0, framebufferSize() }; + setFramebufferBinding(fbObject); + setViewportSize(framebufferSize()); } void QMapboxGLPrivate::invalidate() diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp index 464b66bd73..49a7942cce 100644 --- a/platform/qt/src/qmapboxgl_p.hpp +++ b/platform/qt/src/qmapboxgl_p.hpp @@ -21,12 +21,12 @@ public: virtual ~QMapboxGLPrivate(); mbgl::Size framebufferSize() const; - void updateViewBinding(); // mbgl::View implementation. void bind() final; // mbgl::Backend implementation. + void updateAssumedState() final; void invalidate() final; void activate() final {} void deactivate() final {} diff --git a/src/mbgl/map/backend.cpp b/src/mbgl/map/backend.cpp index c228719ba6..0b4fd01050 100644 --- a/src/mbgl/map/backend.cpp +++ b/src/mbgl/map/backend.cpp @@ -21,6 +21,38 @@ gl::Context& Backend::getContext() { return *context; } +PremultipliedImage Backend::readFramebuffer(const Size& size) const { + assert(context); + return context->readFramebuffer<PremultipliedImage>(size); +} + +void Backend::assumeFramebufferBinding(const gl::FramebufferID fbo) { + getContext().bindFramebuffer.setCurrentValue(fbo); + if (fbo != ImplicitFramebufferBinding) { + assert(gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); + } +} +void Backend::assumeViewportSize(const Size& size) { + getContext().viewport.setCurrentValue({ 0, 0, size }); + assert(gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); +} + +bool Backend::implicitFramebufferBound() { + return getContext().bindFramebuffer.getCurrentValue() == ImplicitFramebufferBinding; +} + +void Backend::setFramebufferBinding(const gl::FramebufferID fbo) { + getContext().bindFramebuffer = fbo; + if (fbo != ImplicitFramebufferBinding) { + assert(gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue()); + } +} + +void Backend::setViewportSize(const Size& size) { + getContext().viewport = { 0, 0, size }; + assert(gl::value::Viewport::Get() == getContext().viewport.getCurrentValue()); +} + Backend::~Backend() = default; } // namespace mbgl diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 9e0b1a7575..8957f3272e 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -285,6 +285,8 @@ void Map::Impl::render(View& view) { contextMode, debugOptions }; + backend.updateAssumedState(); + painter->render(*style, frameData, view, @@ -323,6 +325,8 @@ void Map::Impl::render(View& view) { contextMode, debugOptions }; + backend.updateAssumedState(); + try { painter->render(*style, frameData, |