Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android] use only two threads
Browse files Browse the repository at this point in the history
  • Loading branch information
ivovandongen committed Sep 4, 2017
1 parent 7b9c93b commit 48e2664
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 30 deletions.
75 changes: 75 additions & 0 deletions platform/android/src/android_gl_thread.hpp
Original file line number Diff line number Diff line change
@@ -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
54 changes: 31 additions & 23 deletions platform/android/src/android_renderer_frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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()?
invalidate();
}
))
, glThread(std::make_unique<AndroidGLThread>(
glThreadCallback->self(),
*backend,
pixelRatio,
fileSource,
Expand All @@ -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) {
Expand All @@ -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_) {
Expand All @@ -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?
Expand Down
12 changes: 5 additions & 7 deletions platform/android/src/android_renderer_frontend.hpp
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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;
Expand Down Expand Up @@ -68,7 +65,8 @@ class AndroidRendererFrontend : public RendererFrontend {

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;
Expand Down

0 comments on commit 48e2664

Please sign in to comment.