Add Android Vulkan backend (#2711)

Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
Adrian Cojocaru
2024-09-06 17:40:57 +03:00
committed by GitHub
parent 4b5d06d908
commit ea09bdf2b6
79 changed files with 2580 additions and 1400 deletions

View File

@@ -7,6 +7,7 @@
#include <mbgl/util/run_loop.hpp>
#include <string>
#include <android/native_window_jni.h>
#include "attach_env.hpp"
#include "android_renderer_backend.hpp"
@@ -24,8 +25,7 @@ MapRenderer::MapRenderer(jni::JNIEnv& _env,
localIdeographFontFamily(localIdeographFontFamily_ ? jni::Make<std::string>(_env, localIdeographFontFamily_)
: std::optional<std::string>{}),
threadPool(Scheduler::GetBackground(), {}),
mailboxData(this),
backend(std::make_unique<AndroidRendererBackend>(threadPool)) {}
mailboxData(this) {}
MapRenderer::MailboxData::MailboxData(Scheduler* scheduler_)
: scheduler(scheduler_) {
@@ -163,7 +163,7 @@ void MapRenderer::requestSnapshot(SnapshotCallback callback) {
void MapRenderer::resetRenderer() {
renderer.reset();
backend = std::make_unique<AndroidRendererBackend>(threadPool);
swapBehaviorFlush = false;
}
void MapRenderer::scheduleSnapshot(std::unique_ptr<SnapshotCallback> callback) {
@@ -186,7 +186,7 @@ void MapRenderer::render(JNIEnv&) {
// Activate the backend
assert(backend);
gfx::BackendScope backendGuard{*backend};
gfx::BackendScope backendGuard{backend->getImpl()};
// Ensure that the "current" scheduler on the render thread is
// this scheduler.
@@ -206,14 +206,10 @@ void MapRenderer::render(JNIEnv&) {
}
}
void MapRenderer::onSurfaceCreated(JNIEnv&) {
void MapRenderer::onSurfaceCreated(JNIEnv& env, const jni::Object<AndroidSurface>& surface) {
// Lock as the initialization can come from the main thread or the GL thread first
std::lock_guard<std::mutex> lock(initialisationMutex);
// The GL context is already active if get a new surface.
assert(backend);
gfx::BackendScope backendGuard{*backend, gfx::BackendScope::ScopeType::Implicit};
// The android system will have already destroyed the underlying
// GL resources if this is not the first initialization and an
// attempt to clean them up will fail
@@ -223,12 +219,22 @@ void MapRenderer::onSurfaceCreated(JNIEnv&) {
// Reset in opposite order
renderer.reset();
backend.reset();
window.reset();
if (surface) {
window = std::unique_ptr<ANativeWindow, std::function<void(ANativeWindow*)>>(
ANativeWindow_fromSurface(&env, reinterpret_cast<jobject>(surface.get())),
[](ANativeWindow* window_) { ANativeWindow_release(window_); });
}
// Create the new backend and renderer
backend = std::make_unique<AndroidRendererBackend>(threadPool);
renderer = std::make_unique<Renderer>(*backend, pixelRatio, localIdeographFontFamily);
backend = AndroidRendererBackend::Create(window.get());
renderer = std::make_unique<Renderer>(backend->getImpl(), pixelRatio, localIdeographFontFamily);
rendererRef = std::make_unique<ActorRef<Renderer>>(*renderer, mailboxData.getMailbox());
backend->setSwapBehavior(swapBehaviorFlush ? gfx::Renderable::SwapBehaviour::Flush
: gfx::Renderable::SwapBehaviour::NoFlush);
// Set the observer on the new Renderer implementation
if (rendererObserver) {
renderer->setObserver(rendererObserver.get());
@@ -238,7 +244,8 @@ void MapRenderer::onSurfaceCreated(JNIEnv&) {
void MapRenderer::onSurfaceChanged(JNIEnv& env, jint width, jint height) {
if (!renderer) {
// In case the surface has been destroyed (due to app back-grounding)
onSurfaceCreated(env);
jni::jobject* nullObj = nullptr;
onSurfaceCreated(env, jni::Object<AndroidSurface>(nullObj));
}
backend->resizeFramebuffer(width, height);
@@ -255,10 +262,16 @@ void MapRenderer::onRendererReset(JNIEnv&) {
// needs to be called on GL thread
void MapRenderer::onSurfaceDestroyed(JNIEnv&) {
resetRenderer();
window.reset();
}
void MapRenderer::setSwapBehaviorFlush(JNIEnv&, jboolean flush) {
backend->setSwapBehavior(flush ? gfx::Renderable::SwapBehaviour::Flush : gfx::Renderable::SwapBehaviour::NoFlush);
swapBehaviorFlush = flush;
if (backend) {
backend->setSwapBehavior(flush ? gfx::Renderable::SwapBehaviour::Flush
: gfx::Renderable::SwapBehaviour::NoFlush);
}
}
// Static methods //