diff options
Diffstat (limited to 'platform/android')
-rwxr-xr-x | platform/android/src/android_renderer_backend.cpp | 10 | ||||
-rwxr-xr-x | platform/android/src/android_renderer_backend.hpp | 4 | ||||
-rw-r--r-- | platform/android/src/android_renderer_frontend.cpp | 7 | ||||
-rw-r--r-- | platform/android/src/android_renderer_frontend.hpp | 7 | ||||
-rw-r--r-- | platform/android/src/map_renderer.cpp | 89 | ||||
-rw-r--r-- | platform/android/src/map_renderer.hpp | 26 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 1 |
7 files changed, 99 insertions, 45 deletions
diff --git a/platform/android/src/android_renderer_backend.cpp b/platform/android/src/android_renderer_backend.cpp index 558395d296..9e49915650 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,11 @@ void AndroidRendererBackend::updateAssumedState() { assumeViewport(0, 0, getFramebufferSize()); } +void AndroidRendererBackend::markContextLost() { + 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 8dbc1f2be8..c5c552459f 100755 --- a/platform/android/src/android_renderer_backend.hpp +++ b/platform/android/src/android_renderer_backend.hpp @@ -13,6 +13,10 @@ public: void updateAssumedState() override; mbgl::Size getFramebufferSize() const override; + // Ensures the current context is not + // cleaned up when destroyed + void markContextLost(); + 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 38b1ff252b..ac29639bd4 100644 --- a/platform/android/src/android_renderer_frontend.cpp +++ b/platform/android/src/android_renderer_frontend.cpp @@ -1,6 +1,7 @@ #include "android_renderer_frontend.hpp" #include <mbgl/actor/scheduler.hpp> +#include <mbgl/renderer/renderer.hpp> #include <mbgl/renderer/renderer_observer.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/util/thread.hpp> @@ -63,13 +64,13 @@ AndroidRendererFrontend::~AndroidRendererFrontend() = default; void AndroidRendererFrontend::reset() { mapRenderer.reset(); - rendererObserver.reset(); } void AndroidRendererFrontend::setObserver(RendererObserver& observer) { assert (util::RunLoop::Get()); - rendererObserver = std::make_unique<ForwardingRendererObserver>(*mapRunLoop, observer); - mapRenderer.actor().invoke(&Renderer::setObserver, rendererObserver.get()); + // Don't call the Renderer directly, but use MapRenderer#setObserver to make sure + // the Renderer may be re-initialised without losing the RendererObserver reference. + mapRenderer.setObserver(std::make_unique<ForwardingRendererObserver>(*mapRunLoop, observer)); } 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 598327838e..bb8323b390 100644 --- a/platform/android/src/android_renderer_frontend.hpp +++ b/platform/android/src/android_renderer_frontend.hpp @@ -2,7 +2,6 @@ #include <mbgl/actor/actor.hpp> #include <mbgl/annotation/annotation.hpp> -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/renderer/renderer_frontend.hpp> #include <mbgl/util/geo.hpp> #include <mbgl/util/image.hpp> @@ -17,15 +16,11 @@ namespace mbgl { -class FileSource; -class Scheduler; class RenderedQueryOptions; class SourceQueryOptions; namespace android { -class AndroidRendererBackend; - class AndroidRendererFrontend : public RendererFrontend { public: @@ -51,9 +46,7 @@ public: void requestSnapshot(SnapshotCallback); private: - std::unique_ptr<RendererObserver> rendererObserver; MapRenderer& mapRenderer; - util::RunLoop* mapRunLoop; // TODO diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp index 8346d2f139..b2186e6272 100644 --- a/platform/android/src/map_renderer.cpp +++ b/platform/android/src/map_renderer.cpp @@ -13,29 +13,29 @@ namespace mbgl { namespace android { -MapRenderer::MapRenderer(jni::JNIEnv& _env, - jni::Object<MapRenderer> obj, - jni::Object<FileSource> fileSource, - jni::jfloat pixelRatio, - jni::String programCacheDir) - : javaPeer(SeizeGenericWeakRef(_env, jni::Object<MapRenderer>(jni::NewWeakGlobalRef(_env, obj.Get()).release()))) - , threadPool(sharedThreadPool()) - , backend(std::make_unique<AndroidRendererBackend>()) - , renderer(std::make_unique<Renderer>(*backend, pixelRatio, FileSource::getDefaultFileSource(_env, fileSource), - *threadPool, GLContextMode::Unique, jni::Make<std::string>(_env, programCacheDir))) - , mailbox(std::make_shared<Mailbox>(*this)) - , rendererRef(*renderer, mailbox) { +MapRenderer::MapRenderer(jni::JNIEnv& _env, jni::Object<MapRenderer> obj, + jni::Object<FileSource> _fileSource, jni::jfloat pixelRatio_, + jni::String programCacheDir_) + : javaPeer(SeizeGenericWeakRef(_env, jni::Object<MapRenderer>(jni::NewWeakGlobalRef(_env, obj.Get()).release()))), pixelRatio(pixelRatio_) + , fileSource(FileSource::getDefaultFileSource(_env, _fileSource)) + , programCacheDir(jni::Make<std::string>(_env, programCacheDir_)) + , threadPool(sharedThreadPool()) + , mailbox(std::make_shared<Mailbox>(*this)) { } MapRenderer::~MapRenderer() = default; -void MapRenderer::reset() { +void MapRenderer::reset() { assert (renderer); renderer.reset(); + + // Lock to make sure there is no concurrent initialisation on the gl thread + std::lock_guard<std::mutex> lock(initialisationMutex); + rendererObserver.reset(); } ActorRef<Renderer> MapRenderer::actor() const { - return rendererRef; + return *rendererRef; } void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) { @@ -43,7 +43,8 @@ void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) { android::UniqueEnv _env = android::AttachEnv(); auto runnable = std::make_unique<MapRendererRunnable>(*_env, std::move(scheduled)); - static auto queueEvent = javaClass.GetMethod<void (jni::Object<MapRendererRunnable>)>(*_env, "queueEvent"); + static auto queueEvent = javaClass.GetMethod<void( + jni::Object<MapRendererRunnable>)>(*_env, "queueEvent"); javaPeer->Call(*_env, queueEvent, runnable->getPeer()); // Release the object as it will be destroyed on GC of the Java Peer @@ -52,7 +53,7 @@ void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) { void MapRenderer::requestRender() { android::UniqueEnv _env = android::AttachEnv(); - static auto onInvalidate = javaClass.GetMethod<void ()>(*_env, "requestRender"); + static auto onInvalidate = javaClass.GetMethod<void()>(*_env, "requestRender"); javaPeer->Call(*_env, onInvalidate); } @@ -62,6 +63,18 @@ void MapRenderer::update(std::shared_ptr<UpdateParameters> params) { updateParameters = std::move(params); } +void MapRenderer::setObserver(std::shared_ptr<RendererObserver> _rendererObserver) { + // Lock as the initialization can come from the main thread or the GL thread first + std::lock_guard<std::mutex> lock(initialisationMutex); + + rendererObserver = std::move(_rendererObserver); + + // Set the new observer on the Renderer implementation + if (renderer) { + renderer->setObserver(rendererObserver.get()); + } +} + // Called on OpenGL thread // void MapRenderer::render(JNIEnv&) { @@ -93,7 +106,28 @@ void MapRenderer::render(JNIEnv&) { } void MapRenderer::onSurfaceCreated(JNIEnv&) { - // TODO (re-)create Context, Backend and Renderer + // Lock as the initialization can come from the main thread or the GL thread first + std::lock_guard<std::mutex> lock(initialisationMutex); + + // The android system will have already destroyed the underlying + // GL resources if this is not the first intialization and an + // attempt to clean them up will fail + if (backend) backend->markContextLost(); + + // Reset in opposite order + renderer.reset(); + backend.reset(); + + // Create the new backend and renderer + backend = std::make_unique<AndroidRendererBackend>(); + renderer = std::make_unique<Renderer>(*backend, pixelRatio, fileSource, *threadPool, + GLContextMode::Unique, programCacheDir); + rendererRef = std::make_unique<ActorRef<Renderer>>(*renderer, mailbox); + + // Set the observer on the new Renderer implementation + if (rendererObserver) { + renderer->setObserver(rendererObserver.get()); + } } void MapRenderer::onSurfaceChanged(JNIEnv&, jint width, jint height) { @@ -113,22 +147,19 @@ void MapRenderer::registerNative(jni::JNIEnv& env) { #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) // Register the peer - jni::RegisterNativePeer<MapRenderer>( - env, - MapRenderer::javaClass, - "nativePtr", - std::make_unique<MapRenderer, JNIEnv&, jni::Object<MapRenderer>, jni::Object<FileSource>, jni::jfloat, jni::String>, - "nativeInitialize", - "finalize", - METHOD(&MapRenderer::render, "nativeRender"), - METHOD(&MapRenderer::onSurfaceCreated, "nativeOnSurfaceCreated"), - METHOD(&MapRenderer::onSurfaceChanged, "nativeOnSurfaceChanged") - ); + jni::RegisterNativePeer<MapRenderer>(env, MapRenderer::javaClass, "nativePtr", + std::make_unique<MapRenderer, JNIEnv&, jni::Object<MapRenderer>, jni::Object<FileSource>, jni::jfloat, jni::String>, + "nativeInitialize", "finalize", + METHOD(&MapRenderer::render, "nativeRender"), + METHOD(&MapRenderer::onSurfaceCreated, + "nativeOnSurfaceCreated"), + METHOD(&MapRenderer::onSurfaceChanged, + "nativeOnSurfaceChanged")); } MapRenderer& MapRenderer::getNativePeer(JNIEnv& env, jni::Object<MapRenderer> jObject) { static auto field = MapRenderer::javaClass.GetField<jlong>(env, "nativePtr"); - MapRenderer* mapRenderer = reinterpret_cast<MapRenderer *>(jObject.Get(env, field)); + MapRenderer* mapRenderer = reinterpret_cast<MapRenderer*>(jObject.Get(env, field)); assert(mapRenderer != nullptr); return *mapRenderer; } diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp index 51fca48ee6..ca216fc240 100644 --- a/platform/android/src/map_renderer.hpp +++ b/platform/android/src/map_renderer.hpp @@ -1,21 +1,23 @@ #pragma once -#include <mbgl/actor/actor_ref.hpp> -#include <mbgl/actor/mailbox.hpp> #include <mbgl/actor/scheduler.hpp> -#include <mbgl/renderer/renderer.hpp> #include <memory> #include <utility> #include <jni/jni.hpp> +#include <mbgl/storage/default_file_source.hpp> #include "jni/generic_global_ref_deleter.hpp" namespace mbgl { +template <class> +class ActorRef; +class Mailbox; class Renderer; class RendererBackend; +class RendererObserver; class ThreadPool; class UpdateParameters; @@ -52,6 +54,11 @@ public: // Resets the renderer to clean up on the calling thread void reset(); + // Takes the RendererObserver by shared_ptr so we + // don't have to make the header public. Use + // this instead of Renderer#setObserver directly + void setObserver(std::shared_ptr<RendererObserver>); + // Sets the new update parameters to use on subsequent // renders. Be sure to trigger a render with // requestRender(). @@ -79,11 +86,20 @@ private: private: GenericUniqueWeakObject<MapRenderer> javaPeer; + + float pixelRatio; + DefaultFileSource& fileSource; + std::string programCacheDir; + std::shared_ptr<ThreadPool> threadPool; + std::shared_ptr<Mailbox> mailbox; + + std::mutex initialisationMutex; + std::shared_ptr<RendererObserver> rendererObserver; + std::unique_ptr<AndroidRendererBackend> backend; std::unique_ptr<Renderer> renderer; - std::shared_ptr<Mailbox> mailbox; - ActorRef<Renderer> rendererRef; + std::unique_ptr<ActorRef<Renderer>> rendererRef; std::shared_ptr<UpdateParameters> updateParameters; std::mutex updateMutex; diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index f7f487f227..e44bd023c5 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -26,6 +26,7 @@ #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/filter.hpp> +#include <mbgl/renderer/query.hpp> // Java -> C++ conversion #include "style/android_conversion.hpp" |