summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-09-04 14:48:06 +0300
committerIvo van Dongen <info@ivovandongen.nl>2017-09-18 10:07:04 +0300
commit29fa5bbefeeff508cdbb3923b1f5a7625e4d4c79 (patch)
treef71c2077e8489236ab25a5b3c04356808c72d675
parentf083240c53c7ff7c7124e55a15636bc294cda9ff (diff)
downloadqtlocation-mapboxgl-29fa5bbefeeff508cdbb3923b1f5a7625e4d4c79.tar.gz
[android] use only two threads
-rw-r--r--platform/android/src/android_gl_thread.hpp75
-rw-r--r--platform/android/src/android_renderer_frontend.cpp54
-rw-r--r--platform/android/src/android_renderer_frontend.hpp12
3 files changed, 111 insertions, 30 deletions
diff --git a/platform/android/src/android_gl_thread.hpp b/platform/android/src/android_gl_thread.hpp
new file mode 100644
index 0000000000..06bfce1444
--- /dev/null
+++ b/platform/android/src/android_gl_thread.hpp
@@ -0,0 +1,75 @@
+#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(ActorRef<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);
+ }
+
+ callback.invoke(&InvalidateCallback::operator());
+ }
+
+ // Only safe on the GL Thread
+ void process() {
+ while (true) {
+ 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;
+ ActorRef<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 73cb0a817e..b010022d94 100644
--- a/platform/android/src/android_renderer_frontend.cpp
+++ b/platform/android/src/android_renderer_frontend.cpp
@@ -7,6 +7,7 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/thread.hpp>
#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/logging.hpp>
#include "android_renderer_backend.hpp"
@@ -68,8 +69,16 @@ AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio,
std::string programCacheDir,
InvalidateCallback invalidate)
: backend(std::make_unique<AndroidRendererBackend>())
- , renderer(std::make_unique<util::Thread<Renderer>>(
- "Orchestration Thread",
+ , glThreadCallback(std::make_unique<Actor<AndroidGLThread::InvalidateCallback>>(
+ *Scheduler::GetCurrent(),
+ [&]() {
+ Log::Info(Event::JNI, "GL Thread invalidate callback");
+ // TODO: replace the whole thing with rendererOberver.invalidate()?
+ asyncInvalidate.send();
+ }
+ ))
+ , glThread(std::make_unique<AndroidGLThread>(
+ glThreadCallback->self(),
*backend,
pixelRatio,
fileSource,
@@ -86,15 +95,15 @@ AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio,
AndroidRendererFrontend::~AndroidRendererFrontend() = default;
void AndroidRendererFrontend::reset() {
- assert(renderer);
- renderer.reset();
+ assert(glThread);
+ glThread.reset();
}
void AndroidRendererFrontend::setObserver(RendererObserver& observer) {
- assert (renderer);
+ assert (glThread);
assert (util::RunLoop::Get());
rendererObserver = std::make_unique<ForwardingRendererObserver>(*mapRunLoop, observer);
- renderer->actor().invoke(&Renderer::setObserver, rendererObserver.get());
+ glThread->actor().invoke(&Renderer::setObserver, rendererObserver.get());
}
void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) {
@@ -104,66 +113,66 @@ void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) {
// Called on OpenGL thread
void AndroidRendererFrontend::render() {
- assert (renderer);
+ assert (glThread);
if (!updateParameters) return;
+ // Process the gl thread mailbox
+ glThread->process();
+
// Activate the backend
BackendScope backendGuard { *backend };
- // Block the orchestration thread during render
- util::BlockingThreadGuard<Renderer> rendererGuard { *renderer };
-
// Ensure that the "current" scheduler on the render thread is
// actually the scheduler from the orchestration thread
- Scheduler::SetCurrent(renderer.get());
+ Scheduler::SetCurrent(glThread.get());
if (framebufferSizeChanged) {
backend->updateViewPort();
framebufferSizeChanged = false;
}
- rendererGuard.object().render(*updateParameters);
+ glThread->renderer->render(*updateParameters);
}
void AndroidRendererFrontend::onLowMemory() {
- assert (renderer);
- renderer->actor().invoke(&Renderer::onLowMemory);
+ assert (glThread);
+ glThread->actor().invoke(&Renderer::onLowMemory);
}
std::vector<Feature> AndroidRendererFrontend::querySourceFeatures(const std::string& sourceID,
const SourceQueryOptions& options) const {
- assert (renderer);
+ assert (glThread);
// Waits for the result from the orchestration thread and returns
- return renderer->actor().ask(&Renderer::querySourceFeatures, sourceID, options).get();
+ return glThread->actor().ask(&Renderer::querySourceFeatures, sourceID, options).get();
}
std::vector<Feature> AndroidRendererFrontend::queryRenderedFeatures(const ScreenBox& box,
const RenderedQueryOptions& options) const {
- assert (renderer);
+ 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 renderer->actor().ask(fn, box, options).get();
+ return glThread->actor().ask(fn, box, options).get();
}
std::vector<Feature> AndroidRendererFrontend::queryRenderedFeatures(const ScreenCoordinate& point,
const RenderedQueryOptions& options) const {
- assert (renderer);
+ 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 renderer->actor().ask(fn, point, options).get();
+ return glThread->actor().ask(fn, point, options).get();
}
AnnotationIDs AndroidRendererFrontend::queryPointAnnotations(const ScreenBox& box) const {
- assert (renderer);
+ assert (glThread);
// Waits for the result from the orchestration thread and returns
- return renderer->actor().ask(&Renderer::queryPointAnnotations, box).get();
+ return glThread->actor().ask(&Renderer::queryPointAnnotations, box).get();
}
void AndroidRendererFrontend::requestSnapshot(SnapshotCallback callback_) {
@@ -175,7 +184,6 @@ void AndroidRendererFrontend::requestSnapshot(SnapshotCallback callback_) {
}
void AndroidRendererFrontend::resizeFramebuffer(int width, int height) {
- util::BlockingThreadGuard<Renderer> guard { *renderer };
backend->resizeFramebuffer(width, height);
framebufferSizeChanged = true;
// TODO: thread safe?
diff --git a/platform/android/src/android_renderer_frontend.hpp b/platform/android/src/android_renderer_frontend.hpp
index ca7c27b196..4e57f80d53 100644
--- a/platform/android/src/android_renderer_frontend.hpp
+++ b/platform/android/src/android_renderer_frontend.hpp
@@ -1,6 +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>
@@ -16,17 +19,11 @@
namespace mbgl {
-class Renderer;
-
class FileSource;
class Scheduler;
class RenderedQueryOptions;
class SourceQueryOptions;
-namespace util {
-template <class> class Thread;
-} // namespace util
-
namespace android {
class AndroidRendererBackend;
@@ -68,7 +65,8 @@ public:
private:
std::unique_ptr<AndroidRendererBackend> backend;
- std::unique_ptr<util::Thread<Renderer>> renderer;
+ std::unique_ptr<Actor<AndroidGLThread::InvalidateCallback>> glThreadCallback;
+ std::unique_ptr<AndroidGLThread> glThread;
std::unique_ptr<RendererObserver> rendererObserver;
std::shared_ptr<UpdateParameters> updateParameters;
util::AsyncTask asyncInvalidate;