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

Commit

Permalink
[android] Add jni binding for styleable snapshotter (#16286)
Browse files Browse the repository at this point in the history
* [android] Add jni binding for styleable snapshotter

* Remove Map parameter from factories

- remove unused map from factory interfaces. Map is only needed for repaint.

* implement addlayer function

* Implement addsource function for snapshotter

* Implement addImages function

* format codes

* Apply baseline

* Update CHANGELOG.md

* Update map_snapshotter.cpp

* Destroy snapshotter on the thread it was created

* Activate file sources in start

* Use custom deleter for snapshotter

* format codes

* Release snapshotter pointer to deleting lambda

* Clang format

* Update CHANGELOG.md

* Fix review comments

* FIx review comments

Co-authored-by: Alexander Shalamov <alexander.shalamov@mapbox.com>
  • Loading branch information
Kevin Li and alexshalamov committed Mar 24, 2020
1 parent 1adc436 commit 3f45b0a
Show file tree
Hide file tree
Showing 34 changed files with 429 additions and 243 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

The newly added `Renderer::clearData()` method allows to clear render data and thus save memory and make sure outdated tiles are not shown. It clears data more agressively than `Renderer::reduceMemoryUse()` does, as it clears not only the cache but all orchestration data, including the data used by the currently rendered frame.

- [android] Add jni binding for styleable snapshotter ([#16286](https://github.com/mapbox/mapbox-gl-native/pull/16286))

### 🐞 Bug fixes

- [core] Use `TileCoordinates` instead of `LngLat` for `within` expression calculation ([#16319](https://github.com/mapbox/mapbox-gl-native/pull/16319))
Expand Down
2 changes: 1 addition & 1 deletion metrics/binary-size/android-x86/metrics.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[
"android-x86",
"/tmp/attach/install/android-x86-release/lib/libmapbox-gl.so",
1996967
1997677
]
]
}
22 changes: 15 additions & 7 deletions platform/android/src/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ jni::Local<jni::Array<jni::Object<Layer>>> NativeMapView::getLayers(JNIEnv& env)
auto jLayers = jni::Array<jni::Object<Layer>>::New(env, layers.size());
int index = 0;
for (auto layer : layers) {
jLayers.Set(env, index, LayerManagerAndroid::get()->createJavaLayerPeer(env, *map, *layer));
jLayers.Set(env, index, LayerManagerAndroid::get()->createJavaLayerPeer(env, *layer));
index++;
}

Expand All @@ -926,15 +926,17 @@ jni::Local<jni::Object<Layer>> NativeMapView::getLayer(JNIEnv& env, const jni::S
}

// Create and return the layer's native peer
return LayerManagerAndroid::get()->createJavaLayerPeer(env, *map, *coreLayer);
return LayerManagerAndroid::get()->createJavaLayerPeer(env, *coreLayer);
}

void NativeMapView::addLayer(JNIEnv& env, jlong nativeLayerPtr, const jni::String& before) {
assert(nativeLayerPtr != 0);

Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr);
try {
layer->addToMap(*map, before ? mbgl::optional<std::string>(jni::Make<std::string>(env, before)) : mbgl::optional<std::string>());
layer->addToStyle(
map->getStyle(),
before ? mbgl::optional<std::string>(jni::Make<std::string>(env, before)) : mbgl::optional<std::string>());
} catch (const std::runtime_error& error) {
jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
Expand Down Expand Up @@ -971,7 +973,7 @@ void NativeMapView::addLayerAbove(JNIEnv& env, jlong nativeLayerPtr, const jni::

// Add the layer
try {
layer->addToMap(*map, before);
layer->addToStyle(map->getStyle(), before);
} catch (const std::runtime_error& error) {
jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
Expand All @@ -994,7 +996,7 @@ void NativeMapView::addLayerAt(JNIEnv& env, jlong nativeLayerPtr, jni::jint inde

// Insert it below the current at that index
try {
layer->addToMap(*map, layers.at(index)->getID());
layer->addToStyle(map->getStyle(), layers.at(index)->getID());
} catch (const std::runtime_error& error) {
jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
Expand All @@ -1017,7 +1019,7 @@ jni::jboolean NativeMapView::removeLayerAt(JNIEnv& env, jni::jint index) {
std::unique_ptr<mbgl::style::Layer> coreLayer = map->getStyle().removeLayer(layers.at(index)->getID());
if (coreLayer) {
jni::Local<jni::Object<Layer>> layerObj =
LayerManagerAndroid::get()->createJavaLayerPeer(env, *map, std::move(coreLayer));
LayerManagerAndroid::get()->createJavaLayerPeer(env, std::move(coreLayer));
return jni::jni_true;
}
return jni::jni_false;
Expand Down Expand Up @@ -1141,6 +1143,11 @@ mbgl::Map& NativeMapView::getMap() {
return *map;
}

void NativeMapView::triggerRepaint(JNIEnv&) {
assert(map);
map->triggerRepaint();
}

// Static methods //

void NativeMapView::registerNative(jni::JNIEnv& env) {
Expand Down Expand Up @@ -1248,7 +1255,8 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
METHOD(&NativeMapView::setPrefetchTiles, "nativeSetPrefetchTiles"),
METHOD(&NativeMapView::getPrefetchTiles, "nativeGetPrefetchTiles"),
METHOD(&NativeMapView::setPrefetchZoomDelta, "nativeSetPrefetchZoomDelta"),
METHOD(&NativeMapView::getPrefetchZoomDelta, "nativeGetPrefetchZoomDelta"));
METHOD(&NativeMapView::getPrefetchZoomDelta, "nativeGetPrefetchZoomDelta"),
METHOD(&NativeMapView::triggerRepaint, "nativeTriggerRepaint"));
}

} // namespace android
Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/native_map_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ class NativeMapView : public MapObserver {

mbgl::Map& getMap();

void triggerRepaint(JNIEnv&);

private:
std::unique_ptr<AndroidRendererFrontend> rendererFrontend;

Expand Down
176 changes: 166 additions & 10 deletions platform/android/src/snapshotter/map_snapshotter.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "map_snapshotter.hpp"

#include <mbgl/actor/scheduler.hpp>
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/actor/scheduler.hpp>

#include "../attach_env.hpp"
#include "map_snapshot.hpp"
Expand Down Expand Up @@ -33,6 +33,8 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
return;
}

weakScheduler = mbgl::Scheduler::GetCurrent()->makeWeakPtr();

jFileSource = FileSource::getNativePeer(_env, _jFileSource);
auto size = mbgl::Size { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };

Expand All @@ -43,7 +45,7 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
size,
pixelRatio,
mbgl::android::FileSource::getSharedResourceOptions(_env, _jFileSource),
mbgl::MapSnapshotterObserver::nullObserver(),
*this,
_localIdeographFontFamily ? jni::Make<std::string>(_env, _localIdeographFontFamily) : optional<std::string>{});

if (position) {
Expand All @@ -61,7 +63,17 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env,
}
}

MapSnapshotter::~MapSnapshotter() = default;
MapSnapshotter::~MapSnapshotter() {
auto guard = weakScheduler.lock();
if (weakScheduler && weakScheduler.get() != mbgl::Scheduler::GetCurrent()) {
snapshotter->cancel();
weakScheduler->schedule([ptr = snapshotter.release()]() mutable {
if (ptr) {
delete ptr;
}
});
}
}

void MapSnapshotter::start(JNIEnv& env) {
MBGL_VERIFY_THREAD(tid);
Expand Down Expand Up @@ -126,7 +138,6 @@ void MapSnapshotter::setRegion(JNIEnv& env, const jni::Object<LatLngBounds>& reg
snapshotter->setRegion(LatLngBounds::getLatLngBounds(env, region));
}


// Private methods //

void MapSnapshotter::activateFilesource(JNIEnv& env) {
Expand All @@ -143,6 +154,134 @@ void MapSnapshotter::deactivateFilesource(JNIEnv& env) {
}
}

void MapSnapshotter::onDidFailLoadingStyle(const std::string& error) {
MBGL_VERIFY_THREAD(tid);
android::UniqueEnv _env = android::AttachEnv();
static auto& javaClass = jni::Class<MapSnapshotter>::Singleton(*_env);
static auto onDidFailLoadingStyle = javaClass.GetMethod<void(jni::String)>(*_env, "onDidFailLoadingStyle");
auto weakReference = javaPeer.get(*_env);
if (weakReference) {
weakReference.Call(*_env, onDidFailLoadingStyle, jni::Make<jni::String>(*_env, error));
}
}

void MapSnapshotter::onDidFinishLoadingStyle() {
MBGL_VERIFY_THREAD(tid);
android::UniqueEnv _env = android::AttachEnv();

static auto& javaClass = jni::Class<MapSnapshotter>::Singleton(*_env);
static auto onDidFinishLoadingStyle = javaClass.GetMethod<void()>(*_env, "onDidFinishLoadingStyle");
auto weakReference = javaPeer.get(*_env);
if (weakReference) {
weakReference.Call(*_env, onDidFinishLoadingStyle);
}
}

void MapSnapshotter::onStyleImageMissing(const std::string& imageName) {
MBGL_VERIFY_THREAD(tid);
android::UniqueEnv _env = android::AttachEnv();
static auto& javaClass = jni::Class<MapSnapshotter>::Singleton(*_env);
static auto onStyleImageMissing = javaClass.GetMethod<void(jni::String)>(*_env, "onStyleImageMissing");
auto weakReference = javaPeer.get(*_env);
if (weakReference) {
weakReference.Call(*_env, onStyleImageMissing, jni::Make<jni::String>(*_env, imageName));
}
}

void MapSnapshotter::addLayerAt(JNIEnv& env, jlong nativeLayerPtr, jni::jint index) {
assert(nativeLayerPtr != 0);
const auto layers = snapshotter->getStyle().getLayers();
auto* layer = reinterpret_cast<Layer*>(nativeLayerPtr);
// Check index
const int numLayers = layers.size() - 1;
if (index > numLayers || index < 0) {
Log::Error(Event::JNI, "Index out of range: %i", index);
jni::ThrowNew(env,
jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"),
std::string("Invalid index").c_str());
}
// Insert it below the current at that index
try {
layer->addToStyle(snapshotter->getStyle(), layers.at(index)->getID());
} catch (const std::runtime_error& error) {
jni::ThrowNew(
env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
}

void MapSnapshotter::addLayerBelow(JNIEnv& env, jlong nativeLayerPtr, const jni::String& below) {
assert(nativeLayerPtr != 0);

auto* layer = reinterpret_cast<Layer*>(nativeLayerPtr);
try {
layer->addToStyle(
snapshotter->getStyle(),
below ? mbgl::optional<std::string>(jni::Make<std::string>(env, below)) : mbgl::optional<std::string>());
} catch (const std::runtime_error& error) {
jni::ThrowNew(
env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
}

void MapSnapshotter::addLayerAbove(JNIEnv& env, jlong nativeLayerPtr, const jni::String& above) {
assert(nativeLayerPtr != 0);
auto* newLayer = reinterpret_cast<Layer*>(nativeLayerPtr);

// Find the sibling
const auto snapshotterLayers = snapshotter->getStyle().getLayers();
auto siblingId = jni::Make<std::string>(env, above);

size_t index = 0;
for (auto* snapshotterLayer : snapshotterLayers) {
++index;
if (snapshotterLayer->getID() == siblingId) {
break;
}
}

// Check if we found a sibling to place before
mbgl::optional<std::string> before;
if (index > snapshotterLayers.size()) {
// Not found
jni::ThrowNew(env,
jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"),
std::string("Could not find layer: ").append(siblingId).c_str());
} else if (index < snapshotterLayers.size()) {
// Place before the sibling
before = {snapshotterLayers.at(index)->getID()};
}

// Add the layer
try {
newLayer->addToStyle(snapshotter->getStyle(), before);
} catch (const std::runtime_error& error) {
jni::ThrowNew(
env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
}
}

void MapSnapshotter::addSource(JNIEnv& env, const jni::Object<Source>& obj, jlong sourcePtr) {
assert(sourcePtr != 0);

auto* source = reinterpret_cast<Source*>(sourcePtr);
try {
source->addToStyle(env, obj, snapshotter->getStyle());
} catch (const std::runtime_error& error) {
jni::ThrowNew(
env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what());
}
}

void MapSnapshotter::addImages(JNIEnv& env, const jni::Array<jni::Object<mbgl::android::Image>>& jimages) {
jni::NullCheck(env, &jimages);
std::size_t len = jimages.Length(env);

for (std::size_t i = 0; i < len; ++i) {
auto image = mbgl::android::Image::getImage(env, jimages.Get(env, i));
snapshotter->getStyle().addImage(std::make_unique<mbgl::style::Image>(image));
}
}

// Static methods //

void MapSnapshotter::registerNative(jni::JNIEnv& env) {
Expand All @@ -152,18 +291,35 @@ void MapSnapshotter::registerNative(jni::JNIEnv& env) {
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)

// Register the peer
jni::RegisterNativePeer<MapSnapshotter>(env, javaClass, "nativePtr",
jni::MakePeer<MapSnapshotter, const jni::Object<MapSnapshotter>&, const jni::Object<FileSource>&, jni::jfloat, jni::jint, jni::jint, const jni::String&, const jni::String&, const jni::Object<LatLngBounds>&, const jni::Object<CameraPosition>&, jni::jboolean, const jni::String&>,
"nativeInitialize",
"finalize",
jni::RegisterNativePeer<MapSnapshotter>(env,
javaClass,
"nativePtr",
jni::MakePeer<MapSnapshotter,
const jni::Object<MapSnapshotter>&,
const jni::Object<FileSource>&,
jni::jfloat,
jni::jint,
jni::jint,
const jni::String&,
const jni::String&,
const jni::Object<LatLngBounds>&,
const jni::Object<CameraPosition>&,
jni::jboolean,
const jni::String&>,
"nativeInitialize",
"finalize",
METHOD(&MapSnapshotter::setStyleUrl, "setStyleUrl"),
METHOD(&MapSnapshotter::addLayerAt, "nativeAddLayerAt"),
METHOD(&MapSnapshotter::addLayerBelow, "nativeAddLayerBelow"),
METHOD(&MapSnapshotter::addLayerAbove, "nativeAddLayerAbove"),
METHOD(&MapSnapshotter::addSource, "nativeAddSource"),
METHOD(&MapSnapshotter::addImages, "nativeAddImages"),
METHOD(&MapSnapshotter::setStyleJson, "setStyleJson"),
METHOD(&MapSnapshotter::setSize, "setSize"),
METHOD(&MapSnapshotter::setCameraPosition, "setCameraPosition"),
METHOD(&MapSnapshotter::setRegion, "setRegion"),
METHOD(&MapSnapshotter::start, "nativeStart"),
METHOD(&MapSnapshotter::cancel, "nativeCancel")
);
METHOD(&MapSnapshotter::cancel, "nativeCancel"));
}

} // namespace android
Expand Down
Loading

0 comments on commit 3f45b0a

Please sign in to comment.