diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index d7c40ba5a..0cb68408a 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -159,7 +159,11 @@ void NativeMapView::invalidate() { detach_jni_thread(vm, &env, detach); } -void NativeMapView::swap() { +void NativeMapView::beforeRender() { + // no-op +} + +void NativeMapView::afterRender() { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::swap"); if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) { diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp index 3ae3d6ed9..d5606ae37 100644 --- a/include/mbgl/android/native_map_view.hpp +++ b/include/mbgl/android/native_map_view.hpp @@ -27,7 +27,8 @@ public: void deactivate() override; void notify() override; void invalidate() override; - void swap() override; + void beforeRender() override; + void afterRender() override; void notifyMapChange(mbgl::MapChange) override; diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp index 3086d51aa..fadd035e4 100644 --- a/include/mbgl/map/view.hpp +++ b/include/mbgl/map/view.hpp @@ -62,8 +62,11 @@ public: // (map->renderSync() from the main thread must be called as a result of this) virtual void invalidate() = 0; + // Called from the render thread before the render begins. + virtual void beforeRender() = 0; + // Called from the render thread after the render is complete. - virtual void swap() = 0; + virtual void afterRender() = 0; // Reads the pixel data from the current framebuffer. If your View implementation // doesn't support reading from the framebuffer, return a null pointer. diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp index ec9908073..17050d64d 100644 --- a/include/mbgl/platform/default/glfw_view.hpp +++ b/include/mbgl/platform/default/glfw_view.hpp @@ -24,7 +24,8 @@ public: void deactivate() override; void notify() override; void invalidate() override; - void swap() override; + void beforeRender() override; + void afterRender() override; static void onKey(GLFWwindow *window, int key, int scancode, int action, int mods); static void onScroll(GLFWwindow *window, double xoffset, double yoffset); diff --git a/include/mbgl/platform/default/headless_view.hpp b/include/mbgl/platform/default/headless_view.hpp index ce0ff2a68..50edc4842 100644 --- a/include/mbgl/platform/default/headless_view.hpp +++ b/include/mbgl/platform/default/headless_view.hpp @@ -37,9 +37,11 @@ public: void deactivate() override; void notify() override; void invalidate() override; - void swap() override; + void beforeRender() override; + void afterRender() override; std::unique_ptr readStillImage() override; + void resizeFramebuffer(); void resize(uint16_t width, uint16_t height); private: @@ -52,6 +54,7 @@ private: std::shared_ptr display; const float pixelRatio; std::array dimensions; + bool needsResize; #if MBGL_USE_CGL CGLContextObj glContext = nullptr; diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index 8453845d1..19f337994 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -386,7 +386,11 @@ void GLFWView::invalidate() { glfwPostEmptyEvent(); } -void GLFWView::swap() { +void GLFWView::beforeRender() { + // no-op +} + +void GLFWView::afterRender() { glfwSwapBuffers(window); } diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp index 2d6527785..a582ed579 100644 --- a/platform/default/headless_view.cpp +++ b/platform/default/headless_view.cpp @@ -114,10 +114,10 @@ bool HeadlessView::isActive() { return std::this_thread::get_id() == thread; } -void HeadlessView::resize(const uint16_t width, const uint16_t height) { - activate(); +void HeadlessView::resizeFramebuffer() { + assert(isActive()); - dimensions = {{ width, height }}; + if (!needsResize) return; clearBuffers(); @@ -158,7 +158,12 @@ void HeadlessView::resize(const uint16_t width, const uint16_t height) { throw std::runtime_error(error); } - deactivate(); + needsResize = false; +} + +void HeadlessView::resize(const uint16_t width, const uint16_t height) { + dimensions = {{ width, height }}; + needsResize = true; } std::unique_ptr HeadlessView::readStillImage() { @@ -293,7 +298,11 @@ void HeadlessView::invalidate() { // no-op } -void HeadlessView::swap() { +void HeadlessView::beforeRender() { + resizeFramebuffer(); +} + +void HeadlessView::afterRender() { // no-op } diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index cdd3044dc..803cef9f5 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -2943,7 +2943,12 @@ class MBGLView : public mbgl::View waitUntilDone:NO]; } - void swap() override + void beforeRender() override + { + // no-op + } + + void afterRender() override { // no-op } diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 19e8d02ec..175f98719 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -326,6 +326,8 @@ bool MapContext::renderSync(const TransformState& state, const FrameData& frame) return false; } + view.beforeRender(); + transformState = state; // Cleanup OpenGL objects that we abandoned since the last render call. @@ -345,7 +347,7 @@ bool MapContext::renderSync(const TransformState& state, const FrameData& frame) callback = nullptr; } - view.swap(); + view.afterRender(); viewInvalidated = false; data.setNeedsRepaint(style->hasTransitions() || painter->needsAnimation()); diff --git a/test/fixtures/mock_view.hpp b/test/fixtures/mock_view.hpp index 17ad6ccfa..e608545da 100644 --- a/test/fixtures/mock_view.hpp +++ b/test/fixtures/mock_view.hpp @@ -20,7 +20,8 @@ public: void deactivate() override {}; void notify() override {}; void invalidate() override {} - void swap() override {} + void beforeRender() override {} + void afterRender() override {} }; }