[android] schedule work on the gl thread using GLSurfaceView#queueEvent

This commit is contained in:
Ivo van Dongen
2017-09-11 11:04:53 +03:00
committed by Ivo van Dongen
parent 347d7c19c0
commit 15a47d116a
9 changed files with 124 additions and 49 deletions

View File

@@ -44,20 +44,18 @@ public:
// Only safe on the GL Thread
void process() {
while (true) {
std::unique_lock<std::mutex> lock(mutex);
std::unique_lock<std::mutex> lock(mutex);
if (queue.empty()) {
return;
}
auto scheduled = queue.front();
queue.pop();
lock.unlock();
Mailbox::maybeReceive(scheduled);
if (queue.empty()) {
return;
}
auto scheduled = queue.front();
queue.pop();
lock.unlock();
Mailbox::maybeReceive(scheduled);
}
// Only safe to access on the GL Thread

View File

@@ -58,10 +58,11 @@ AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio,
FileSource& fileSource,
Scheduler& scheduler,
std::string programCacheDir,
InvalidateCallback invalidate)
RequestRenderCallback requestRender,
RequestProcessingCallback requestProcessing)
: backend(std::make_unique<AndroidRendererBackend>())
, glThread(std::make_unique<AndroidGLThread>(
invalidate,
std::move(requestProcessing),
*backend,
pixelRatio,
fileSource,
@@ -69,8 +70,8 @@ AndroidRendererFrontend::AndroidRendererFrontend(float pixelRatio,
GLContextMode::Unique,
programCacheDir
))
, asyncInvalidate([=]() {
invalidate();
, asyncInvalidate([requestRender=std::move(requestRender)]() {
requestRender();
})
, mapRunLoop(util::RunLoop::Get()) {
}
@@ -112,9 +113,6 @@ void AndroidRendererFrontend::render() {
params = updateParameters;
}
// Process the gl thread mailbox
glThread->process();
// Activate the backend
BackendScope backendGuard { *backend };
@@ -130,6 +128,11 @@ void AndroidRendererFrontend::render() {
glThread->renderer->render(*params);
}
void AndroidRendererFrontend::process() {
// Process the gl thread mailbox
glThread->process();
}
void AndroidRendererFrontend::onLowMemory() {
assert (glThread);
glThread->actor().invoke(&Renderer::onLowMemory);

View File

@@ -30,13 +30,15 @@ class AndroidRendererBackend;
class AndroidRendererFrontend : public RendererFrontend {
public:
using InvalidateCallback = std::function<void ()>;
using RequestRenderCallback = std::function<void ()>;
using RequestProcessingCallback = std::function<void ()>;
AndroidRendererFrontend(float pixelRatio,
mbgl::FileSource&,
mbgl::Scheduler&,
std::string programCacheDir,
InvalidateCallback);
RequestRenderCallback,
RequestProcessingCallback);
~AndroidRendererFrontend() override;
void reset() override;
@@ -46,6 +48,7 @@ public:
// Called from OpenGL Thread
void render();
void process();
// Feature querying
std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate&, const RenderedQueryOptions&) const;

View File

@@ -78,7 +78,8 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env,
*threadPool,
jni::Make<std::string>(_env,
_programCacheDir),
[this] { this->invalidate(); });
[this] { this->requestRender(); },
[this] { this->requestProcessing(); });
// Create the core map
map = std::make_unique<mbgl::Map>(*rendererFrontend, *this,
@@ -97,17 +98,23 @@ NativeMapView::~NativeMapView() {
}
/**
* Callback to java NativeMapView#onInvalidate().
* Callback to java NativeMapView#requestRender().
*
* Called to invalidate the View and schedule a render on the next
* Called to schedule a render on the next
* runloop iteration.
*/
void NativeMapView::invalidate() {
void NativeMapView::requestRender() {
android::UniqueEnv _env = android::AttachEnv();
static auto onInvalidate = javaClass.GetMethod<void ()>(*_env, "onInvalidate");
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).
*
@@ -195,8 +202,9 @@ void NativeMapView::render(jni::JNIEnv& ) {
updateFps();
}
void NativeMapView::update(jni::JNIEnv&) {
invalidate();
// Called from the OpenGL renderer thread
void NativeMapView::process(jni::JNIEnv&) {
rendererFrontend->process();
}
void NativeMapView::resizeView(jni::JNIEnv&, int w, int h) {
@@ -1004,7 +1012,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
"nativeInitialize",
"nativeDestroy",
METHOD(&NativeMapView::render, "nativeRender"),
METHOD(&NativeMapView::update, "nativeUpdate"),
METHOD(&NativeMapView::process, "nativeProcess"),
METHOD(&NativeMapView::resizeView, "nativeResizeView"),
METHOD(&NativeMapView::resizeFramebuffer, "nativeResizeFramebuffer"),
METHOD(&NativeMapView::getStyleUrl, "nativeGetStyleUrl"),

View File

@@ -73,7 +73,10 @@ public:
void onSourceChanged(mbgl::style::Source&) override;
// Signal the view system, we want to redraw
void invalidate();
void requestRender();
// Request processing on the GL Thread
void requestProcessing();
// JNI //
@@ -81,9 +84,10 @@ public:
void onSurfaceCreated(jni::JNIEnv&);
// Called on OpenGL Thread
void render(jni::JNIEnv&);
void process(jni::JNIEnv&);
void update(jni::JNIEnv&);
// Called on OpenGL Thread
void render(jni::JNIEnv&);
void resizeView(jni::JNIEnv&, int, int);