summaryrefslogtreecommitdiff
path: root/platform/android/src
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-09-14 21:23:07 +0300
committerIvo van Dongen <ivovandongen@users.noreply.github.com>2017-09-22 23:33:56 +0300
commit5d12503302dff168137d6f3b1444e4dc32ad44dd (patch)
tree98128bdddb287c30b2c1445eb88d44e9a97d57ab /platform/android/src
parent15a47d116a0fc15d249b37574fcd932ce88909df (diff)
downloadqtlocation-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.hpp74
-rw-r--r--platform/android/src/android_renderer_frontend.cpp92
-rw-r--r--platform/android/src/android_renderer_frontend.hpp35
-rwxr-xr-xplatform/android/src/jni.cpp4
-rw-r--r--platform/android/src/map_renderer.cpp137
-rw-r--r--platform/android/src/map_renderer.hpp95
-rw-r--r--platform/android/src/map_renderer_runnable.cpp49
-rw-r--r--platform/android/src/map_renderer_runnable.hpp50
-rwxr-xr-xplatform/android/src/native_map_view.cpp62
-rwxr-xr-xplatform/android/src/native_map_view.hpp26
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);