drive Android rendering from the main thread via invalidate() calls

This commit is contained in:
Konstantin Käfer
2015-06-25 14:39:42 +02:00
committed by John Firebaugh
parent 84e2ea886d
commit dca42018d2
6 changed files with 92 additions and 3 deletions

View File

@@ -30,6 +30,7 @@ std::string dataPath;
std::string apkPath;
std::string androidRelease;
jmethodID onInvalidateId = nullptr;
jmethodID onMapChangedId = nullptr;
jmethodID onFpsChangedId = nullptr;
@@ -277,6 +278,13 @@ void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
nativeMapView->getMap().update();
}
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();
}
void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height,
jfloat ratio, jint fbWidth, jint fbHeight) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResize");
@@ -805,6 +813,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
onInvalidateId = env->GetMethodID(nativeMapViewClass, "onInvalidate", "()V");
if (onInvalidateId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
onMapChangedId = env->GetMethodID(nativeMapViewClass, "onMapChanged", "()V");
if (onMapChangedId == nullptr) {
env->ExceptionDescribe();
@@ -921,6 +935,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", "(J)V", reinterpret_cast<void *>(&nativeOnInvalidate)},
{"nativeResize", "(JIIFII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
*)(JNIEnv *, jobject, jlong, jint, jint, jfloat, jint, jint)>(&nativeResize))},
@@ -1092,6 +1107,7 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
latLngZoomLatitudeId = nullptr;
latLngZoomZoomId = nullptr;
onInvalidateId = nullptr;
onMapChangedId = nullptr;
onFpsChangedId = nullptr;

View File

@@ -125,13 +125,49 @@ void NativeMapView::deactivate() {
}
void NativeMapView::invalidate() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::invalidate");
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::invalidate()");
// TODO: inform the main thread that it must call map->renderSync();
clean.clear();
assert(vm != nullptr);
assert(obj != nullptr);
JavaVMAttachArgs args = {JNI_VERSION_1_2, "NativeMapView::invalidate()", NULL};
jint ret;
JNIEnv *env = nullptr;
bool detach = false;
ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
if (ret != JNI_EDETACHED) {
mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
throw new std::runtime_error("GetEnv() failed");
} else {
ret = vm->AttachCurrentThread(&env, &args);
if (ret != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
throw new std::runtime_error("AttachCurrentThread() failed");
}
detach = true;
}
}
env->CallVoidMethod(obj, onInvalidateId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
if (detach) {
if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
throw new std::runtime_error("DetachCurrentThread() failed");
}
}
env = nullptr;
}
void NativeMapView::swap() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::invalidate");
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::swap");
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) {
if (!eglSwapBuffers(display, surface)) {
@@ -709,5 +745,14 @@ void NativeMapView::updateFps() {
env = nullptr;
}
void NativeMapView::onInvalidate() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::onInvalidate()");
const bool dirty = !clean.test_and_set();
if (dirty) {
map.renderSync();
}
}
}
}

View File

@@ -26,6 +26,7 @@ import android.view.SurfaceView;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.ZoomButtonsController;
import android.util.Log;
import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
@@ -1168,6 +1169,18 @@ public class MapView extends SurfaceView {
// Map events
//
// Called when the map needs to be rerendered
// Called via JNI from NativeMapView
protected void onInvalidate() {
post(new Runnable() {
@Override
public void run() {
mNativeMapView.invalidate();
}
});
}
public interface OnMapChangedListener {
void onMapChanged();
}

View File

@@ -2,6 +2,7 @@ package com.mapbox.mapboxgl.views;
import android.graphics.PointF;
import android.view.Surface;
import android.util.Log;
import com.mapbox.mapboxgl.geometry.LatLng;
import com.mapbox.mapboxgl.geometry.LatLngZoom;
@@ -85,6 +86,10 @@ class NativeMapView {
nativeUpdate(mNativeMapViewPtr);
}
public void invalidate() {
nativeOnInvalidate(mNativeMapViewPtr);
}
public void resize(int width, int height, float ratio, int fbWidth,
int fbHeight) {
if (width < 0) {
@@ -342,6 +347,10 @@ class NativeMapView {
// Callbacks
//
protected void onInvalidate() {
mMapView.onInvalidate();
}
protected void onMapChanged() {
mMapView.onMapChanged();
}
@@ -384,6 +393,8 @@ class NativeMapView {
private native void nativeUpdate(long nativeMapViewPtr);
private native void nativeOnInvalidate(long nativeMapViewPtr);
private native void nativeResize(long nativeMapViewPtr, int width,
int height, float ratio, int fbWidth, int fbHeight);

View File

@@ -16,6 +16,7 @@ extern std::string dataPath;
extern std::string apkPath;
extern std::string androidRelease;
extern jmethodID onInvalidateId;
extern jmethodID onMapChangedId;
extern jmethodID onFpsChangedId;

View File

@@ -46,6 +46,8 @@ public:
void enableFps(bool enable);
void updateFps();
void onInvalidate();
private:
EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs);
@@ -76,6 +78,7 @@ private:
mbgl::DefaultFileSource fileSource;
mbgl::Map map;
std::atomic_flag clean = ATOMIC_FLAG_INIT;
};
}
}