diff options
author | Tobrun Van Nuland <tobrun.van.nuland@gmail.com> | 2016-07-27 18:39:32 +0200 |
---|---|---|
committer | Tobrun <tobrun.van.nuland@gmail.com> | 2016-08-03 14:55:45 -0400 |
commit | 6016b2981e73be81f6a74a789ffabb51b7e91700 (patch) | |
tree | 4a3a4f50978dbfd2ff9ca304ce7c8638819a973d /platform/android/src | |
parent | 9b871a9a0fcbbeb40cec07fc976cbdbaebf00856 (diff) | |
download | qtlocation-mapboxgl-6016b2981e73be81f6a74a789ffabb51b7e91700.tar.gz |
[android] SurfaceView compatible snapshot api
[android] #5587 - snapshot API on surface view, create Bitmap with a ByteBuffer
[android] #5587 - write bitmap to external storage
PreMultipliedImage approach
callback implemented
clean up code
introduce bitmap reuse
cleanup
renaming surfaceContent to bitmap
Diffstat (limited to 'platform/android/src')
-rwxr-xr-x | platform/android/src/jni.cpp | 12 | ||||
-rw-r--r-- | platform/android/src/jni.hpp | 1 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 33 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.hpp | 3 |
4 files changed, 48 insertions, 1 deletions
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 5fc29f4c29..5907a0ff9d 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -45,6 +45,7 @@ std::string androidRelease; jni::jmethodID* onInvalidateId = nullptr; jni::jmethodID* onMapChangedId = nullptr; jni::jmethodID* onFpsChangedId = nullptr; +jni::jmethodID* onSnapshotReadyId = nullptr; jni::jclass* latLngClass = nullptr; jni::jmethodID* latLngConstructorId = nullptr; @@ -1172,6 +1173,13 @@ void nativeRemoveSource(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, } } +void nativeScheduleTakeSnapshot(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) { + mbgl::Log::Error(mbgl::Event::JNI, "nativeRenderToOffscreen"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr); + nativeMapView->scheduleTakeSnapshot(); +} + // Offline calls begin jlong createDefaultFileSource(JNIEnv *env, jni::jobject* obj, jni::jstring* cachePath_, jni::jstring* assetRoot_, jlong maximumCacheSize) { @@ -1706,6 +1714,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { onInvalidateId = &jni::GetMethodID(env, nativeMapViewClass, "onInvalidate", "()V"); onMapChangedId = &jni::GetMethodID(env, nativeMapViewClass, "onMapChanged", "(I)V"); onFpsChangedId = &jni::GetMethodID(env, nativeMapViewClass, "onFpsChanged", "(D)V"); + onSnapshotReadyId = &jni::GetMethodID(env, nativeMapViewClass, "onSnapshotReady","([B)V"); #define MAKE_NATIVE_METHOD(name, sig) jni::MakeNativeMethod<decltype(name), name>( #name, sig ) @@ -1786,7 +1795,8 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { MAKE_NATIVE_METHOD(nativeRemoveLayer, "(JLjava/lang/String;)V"), MAKE_NATIVE_METHOD(nativeAddSource, "(JLjava/lang/String;Lcom/mapbox/mapboxsdk/style/sources/Source;)V"), MAKE_NATIVE_METHOD(nativeRemoveSource, "(JLjava/lang/String;)V"), - MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V") + MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V"), + MAKE_NATIVE_METHOD(nativeScheduleTakeSnapshot, "(J)V") ); // Offline begin diff --git a/platform/android/src/jni.hpp b/platform/android/src/jni.hpp index 57f84f0ccc..0810ee656d 100644 --- a/platform/android/src/jni.hpp +++ b/platform/android/src/jni.hpp @@ -19,6 +19,7 @@ extern std::string androidRelease; extern jmethodID onInvalidateId; extern jmethodID onMapChangedId; extern jmethodID onFpsChangedId; +extern jmethodID onSnapshotReadyId; extern bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName); extern void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 0b849976eb..578e5d0033 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -194,6 +194,35 @@ void NativeMapView::render() { map->render(); + if(snapshot){ + snapshot = false; + + // take snapshot + const unsigned int w = fbWidth; + const unsigned int h = fbHeight; + mbgl::PremultipliedImage image { w, h }; + MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data.get())); + const size_t stride = image.stride(); + auto tmp = std::make_unique<uint8_t[]>(stride); + uint8_t *rgba = image.data.get(); + for (int i = 0, j = h - 1; i < j; i++, j--) { + std::memcpy(tmp.get(), rgba + i * stride, stride); + std::memcpy(rgba + i * stride, rgba + j * stride, stride); + std::memcpy(rgba + j * stride, tmp.get(), stride); + } + + // encode and convert to jbytes + std::string string = encodePNG(image); + jbyteArray arr = env->NewByteArray(string.length()); + env->SetByteArrayRegion(arr,0,string.length(),(jbyte*)string.c_str()); + + // invoke Mapview#OnSnapshotReady + env->CallVoidMethod(obj, onSnapshotReadyId, arr); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + } + } + if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) { if (!eglSwapBuffers(display, surface)) { mbgl::Log::Error(mbgl::Event::OpenGL, "eglSwapBuffers() returned error %d", @@ -436,6 +465,10 @@ void NativeMapView::destroySurface() { } } +void NativeMapView::scheduleTakeSnapshot() { + snapshot = true; +} + // Speed /* typedef enum { diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 40cb012b0b..9b5af76dfe 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -49,6 +49,8 @@ public: mbgl::EdgeInsets getInsets() { return insets;} void setInsets(mbgl::EdgeInsets insets_); + void scheduleTakeSnapshot(); + private: EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs); @@ -79,6 +81,7 @@ private: bool firstTime = false; bool fpsEnabled = false; bool sizeChanged = false; + bool snapshot = false; double fps = 0.0; int width = 0; |