diff options
author | Ivo van Dongen <info@ivovandongen.nl> | 2017-09-14 21:23:07 +0300 |
---|---|---|
committer | Ivo van Dongen <ivovandongen@users.noreply.github.com> | 2017-09-22 23:33:56 +0300 |
commit | 5d12503302dff168137d6f3b1444e4dc32ad44dd (patch) | |
tree | 98128bdddb287c30b2c1445eb88d44e9a97d57ab /platform/android/src | |
parent | 15a47d116a0fc15d249b37574fcd932ce88909df (diff) | |
download | qtlocation-mapboxgl-5d12503302dff168137d6f3b1444e4dc32ad44dd.tar.gz |
[android] self-contained map renderer
- Isolates the GL thread in a MapRenderer class with a native peer
Diffstat (limited to 'platform/android/src')
-rw-r--r-- | platform/android/src/android_gl_thread.hpp | 74 | ||||
-rw-r--r-- | platform/android/src/android_renderer_frontend.cpp | 92 | ||||
-rw-r--r-- | platform/android/src/android_renderer_frontend.hpp | 35 | ||||
-rwxr-xr-x | platform/android/src/jni.cpp | 4 | ||||
-rw-r--r-- | platform/android/src/map_renderer.cpp | 137 | ||||
-rw-r--r-- | platform/android/src/map_renderer.hpp | 95 | ||||
-rw-r--r-- | platform/android/src/map_renderer_runnable.cpp | 49 | ||||
-rw-r--r-- | platform/android/src/map_renderer_runnable.hpp | 50 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 62 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.hpp | 26 |
10 files changed, 366 insertions, 258 deletions
diff --git a/platform/android/src/android_gl_thread.hpp b/platform/android/src/android_gl_thread.hpp deleted file mode 100644 index 78777aa475..0000000000 --- a/platform/android/src/android_gl_thread.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include <mbgl/actor/actor.hpp> -#include <mbgl/actor/mailbox.hpp> -#include <mbgl/actor/scheduler.hpp> -#include <mbgl/renderer/renderer.hpp> - -#include <functional> -#include <memory> -#include <mutex> -#include <queue> -#include <utility> - -namespace mbgl { -namespace android { - -class AndroidGLThread : public Scheduler { -public: - using InvalidateCallback = std::function<void ()>; - - template <class... Args> - AndroidGLThread(InvalidateCallback callback_, Args&&... args) - : renderer(std::make_unique<Renderer>(std::forward<Args>(args)...)) - , mailbox(std::make_shared<Mailbox>(*this)) - , callback(callback_) - , rendererRef(*renderer, mailbox) { - } - - ~AndroidGLThread() override = default; - - ActorRef<Renderer> actor() const { - return rendererRef; - } - - void schedule(std::weak_ptr<Mailbox> scheduled) override { - { - std::lock_guard<std::mutex> lock(mutex); - queue.push(scheduled); - } - - // Invalidate so we get processing time later - callback(); - } - - // Only safe on the GL Thread - void process() { - std::unique_lock<std::mutex> lock(mutex); - - if (queue.empty()) { - return; - } - - auto scheduled = queue.front(); - queue.pop(); - - lock.unlock(); - - Mailbox::maybeReceive(scheduled); - } - - // Only safe to access on the GL Thread - std::unique_ptr<Renderer> renderer; - -private: - std::mutex mutex; - std::queue<std::weak_ptr<Mailbox>> queue; - - std::shared_ptr<Mailbox> mailbox; - InvalidateCallback callback; - ActorRef<Renderer> rendererRef; -}; - -} // namespace android -} // namespace mbgl diff --git a/platform/android/src/android_renderer_frontend.cpp b/platform/android/src/android_renderer_frontend.cpp index 0619ba4cb5..38b1ff252b 100644 --- a/platform/android/src/android_renderer_frontend.cpp +++ b/platform/android/src/android_renderer_frontend.cpp @@ -54,124 +54,62 @@ private: ActorRef<RendererObserver> delegate; }; -AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio, - FileSource& fileSource, - Scheduler& scheduler, - std::string programCacheDir, - RequestRenderCallback requestRender, - RequestProcessingCallback requestProcessing) - : backend(std::make_unique<AndroidRendererBackend>()) - , glThread(std::make_unique<AndroidGLThread>( - std::move(requestProcessing), - *backend, - pixelRatio, - fileSource, - scheduler, - GLContextMode::Unique, - programCacheDir - )) - , asyncInvalidate([requestRender=std::move(requestRender)]() { - requestRender(); - }) +AndroidRendererFrontend::AndroidRendererFrontend(MapRenderer& mapRenderer_) + : mapRenderer(mapRenderer_) , mapRunLoop(util::RunLoop::Get()) { } AndroidRendererFrontend::~AndroidRendererFrontend() = default; void AndroidRendererFrontend::reset() { - assert(glThread); - glThread.reset(); + mapRenderer.reset(); + rendererObserver.reset(); } void AndroidRendererFrontend::setObserver(RendererObserver& observer) { - assert (glThread); assert (util::RunLoop::Get()); rendererObserver = std::make_unique<ForwardingRendererObserver>(*mapRunLoop, observer); - glThread->actor().invoke(&Renderer::setObserver, rendererObserver.get()); + mapRenderer.actor().invoke(&Renderer::setObserver, rendererObserver.get()); } void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) { - { - // Lock on the parameters - std::lock_guard<std::mutex> lock(updateMutex); - updateParameters = std::move(params); - } - asyncInvalidate.send(); -} - -// Called on OpenGL thread -void AndroidRendererFrontend::render() { - assert (glThread); - - std::shared_ptr<UpdateParameters> params; - { - // Lock on the parameters - std::unique_lock<std::mutex> lock(updateMutex); - if (!updateParameters) return; - - // Hold on to the update parameters during render - params = updateParameters; - } - - // Activate the backend - BackendScope backendGuard { *backend }; - - // Ensure that the "current" scheduler on the render thread is - // actually the scheduler from the orchestration thread - Scheduler::SetCurrent(glThread.get()); - - if (framebufferSizeChanged) { - backend->updateViewPort(); - framebufferSizeChanged = false; - } - - glThread->renderer->render(*params); -} - -void AndroidRendererFrontend::process() { - // Process the gl thread mailbox - glThread->process(); + mapRenderer.update(std::move(params)); + mapRenderer.requestRender(); } void AndroidRendererFrontend::onLowMemory() { - assert (glThread); - glThread->actor().invoke(&Renderer::onLowMemory); + mapRenderer.actor().invoke(&Renderer::onLowMemory); } std::vector<Feature> AndroidRendererFrontend::querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options) const { - assert (glThread); // Waits for the result from the orchestration thread and returns - return glThread->actor().ask(&Renderer::querySourceFeatures, sourceID, options).get(); + return mapRenderer.actor().ask(&Renderer::querySourceFeatures, sourceID, options).get(); } std::vector<Feature> AndroidRendererFrontend::queryRenderedFeatures(const ScreenBox& box, const RenderedQueryOptions& options) const { - assert (glThread); // Select the right overloaded method std::vector<Feature> (Renderer::*fn)(const ScreenBox&, const RenderedQueryOptions&) const = &Renderer::queryRenderedFeatures; // Waits for the result from the orchestration thread and returns - return glThread->actor().ask(fn, box, options).get(); + return mapRenderer.actor().ask(fn, box, options).get(); } std::vector<Feature> AndroidRendererFrontend::queryRenderedFeatures(const ScreenCoordinate& point, const RenderedQueryOptions& options) const { - assert (glThread); // Select the right overloaded method std::vector<Feature> (Renderer::*fn)(const ScreenCoordinate&, const RenderedQueryOptions&) const = &Renderer::queryRenderedFeatures; // Waits for the result from the orchestration thread and returns - return glThread->actor().ask(fn, point, options).get(); + return mapRenderer.actor().ask(fn, point, options).get(); } AnnotationIDs AndroidRendererFrontend::queryPointAnnotations(const ScreenBox& box) const { - assert (glThread); - // Waits for the result from the orchestration thread and returns - return glThread->actor().ask(&Renderer::queryPointAnnotations, box).get(); + return mapRenderer.actor().ask(&Renderer::queryPointAnnotations, box).get(); } void AndroidRendererFrontend::requestSnapshot(SnapshotCallback callback_) { @@ -182,12 +120,6 @@ void AndroidRendererFrontend::requestSnapshot(SnapshotCallback callback_) { }); } -void AndroidRendererFrontend::resizeFramebuffer(int width, int height) { - backend->resizeFramebuffer(width, height); - framebufferSizeChanged = true; - asyncInvalidate.send(); -} - } // namespace android } // namespace mbgl diff --git a/platform/android/src/android_renderer_frontend.hpp b/platform/android/src/android_renderer_frontend.hpp index 57bfd62b26..598327838e 100644 --- a/platform/android/src/android_renderer_frontend.hpp +++ b/platform/android/src/android_renderer_frontend.hpp @@ -1,13 +1,9 @@ - #pragma once -#include "android_gl_thread.hpp" - #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/async_task.hpp> #include <mbgl/util/geo.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/run_loop.hpp> @@ -17,6 +13,8 @@ #include <vector> #include <string> +#include "map_renderer.hpp" + namespace mbgl { class FileSource; @@ -30,15 +28,8 @@ class AndroidRendererBackend; class AndroidRendererFrontend : public RendererFrontend { public: - using RequestRenderCallback = std::function<void ()>; - using RequestProcessingCallback = std::function<void ()>; - - AndroidRendererFrontend(float pixelRatio, - mbgl::FileSource&, - mbgl::Scheduler&, - std::string programCacheDir, - RequestRenderCallback, - RequestProcessingCallback); + + AndroidRendererFrontend(MapRenderer&); ~AndroidRendererFrontend() override; void reset() override; @@ -46,19 +37,12 @@ public: void update(std::shared_ptr<UpdateParameters>) override; - // Called from OpenGL Thread - void render(); - void process(); - // Feature querying std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate&, const RenderedQueryOptions&) const; std::vector<Feature> queryRenderedFeatures(const ScreenBox&, const RenderedQueryOptions&) const; std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions&) const; AnnotationIDs queryPointAnnotations(const ScreenBox& box) const; - // RenderBackend proxy - Called from OpenGL Thread - void resizeFramebuffer(int width, int height); - // Memory void onLowMemory(); @@ -67,19 +51,12 @@ public: void requestSnapshot(SnapshotCallback); private: - std::unique_ptr<AndroidRendererBackend> backend; - std::unique_ptr<AndroidGLThread> glThread; std::unique_ptr<RendererObserver> rendererObserver; - - std::mutex updateMutex; - std::shared_ptr<UpdateParameters> updateParameters; - - - util::AsyncTask asyncInvalidate; + MapRenderer& mapRenderer; util::RunLoop* mapRunLoop; - bool framebufferSizeChanged = true; + // TODO std::unique_ptr<SnapshotCallback> snapshotCallback; }; diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index f7d1e4afbc..6acb6a3664 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -32,6 +32,8 @@ #include "gson/json_object.hpp" #include "gson/json_primitive.hpp" #include "java_types.hpp" +#include "map_renderer.hpp" +#include "map_renderer_runnable.hpp" #include "native_map_view.hpp" #include "offline/offline_manager.hpp" #include "offline/offline_region.hpp" @@ -144,6 +146,8 @@ void registerNatives(JavaVM *vm) { Polyline::registerNative(env); // Map + MapRenderer::registerNative(env); + MapRendererRunnable::registerNative(env); NativeMapView::registerNative(env); // Http diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp new file mode 100644 index 0000000000..8346d2f139 --- /dev/null +++ b/platform/android/src/map_renderer.cpp @@ -0,0 +1,137 @@ +#include "map_renderer.hpp" + +#include <mbgl/renderer/renderer.hpp> +#include <mbgl/util/shared_thread_pool.hpp> + +#include <string> + +#include "attach_env.hpp" +#include "android_renderer_backend.hpp" +#include "map_renderer_runnable.hpp" +#include "file_source.hpp" + +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() = default; + +void MapRenderer::reset() { + assert (renderer); + renderer.reset(); +} + +ActorRef<Renderer> MapRenderer::actor() const { + return rendererRef; +} + +void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) { + // Create a runnable and schedule it on the gl thread + 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"); + javaPeer->Call(*_env, queueEvent, runnable->getPeer()); + + // Release the object as it will be destroyed on GC of the Java Peer + runnable.release(); +} + +void MapRenderer::requestRender() { + android::UniqueEnv _env = android::AttachEnv(); + static auto onInvalidate = javaClass.GetMethod<void ()>(*_env, "requestRender"); + javaPeer->Call(*_env, onInvalidate); +} + +void MapRenderer::update(std::shared_ptr<UpdateParameters> params) { + // Lock on the parameters + std::lock_guard<std::mutex> lock(updateMutex); + updateParameters = std::move(params); +} + +// Called on OpenGL thread // + +void MapRenderer::render(JNIEnv&) { + assert (renderer); + + std::shared_ptr<UpdateParameters> params; + { + // Lock on the parameters + std::unique_lock<std::mutex> lock(updateMutex); + if (!updateParameters) return; + + // Hold on to the update parameters during render + params = updateParameters; + } + + // Activate the backend + BackendScope backendGuard { *backend }; + + // Ensure that the "current" scheduler on the render thread is + // this scheduler. + Scheduler::SetCurrent(this); + + if (framebufferSizeChanged) { + backend->updateViewPort(); + framebufferSizeChanged = false; + } + + renderer->render(*params); +} + +void MapRenderer::onSurfaceCreated(JNIEnv&) { + // TODO (re-)create Context, Backend and Renderer +} + +void MapRenderer::onSurfaceChanged(JNIEnv&, jint width, jint height) { + backend->resizeFramebuffer(width, height); + framebufferSizeChanged = true; + requestRender(); +} + +// Static methods // + +jni::Class<MapRenderer> MapRenderer::javaClass; + +void MapRenderer::registerNative(jni::JNIEnv& env) { + // Lookup the class + MapRenderer::javaClass = *jni::Class<MapRenderer>::Find(env).NewGlobalRef(env).release(); + +#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") + ); +} + +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)); + assert(mapRenderer != nullptr); + return *mapRenderer; +} + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp new file mode 100644 index 0000000000..51fca48ee6 --- /dev/null +++ b/platform/android/src/map_renderer.hpp @@ -0,0 +1,95 @@ +#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 "jni/generic_global_ref_deleter.hpp" + +namespace mbgl { + +class Renderer; +class RendererBackend; +class ThreadPool; +class UpdateParameters; + +namespace android { + +class AndroidRendererBackend; +class FileSource; + +/** + * The MapRenderer is a peer class that encapsulates the actions + * performed on the GL Thread. + * + * The public methods are safe to call from the main thread, others are not. + */ +class MapRenderer : public Scheduler { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/maps/renderer/MapRenderer"; }; + + static jni::Class<MapRenderer> javaClass; + + static void registerNative(jni::JNIEnv&); + + static MapRenderer& getNativePeer(JNIEnv&, jni::Object<MapRenderer>); + + MapRenderer(jni::JNIEnv& _env, + jni::Object<MapRenderer>, + jni::Object<FileSource>, + jni::jfloat pixelRatio, + jni::String programCacheDir); + + ~MapRenderer() override; + + // Resets the renderer to clean up on the calling thread + void reset(); + + // Sets the new update parameters to use on subsequent + // renders. Be sure to trigger a render with + // requestRender(). + void update(std::shared_ptr<UpdateParameters>); + + // Gives a handle to the Renderer to enable actions on + // any thread. + ActorRef<Renderer> actor() const; + + // From Scheduler. Schedules by using callbacks to the + // JVM to process the mailbox on the right thread. + void schedule(std::weak_ptr<Mailbox> scheduled) override; + + void requestRender(); + +private: + // Called from the GL Thread // + + // Renders a frame. + void render(JNIEnv&); + + void onSurfaceCreated(JNIEnv&); + + void onSurfaceChanged(JNIEnv&, jint width, jint height); + +private: + GenericUniqueWeakObject<MapRenderer> javaPeer; + std::shared_ptr<ThreadPool> threadPool; + std::unique_ptr<AndroidRendererBackend> backend; + std::unique_ptr<Renderer> renderer; + std::shared_ptr<Mailbox> mailbox; + ActorRef<Renderer> rendererRef; + + std::shared_ptr<UpdateParameters> updateParameters; + std::mutex updateMutex; + + bool framebufferSizeChanged = false; +}; + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/map_renderer_runnable.cpp b/platform/android/src/map_renderer_runnable.cpp new file mode 100644 index 0000000000..df8cba5e55 --- /dev/null +++ b/platform/android/src/map_renderer_runnable.cpp @@ -0,0 +1,49 @@ +#include "map_renderer_runnable.hpp" + +#include <mbgl/util/logging.hpp> + +namespace mbgl { +namespace android { + +MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::weak_ptr<Mailbox> mailbox_) + : mailbox(std::move(mailbox_)) { + + // Create the Java peer + jni::UniqueLocalFrame frame = jni::PushLocalFrame(env, 5); + static auto constructor = javaClass.GetConstructor<jlong>(env); + auto instance = javaClass.New(env, constructor, reinterpret_cast<jlong>(this)); + javaPeer = SeizeGenericWeakRef(env, jni::Object<MapRendererRunnable>(jni::NewWeakGlobalRef(env, instance.Get()).release())); +} + +MapRendererRunnable::~MapRendererRunnable() = default; + +void MapRendererRunnable::run(jni::JNIEnv&) { + Mailbox::maybeReceive(mailbox); +} + +jni::Object<MapRendererRunnable> MapRendererRunnable::getPeer() { + return *javaPeer; +} + +// Static methods // + +jni::Class<MapRendererRunnable> MapRendererRunnable::javaClass; + +void MapRendererRunnable::registerNative(jni::JNIEnv& env) { + // Lookup the class + MapRendererRunnable::javaClass = *jni::Class<MapRendererRunnable>::Find(env).NewGlobalRef(env).release(); + +#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + jni::RegisterNativePeer<MapRendererRunnable>( + env, + MapRendererRunnable::javaClass, + "nativePtr", + std::make_unique<MapRendererRunnable, JNIEnv&>, + "nativeInitialize", + "finalize", + METHOD(&MapRendererRunnable::run, "run")); +} + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/map_renderer_runnable.hpp b/platform/android/src/map_renderer_runnable.hpp new file mode 100644 index 0000000000..75646a442d --- /dev/null +++ b/platform/android/src/map_renderer_runnable.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include <mbgl/actor/mailbox.hpp> +#include <mbgl/actor/scheduler.hpp> + +#include <memory> +#include <utility> + +#include <jni/jni.hpp> + +#include "jni/generic_global_ref_deleter.hpp" + +namespace mbgl { +namespace android { + +/** + * The MapRendererRunnable is a peer class that encapsulates + * a scheduled mailbox in a Java Runnable so it can be + * scheduled on the map renderer thread. + * + */ +class MapRendererRunnable { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/maps/renderer/MapRendererRunnable"; }; + + static jni::Class<MapRendererRunnable> javaClass; + + static void registerNative(jni::JNIEnv&); + + MapRendererRunnable(jni::JNIEnv&, std::weak_ptr<Mailbox>); + + // Only for jni registration, unused + MapRendererRunnable(jni::JNIEnv&) { + assert(false); + } + + ~MapRendererRunnable(); + + void run(jni::JNIEnv&); + + jni::Object<MapRendererRunnable> getPeer(); + +private: + GenericUniqueWeakObject<MapRendererRunnable> javaPeer; + std::weak_ptr<Mailbox> mailbox; +}; + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 51edd8079f..f7f487f227 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -9,12 +9,10 @@ #include <sys/system_properties.h> -#include <EGL/egl.h> #include <android/native_window_jni.h> #include <jni/jni.hpp> -#include <mbgl/renderer/backend_scope.hpp> #include <mbgl/math/minmax.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/event.hpp> @@ -28,7 +26,6 @@ #include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/filter.hpp> -#include <mbgl/renderer/renderer.hpp> // Java -> C++ conversion #include "style/android_conversion.hpp" @@ -43,8 +40,9 @@ #include "jni.hpp" #include "attach_env.hpp" -#include "android_renderer_backend.hpp" +#include "map_renderer.hpp" #include "android_renderer_frontend.hpp" +#include "file_source.hpp" #include "bitmap.hpp" #include "run_loop_impl.hpp" #include "java/util.hpp" @@ -59,8 +57,8 @@ namespace android { NativeMapView::NativeMapView(jni::JNIEnv& _env, jni::Object<NativeMapView> _obj, jni::Object<FileSource> jFileSource, - jni::jfloat _pixelRatio, - jni::String _programCacheDir) + jni::Object<MapRenderer> jMapRenderer, + jni::jfloat _pixelRatio) : javaPeer(_obj.NewWeakGlobalRef(_env)), pixelRatio(_pixelRatio), threadPool(sharedThreadPool()) { @@ -71,15 +69,12 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env, return; } + // Get native peers mbgl::FileSource& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource); + MapRenderer& mapRenderer = MapRenderer::getNativePeer(_env, jMapRenderer); // Create a renderer frontend - rendererFrontend = std::make_unique<AndroidRendererFrontend>(pixelRatio, fileSource, - *threadPool, - jni::Make<std::string>(_env, - _programCacheDir), - [this] { this->requestRender(); }, - [this] { this->requestProcessing(); }); + rendererFrontend = std::make_unique<AndroidRendererFrontend>(mapRenderer); // Create the core map map = std::make_unique<mbgl::Map>(*rendererFrontend, *this, @@ -98,24 +93,6 @@ NativeMapView::~NativeMapView() { } /** - * Callback to java NativeMapView#requestRender(). - * - * Called to schedule a render on the next - * runloop iteration. - */ -void NativeMapView::requestRender() { - android::UniqueEnv _env = android::AttachEnv(); - static auto onInvalidate = javaClass.GetMethod<void ()>(*_env, "requestRender"); - javaPeer->Call(*_env, onInvalidate); -} - -void NativeMapView::requestProcessing() { - android::UniqueEnv _env = android::AttachEnv(); - static auto requestProcessing = javaClass.GetMethod<void ()>(*_env, "requestProcessing"); - javaPeer->Call(*_env, requestProcessing); -} - -/** * From mbgl::RendererBackend. Callback to java NativeMapView#onMapChanged(int). * * May be called from any thread @@ -194,31 +171,12 @@ void NativeMapView::onSourceChanged(mbgl::style::Source&) { // JNI Methods // -// Called from the OpenGL renderer thread -void NativeMapView::render(jni::JNIEnv& ) { - rendererFrontend->render(); - - // TODO - updateFps(); -} - -// Called from the OpenGL renderer thread -void NativeMapView::process(jni::JNIEnv&) { - rendererFrontend->process(); -} - void NativeMapView::resizeView(jni::JNIEnv&, int w, int h) { width = util::max(64, w); height = util::max(64, h); map->setSize({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) }); } -void NativeMapView::resizeFramebuffer(jni::JNIEnv&, int w, int h) { - rendererFrontend->resizeFramebuffer(w, h); -// framebufferSizeChanged = true; -// invalidate(); -} - jni::String NativeMapView::getStyleUrl(jni::JNIEnv& env) { return jni::Make<jni::String>(env, map->getStyle().getURL()); } @@ -969,6 +927,7 @@ jni::jboolean NativeMapView::getPrefetchesTiles(JNIEnv&) { // Private methods // +// TODO void NativeMapView::updateFps() { if (!fpsEnabled) { return; @@ -1008,13 +967,10 @@ void NativeMapView::registerNative(jni::JNIEnv& env) { // Register the peer jni::RegisterNativePeer<NativeMapView>(env, NativeMapView::javaClass, "nativePtr", - std::make_unique<NativeMapView, JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, jni::jfloat, jni::String>, + std::make_unique<NativeMapView, JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, jni::Object<MapRenderer>, jni::jfloat>, "nativeInitialize", "nativeDestroy", - METHOD(&NativeMapView::render, "nativeRender"), - METHOD(&NativeMapView::process, "nativeProcess"), METHOD(&NativeMapView::resizeView, "nativeResizeView"), - METHOD(&NativeMapView::resizeFramebuffer, "nativeResizeFramebuffer"), METHOD(&NativeMapView::getStyleUrl, "nativeGetStyleUrl"), METHOD(&NativeMapView::setStyleUrl, "nativeSetStyleUrl"), METHOD(&NativeMapView::getStyleJson, "nativeGetStyleJson"), diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 7376f82c24..d88647914e 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -1,6 +1,5 @@ #pragma once -#include <mbgl/renderer/renderer_backend.hpp> #include <mbgl/map/change.hpp> #include <mbgl/map/camera.hpp> #include <mbgl/map/map.hpp> @@ -10,7 +9,6 @@ #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/network_status.hpp> -#include "file_source.hpp" #include "annotation/marker.hpp" #include "annotation/polygon.hpp" #include "annotation/polyline.hpp" @@ -37,6 +35,8 @@ namespace mbgl { namespace android { class AndroidRendererFrontend; +class FileSource; +class MapRenderer; class NativeMapView : public MapObserver { public: @@ -50,8 +50,8 @@ public: NativeMapView(jni::JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, - jni::jfloat pixelRatio, - jni::String programCacheDir); + jni::Object<MapRenderer>, + jni::jfloat pixelRatio); virtual ~NativeMapView(); @@ -72,28 +72,10 @@ public: void onDidFinishLoadingStyle() override; void onSourceChanged(mbgl::style::Source&) override; - // Signal the view system, we want to redraw - void requestRender(); - - // Request processing on the GL Thread - void requestProcessing(); - // JNI // - // Called on OpenGL Thread - void onSurfaceCreated(jni::JNIEnv&); - - // Called on OpenGL Thread - void process(jni::JNIEnv&); - - // Called on OpenGL Thread - void render(jni::JNIEnv&); - void resizeView(jni::JNIEnv&, int, int); - // Called on OpenGL Thread - void resizeFramebuffer(jni::JNIEnv&, int, int); - jni::String getStyleUrl(jni::JNIEnv&); void setStyleUrl(jni::JNIEnv&, jni::String); |