Rendering statistics view (#3322)
Co-authored-by: Bart Louwers <bart@emeel.net>
This commit is contained in:
@@ -122,6 +122,8 @@ add_library(maplibre SHARED
|
||||
${PROJECT_SOURCE_DIR}/offline/offline_region_error.hpp
|
||||
${PROJECT_SOURCE_DIR}/offline/offline_region_status.cpp
|
||||
${PROJECT_SOURCE_DIR}/offline/offline_region_status.hpp
|
||||
${PROJECT_SOURCE_DIR}/rendering_stats.cpp
|
||||
${PROJECT_SOURCE_DIR}/rendering_stats.hpp
|
||||
${PROJECT_SOURCE_DIR}/snapshotter/map_snapshot.cpp
|
||||
${PROJECT_SOURCE_DIR}/snapshotter/map_snapshot.hpp
|
||||
${PROJECT_SOURCE_DIR}/snapshotter/map_snapshotter.cpp
|
||||
|
||||
@@ -36,11 +36,10 @@ public:
|
||||
void onDidFinishRenderingFrame(RenderMode mode,
|
||||
bool repaintNeeded,
|
||||
bool placementChanged,
|
||||
double frameEncodingTime,
|
||||
double frameRenderingTime) override {
|
||||
const gfx::RenderingStats& stats) override {
|
||||
void (RendererObserver::*f)(
|
||||
RenderMode, bool, bool, double, double) = &RendererObserver::onDidFinishRenderingFrame;
|
||||
delegate.invoke(f, mode, repaintNeeded, placementChanged, frameEncodingTime, frameRenderingTime);
|
||||
RenderMode, bool, bool, const gfx::RenderingStats&) = &RendererObserver::onDidFinishRenderingFrame;
|
||||
delegate.invoke(f, mode, repaintNeeded, placementChanged, stats);
|
||||
}
|
||||
|
||||
void onDidFinishRenderingMap() override { delegate.invoke(&RendererObserver::onDidFinishRenderingMap); }
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "maplibre.hpp"
|
||||
#include "native_map_view.hpp"
|
||||
#include "native_map_options.hpp"
|
||||
#include "rendering_stats.hpp"
|
||||
#include "util/tile_server_options.hpp"
|
||||
#ifndef MBGL_MODULE_OFFLINE_DISABLE
|
||||
#include "offline/offline_manager.hpp"
|
||||
@@ -111,6 +112,7 @@ void registerNatives(JavaVM* vm) {
|
||||
MapRendererRunnable::registerNative(env);
|
||||
NativeMapView::registerNative(env);
|
||||
NativeMapOptions::registerNative(env);
|
||||
RenderingStats::registerNative(env);
|
||||
|
||||
// Http
|
||||
RegisterNativeHTTPRequest(env);
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "conversion/collection.hpp"
|
||||
#include "style/conversion/filter.hpp"
|
||||
#include "geojson/feature.hpp"
|
||||
#include "rendering_stats.hpp"
|
||||
|
||||
#include "android_renderer_frontend.hpp"
|
||||
#include "attach_env.hpp"
|
||||
@@ -187,20 +188,25 @@ void NativeMapView::onWillStartRenderingFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderFrameStatus status) {
|
||||
void NativeMapView::onDidFinishRenderingFrame(const MapObserver::RenderFrameStatus& status) {
|
||||
assert(vm != nullptr);
|
||||
|
||||
android::UniqueEnv _env = android::AttachEnv();
|
||||
static auto& javaClass = jni::Class<NativeMapView>::Singleton(*_env);
|
||||
static auto onDidFinishRenderingFrame = javaClass.GetMethod<void(jboolean, jdouble, jdouble)>(
|
||||
static auto onDidFinishRenderingFrame = javaClass.GetMethod<void(jboolean, jni::Object<RenderingStats>)>(
|
||||
*_env, "onDidFinishRenderingFrame");
|
||||
auto weakReference = javaPeer.get(*_env);
|
||||
if (weakReference) {
|
||||
if (!renderingStats) {
|
||||
renderingStats = jni::NewGlobal(*_env, RenderingStats::Create(*_env));
|
||||
}
|
||||
|
||||
RenderingStats::Update(*_env, renderingStats, status.renderingStats);
|
||||
|
||||
weakReference.Call(*_env,
|
||||
onDidFinishRenderingFrame,
|
||||
(jboolean)(status.mode != MapObserver::RenderMode::Partial),
|
||||
(jdouble)status.frameEncodingTime,
|
||||
(jdouble)status.frameRenderingTime);
|
||||
renderingStats);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1272,6 +1278,16 @@ void NativeMapView::triggerRepaint(JNIEnv&) {
|
||||
map->triggerRepaint();
|
||||
}
|
||||
|
||||
jni::jboolean NativeMapView::isRenderingStatsViewEnabled(JNIEnv&) {
|
||||
assert(map);
|
||||
return jni::jboolean(map->isRenderingStatsViewEnabled());
|
||||
}
|
||||
|
||||
void NativeMapView::enableRenderingStatsView(JNIEnv&, jni::jboolean value) {
|
||||
assert(map);
|
||||
map->enableRenderingStatsView(value);
|
||||
}
|
||||
|
||||
// Static methods //
|
||||
|
||||
void NativeMapView::registerNative(jni::JNIEnv& env) {
|
||||
@@ -1384,7 +1400,9 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
|
||||
METHOD(&NativeMapView::getPrefetchZoomDelta, "nativeGetPrefetchZoomDelta"),
|
||||
METHOD(&NativeMapView::setTileCacheEnabled, "nativeSetTileCacheEnabled"),
|
||||
METHOD(&NativeMapView::getTileCacheEnabled, "nativeGetTileCacheEnabled"),
|
||||
METHOD(&NativeMapView::triggerRepaint, "nativeTriggerRepaint"));
|
||||
METHOD(&NativeMapView::triggerRepaint, "nativeTriggerRepaint"),
|
||||
METHOD(&NativeMapView::isRenderingStatsViewEnabled, "nativeIsRenderingStatsViewEnabled"),
|
||||
METHOD(&NativeMapView::enableRenderingStatsView, "nativeEnableRenderingStatsView"));
|
||||
}
|
||||
|
||||
void NativeMapView::onRegisterShaders(gfx::ShaderRegistry&) {};
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace android {
|
||||
class AndroidRendererFrontend;
|
||||
class FileSource;
|
||||
class MapRenderer;
|
||||
class RenderingStats;
|
||||
|
||||
class NativeMapView : public MapObserver {
|
||||
public:
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
void onDidFinishLoadingMap() override;
|
||||
void onDidFailLoadingMap(MapLoadError, const std::string&) override;
|
||||
void onWillStartRenderingFrame() override;
|
||||
void onDidFinishRenderingFrame(MapObserver::RenderFrameStatus) override;
|
||||
void onDidFinishRenderingFrame(const MapObserver::RenderFrameStatus&) override;
|
||||
void onWillStartRenderingMap() override;
|
||||
void onDidFinishRenderingMap(MapObserver::RenderMode) override;
|
||||
void onDidBecomeIdle() override;
|
||||
@@ -305,6 +306,9 @@ public:
|
||||
|
||||
void triggerRepaint(JNIEnv&);
|
||||
|
||||
jni::jboolean isRenderingStatsViewEnabled(JNIEnv&);
|
||||
void enableRenderingStatsView(JNIEnv&, jni::jboolean);
|
||||
|
||||
// Shader compilation
|
||||
void onRegisterShaders(mbgl::gfx::ShaderRegistry&) override;
|
||||
void onPreCompileShader(mbgl::shaders::BuiltIn, mbgl::gfx::Backend::Type, const std::string&) override;
|
||||
@@ -336,6 +340,8 @@ private:
|
||||
|
||||
float pixelRatio;
|
||||
|
||||
jni::Global<jni::Object<RenderingStats>> renderingStats;
|
||||
|
||||
// Minimum texture size according to OpenGL ES 2.0 specification.
|
||||
int width = 64;
|
||||
int height = 64;
|
||||
|
||||
61
platform/android/MapLibreAndroid/src/cpp/rendering_stats.cpp
Normal file
61
platform/android/MapLibreAndroid/src/cpp/rendering_stats.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "rendering_stats.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
void RenderingStats::registerNative(jni::JNIEnv& env) {
|
||||
jni::Class<RenderingStats>::Singleton(env);
|
||||
}
|
||||
|
||||
jni::Local<jni::Object<RenderingStats>> RenderingStats::Create(jni::JNIEnv& env) {
|
||||
auto& javaClass = jni::Class<RenderingStats>::Singleton(env);
|
||||
auto constructor = javaClass.GetConstructor(env);
|
||||
return javaClass.New(env, constructor);
|
||||
}
|
||||
|
||||
void RenderingStats::Update(jni::JNIEnv& env,
|
||||
jni::Object<RenderingStats>& javaObject,
|
||||
const gfx::RenderingStats& stats) {
|
||||
static auto& javaClass = jni::Class<RenderingStats>::Singleton(env);
|
||||
|
||||
#define SetField(name, type) \
|
||||
static auto name##Field = javaClass.GetField<type>(env, #name); \
|
||||
javaObject.Set(env, name##Field, static_cast<type>(stats.name));
|
||||
|
||||
SetField(encodingTime, jni::jdouble);
|
||||
SetField(renderingTime, jni::jdouble);
|
||||
SetField(numFrames, jni::jint);
|
||||
SetField(numDrawCalls, jni::jint);
|
||||
SetField(totalDrawCalls, jni::jint);
|
||||
SetField(numCreatedTextures, jni::jint);
|
||||
SetField(numActiveTextures, jni::jint);
|
||||
SetField(numTextureBindings, jni::jint);
|
||||
SetField(numTextureUpdates, jni::jint);
|
||||
SetField(textureUpdateBytes, jni::jlong);
|
||||
SetField(totalBuffers, jni::jlong);
|
||||
SetField(totalBufferObjs, jni::jlong);
|
||||
SetField(bufferUpdates, jni::jlong);
|
||||
SetField(bufferObjUpdates, jni::jlong);
|
||||
SetField(bufferUpdateBytes, jni::jlong);
|
||||
SetField(numBuffers, jni::jint);
|
||||
SetField(numFrameBuffers, jni::jint);
|
||||
SetField(numIndexBuffers, jni::jint);
|
||||
SetField(indexUpdateBytes, jni::jlong);
|
||||
SetField(numVertexBuffers, jni::jint);
|
||||
SetField(vertexUpdateBytes, jni::jlong);
|
||||
SetField(numUniformBuffers, jni::jint);
|
||||
SetField(numUniformUpdates, jni::jint);
|
||||
SetField(uniformUpdateBytes, jni::jlong);
|
||||
SetField(memTextures, jni::jint);
|
||||
SetField(memBuffers, jni::jint);
|
||||
SetField(memIndexBuffers, jni::jint);
|
||||
SetField(memVertexBuffers, jni::jint);
|
||||
SetField(memUniformBuffers, jni::jint);
|
||||
SetField(stencilClears, jni::jint);
|
||||
SetField(stencilUpdates, jni::jint);
|
||||
|
||||
#undef SetField
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
22
platform/android/MapLibreAndroid/src/cpp/rendering_stats.hpp
Normal file
22
platform/android/MapLibreAndroid/src/cpp/rendering_stats.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/rendering_stats.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <jni.h>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class RenderingStats {
|
||||
public:
|
||||
static constexpr auto Name() { return "org/maplibre/android/maps/RenderingStats"; };
|
||||
static void registerNative(jni::JNIEnv& env);
|
||||
|
||||
static jni::Local<jni::Object<RenderingStats>> Create(jni::JNIEnv&);
|
||||
static void Update(jni::JNIEnv&, jni::Object<RenderingStats>&, const gfx::RenderingStats&);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -249,6 +249,11 @@ jni::Local<jni::Object<>> SymbolLayer::getTextOptional(jni::JNIEnv& env) {
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getTextOptional()));
|
||||
}
|
||||
|
||||
jni::Local<jni::Object<>> SymbolLayer::getSymbolScreenSpace(jni::JNIEnv& env) {
|
||||
using namespace mbgl::android::conversion;
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getSymbolScreenSpace()));
|
||||
}
|
||||
|
||||
jni::Local<jni::Object<>> SymbolLayer::getIconOpacity(jni::JNIEnv& env) {
|
||||
using namespace mbgl::android::conversion;
|
||||
return std::move(*convert<jni::Local<jni::Object<>>>(env, toSymbolLayer(layer).getIconOpacity()));
|
||||
@@ -557,6 +562,7 @@ void SymbolJavaLayerPeerFactory::registerNative(jni::JNIEnv& env) {
|
||||
METHOD(&SymbolLayer::getTextAllowOverlap, "nativeGetTextAllowOverlap"),
|
||||
METHOD(&SymbolLayer::getTextIgnorePlacement, "nativeGetTextIgnorePlacement"),
|
||||
METHOD(&SymbolLayer::getTextOptional, "nativeGetTextOptional"),
|
||||
METHOD(&SymbolLayer::getSymbolScreenSpace, "nativeGetSymbolScreenSpace"),
|
||||
METHOD(&SymbolLayer::getIconOpacityTransition, "nativeGetIconOpacityTransition"),
|
||||
METHOD(&SymbolLayer::setIconOpacityTransition, "nativeSetIconOpacityTransition"),
|
||||
METHOD(&SymbolLayer::getIconOpacity, "nativeGetIconOpacity"),
|
||||
|
||||
@@ -110,6 +110,8 @@ public:
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getTextOptional(jni::JNIEnv&);
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getSymbolScreenSpace(jni::JNIEnv&);
|
||||
|
||||
jni::Local<jni::Object<jni::ObjectTag>> getIconOpacity(jni::JNIEnv&);
|
||||
void setIconOpacityTransition(jni::JNIEnv&, jlong duration, jlong delay);
|
||||
jni::Local<jni::Object<TransitionOptions>> getIconOpacityTransition(jni::JNIEnv&);
|
||||
|
||||
Reference in New Issue
Block a user