From 56a4268ccaf34fbb5e45d3a63c27efea9e23178e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 4 Aug 2015 17:45:26 +0200 Subject: [PATCH 1/9] manually premultiply the image if libpng can't do it --- platform/default/png_reader.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 42b694609..04f547d8e 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -160,8 +160,6 @@ void PngReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * #ifdef PNG_ALPHA_PREMULTIPLIED png_set_alpha_mode(png_ptr, PNG_ALPHA_PREMULTIPLIED, PNG_GAMMA_LINEAR); -#else - // TODO: Manually premultiply the image data. #endif if (x0 == 0 && y0 == 0 && w >= width_ && h >= height_) @@ -180,6 +178,20 @@ void PngReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * for (unsigned row = 0; row < height_; ++row) rows[row] = (png_bytep)image + row * width_ * 4 ; png_read_image(png_ptr, rows.get()); + fprintf(stderr, "manual premultiplication\n"); + +#ifndef PNG_ALPHA_PREMULTIPLIED + // Manually premultiply the image if libpng didn't do it for us. + for (unsigned row = 0; row < height_; ++row) { + for (unsigned x = 0; x < width_; x++) { + png_byte* ptr = &(rows[row][x * 4]); + const float a = ptr[3] / 255.0f; + ptr[0] *= a; + ptr[1] *= a; + ptr[2] *= a; + } + } +#endif } else { @@ -193,6 +205,7 @@ void PngReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * png_read_row(png_ptr,row.get(),0); if (i >= y0 && i < (y0 + h)) { + // TODO: premultiply this std::copy(&row[x0 * 4], &row[x0 * 4] + w * 4, image + i * width_* 4); } } From 27e24578f9f6101daa625516d0873c2b1e3464b8 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 5 Aug 2015 14:55:57 +0300 Subject: [PATCH 2/9] Bring run-linux targets back --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 59bd1dfef..61f2a4c0c 100644 --- a/Makefile +++ b/Makefile @@ -57,8 +57,11 @@ endif #### All platforms targets ##################################################### -.PHONY: linux xlinux run-linux run-xlinux +.PHONY: linux run-linux run-valgrind-linux linux: ; $(RUN) Makefile/linuxapp +run-linux: linux ; (cd build/linux-x86_64/$(BUILDTYPE) && ./mapbox-gl) +run-valgrind-linux: linux + (cd build/linux-x86_64/$(BUILDTYPE) && valgrind --leak-check=full --suppressions=../../../scripts/valgrind.sup ./mapbox-gl) .PHONY: android android-lib # Builds a particular android architecture. From 92d78eae383ce3f6f8b523219558d9995fe87e4c Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Wed, 5 Aug 2015 14:56:48 +0300 Subject: [PATCH 3/9] Removed debug leftover --- platform/default/png_reader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 04f547d8e..ede7e52be 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -178,7 +178,6 @@ void PngReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * for (unsigned row = 0; row < height_; ++row) rows[row] = (png_bytep)image + row * width_ * 4 ; png_read_image(png_ptr, rows.get()); - fprintf(stderr, "manual premultiplication\n"); #ifndef PNG_ALPHA_PREMULTIPLIED // Manually premultiply the image if libpng didn't do it for us. From 0eb7effad729aa66cc05067b75d89b4d41ee0024 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Sun, 2 Aug 2015 22:34:29 +0300 Subject: [PATCH 4/9] Make MapContext use StillImageCallback definition from Map --- src/mbgl/map/map_context.cpp | 2 +- src/mbgl/map/map_context.hpp | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 56bca24af..f6a6462c4 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -280,7 +280,7 @@ void MapContext::update() { updated = static_cast(Update::Nothing); } -void MapContext::renderStill(const TransformState& state, const FrameData& frame, StillImageCallback fn) { +void MapContext::renderStill(const TransformState& state, const FrameData& frame, Map::StillImageCallback fn) { if (!fn) { Log::Error(Event::General, "StillImageCallback not set"); return; diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index 8c8c90ff8..764bf08b1 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -44,10 +45,8 @@ public: void pause(); - using StillImageCallback = std::function)>; - void triggerUpdate(const TransformState&, Update = Update::Nothing); - void renderStill(const TransformState&, const FrameData&, StillImageCallback callback); + void renderStill(const TransformState&, const FrameData&, Map::StillImageCallback callback); RenderResult renderSync(const TransformState&, const FrameData&); void setStyleURL(const std::string&); @@ -95,7 +94,7 @@ private: Request* styleRequest = nullptr; - StillImageCallback callback; + Map::StillImageCallback callback; size_t sourceCacheSize; TransformState transformState; FrameData frameData; From 58357b7964fcc44cbb824da64225fe58bb3d3dd1 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 3 Aug 2015 00:14:07 +0300 Subject: [PATCH 5/9] Removed Transform::needsTransition() Transform::updateTransitions() already checks if there is a callback to update transitions. --- src/mbgl/map/map.cpp | 8 ++++---- src/mbgl/map/transform.cpp | 4 ---- src/mbgl/map/transform.hpp | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index f357c05e8..d2cd7a53b 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -73,11 +73,11 @@ bool Map::renderSync() { } void Map::nudgeTransitions(bool forceRerender) { - if (transform->needsTransition()) { - update(Update(transform->updateTransitions(Clock::now()))); - } else if (forceRerender) { - update(); + UpdateType update_ = transform->updateTransitions(Clock::now()); + if (forceRerender) { + update_ |= static_cast(Update::Repaint); } + update(Update(update_)); } void Map::update(Update update_) { diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 08cca3db2..29ca54d78 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -377,10 +377,6 @@ void Transform::startTransition(std::function frame, transitionFinishFn = finish; } -bool Transform::needsTransition() const { - return !!transitionFrameFn; -} - UpdateType Transform::updateTransitions(const TimePoint& now) { return static_cast(transitionFrameFn ? transitionFrameFn(now) : Update::Nothing); } diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index badb811af..f4a78bbcb 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -42,7 +42,6 @@ public: double getAngle() const; // Transitions - bool needsTransition() const; UpdateType updateTransitions(const TimePoint& now); void cancelTransitions(); From 492bcf0bd7eb62f3aedb148e103dd8ea9cb851ca Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Sun, 2 Aug 2015 22:07:55 +0300 Subject: [PATCH 6/9] Added Update::Repaint --- android/cpp/jni.cpp | 2 +- android/cpp/native_map_view.cpp | 1 + include/mbgl/map/map.hpp | 2 +- include/mbgl/map/update.hpp | 1 + platform/default/glfw_view.cpp | 2 +- src/mbgl/map/map.cpp | 24 ++++++++++++------------ src/mbgl/map/map_context.cpp | 2 ++ 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index eee6bd8f6..476d43729 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -409,7 +409,7 @@ void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdate"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->getMap().update(); + nativeMapView->getMap().update(mbgl::Update::Repaint); } void JNICALL nativeOnInvalidate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean inProgress) { diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index 351833a07..9a24bddfe 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -792,6 +792,7 @@ void NativeMapView::resizeView(int w, int h) { void NativeMapView::resizeFramebuffer(int w, int h) { fbWidth = w; fbHeight = h; + map.update(mbgl::Update::Repaint); } } diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 6e24d177a..e35a738d6 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -73,7 +73,7 @@ public: void nudgeTransitions(bool forceRerender); // Notifies the Map thread that the state has changed and an update might be necessary. - void update(Update update = Update::Nothing); + void update(Update update); // Styling void addClass(const std::string&); diff --git a/include/mbgl/map/update.hpp b/include/mbgl/map/update.hpp index d2d6133bc..d5978d80b 100644 --- a/include/mbgl/map/update.hpp +++ b/include/mbgl/map/update.hpp @@ -14,6 +14,7 @@ enum class Update : UpdateType { Classes = 1 << 3, Zoom = 1 << 4, RenderStill = 1 << 5, + Repaint = 1 << 6, }; } diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index fb08b9234..8336b3293 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -288,7 +288,7 @@ void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) { view->fbWidth = width; view->fbHeight = height; - view->map->update(); + view->map->update(mbgl::Update::Repaint); } void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modifiers) { diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index d2cd7a53b..4990d24fc 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -110,24 +110,24 @@ std::string Map::getStyleJSON() const { void Map::cancelTransitions() { transform->cancelTransitions(); - update(); + update(Update::Repaint); } void Map::setGestureInProgress(bool inProgress) { transform->setGestureInProgress(inProgress); - update(); + update(Update::Repaint); } #pragma mark - Position void Map::moveBy(double dx, double dy, const Duration& duration) { transform->moveBy(dx, dy, duration); - update(); + update(Update::Repaint); } void Map::setLatLng(LatLng latLng, const Duration& duration) { transform->setLatLng(latLng, duration); - update(); + update(Update::Repaint); } LatLng Map::getLatLng() const { @@ -249,17 +249,17 @@ uint16_t Map::getHeight() const { void Map::rotateBy(double sx, double sy, double ex, double ey, const Duration& duration) { transform->rotateBy(sx, sy, ex, ey, duration); - update(); + update(Update::Repaint); } void Map::setBearing(double degrees, const Duration& duration) { transform->setAngle(-degrees * M_PI / 180, duration); - update(); + update(Update::Repaint); } void Map::setBearing(double degrees, double cx, double cy) { transform->setAngle(-degrees * M_PI / 180, cx, cy); - update(); + update(Update::Repaint); } double Map::getBearing() const { @@ -268,7 +268,7 @@ double Map::getBearing() const { void Map::resetNorth() { transform->setAngle(0, std::chrono::milliseconds(500)); - update(); + update(Update::Repaint); } @@ -365,12 +365,12 @@ void Map::removeSprite(const std::string& name) { void Map::setDebug(bool value) { data->setDebug(value); - update(); + update(Update::Repaint); } void Map::toggleDebug() { data->toggleDebug(); - update(); + update(Update::Repaint); } bool Map::getDebug() const { @@ -379,12 +379,12 @@ bool Map::getDebug() const { void Map::setCollisionDebug(bool value) { data->setCollisionDebug(value); - update(); + update(Update::Repaint); } void Map::toggleCollisionDebug() { data->toggleCollisionDebug(); - update(); + update(Update::Repaint); } bool Map::getCollisionDebug() const { diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index f6a6462c4..c5a0ee07a 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -396,6 +396,8 @@ void MapContext::setSprite(const std::string& name, std::shared_ptr(Update::Repaint); asyncUpdate->send(); } From 9fd7e883a7515f97ec4edd097a0db5cbebce3ca1 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 3 Aug 2015 02:00:37 +0300 Subject: [PATCH 7/9] Coalesce view invalidation calls Do not call for view invalidation until painter has rendered a new frame. --- src/mbgl/map/map_context.cpp | 22 ++++++++++++++++------ src/mbgl/map/map_context.hpp | 3 +++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index c5a0ee07a..4f8052f29 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -35,7 +35,8 @@ MapContext::MapContext(View& view_, FileSource& fileSource, MapData& data_) data(data_), updated(static_cast(Update::Nothing)), asyncUpdate(std::make_unique(util::RunLoop::getLoop(), [this] { update(); })), - texturePool(std::make_unique()) { + texturePool(std::make_unique()), + viewInvalidated(false) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); util::ThreadContext::setFileSource(&fileSource); @@ -272,8 +273,8 @@ void MapContext::update() { style->update(transformState, *texturePool); if (data.mode == MapMode::Continuous) { - view.invalidate(); - } else if (callback && style->isLoaded()) { + invalidateView(); + } else if (callback && isLoaded()) { renderSync(transformState, frameData); } @@ -342,8 +343,10 @@ MapContext::RenderResult MapContext::renderSync(const TransformState& state, con view.swap(); + viewInvalidated = false; + return RenderResult { - style->isLoaded(), + isLoaded(), style->hasTransitions() || painter->needsAnimation() }; } @@ -370,7 +373,7 @@ void MapContext::setSourceTileCacheSize(size_t size) { for (const auto &source : style->sources) { source->setCacheSize(sourceCacheSize); } - view.invalidate(); + invalidateView(); } } @@ -380,7 +383,7 @@ void MapContext::onLowMemory() { for (const auto &source : style->sources) { source->onLowMemory(); } - view.invalidate(); + invalidateView(); } void MapContext::setSprite(const std::string& name, std::shared_ptr sprite) { @@ -410,4 +413,11 @@ void MapContext::onResourceLoadingFailed(std::exception_ptr error) { } } +void MapContext::invalidateView() { + if (!viewInvalidated) { + viewInvalidated = true; + view.invalidate(); + } +} + } diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index 764bf08b1..dd211d4a1 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -77,6 +77,8 @@ private: // Loads the actual JSON object an creates a new Style object. void loadStyleJSON(const std::string& json, const std::string& base); + void invalidateView(); + View& view; MapData& data; @@ -98,6 +100,7 @@ private: size_t sourceCacheSize; TransformState transformState; FrameData frameData; + bool viewInvalidated; }; } From fa4636ffe4d2c00446292c229cd549cbaee9e20c Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 3 Aug 2015 01:36:19 +0300 Subject: [PATCH 8/9] Map::nudgeTransitions no longer depends on client information Clients no longer need to provide data (eg. if gesturing or in a custom animation) to Map::nudgeTransitions(). Upon MapContext::renderSync(), a new atomic bool 'needsRepaint' in MapData allows thread-safe communication between Map and MapContext. --- android/cpp/jni.cpp | 6 +++--- android/cpp/native_map_view.cpp | 8 +++----- .../java/com/mapbox/mapboxgl/views/MapView.java | 3 +-- .../com/mapbox/mapboxgl/views/NativeMapView.java | 6 +++--- include/mbgl/android/native_map_view.hpp | 2 +- include/mbgl/map/map.hpp | 8 ++++---- platform/default/glfw_view.cpp | 7 ++----- platform/ios/MGLMapView.mm | 10 ++-------- src/mbgl/map/map.cpp | 16 +++++++--------- src/mbgl/map/map_context.cpp | 16 ++++++++++------ src/mbgl/map/map_context.hpp | 9 +++------ src/mbgl/map/map_data.hpp | 9 +++++++++ 12 files changed, 48 insertions(+), 52 deletions(-) diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index 476d43729..6d7def861 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -412,11 +412,11 @@ void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { nativeMapView->getMap().update(mbgl::Update::Repaint); } -void JNICALL nativeOnInvalidate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean inProgress) { +void JNICALL nativeOnInvalidate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnInvalidate"); assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - nativeMapView->onInvalidate(inProgress); + nativeMapView->onInvalidate(); } void JNICALL nativeViewResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height) { @@ -1440,7 +1440,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativePause", "(J)V", reinterpret_cast(&nativePause)}, {"nativeResume", "(J)V", reinterpret_cast(&nativeResume)}, {"nativeUpdate", "(J)V", reinterpret_cast(&nativeUpdate)}, - {"nativeOnInvalidate", "(JZ)V", reinterpret_cast(&nativeOnInvalidate)}, + {"nativeOnInvalidate", "(J)V", reinterpret_cast(&nativeOnInvalidate)}, {"nativeViewResize", "(JII)V", reinterpret_cast(static_cast(&nativeViewResize))}, diff --git a/android/cpp/native_map_view.cpp b/android/cpp/native_map_view.cpp index 9a24bddfe..d0581212d 100644 --- a/android/cpp/native_map_view.cpp +++ b/android/cpp/native_map_view.cpp @@ -761,7 +761,7 @@ void NativeMapView::updateFps() { env = nullptr; } -void NativeMapView::onInvalidate(bool inProgress) { +void NativeMapView::onInvalidate() { mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::onInvalidate()"); const bool dirty = !clean.test_and_set(); @@ -776,10 +776,8 @@ void NativeMapView::onInvalidate(bool inProgress) { map.setSourceTileCacheSize(cacheSize); - const bool needsRerender = map.renderSync(); - if (!inProgress) { - map.nudgeTransitions(needsRerender); - } + map.renderSync(); + map.nudgeTransitions(); } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java index 473f33a1a..1ecf7f11b 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java @@ -1285,8 +1285,7 @@ public class MapView extends SurfaceView { post(new Runnable() { @Override public void run() { - boolean inProgress = mRotateGestureDetector.isInProgress() || mScaleGestureDetector.isInProgress(); - mNativeMapView.invalidate(inProgress); + mNativeMapView.invalidate(); } }); } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java index cc65de52f..774c20a05 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java @@ -96,8 +96,8 @@ class NativeMapView { nativeUpdate(mNativeMapViewPtr); } - public void invalidate(boolean inProgress) { - nativeOnInvalidate(mNativeMapViewPtr, inProgress); + public void invalidate() { + nativeOnInvalidate(mNativeMapViewPtr); } public void resizeView(int width, int height) { @@ -463,7 +463,7 @@ class NativeMapView { private native void nativeUpdate(long nativeMapViewPtr); - private native void nativeOnInvalidate(long nativeMapViewPtr, boolean inProgress); + private native void nativeOnInvalidate(long nativeMapViewPtr); private native void nativeViewResize(long nativeMapViewPtr, int width, int height); diff --git a/include/mbgl/android/native_map_view.hpp b/include/mbgl/android/native_map_view.hpp index 1ea67a0da..3ae3d6ed9 100644 --- a/include/mbgl/android/native_map_view.hpp +++ b/include/mbgl/android/native_map_view.hpp @@ -49,7 +49,7 @@ public: void enableFps(bool enable); void updateFps(); - void onInvalidate(bool inProgress); + void onInvalidate(); void resizeView(int width, int height); void resizeFramebuffer(int width, int height); diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index e35a738d6..ae43dc8a8 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -66,11 +66,11 @@ public: using StillImageCallback = std::function)>; void renderStill(StillImageCallback callback); - // Triggers a synchronous or asynchronous render. - bool renderSync(); + // Triggers a synchronous render. + void renderSync(); - // Nudges transitions one step, possibly notifying of the need for a rerender. - void nudgeTransitions(bool forceRerender); + // Nudges transitions one step, possibly notifying of the need for a rerender, if any. + void nudgeTransitions(); // Notifies the Map thread that the state has changed and an update might be necessary. void update(Update update); diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index 8336b3293..078c26fee 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -336,11 +336,8 @@ void GLFWView::run() { glfwWaitEvents(); const bool dirty = !clean.test_and_set(); if (dirty) { - const bool needsRerender = map->renderSync(); - GLFWView *view = reinterpret_cast(glfwGetWindowUserPointer(window)); - if (!view->tracking || !view->rotating) { - map->nudgeTransitions(needsRerender); - } + map->renderSync(); + map->nudgeTransitions(); } } } diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index e95305d0c..81338f288 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -710,17 +710,11 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration) _mbglMap->setSourceTileCacheSize(cacheSize); - bool needsRerender = _mbglMap->renderSync(); + _mbglMap->renderSync(); [self updateUserLocationAnnotationView]; - // don't nudge transitions if in the midst of a gesture. - if (self.pan.state == UIGestureRecognizerStateChanged || - self.pinch.state == UIGestureRecognizerStateChanged || - self.rotate.state == UIGestureRecognizerStateChanged || - self.quickZoom.state == UIGestureRecognizerStateChanged) return; - - _mbglMap->nudgeTransitions(needsRerender); + _mbglMap->nudgeTransitions(); } } diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 4990d24fc..fadd4c48d 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -48,33 +48,31 @@ void Map::renderStill(StillImageCallback callback) { FrameData{ view.getFramebufferSize() }, callback); } -bool Map::renderSync() { +void Map::renderSync() { if (renderState == RenderState::never) { view.notifyMapChange(MapChangeWillStartRenderingMap); } view.notifyMapChange(MapChangeWillStartRenderingFrame); - MapContext::RenderResult result = context->invokeSync( - &MapContext::renderSync, transform->getState(), FrameData{ view.getFramebufferSize() }); + const bool fullyLoaded = context->invokeSync( + &MapContext::renderSync, transform->getState(), FrameData { view.getFramebufferSize() }); - view.notifyMapChange(result.fullyLoaded ? + view.notifyMapChange(fullyLoaded ? MapChangeDidFinishRenderingFrameFullyRendered : MapChangeDidFinishRenderingFrame); - if (!result.fullyLoaded) { + if (!fullyLoaded) { renderState = RenderState::partial; } else if (renderState != RenderState::fully) { renderState = RenderState::fully; view.notifyMapChange(MapChangeDidFinishRenderingMapFullyRendered); } - - return result.needsRerender; } -void Map::nudgeTransitions(bool forceRerender) { +void Map::nudgeTransitions() { UpdateType update_ = transform->updateTransitions(Clock::now()); - if (forceRerender) { + if (data->getNeedsRepaint()) { update_ |= static_cast(Update::Repaint); } update(Update(update_)); diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 4f8052f29..33e4e6d18 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -256,6 +256,9 @@ void MapContext::update() { if (!style) { updated = static_cast(Update::Nothing); + } + + if (updated == static_cast(Update::Nothing)) { return; } @@ -315,12 +318,12 @@ void MapContext::renderStill(const TransformState& state, const FrameData& frame asyncUpdate->send(); } -MapContext::RenderResult MapContext::renderSync(const TransformState& state, const FrameData& frame) { +bool MapContext::renderSync(const TransformState& state, const FrameData& frame) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); // Style was not loaded yet. if (!style) { - return { false, false }; + return false; } transformState = state; @@ -345,10 +348,11 @@ MapContext::RenderResult MapContext::renderSync(const TransformState& state, con viewInvalidated = false; - return RenderResult { - isLoaded(), - style->hasTransitions() || painter->needsAnimation() - }; + if (style->hasTransitions() || painter->needsAnimation()) { + data.setNeedsRepaint(true); + } + + return isLoaded(); } bool MapContext::isLoaded() const { diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index dd211d4a1..215f5d377 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -38,16 +38,13 @@ public: MapContext(View&, FileSource&, MapData&); ~MapContext(); - struct RenderResult { - bool fullyLoaded; - bool needsRerender; - }; - void pause(); void triggerUpdate(const TransformState&, Update = Update::Nothing); void renderStill(const TransformState&, const FrameData&, Map::StillImageCallback callback); - RenderResult renderSync(const TransformState&, const FrameData&); + + // Triggers a synchronous render. Returns true if style has been fully loaded. + bool renderSync(const TransformState&, const FrameData&); void setStyleURL(const std::string&); void setStyleJSON(const std::string& json, const std::string& base); diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp index aadc8dcd6..9eac6162e 100644 --- a/src/mbgl/map/map_data.hpp +++ b/src/mbgl/map/map_data.hpp @@ -101,6 +101,14 @@ public: defaultTransitionDelay = delay; } + inline bool getNeedsRepaint() const { + return needsRepaint; + } + + inline void setNeedsRepaint(const bool needsRepaint_) { + needsRepaint = needsRepaint_; + } + util::exclusive getAnnotationManager() { return util::exclusive( &annotationManager, @@ -124,6 +132,7 @@ private: std::atomic defaultFadeDuration; std::atomic defaultTransitionDuration; std::atomic defaultTransitionDelay; + std::atomic needsRepaint; // TODO: make private public: From 5eebda7199025bb59ad2d28a49a197250e1d18d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Wed, 5 Aug 2015 09:23:50 -0700 Subject: [PATCH 9/9] Updated Mason submodule pin Pulled in mason/mason@41d8b2eb28b3cd942d9f15583467b27c549675ea for mapbox/mason#106 and mason/mason@d8597d944533dbb5e28d08dfdba22a82c93171b7 for mapbox/mason#110. Fixes #1957 and fixes #1707. --- .mason | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mason b/.mason index 1d5789dfa..d8597d944 160000 --- a/.mason +++ b/.mason @@ -1 +1 @@ -Subproject commit 1d5789dfadeffa5df8e58770e3326840d1e6d9c9 +Subproject commit d8597d944533dbb5e28d08dfdba22a82c93171b7