summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-09-13 14:34:05 +0300
committerIvo van Dongen <info@ivovandongen.nl>2017-09-13 14:37:11 +0300
commit8d5fef5f9941c62ac49cd01af18e47e85927d8e9 (patch)
tree5f2dcae3d3458ca0932f99547467dd6fd5f54076
parente76d7df35a26c8e6274d5386463145506a3cf160 (diff)
downloadqtlocation-mapboxgl-upstream/ivd-android-glsurfaceview-3tier.tar.gz
[android] Re-initialise renderer, backend and context when the android system destroyed the underlying gl resourcesupstream/ivd-android-glsurfaceview-3tier
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java3
-rwxr-xr-xplatform/android/src/android_renderer_backend.cpp11
-rwxr-xr-xplatform/android/src/android_renderer_backend.hpp4
-rw-r--r--platform/android/src/android_renderer_frontend.cpp69
-rw-r--r--platform/android/src/android_renderer_frontend.hpp7
-rwxr-xr-xplatform/android/src/native_map_view.cpp5
6 files changed, 80 insertions, 19 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index d1faa910bb..dece1a1dce 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -903,6 +903,8 @@ final class NativeMapView implements GLSurfaceView.Renderer {
float pixelRatio,
String programCacheDir);
+ private native void nativeOnSurfaceCreated();
+
private native void nativeDestroy();
private native void nativeInitializeDisplay();
@@ -1142,6 +1144,7 @@ final class NativeMapView implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Timber.i("[%s] onSurfaceCreated", Thread.currentThread().getName());
+ nativeOnSurfaceCreated();
//TODO: callback to map to re-create renderer?
}
diff --git a/platform/android/src/android_renderer_backend.cpp b/platform/android/src/android_renderer_backend.cpp
index eac12177a5..536090ddec 100755
--- a/platform/android/src/android_renderer_backend.cpp
+++ b/platform/android/src/android_renderer_backend.cpp
@@ -1,5 +1,7 @@
#include "android_renderer_backend.hpp"
+#include <mbgl/gl/context.hpp>
+
#include <EGL/egl.h>
#include <cassert>
@@ -51,5 +53,12 @@ void AndroidRendererBackend::updateAssumedState() {
assumeViewport(0, 0, getFramebufferSize());
}
+
+void AndroidRendererBackend::abandonContext() {
+ if (context) {
+ context->setCleanupOnDestruction(false);
+ }
}
-}
+
+} // namespace android
+} // namspace mbgl
diff --git a/platform/android/src/android_renderer_backend.hpp b/platform/android/src/android_renderer_backend.hpp
index 0cc9d1b682..16cc782132 100755
--- a/platform/android/src/android_renderer_backend.hpp
+++ b/platform/android/src/android_renderer_backend.hpp
@@ -12,6 +12,10 @@ public:
void bind() override;
void updateAssumedState() override;
+ // Ensures the current context is not
+ // cleaned up when destroyed
+ void abandonContext();
+
void updateViewPort();
void resizeFramebuffer(int width, int height);
diff --git a/platform/android/src/android_renderer_frontend.cpp b/platform/android/src/android_renderer_frontend.cpp
index 6ad7872f89..11bb9ab3fc 100644
--- a/platform/android/src/android_renderer_frontend.cpp
+++ b/platform/android/src/android_renderer_frontend.cpp
@@ -62,22 +62,16 @@ private:
RendererObserver& delegate;
};
-AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio,
- FileSource& fileSource,
- Scheduler& scheduler,
- std::string programCacheDir,
- InvalidateCallback invalidate)
- : backend(std::make_unique<AndroidRendererBackend>())
- , renderer(std::make_unique<util::Thread<Renderer>>(
- "Orchestration Thread",
- *backend,
- pixelRatio,
- fileSource,
- scheduler,
- GLContextMode::Unique,
- programCacheDir
- ))
- , asyncInvalidate([=, invalidate=std::move(invalidate)]() {
+AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio_,
+ FileSource& fileSource_,
+ Scheduler& scheduler_,
+ std::string programCacheDir_,
+ InvalidateCallback invalidate_)
+ : pixelRatio(pixelRatio_)
+ , fileSource(fileSource_)
+ , scheduler(scheduler_)
+ , programCacheDir(programCacheDir_)
+ , asyncInvalidate([=, invalidate=std::move(invalidate_)]() {
invalidate();
})
, mapRunLoop(util::RunLoop::Get()) {
@@ -90,11 +84,50 @@ void AndroidRendererFrontend::reset() {
renderer.reset();
}
+void AndroidRendererFrontend::initialise() {
+ // Lock as the initialization can come from the main thread or the GL thread first
+ std::lock_guard<std::mutex> lock(intitialisationMutex);
+
+ if (backend) {
+ // The android system will have already destroyed the underlying
+ // GL resources and an attempt to clean them up will fail
+ backend->abandonContext();
+ }
+
+ // Destroy in reverse order
+ renderer.reset();
+ backend.reset();
+
+ // Re-create
+ backend = std::make_unique<AndroidRendererBackend>();
+ renderer = std::make_unique<util::Thread<Renderer>>(
+ "Orchestration Thread",
+ *backend,
+ pixelRatio,
+ fileSource,
+ scheduler,
+ GLContextMode::Unique,
+ programCacheDir
+ );
+
+ // Set the observer on the new Renderer implementation
+ if (rendererObserver) {
+ renderer->actor().invoke(&Renderer::setObserver, rendererObserver.get());
+ }
+}
+
void AndroidRendererFrontend::setObserver(RendererObserver& observer) {
- assert (renderer);
assert (util::RunLoop::Get());
+
+ // Lock as the initialization can come from the main thread or the GL thread first
+ std::lock_guard<std::mutex> lock(intitialisationMutex);
+
rendererObserver = std::make_unique<ForwardingRendererObserver>(*mapRunLoop, observer);
- renderer->actor().invoke(&Renderer::setObserver, rendererObserver.get());
+
+ // Set the new observer on the Renderer implementation
+ if (renderer) {
+ renderer->actor().invoke(&Renderer::setObserver, rendererObserver.get());
+ }
}
void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) {
diff --git a/platform/android/src/android_renderer_frontend.hpp b/platform/android/src/android_renderer_frontend.hpp
index 36db705f2e..9c90e63c83 100644
--- a/platform/android/src/android_renderer_frontend.hpp
+++ b/platform/android/src/android_renderer_frontend.hpp
@@ -42,6 +42,7 @@ public:
InvalidateCallback);
~AndroidRendererFrontend() override;
+ void initialise();
void reset() override;
void setObserver(RendererObserver&) override;
@@ -67,6 +68,11 @@ public:
void requestSnapshot(SnapshotCallback);
private:
+ float pixelRatio;
+ FileSource& fileSource;
+ Scheduler& scheduler;
+ std::string programCacheDir;
+
std::unique_ptr<AndroidRendererBackend> backend;
std::unique_ptr<util::Thread<Renderer>> renderer;
std::unique_ptr<RendererObserver> rendererObserver;
@@ -74,6 +80,7 @@ private:
std::mutex updateMutex;
std::shared_ptr<UpdateParameters> updateParameters;
+ std::mutex intitialisationMutex;
util::AsyncTask asyncInvalidate;
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 1a0dc34bbc..e55628b202 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -187,6 +187,10 @@ void NativeMapView::onSourceChanged(mbgl::style::Source&) {
// JNI Methods //
+void NativeMapView::onSurfaceCreated(jni::JNIEnv&) {
+ rendererFrontend->initialise();
+}
+
// Called from the OpenGL renderer thread
void NativeMapView::render(jni::JNIEnv& ) {
rendererFrontend->render();
@@ -1003,6 +1007,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
std::make_unique<NativeMapView, JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, jni::jfloat, jni::String>,
"nativeInitialize",
"nativeDestroy",
+ METHOD(&NativeMapView::onSurfaceCreated, "nativeOnSurfaceCreated"),
METHOD(&NativeMapView::render, "nativeRender"),
METHOD(&NativeMapView::update, "nativeUpdate"),
METHOD(&NativeMapView::resizeView, "nativeResizeView"),