summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-04-02 16:38:08 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-04-02 16:38:08 -0700
commit3bd180dbe84748b51517163b7e45c48a21f0b252 (patch)
tree0dcaf8906d8e3b2df9b5c7481778ab176b7ae335
parent7c05f941a8c001ad770a79fc2ae59093d0dcdcd2 (diff)
parent12c07b916b106272ba68f0fc85a10b774fd07a50 (diff)
downloadqtlocation-mapboxgl-3bd180dbe84748b51517163b7e45c48a21f0b252.tar.gz
Merge pull request #1155 from mapbox/1155-update-as-needed
Only run Style::updateProperties when required
-rw-r--r--android/cpp/jni.cpp48
-rw-r--r--android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/NativeMapView.java36
-rw-r--r--include/mbgl/map/map.hpp16
-rw-r--r--include/mbgl/map/transform.hpp28
-rw-r--r--include/mbgl/map/transform_state.hpp1
-rw-r--r--include/mbgl/map/update.hpp19
-rw-r--r--platform/default/glfw_view.cpp9
-rw-r--r--platform/ios/MGLMapView.mm12
-rw-r--r--src/mbgl/map/map.cpp95
-rw-r--r--src/mbgl/map/transform.cpp182
-rw-r--r--src/mbgl/map/transform_state.cpp2
-rw-r--r--src/mbgl/util/raster.cpp15
-rw-r--r--src/mbgl/util/raster.hpp9
13 files changed, 163 insertions, 309 deletions
diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp
index ce61a01bf9..b6e46ed5ac 100644
--- a/android/cpp/jni.cpp
+++ b/android/cpp/jni.cpp
@@ -461,20 +461,6 @@ jobject JNICALL nativeGetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr
return ret;
}
-void JNICALL nativeStartPanning(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStartPanning");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().startPanning();
-}
-
-void JNICALL nativeStopPanning(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStopPanning");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().stopPanning();
-}
-
void JNICALL nativeResetPosition(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetPosition");
assert(nativeMapViewPtr != 0);
@@ -570,20 +556,6 @@ void JNICALL nativeResetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
nativeMapView->getMap().resetZoom();
}
-void JNICALL nativeStartScaling(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStartScaling");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().startScaling();
-}
-
-void JNICALL nativeStopScaling(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStopScaling");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- return nativeMapView->getMap().stopScaling();
-}
-
jdouble JNICALL nativeGetMinZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMinZoom");
assert(nativeMapViewPtr != 0);
@@ -636,20 +608,6 @@ void JNICALL nativeResetNorth(JNIEnv *env, jobject obj, jlong nativeMapViewPtr)
nativeMapView->getMap().resetNorth();
}
-void JNICALL nativeStartRotating(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStartRotating");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().startRotating();
-}
-
-void JNICALL nativeStopRotating(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
- mbgl::Log::Debug(mbgl::Event::JNI, "nativeStopRotating");
- assert(nativeMapViewPtr != 0);
- NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- nativeMapView->getMap().stopRotating();
-}
-
void JNICALL nativeSetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean debug) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDebug");
assert(nativeMapViewPtr != 0);
@@ -1029,8 +987,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
reinterpret_cast<void *>(&nativeSetLatLng)},
{"nativeGetLatLng", "(J)Lcom/mapbox/mapboxgl/geometry/LatLng;",
reinterpret_cast<void *>(&nativeGetLatLng)},
- {"nativeStartPanning", "(J)V", reinterpret_cast<void *>(&nativeStartPanning)},
- {"nativeStopPanning", "(J)V", reinterpret_cast<void *>(&nativeStopPanning)},
{"nativeResetPosition", "(J)V", reinterpret_cast<void *>(&nativeResetPosition)},
{"nativeScaleBy", "(JDDDJ)V", reinterpret_cast<void *>(&nativeScaleBy)},
{"nativeSetScale", "(JDDDJ)V", reinterpret_cast<void *>(&nativeSetScale)},
@@ -1042,8 +998,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
{"nativeGetLatLngZoom", "(J)Lcom/mapbox/mapboxgl/geometry/LatLngZoom;",
reinterpret_cast<void *>(&nativeGetLatLngZoom)},
{"nativeResetZoom", "(J)V", reinterpret_cast<void *>(&nativeResetZoom)},
- {"nativeStartPanning", "(J)V", reinterpret_cast<void *>(&nativeStartScaling)},
- {"nativeStopPanning", "(J)V", reinterpret_cast<void *>(&nativeStopScaling)},
{"nativeGetMinZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMinZoom)},
{"nativeGetMaxZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMaxZoom)},
{"nativeRotateBy", "(JDDDDJ)V", reinterpret_cast<void *>(&nativeRotateBy)},
@@ -1057,8 +1011,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
&nativeSetBearing))},
{"nativeGetBearing", "(J)D", reinterpret_cast<void *>(&nativeGetBearing)},
{"nativeResetNorth", "(J)V", reinterpret_cast<void *>(&nativeResetNorth)},
- {"nativeStartRotating", "(J)V", reinterpret_cast<void *>(&nativeStartRotating)},
- {"nativeStopRotating", "(J)V", reinterpret_cast<void *>(&nativeStopRotating)},
{"nativeSetDebug", "(JZ)V", reinterpret_cast<void *>(&nativeSetDebug)},
{"nativeToggleDebug", "(J)V", reinterpret_cast<void *>(&nativeToggleDebug)},
{"nativeGetDebug", "(J)Z", reinterpret_cast<void *>(&nativeGetDebug)},
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 186b391a84..d7ca950fbf 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
@@ -213,14 +213,6 @@ class NativeMapView {
return nativeGetLatLng(mNativeMapViewPtr);
}
- public void startPanning() {
- nativeStartPanning(mNativeMapViewPtr);
- }
-
- public void stopPanning() {
- nativeStopPanning(mNativeMapViewPtr);
- }
-
public void resetPosition() {
nativeResetPosition(mNativeMapViewPtr);
}
@@ -281,14 +273,6 @@ class NativeMapView {
nativeResetZoom(mNativeMapViewPtr);
}
- public void startScaling() {
- nativeStartScaling(mNativeMapViewPtr);
- }
-
- public void stopScaling() {
- nativeStopScaling(mNativeMapViewPtr);
- }
-
public double getMinZoom() {
return nativeGetMinZoom(mNativeMapViewPtr);
}
@@ -326,14 +310,6 @@ class NativeMapView {
nativeResetNorth(mNativeMapViewPtr);
}
- public void startRotating() {
- nativeStartRotating(mNativeMapViewPtr);
- }
-
- public void stopRotating() {
- nativeStopRotating(mNativeMapViewPtr);
- }
-
public void setDebug(boolean debug) {
nativeSetDebug(mNativeMapViewPtr, debug);
}
@@ -468,10 +444,6 @@ class NativeMapView {
private native LatLng nativeGetLatLng(long nativeMapViewPtr);
- private native void nativeStartPanning(long nativeMapViewPtr);
-
- private native void nativeStopPanning(long nativeMapViewPtr);
-
private native void nativeResetPosition(long nativeMapViewPtr);
private native void nativeScaleBy(long nativeMapViewPtr, double ds,
@@ -494,10 +466,6 @@ class NativeMapView {
private native void nativeResetZoom(long nativeMapViewPtr);
- private native void nativeStartScaling(long nativeMapViewPtr);
-
- private native void nativeStopScaling(long nativeMapViewPtr);
-
private native double nativeGetMinZoom(long nativeMapViewPtr);
private native double nativeGetMaxZoom(long nativeMapViewPtr);
@@ -515,10 +483,6 @@ class NativeMapView {
private native void nativeResetNorth(long nativeMapViewPtr);
- private native void nativeStartRotating(long nativeMapViewPtr);
-
- private native void nativeStopRotating(long nativeMapViewPtr);
-
private native void nativeSetDebug(long nativeMapViewPtr, boolean debug);
private native void nativeToggleDebug(long nativeMapViewPtr);
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 83bb055214..cdcfa27e42 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -3,6 +3,7 @@
#include <mbgl/map/transform.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/map/update.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/projection.hpp>
#include <mbgl/util/noncopyable.hpp>
@@ -76,14 +77,6 @@ public:
void render();
// Notifies the Map thread that the state has changed and an update might be necessary.
- using UpdateType = uint32_t;
- enum class Update : UpdateType {
- Nothing = 0,
- StyleInfo = 1 << 0,
- Debug = 1 << 1,
- DefaultTransitionDuration = 1 << 2,
- Classes = 1 << 3,
- };
void triggerUpdate(Update = Update::Nothing);
// Triggers a render. Can be called from any thread.
@@ -107,13 +100,12 @@ public:
// Transition
void cancelTransitions();
+ void setGestureInProgress(bool);
// Position
void moveBy(double dx, double dy, Duration = Duration::zero());
void setLatLng(LatLng latLng, Duration = Duration::zero());
LatLng getLatLng() const;
- void startPanning();
- void stopPanning();
void resetPosition();
// Scale
@@ -124,8 +116,6 @@ public:
double getZoom() const;
void setLatLngZoom(LatLng latLng, double zoom, Duration = Duration::zero());
void resetZoom();
- void startScaling();
- void stopScaling();
double getMinZoom() const;
double getMaxZoom() const;
@@ -135,8 +125,6 @@ public:
void setBearing(double degrees, double cx, double cy);
double getBearing() const;
void resetNorth();
- void startRotating();
- void stopRotating();
// API
void setAccessToken(const std::string &token);
diff --git a/include/mbgl/map/transform.hpp b/include/mbgl/map/transform.hpp
index b15c119c44..ef89a4eefa 100644
--- a/include/mbgl/map/transform.hpp
+++ b/include/mbgl/map/transform.hpp
@@ -3,6 +3,7 @@
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/map/update.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/vec.hpp>
@@ -31,8 +32,6 @@ public:
void setLatLng(LatLng latLng, Duration = Duration::zero());
void setLatLngZoom(LatLng latLng, double zoom, Duration = Duration::zero());
inline const LatLng getLatLng() const { return current.getLatLng(); }
- void startPanning();
- void stopPanning();
// Zoom
void scaleBy(double ds, double cx = -1, double cy = -1, Duration = Duration::zero());
@@ -40,8 +39,6 @@ public:
void setZoom(double zoom, Duration = Duration::zero());
double getZoom() const;
double getScale() const;
- void startScaling();
- void stopScaling();
double getMinZoom() const;
double getMaxZoom() const;
@@ -50,14 +47,15 @@ public:
void setAngle(double angle, Duration = Duration::zero());
void setAngle(double angle, double cx, double cy);
double getAngle() const;
- void startRotating();
- void stopRotating();
// Transitions
bool needsTransition() const;
- void updateTransitions(TimePoint now);
+ UpdateType updateTransitions(TimePoint now);
void cancelTransitions();
+ // Gesture
+ void setGestureInProgress(bool);
+
// Transform state
const TransformState currentState() const;
const TransformState finalState() const;
@@ -69,13 +67,9 @@ private:
void _setScale(double scale, double cx, double cy, Duration = Duration::zero());
void _setScaleXY(double new_scale, double xn, double yn, Duration = Duration::zero());
void _setAngle(double angle, Duration = Duration::zero());
- void _clearPanning();
- void _clearRotating();
- void _clearScaling();
void constrain(double& scale, double& y) const;
-private:
View &view;
mutable std::recursive_mutex mtx;
@@ -92,10 +86,14 @@ private:
const double min_scale = std::pow(2, 0);
const double max_scale = std::pow(2, 18);
- std::forward_list<util::ptr<util::transition>> transitions;
- util::ptr<util::transition> scale_timeout;
- util::ptr<util::transition> rotate_timeout;
- util::ptr<util::transition> pan_timeout;
+ void startTransition(std::function<Update(double)> frame,
+ std::function<void()> finish,
+ Duration);
+
+ TimePoint transitionStart;
+ Duration transitionDuration;
+ std::function<Update(TimePoint)> transitionFrameFn;
+ std::function<void()> transitionFinishFn;
};
}
diff --git a/include/mbgl/map/transform_state.hpp b/include/mbgl/map/transform_state.hpp
index 5f2dfa49e4..c1a324a899 100644
--- a/include/mbgl/map/transform_state.hpp
+++ b/include/mbgl/map/transform_state.hpp
@@ -77,6 +77,7 @@ private:
bool rotating = false;
bool scaling = false;
bool panning = false;
+ bool gestureInProgress = false;
// map position
double x = 0, y = 0;
diff --git a/include/mbgl/map/update.hpp b/include/mbgl/map/update.hpp
new file mode 100644
index 0000000000..3aa871bf03
--- /dev/null
+++ b/include/mbgl/map/update.hpp
@@ -0,0 +1,19 @@
+#ifndef MBGL_MAP_UPDATE
+#define MBGL_MAP_UPDATE
+
+namespace mbgl {
+
+using UpdateType = uint32_t;
+
+enum class Update : UpdateType {
+ Nothing = 0,
+ StyleInfo = 1 << 0,
+ Debug = 1 << 1,
+ DefaultTransitionDuration = 1 << 2,
+ Classes = 1 << 3,
+ Zoom = 1 << 4,
+};
+
+}
+
+#endif
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index fd9c701f92..7cedd634cd 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -212,7 +212,6 @@ void GLFWView::onScroll(GLFWwindow *window, double /*xOffset*/, double yOffset)
scale = 1.0 / scale;
}
- view->map->startScaling();
view->map->scaleBy(scale, view->lastX, view->lastY);
}
@@ -231,14 +230,12 @@ void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modi
if (button == GLFW_MOUSE_BUTTON_RIGHT ||
(button == GLFW_MOUSE_BUTTON_LEFT && modifiers & GLFW_MOD_CONTROL)) {
view->rotating = action == GLFW_PRESS;
- if (!view->rotating) {
- view->map->stopRotating();
- }
+ view->map->setGestureInProgress(view->rotating);
} else if (button == GLFW_MOUSE_BUTTON_LEFT) {
view->tracking = action == GLFW_PRESS;
+ view->map->setGestureInProgress(view->tracking);
if (action == GLFW_RELEASE) {
- view->map->stopPanning();
double now = glfwGetTime();
if (now - view->lastClick < 0.4 /* ms */) {
if (modifiers & GLFW_MOD_SHIFT) {
@@ -258,11 +255,9 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
double dx = x - view->lastX;
double dy = y - view->lastY;
if (dx || dy) {
- view->map->startPanning();
view->map->moveBy(dx, dy);
}
} else if (view->rotating) {
- view->map->startRotating();
view->map->rotateBy(view->lastX, view->lastY, x, y);
}
view->lastX = x;
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 4a55ada173..962e3a1126 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -615,6 +615,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
{
[self trackGestureEvent:MGLEventGesturePanStart forRecognizer:pan];
+ mbglMap->setGestureInProgress(true);
+
self.centerPoint = CGPointMake(0, 0);
self.userTrackingMode = MGLUserTrackingModeNone;
@@ -651,6 +653,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
mbglMap->moveBy(offset.x, offset.y, secondsAsDuration(duration));
+ mbglMap->setGestureInProgress(false);
+
if (duration)
{
self.animatingGesture = YES;
@@ -694,7 +698,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
{
[self trackGestureEvent:MGLEventGesturePinchStart forRecognizer:pinch];
- mbglMap->startScaling();
+ mbglMap->setGestureInProgress(true);
self.scale = mbglMap->getScale();
@@ -712,7 +716,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
}
else if (pinch.state == UIGestureRecognizerStateEnded || pinch.state == UIGestureRecognizerStateCancelled)
{
- mbglMap->stopScaling();
+ mbglMap->setGestureInProgress(false);
[self unrotateIfNeededAnimated:YES];
@@ -730,7 +734,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
{
[self trackGestureEvent:MGLEventGestureRotateStart forRecognizer:rotate];
- mbglMap->startRotating();
+ mbglMap->setGestureInProgress(true);
self.angle = [MGLMapView degreesToRadians:mbglMap->getBearing()] * -1;
@@ -754,7 +758,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
}
else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled)
{
- mbglMap->stopRotating();
+ mbglMap->setGestureInProgress(false);
[self unrotateIfNeededAnimated:YES];
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 9dad7a58b3..509986a6d2 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -7,7 +7,6 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/map/annotation.hpp>
#include <mbgl/map/sprite.hpp>
-#include <mbgl/util/transition.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/clip_ids.hpp>
#include <mbgl/util/string.hpp>
@@ -72,7 +71,8 @@ Map::Map(View& view_, FileSource& fileSource_)
texturePool(std::make_shared<TexturePool>()),
painter(util::make_unique<Painter>(*spriteAtlas, *glyphAtlas, *lineAtlas)),
annotationManager(util::make_unique<AnnotationManager>()),
- data(util::make_unique<MapData>())
+ data(util::make_unique<MapData>()),
+ updated(static_cast<UpdateType>(Update::Nothing))
{
view.initialize(this);
}
@@ -449,10 +449,13 @@ void Map::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth,
void Map::cancelTransitions() {
transform.cancelTransitions();
-
triggerUpdate();
}
+void Map::setGestureInProgress(bool inProgress) {
+ transform.setGestureInProgress(inProgress);
+ triggerUpdate();
+}
#pragma mark - Position
@@ -470,21 +473,11 @@ LatLng Map::getLatLng() const {
return state.getLatLng();
}
-void Map::startPanning() {
- transform.startPanning();
- triggerUpdate();
-}
-
-void Map::stopPanning() {
- transform.stopPanning();
- triggerUpdate();
-}
-
void Map::resetPosition() {
transform.setAngle(0);
transform.setLatLng(LatLng(0, 0));
transform.setZoom(0);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
@@ -492,12 +485,12 @@ void Map::resetPosition() {
void Map::scaleBy(double ds, double cx, double cy, Duration duration) {
transform.scaleBy(ds, cx, cy, duration);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
void Map::setScale(double scale, double cx, double cy, Duration duration) {
transform.setScale(scale, cx, cy, duration);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
double Map::getScale() const {
@@ -506,7 +499,7 @@ double Map::getScale() const {
void Map::setZoom(double zoom, Duration duration) {
transform.setZoom(zoom, duration);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
double Map::getZoom() const {
@@ -515,23 +508,13 @@ double Map::getZoom() const {
void Map::setLatLngZoom(LatLng latLng, double zoom, Duration duration) {
transform.setLatLngZoom(latLng, zoom, duration);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
void Map::resetZoom() {
setZoom(0);
}
-void Map::startScaling() {
- transform.startScaling();
- triggerUpdate();
-}
-
-void Map::stopScaling() {
- transform.stopScaling();
- triggerUpdate();
-}
-
double Map::getMinZoom() const {
return transform.getMinZoom();
}
@@ -567,16 +550,6 @@ void Map::resetNorth() {
triggerUpdate();
}
-void Map::startRotating() {
- transform.startRotating();
- triggerUpdate();
-}
-
-void Map::stopRotating() {
- transform.stopRotating();
- triggerUpdate();
-}
-
#pragma mark - Access Token
void Map::setAccessToken(const std::string &token) {
@@ -802,44 +775,49 @@ void Map::loadStyleJSON(const std::string& json, const std::string& base) {
const std::string glyphURL = util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken());
glyphStore->setURL(glyphURL);
- triggerUpdate();
+ triggerUpdate(Update::Zoom);
}
void Map::prepare() {
assert(Environment::currentlyOn(ThreadType::Map));
- const auto u = updated.exchange(static_cast<UpdateType>(Update::Nothing));
- if ((u & static_cast<UpdateType>(Update::StyleInfo)) || !style) {
+ const auto now = Clock::now();
+ data->setAnimationTime(now);
+
+ auto u = updated.exchange(static_cast<UpdateType>(Update::Nothing)) |
+ transform.updateTransitions(now);
+
+ if (!style) {
+ u |= static_cast<UpdateType>(Update::StyleInfo);
+ }
+
+ state = transform.currentState();
+
+ if (u & static_cast<UpdateType>(Update::StyleInfo)) {
reloadStyle();
}
+
if (u & static_cast<UpdateType>(Update::Debug)) {
assert(painter);
painter->setDebug(data->getDebug());
}
- if (u & static_cast<UpdateType>(Update::DefaultTransitionDuration)) {
- if (style) {
+
+ if (style) {
+ if (u & static_cast<UpdateType>(Update::DefaultTransitionDuration)) {
style->setDefaultTransitionDuration(data->getDefaultTransitionDuration());
}
- }
- if (u & static_cast<UpdateType>(Update::Classes)) {
- if (style) {
+
+ if (u & static_cast<UpdateType>(Update::Classes)) {
style->cascade(data->getClasses());
}
- }
-
- // Update transform transitions.
- const auto animationTime = Clock::now();
- data->setAnimationTime(animationTime);
- if (transform.needsTransition()) {
- transform.updateTransitions(animationTime);
- }
-
- state = transform.currentState();
+ if (u & static_cast<UpdateType>(Update::StyleInfo) ||
+ u & static_cast<UpdateType>(Update::Classes) ||
+ u & static_cast<UpdateType>(Update::Zoom)) {
+ style->recalculate(state.getNormalizedZoom(), now);
+ }
- if (style) {
updateSources();
- style->recalculate(state.getNormalizedZoom(), animationTime);
// Allow the sprite atlas to potentially pull new sprite images if needed.
spriteAtlas->resize(state.getPixelRatio());
@@ -863,6 +841,7 @@ void Map::render() {
assert(painter);
painter->render(*style, activeSources,
state, data->getAnimationTime());
+
// Schedule another rerender when we definitely need a next frame.
if (transform.needsTransition() || style->hasTransitions()) {
triggerUpdate();
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index dd0fd620b1..10f69e2edc 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -4,7 +4,8 @@
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/math.hpp>
-#include <mbgl/util/transition.hpp>
+#include <mbgl/util/unitbezier.hpp>
+#include <mbgl/util/interpolate.hpp>
#include <mbgl/platform/platform.hpp>
#include <cstdio>
@@ -66,12 +67,19 @@ void Transform::_moveBy(const double dx, const double dy, const Duration duratio
current.x = final.x;
current.y = final.y;
} else {
- // Use a common start time for all of the transitions to avoid divergent transitions.
- TimePoint start = Clock::now();
- transitions.emplace_front(
- std::make_shared<util::ease_transition<double>>(current.x, final.x, current.x, start, duration));
- transitions.emplace_front(
- std::make_shared<util::ease_transition<double>>(current.y, final.y, current.y, start, duration));
+ const double startX = current.x;
+ const double startY = current.y;
+ current.panning = true;
+
+ startTransition(
+ [=](double t) {
+ current.x = util::interpolate(startX, final.x, t);
+ current.y = util::interpolate(startY, final.y, t);
+ return Update::Nothing;
+ },
+ [=] {
+ current.panning = false;
+ }, duration);
}
view.notifyMapChange(duration != Duration::zero() ?
@@ -110,31 +118,6 @@ void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Dura
_setScaleXY(new_scale, xn, yn, duration);
}
-void Transform::startPanning() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- _clearPanning();
-
- // Add a 200ms timeout for resetting this to false
- current.panning = true;
- TimePoint start = Clock::now();
- pan_timeout = std::make_shared<util::timeout<bool>>(false, current.panning, start, std::chrono::milliseconds(200));
- transitions.emplace_front(pan_timeout);
-}
-
-void Transform::stopPanning() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- _clearPanning();
-}
-
-void Transform::_clearPanning() {
- current.panning = false;
- if (pan_timeout) {
- transitions.remove(pan_timeout);
- pan_timeout.reset();
- }
-}
#pragma mark - Zoom
@@ -177,24 +160,6 @@ double Transform::getScale() const {
return final.scale;
}
-void Transform::startScaling() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- _clearScaling();
-
- // Add a 200ms timeout for resetting this to false
- current.scaling = true;
- TimePoint start = Clock::now();
- scale_timeout = std::make_shared<util::timeout<bool>>(false, current.scaling, start, std::chrono::milliseconds(200));
- transitions.emplace_front(scale_timeout);
-}
-
-void Transform::stopScaling() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- _clearScaling();
-}
-
double Transform::getMinZoom() const {
double test_scale = current.scale;
double test_y = current.y;
@@ -207,16 +172,6 @@ double Transform::getMaxZoom() const {
return std::log2(max_scale);
}
-void Transform::_clearScaling() {
- // This is only called internally, so we don't need a lock here.
-
- current.scaling = false;
- if (scale_timeout) {
- transitions.remove(scale_timeout);
- scale_timeout.reset();
- }
-}
-
void Transform::_setScale(double new_scale, double cx, double cy, const Duration duration) {
// This is only called internally, so we don't need a lock here.
@@ -269,14 +224,23 @@ void Transform::_setScaleXY(const double new_scale, const double xn, const doubl
current.x = final.x;
current.y = final.y;
} else {
- // Use a common start time for all of the transitions to avoid divergent transitions.
- TimePoint start = Clock::now();
- transitions.emplace_front(std::make_shared<util::ease_transition<double>>(
- current.scale, final.scale, current.scale, start, duration));
- transitions.emplace_front(
- std::make_shared<util::ease_transition<double>>(current.x, final.x, current.x, start, duration));
- transitions.emplace_front(
- std::make_shared<util::ease_transition<double>>(current.y, final.y, current.y, start, duration));
+ const double startS = current.scale;
+ const double startX = current.x;
+ const double startY = current.y;
+ current.panning = true;
+ current.scaling = true;
+
+ startTransition(
+ [=](double t) {
+ current.scale = util::interpolate(startS, final.scale, t);
+ current.x = util::interpolate(startX, final.x, t);
+ current.y = util::interpolate(startY, final.y, t);
+ return Update::Zoom;
+ },
+ [=] {
+ current.panning = false;
+ current.scaling = false;
+ }, duration);
}
const double s = final.scale * util::tileSize;
@@ -376,9 +340,17 @@ void Transform::_setAngle(double new_angle, const Duration duration) {
if (duration == Duration::zero()) {
current.angle = final.angle;
} else {
- TimePoint start = Clock::now();
- transitions.emplace_front(std::make_shared<util::ease_transition<double>>(
- current.angle, final.angle, current.angle, start, duration));
+ const double startA = current.angle;
+ current.rotating = true;
+
+ startTransition(
+ [=](double t) {
+ current.angle = util::interpolate(startA, final.angle, t);
+ return Update::Nothing;
+ },
+ [=] {
+ current.rotating = false;
+ }, duration);
}
view.notifyMapChange(duration != Duration::zero() ?
@@ -393,55 +365,61 @@ double Transform::getAngle() const {
return final.angle;
}
-void Transform::startRotating() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- _clearRotating();
- // Add a 200ms timeout for resetting this to false
- current.rotating = true;
- TimePoint start = Clock::now();
- rotate_timeout = std::make_shared<util::timeout<bool>>(false, current.rotating, start, std::chrono::milliseconds(200));
- transitions.emplace_front(rotate_timeout);
-}
+#pragma mark - Transition
-void Transform::stopRotating() {
- std::lock_guard<std::recursive_mutex> lock(mtx);
+void Transform::startTransition(std::function<Update(double)> frame,
+ std::function<void()> finish,
+ Duration duration) {
+ if (transitionFinishFn) {
+ transitionFinishFn();
+ }
- _clearRotating();
-}
+ transitionStart = Clock::now();
+ transitionDuration = duration;
-void Transform::_clearRotating() {
- // This is only called internally, so we don't need a lock here.
+ transitionFrameFn = [frame, this](TimePoint now) {
+ float t = std::chrono::duration<float>(now - transitionStart) / transitionDuration;
+ if (t >= 1.0) {
+ Update result = frame(1.0);
+ transitionFinishFn();
+ transitionFrameFn = nullptr;
+ transitionFinishFn = nullptr;
+ return result;
+ } else {
+ util::UnitBezier ease(0, 0, 0.25, 1);
+ return frame(ease.solve(t, 0.001));
+ }
+ };
- current.rotating = false;
- if (rotate_timeout) {
- transitions.remove(rotate_timeout);
- rotate_timeout.reset();
- }
+ transitionFinishFn = finish;
}
-
-#pragma mark - Transition
-
bool Transform::needsTransition() const {
std::lock_guard<std::recursive_mutex> lock(mtx);
+ return !!transitionFrameFn;
+}
- return !transitions.empty();
+UpdateType Transform::updateTransitions(const TimePoint now) {
+ std::lock_guard<std::recursive_mutex> lock(mtx);
+ return static_cast<UpdateType>(transitionFrameFn ? transitionFrameFn(now) : Update::Nothing);
}
-void Transform::updateTransitions(const TimePoint now) {
+void Transform::cancelTransitions() {
std::lock_guard<std::recursive_mutex> lock(mtx);
- transitions.remove_if([now](const util::ptr<util::transition> &transition) {
- return transition->update(now) == util::transition::complete;
- });
+ if (transitionFinishFn) {
+ transitionFinishFn();
+ }
+
+ transitionFrameFn = nullptr;
+ transitionFinishFn = nullptr;
}
-void Transform::cancelTransitions() {
+void Transform::setGestureInProgress(bool inProgress) {
std::lock_guard<std::recursive_mutex> lock(mtx);
- transitions.clear();
+ current.gestureInProgress = inProgress;
}
#pragma mark - Transform state
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 8c007210e0..32ce184fa9 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -249,7 +249,7 @@ const LatLng TransformState::latLngForPixel(const vec2<double> pixel) const {
#pragma mark - Changing
bool TransformState::isChanging() const {
- return rotating || scaling || panning;
+ return rotating || scaling || panning || gestureInProgress;
}
diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp
index 7300c291e5..d0e305c33a 100644
--- a/src/mbgl/util/raster.cpp
+++ b/src/mbgl/util/raster.cpp
@@ -89,18 +89,3 @@ void Raster::bind(const GLuint custom_texture) {
}
}
-
-void Raster::beginFadeInTransition() {
- TimePoint start = Clock::now();
- fade_transition = std::make_shared<util::ease_transition<double>>(opacity, 1.0, opacity, start, std::chrono::milliseconds(250));
-}
-
-bool Raster::needsTransition() const {
- return fade_transition != nullptr;
-}
-
-void Raster::updateTransitions(TimePoint now) {
- if (fade_transition->update(now) == util::transition::complete) {
- fade_transition = nullptr;
- }
-}
diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp
index 6e5a819916..f19ff7178a 100644
--- a/src/mbgl/util/raster.hpp
+++ b/src/mbgl/util/raster.hpp
@@ -1,7 +1,6 @@
#ifndef MBGL_UTIL_RASTER
#define MBGL_UTIL_RASTER
-#include <mbgl/util/transition.hpp>
#include <mbgl/util/texture_pool.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/ptr.hpp>
@@ -32,11 +31,6 @@ public:
// loaded status
bool isLoaded() const;
- // transitions
- void beginFadeInTransition();
- bool needsTransition() const;
- void updateTransitions(TimePoint now);
-
public:
// loaded image dimensions
uint32_t width = 0, height = 0;
@@ -64,9 +58,6 @@ private:
// the raw pixels
std::unique_ptr<util::Image> img;
-
- // fade in transition
- util::ptr<util::transition> fade_transition = nullptr;
};
}