diff options
Diffstat (limited to 'platform/android/src')
-rwxr-xr-x | platform/android/src/jni.cpp | 4 | ||||
-rw-r--r-- | platform/android/src/map/camera_position.cpp | 18 | ||||
-rw-r--r-- | platform/android/src/map/camera_position.hpp | 2 | ||||
-rw-r--r-- | platform/android/src/snapshotter/map_snapshotter.cpp | 110 | ||||
-rw-r--r-- | platform/android/src/snapshotter/map_snapshotter.hpp | 61 |
5 files changed, 195 insertions, 0 deletions
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index db8dd1dbdf..f7d1e4afbc 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -47,6 +47,7 @@ #include "style/layers/layers.hpp" #include "style/sources/sources.hpp" #include "style/light.hpp" +#include "snapshotter/map_snapshotter.hpp" namespace mbgl { namespace android { @@ -177,6 +178,9 @@ void registerNatives(JavaVM *vm) { OfflineTilePyramidRegionDefinition::registerNative(env); OfflineRegionError::registerNative(env); OfflineRegionStatus::registerNative(env); + + // Snapshotter + MapSnapshotter::registerNative(env); } } // namespace android diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index d6f2cb83e8..1fc5f9789f 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -27,6 +27,24 @@ jni::Object<CameraPosition> CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOp return CameraPosition::javaClass.New(env, constructor, LatLng::New(env, center), options.zoom.value_or(0), tilt_degrees, bearing_degrees); } +mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, jni::Object<CameraPosition> position) { + static auto bearing = CameraPosition::javaClass.GetField<jni::jdouble>(env, "bearing"); + static auto target = CameraPosition::javaClass.GetField<jni::Object<LatLng>>(env, "target"); + static auto tilt = CameraPosition::javaClass.GetField<jni::jdouble>(env, "tilt"); + static auto zoom = CameraPosition::javaClass.GetField<jni::jdouble>(env, "zoom"); + + auto center = LatLng::getLatLng(env, position.Get(env, target)); + + return mbgl::CameraOptions { + center, + {}, + {}, + position.Get(env, zoom), + position.Get(env, bearing) * util::DEG2RAD, + position.Get(env, tilt) + }; +} + void CameraPosition::registerNative(jni::JNIEnv &env) { // Lookup the class CameraPosition::javaClass = *jni::Class<CameraPosition>::Find(env).NewGlobalRef(env).release(); diff --git a/platform/android/src/map/camera_position.hpp b/platform/android/src/map/camera_position.hpp index b9f1646cc9..4eee8be758 100644 --- a/platform/android/src/map/camera_position.hpp +++ b/platform/android/src/map/camera_position.hpp @@ -15,6 +15,8 @@ public: static jni::Object<CameraPosition> New(jni::JNIEnv&, mbgl::CameraOptions); + static mbgl::CameraOptions getCameraOptions(jni::JNIEnv&, jni::Object<CameraPosition>); + static jni::Class<CameraPosition> javaClass; static void registerNative(jni::JNIEnv&); diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp new file mode 100644 index 0000000000..d64218d11a --- /dev/null +++ b/platform/android/src/snapshotter/map_snapshotter.cpp @@ -0,0 +1,110 @@ +#include "map_snapshotter.hpp" + +#include <mbgl/renderer/renderer.hpp> +#include <mbgl/style/style.hpp> +#include <mbgl/util/shared_thread_pool.hpp> +#include <mbgl/util/logging.hpp> +#include <mbgl/util/string.hpp> +#include <mbgl/actor/scheduler.hpp> + +#include "../attach_env.hpp" +#include "../bitmap.hpp" + +namespace mbgl { +namespace android { + +MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, + jni::Object<MapSnapshotter> _obj, + jni::Object<FileSource> jFileSource, + jni::jfloat _pixelRatio, + jni::jint width, + jni::jint height, + jni::String styleURL, + jni::Object<LatLngBounds> region, + jni::Object<CameraPosition> position, + jni::String _programCacheDir) + : javaPeer(SeizeGenericWeakRef(_env, jni::Object<MapSnapshotter>(jni::NewWeakGlobalRef(_env, _obj.Get()).release()))) + , pixelRatio(_pixelRatio) + , threadPool(sharedThreadPool()) { + + // Get a reference to the JavaVM for callbacks + if (_env.GetJavaVM(&vm) < 0) { + _env.ExceptionDescribe(); + return; + } + + auto& fileSource = mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource); + auto size = mbgl::Size { static_cast<uint32_t>(width), static_cast<uint32_t>(height) }; + auto cameraOptions = position ? CameraPosition::getCameraOptions(_env, position) : CameraOptions(); + optional<mbgl::LatLngBounds> bounds; + if (region) { + bounds = LatLngBounds::getLatLngBounds(_env, region); + } + + // Create the core snapshotter + snapshotter = std::make_unique<mbgl::MapSnapshotter>(fileSource, + *threadPool, + jni::Make<std::string>(_env, styleURL), + size, + pixelRatio, + cameraOptions, + bounds, + jni::Make<std::string>(_env, _programCacheDir)); + +} + +MapSnapshotter::~MapSnapshotter() = default; + +void MapSnapshotter::start(JNIEnv&) { + MBGL_VERIFY_THREAD(tid); + + snapshotCallback = std::make_unique<Actor<mbgl::MapSnapshotter::Callback>>(*Scheduler::GetCurrent(), [this](std::exception_ptr err, PremultipliedImage image) { + MBGL_VERIFY_THREAD(tid); + android::UniqueEnv _env = android::AttachEnv(); + + if (err) { + // error handler callback + static auto onSnapshotFailed = javaClass.GetMethod<void (jni::String)>(*_env, "onSnapshotFailed"); + javaPeer->Call(*_env, onSnapshotFailed, jni::Make<jni::String>(*_env, util::toString(err))); + } else { + // Create the bitmap + auto bitmap = Bitmap::CreateBitmap(*_env, std::move(image)); + + // invoke callback + static auto onSnapshotReady = javaClass.GetMethod<void (jni::Object<Bitmap>)>(*_env, "onSnapshotReady"); + javaPeer->Call(*_env, onSnapshotReady, bitmap); + } + }); + + snapshotter->snapshot(snapshotCallback->self()); +} + +void MapSnapshotter::cancel(JNIEnv&) { + MBGL_VERIFY_THREAD(tid); + + snapshotCallback.reset(); + snapshotter.reset(); +} + +// Static methods // + +jni::Class<MapSnapshotter> MapSnapshotter::javaClass; + +void MapSnapshotter::registerNative(jni::JNIEnv& env) { + // Lookup the class + MapSnapshotter::javaClass = *jni::Class<MapSnapshotter>::Find(env).NewGlobalRef(env).release(); + +#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + // Register the peer + jni::RegisterNativePeer<MapSnapshotter>(env, MapSnapshotter::javaClass, "nativePtr", + std::make_unique<MapSnapshotter, JNIEnv&, jni::Object<MapSnapshotter>, jni::Object<FileSource>, jni::jfloat, jni::jint, jni::jint, jni::String, jni::Object<LatLngBounds>, jni::Object<CameraPosition>, jni::String>, + "nativeInitialize", + "finalize", + METHOD(&MapSnapshotter::start, "nativeStart"), + METHOD(&MapSnapshotter::cancel, "nativeCancel") + ); +} + +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/snapshotter/map_snapshotter.hpp b/platform/android/src/snapshotter/map_snapshotter.hpp new file mode 100644 index 0000000000..093f589c05 --- /dev/null +++ b/platform/android/src/snapshotter/map_snapshotter.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include <mbgl/map/map_snapshotter.hpp> +#include <mbgl/util/default_thread_pool.hpp> +#include <mbgl/util/util.hpp> + +#include "../file_source.hpp" +#include "../geometry/lat_lng_bounds.hpp" +#include "../map/camera_position.hpp" + +#include <jni/jni.hpp> +#include "../jni/generic_global_ref_deleter.hpp" + +#include <memory> + +namespace mbgl { +namespace android { + +class SnapshotterRendererFrontend; + +class MapSnapshotter { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/snapshotter/MapSnapshotter"; }; + + static jni::Class<MapSnapshotter> javaClass; + + static void registerNative(jni::JNIEnv&); + + MapSnapshotter(jni::JNIEnv&, + jni::Object<MapSnapshotter>, + jni::Object<FileSource>, + jni::jfloat pixelRatio, + jni::jint width, + jni::jint height, + jni::String styleURL, + jni::Object<LatLngBounds> region, + jni::Object<CameraPosition> position, + jni::String programCacheDir); + + ~MapSnapshotter(); + + void start(JNIEnv&); + + void cancel(JNIEnv&); + +private: + MBGL_STORE_THREAD(tid); + + JavaVM *vm = nullptr; + GenericUniqueWeakObject<MapSnapshotter> javaPeer; + + float pixelRatio; + + std::shared_ptr<mbgl::ThreadPool> threadPool; + std::unique_ptr<Actor<mbgl::MapSnapshotter::Callback>> snapshotCallback; + std::unique_ptr<mbgl::MapSnapshotter> snapshotter; +}; + +} // namespace android +} // namespace mbgl
\ No newline at end of file |