[android] map snapshots

This commit is contained in:
Ivo van Dongen
2017-09-18 11:31:45 +03:00
committed by Ivo van Dongen
parent 8182b26dfe
commit c17be060fd
7 changed files with 49 additions and 32 deletions

View File

@@ -807,13 +807,6 @@ final class NativeMapView {
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}
public void scheduleTakeSnapshot() {
if (isDestroyedOn("scheduleTakeSnapshot")) {
return;
}
nativeTakeSnapshot();
}
public void setApiBaseUrl(String baseUrl) {
if (isDestroyedOn("setApiBaseUrl")) {
return;
@@ -1076,9 +1069,11 @@ final class NativeMapView {
//
void addSnapshotCallback(@NonNull MapboxMap.SnapshotReadyCallback callback) {
if (isDestroyedOn("addSnapshotCallback")) {
return;
}
snapshotReadyCallback = callback;
scheduleTakeSnapshot();
scheduler.requestRender();
nativeTakeSnapshot();
}
}

View File

@@ -6,7 +6,6 @@
#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"
@@ -113,14 +112,6 @@ AnnotationIDs AndroidRendererFrontend::queryPointAnnotations(const ScreenBox& bo
return mapRenderer.actor().ask(&Renderer::queryPointAnnotations, box).get();
}
void AndroidRendererFrontend::requestSnapshot(SnapshotCallback callback_) {
snapshotCallback = std::make_unique<SnapshotCallback>([callback=std::move(callback_), runloop=util::RunLoop::Get()](PremultipliedImage image){
runloop->invoke([&]() {
callback(std::move(image));
});
});
}
} // namespace android
} // namespace mbgl

View File

@@ -4,7 +4,6 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/renderer/renderer_frontend.hpp>
#include <mbgl/util/geo.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/run_loop.hpp>
#include <functional>
@@ -41,16 +40,9 @@ public:
// Memory
void onLowMemory();
// Snapshot - Callback will be called on calling thread through RunLoop
using SnapshotCallback = std::function<void (PremultipliedImage)>;
void requestSnapshot(SnapshotCallback);
private:
MapRenderer& mapRenderer;
util::RunLoop* mapRunLoop;
// TODO
std::unique_ptr<SnapshotCallback> snapshotCallback;
};
} // namespace android

View File

@@ -2,6 +2,7 @@
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/util/shared_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
#include <string>
@@ -75,8 +76,26 @@ void MapRenderer::setObserver(std::shared_ptr<RendererObserver> _rendererObserve
}
}
void MapRenderer::requestSnapshot(SnapshotCallback callback) {
auto self = ActorRef<MapRenderer>(*this, mailbox);
self.invoke(
&MapRenderer::scheduleSnapshot,
std::make_unique<SnapshotCallback>([&, callback=std::move(callback), runloop=util::RunLoop::Get()](PremultipliedImage image) {
runloop->invoke([callback=std::move(callback), image=std::move(image)]() mutable {
callback(std::move(image));
});
snapshotCallback.reset();
})
);
}
// Called on OpenGL thread //
void MapRenderer::scheduleSnapshot(std::unique_ptr<SnapshotCallback> callback) {
snapshotCallback = std::move(callback);
requestRender();
}
void MapRenderer::render(JNIEnv&) {
assert (renderer);
@@ -103,6 +122,12 @@ void MapRenderer::render(JNIEnv&) {
}
renderer->render(*params);
// Deliver the snapshot if requested
if (snapshotCallback) {
snapshotCallback->operator()(backend->readFramebuffer());
snapshotCallback.reset();
}
}
void MapRenderer::onSurfaceCreated(JNIEnv&) {

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/image.hpp>
#include <memory>
#include <utility>
@@ -74,6 +75,15 @@ public:
void requestRender();
// Snapshot - requires a RunLoop on the calling thread
using SnapshotCallback = std::function<void (PremultipliedImage)>;
void requestSnapshot(SnapshotCallback);
protected:
// Called from the GL Thread //
void scheduleSnapshot(std::unique_ptr<SnapshotCallback>);
private:
// Called from the GL Thread //
@@ -105,6 +115,8 @@ private:
std::mutex updateMutex;
bool framebufferSizeChanged = false;
std::unique_ptr<SnapshotCallback> snapshotCallback;
};
} // namespace android

View File

@@ -60,9 +60,10 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env,
jni::Object<FileSource> jFileSource,
jni::Object<MapRenderer> jMapRenderer,
jni::jfloat _pixelRatio)
: javaPeer(_obj.NewWeakGlobalRef(_env)),
pixelRatio(_pixelRatio),
threadPool(sharedThreadPool()) {
: javaPeer(_obj.NewWeakGlobalRef(_env))
, mapRenderer(MapRenderer::getNativePeer(_env, jMapRenderer))
, pixelRatio(_pixelRatio)
, threadPool(sharedThreadPool()) {
// Get a reference to the JavaVM for callbacks
if (_env.GetJavaVM(&vm) < 0) {
@@ -70,9 +71,8 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env,
return;
}
// Get native peers
// Get native peer for file source
mbgl::FileSource& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource);
MapRenderer& mapRenderer = MapRenderer::getNativePeer(_env, jMapRenderer);
// Create a renderer frontend
rendererFrontend = std::make_unique<AndroidRendererFrontend>(mapRenderer);
@@ -395,7 +395,7 @@ void NativeMapView::setContentPadding(JNIEnv&, double top, double left, double b
}
void NativeMapView::scheduleSnapshot(jni::JNIEnv&) {
rendererFrontend->requestSnapshot([&](PremultipliedImage image) {
mapRenderer.requestSnapshot([&](PremultipliedImage image) {
auto _env = android::AttachEnv();
// Convert image to bitmap
auto bitmap = Bitmap::CreateBitmap(*_env, std::move(image));

View File

@@ -252,6 +252,8 @@ private:
JavaVM *vm = nullptr;
jni::UniqueWeakObject<NativeMapView> javaPeer;
MapRenderer& mapRenderer;
std::string styleUrl;
std::string apiKey;