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.
This commit is contained in:
Bruno de Oliveira Abinader
2015-08-03 01:36:19 +03:00
parent 9fd7e883a7
commit fa4636ffe4
12 changed files with 48 additions and 52 deletions

View File

@@ -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<NativeMapView *>(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<void *>(&nativePause)},
{"nativeResume", "(J)V", reinterpret_cast<void *>(&nativeResume)},
{"nativeUpdate", "(J)V", reinterpret_cast<void *>(&nativeUpdate)},
{"nativeOnInvalidate", "(JZ)V", reinterpret_cast<void *>(&nativeOnInvalidate)},
{"nativeOnInvalidate", "(J)V", reinterpret_cast<void *>(&nativeOnInvalidate)},
{"nativeViewResize", "(JII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
*)(JNIEnv *, jobject, jlong, jint, jint)>(&nativeViewResize))},

View File

@@ -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();
}
}

View File

@@ -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();
}
});
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -66,11 +66,11 @@ public:
using StillImageCallback = std::function<void(std::exception_ptr, std::unique_ptr<const StillImage>)>;
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);

View File

@@ -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<GLFWView *>(glfwGetWindowUserPointer(window));
if (!view->tracking || !view->rotating) {
map->nudgeTransitions(needsRerender);
}
map->renderSync();
map->nudgeTransitions();
}
}
}

View File

@@ -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();
}
}

View File

@@ -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::RenderResult>(
&MapContext::renderSync, transform->getState(), FrameData{ view.getFramebufferSize() });
const bool fullyLoaded = context->invokeSync<bool>(
&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<UpdateType>(Update::Repaint);
}
update(Update(update_));

View File

@@ -256,6 +256,9 @@ void MapContext::update() {
if (!style) {
updated = static_cast<UpdateType>(Update::Nothing);
}
if (updated == static_cast<UpdateType>(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 {

View File

@@ -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);

View File

@@ -101,6 +101,14 @@ public:
defaultTransitionDelay = delay;
}
inline bool getNeedsRepaint() const {
return needsRepaint;
}
inline void setNeedsRepaint(const bool needsRepaint_) {
needsRepaint = needsRepaint_;
}
util::exclusive<AnnotationManager> getAnnotationManager() {
return util::exclusive<AnnotationManager>(
&annotationManager,
@@ -124,6 +132,7 @@ private:
std::atomic<Duration> defaultFadeDuration;
std::atomic<Duration> defaultTransitionDuration;
std::atomic<Duration> defaultTransitionDelay;
std::atomic<bool> needsRepaint;
// TODO: make private
public: