Rendering statistics view (#3322)
Co-authored-by: Bart Louwers <bart@emeel.net>
This commit is contained in:
@@ -23,6 +23,8 @@ class MapChangeReceiver implements NativeMapView.StateCallback {
|
||||
= new CopyOnWriteArrayList<>();
|
||||
private final List<MapView.OnDidFinishRenderingFrameListener> onDidFinishRenderingFrameList
|
||||
= new CopyOnWriteArrayList<>();
|
||||
private final List<MapView.OnDidFinishRenderingFrameWithStatsListener> onDidFinishRenderingFrameWithStatsList
|
||||
= new CopyOnWriteArrayList<>();
|
||||
private final List<MapView.OnWillStartRenderingMapListener> onWillStartRenderingMapListenerList
|
||||
= new CopyOnWriteArrayList<>();
|
||||
private final List<MapView.OnDidFinishRenderingMapListener> onDidFinishRenderingMapListenerList
|
||||
@@ -156,11 +158,17 @@ class MapChangeReceiver implements NativeMapView.StateCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) {
|
||||
public void onDidFinishRenderingFrame(boolean fully, RenderingStats stats) {
|
||||
try {
|
||||
if (!onDidFinishRenderingFrameList.isEmpty()) {
|
||||
for (MapView.OnDidFinishRenderingFrameListener listener : onDidFinishRenderingFrameList) {
|
||||
listener.onDidFinishRenderingFrame(fully, frameEncodingTime, frameRenderingTime);
|
||||
listener.onDidFinishRenderingFrame(fully, stats.encodingTime, stats.renderingTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (!onDidFinishRenderingFrameWithStatsList.isEmpty()) {
|
||||
for (MapView.OnDidFinishRenderingFrameWithStatsListener listener : onDidFinishRenderingFrameWithStatsList) {
|
||||
listener.onDidFinishRenderingFrame(fully, stats);
|
||||
}
|
||||
}
|
||||
} catch (Throwable err) {
|
||||
@@ -480,6 +488,14 @@ class MapChangeReceiver implements NativeMapView.StateCallback {
|
||||
onDidFinishRenderingFrameList.remove(listener);
|
||||
}
|
||||
|
||||
void addOnDidFinishRenderingFrameListener(MapView.OnDidFinishRenderingFrameWithStatsListener listener) {
|
||||
onDidFinishRenderingFrameWithStatsList.add(listener);
|
||||
}
|
||||
|
||||
void removeOnDidFinishRenderingFrameListener(MapView.OnDidFinishRenderingFrameWithStatsListener listener) {
|
||||
onDidFinishRenderingFrameWithStatsList.remove(listener);
|
||||
}
|
||||
|
||||
void addOnWillStartRenderingMapListener(MapView.OnWillStartRenderingMapListener listener) {
|
||||
onWillStartRenderingMapListenerList.add(listener);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,20 @@ public final class MapLibreMap {
|
||||
nativeMapView.triggerRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query rendering statistics overlay status.
|
||||
*/
|
||||
public boolean isRenderingStatsViewEnabled() {
|
||||
return nativeMapView.isRenderingStatsViewEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rendering statistics overlay with {@link RenderingStats} values.
|
||||
*/
|
||||
public void enableRenderingStatsView(boolean value) {
|
||||
nativeMapView.enableRenderingStatsView(value);
|
||||
}
|
||||
|
||||
public void setSwapBehaviorFlush(boolean flush) {
|
||||
nativeMapView.setSwapBehaviorFlush(flush);
|
||||
}
|
||||
|
||||
@@ -763,6 +763,24 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
mapChangeReceiver.removeOnDidFinishRenderingFrameListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that's invoked when the map has finished rendering a frame.
|
||||
*
|
||||
* @param listener The callback that's invoked when the map has finished rendering a frame
|
||||
*/
|
||||
public void addOnDidFinishRenderingFrameListener(@NonNull OnDidFinishRenderingFrameWithStatsListener listener) {
|
||||
mapChangeReceiver.addOnDidFinishRenderingFrameListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that's invoked when the map has finished rendering a frame.
|
||||
*
|
||||
* @param listener The callback that's invoked when the map has finished rendering a frame
|
||||
*/
|
||||
public void removeOnDidFinishRenderingFrameListener(@NonNull OnDidFinishRenderingFrameWithStatsListener listener) {
|
||||
mapChangeReceiver.removeOnDidFinishRenderingFrameListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback that's invoked when the map will start rendering.
|
||||
*
|
||||
@@ -1182,14 +1200,34 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
* </p>
|
||||
*/
|
||||
public interface OnDidFinishRenderingFrameListener {
|
||||
|
||||
/**
|
||||
* Called when the map has finished rendering a frame
|
||||
*
|
||||
* @param fully true if all frames have been rendered, false if partially rendered
|
||||
* @param frameEncodingTime CPU encoding time
|
||||
* @param frameRenderingTime CPU rendering time
|
||||
*/
|
||||
void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when the map finished rendering a frame.
|
||||
* <p>
|
||||
* {@link MapView#addOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener)}
|
||||
* </p>
|
||||
*/
|
||||
public interface OnDidFinishRenderingFrameWithStatsListener {
|
||||
|
||||
/**
|
||||
* Called when the map has finished rendering a frame
|
||||
*
|
||||
* @param fully true if all frames have been rendered, false if partially rendered
|
||||
* @param stats rendering statistics
|
||||
*/
|
||||
void onDidFinishRenderingFrame(boolean fully, RenderingStats stats);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when the map will start rendering the map.
|
||||
* <p>
|
||||
@@ -1528,7 +1566,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
* The initial render callback waits for rendering to happen before making the map visible for end-users.
|
||||
* We wait for the second DID_FINISH_RENDERING_FRAME map change event as the first will still show a black surface.
|
||||
*/
|
||||
private class InitialRenderCallback implements OnDidFinishRenderingFrameListener {
|
||||
private class InitialRenderCallback implements OnDidFinishRenderingFrameWithStatsListener {
|
||||
|
||||
private int renderCount;
|
||||
|
||||
@@ -1537,7 +1575,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) {
|
||||
public void onDidFinishRenderingFrame(boolean fully, RenderingStats stats) {
|
||||
if (maplibreMap != null && maplibreMap.getStyle() != null && maplibreMap.getStyle().isFullyLoaded()) {
|
||||
renderCount++;
|
||||
if (renderCount == 3) {
|
||||
@@ -1643,7 +1681,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
}
|
||||
|
||||
private class MapCallback implements OnDidFinishLoadingStyleListener,
|
||||
OnDidFinishRenderingFrameListener, OnDidFinishLoadingMapListener,
|
||||
OnDidFinishRenderingFrameWithStatsListener, OnDidFinishLoadingMapListener,
|
||||
OnCameraIsChangingListener, OnCameraDidChangeListener, OnDidFailLoadingMapListener {
|
||||
|
||||
private final List<OnMapReadyCallback> onMapReadyCallbackList = new ArrayList<>();
|
||||
@@ -1709,7 +1747,7 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) {
|
||||
public void onDidFinishRenderingFrame(boolean fully, RenderingStats stats) {
|
||||
if (maplibreMap != null) {
|
||||
maplibreMap.onUpdateFullyRendered();
|
||||
}
|
||||
|
||||
@@ -250,6 +250,10 @@ interface NativeMap {
|
||||
|
||||
void triggerRepaint();
|
||||
|
||||
boolean isRenderingStatsViewEnabled();
|
||||
|
||||
void enableRenderingStatsView(boolean value);
|
||||
|
||||
void setSwapBehaviorFlush(boolean flush);
|
||||
|
||||
//
|
||||
|
||||
@@ -1075,6 +1075,16 @@ final class NativeMapView implements NativeMap {
|
||||
nativeTriggerRepaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRenderingStatsViewEnabled() {
|
||||
return nativeIsRenderingStatsViewEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableRenderingStatsView(boolean value) {
|
||||
nativeEnableRenderingStatsView(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSwapBehaviorFlush(boolean flush) {
|
||||
mapRenderer.setSwapBehaviorFlush(flush);
|
||||
@@ -1145,9 +1155,9 @@ final class NativeMapView implements NativeMap {
|
||||
}
|
||||
|
||||
@Keep
|
||||
private void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime) {
|
||||
private void onDidFinishRenderingFrame(boolean fully, RenderingStats stats) {
|
||||
if (stateCallback != null) {
|
||||
stateCallback.onDidFinishRenderingFrame(fully, frameEncodingTime, frameRenderingTime);
|
||||
stateCallback.onDidFinishRenderingFrame(fully, stats);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1642,6 +1652,12 @@ final class NativeMapView implements NativeMap {
|
||||
@Keep
|
||||
private native void nativeTriggerRepaint();
|
||||
|
||||
@Keep
|
||||
private native boolean nativeIsRenderingStatsViewEnabled();
|
||||
|
||||
@Keep
|
||||
private native void nativeEnableRenderingStatsView(boolean enabled);
|
||||
|
||||
//
|
||||
// Snapshot
|
||||
//
|
||||
@@ -1719,7 +1735,7 @@ final class NativeMapView implements NativeMap {
|
||||
|
||||
void onWillStartRenderingFrame();
|
||||
|
||||
void onDidFinishRenderingFrame(boolean fully, double frameEncodingTime, double frameRenderingTime);
|
||||
void onDidFinishRenderingFrame(boolean fully, RenderingStats stats);
|
||||
|
||||
void onWillStartRenderingMap();
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.maplibre.android.maps;
|
||||
|
||||
public class RenderingStats {
|
||||
/// Frame CPU encoding time (milliseconds)
|
||||
public double encodingTime = 0.0;
|
||||
/// Frame CPU rendering time (milliseconds)
|
||||
public double renderingTime = 0.0;
|
||||
|
||||
/// Number of frames rendered
|
||||
public int numFrames = 0;
|
||||
/// Number of draw calls (`glDrawElements`, `drawIndexedPrimitives`, etc.) executed during the most recent frame
|
||||
public int numDrawCalls = 0;
|
||||
/// Total number of draw calls executed during all the frames
|
||||
public int totalDrawCalls = 0;
|
||||
|
||||
/// Total number of textures created
|
||||
public int numCreatedTextures = 0;
|
||||
/// Net textures
|
||||
public int numActiveTextures = 0;
|
||||
/// Net texture bindings
|
||||
public int numTextureBindings = 0;
|
||||
/// Number of times a texture was updated
|
||||
public int numTextureUpdates = 0;
|
||||
/// Number of bytes used in texture updates
|
||||
public long textureUpdateBytes = 0;
|
||||
|
||||
/// Number of buffers created
|
||||
public long totalBuffers = 0;
|
||||
/// Number of SDK-specific buffers created
|
||||
public long totalBufferObjs = 0;
|
||||
/// Number of times a buffer is updated
|
||||
public long bufferUpdates = 0;
|
||||
/// Number of times an SDK-specific buffer is updated
|
||||
public long bufferObjUpdates = 0;
|
||||
/// Sum of update sizes
|
||||
public long bufferUpdateBytes = 0;
|
||||
|
||||
/// Number of active buffers
|
||||
public int numBuffers = 0;
|
||||
/// Number of active offscreen frame buffers
|
||||
public int numFrameBuffers = 0;
|
||||
|
||||
/// Number of active index buffers
|
||||
public int numIndexBuffers = 0;
|
||||
/// Sum of index buffers update sizes
|
||||
public long indexUpdateBytes = 0;
|
||||
|
||||
/// Number of active vertex buffers
|
||||
public int numVertexBuffers = 0;
|
||||
/// Sum of vertex buffers update sizes
|
||||
public long vertexUpdateBytes = 0;
|
||||
|
||||
/// Number of active uniform buffers
|
||||
public int numUniformBuffers = 0;
|
||||
/// Number of times a uniform buffer is updated
|
||||
public int numUniformUpdates = 0;
|
||||
/// Sum of uniform buffers update sizes
|
||||
public long uniformUpdateBytes = 0;
|
||||
|
||||
/// Total texture memory
|
||||
public int memTextures = 0;
|
||||
/// Total buffer memory
|
||||
public int memBuffers = 0;
|
||||
/// Total index buffer memory
|
||||
public int memIndexBuffers = 0;
|
||||
/// Total vertex buffer memory
|
||||
public int memVertexBuffers = 0;
|
||||
/// Total uniform buffer memory
|
||||
public int memUniformBuffers = 0;
|
||||
|
||||
/// Number of stencil buffer clears
|
||||
public int stencilClears = 0;
|
||||
/// Number of stencil buffer updates
|
||||
public int stencilUpdates = 0;
|
||||
}
|
||||
@@ -2651,6 +2651,26 @@ The unit is in density-independent pixels only for SDF sprites that were created
|
||||
return new LayoutPropertyValue<>("text-optional", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only
|
||||
*
|
||||
* @param value a Boolean value
|
||||
* @return property wrapper around Boolean
|
||||
*/
|
||||
public static PropertyValue<Boolean> symbolScreenSpace(Boolean value) {
|
||||
return new LayoutPropertyValue<>("symbol-screen-space", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal use only
|
||||
*
|
||||
* @param value a Boolean value
|
||||
* @return property wrapper around Boolean
|
||||
*/
|
||||
public static PropertyValue<Expression> symbolScreenSpace(Expression value) {
|
||||
return new LayoutPropertyValue<>("symbol-screen-space", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.
|
||||
*
|
||||
|
||||
@@ -649,6 +649,18 @@ public class SymbolLayer extends Layer {
|
||||
return (PropertyValue<Boolean>) new PropertyValue("text-optional", nativeGetTextOptional());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SymbolScreenSpace property
|
||||
*
|
||||
* @return property wrapper value around Boolean
|
||||
*/
|
||||
@NonNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public PropertyValue<Boolean> getSymbolScreenSpace() {
|
||||
checkThread();
|
||||
return (PropertyValue<Boolean>) new PropertyValue("symbol-screen-space", nativeGetSymbolScreenSpace());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IconOpacity property
|
||||
*
|
||||
@@ -1305,6 +1317,10 @@ public class SymbolLayer extends Layer {
|
||||
@Keep
|
||||
private native Object nativeGetTextOptional();
|
||||
|
||||
@NonNull
|
||||
@Keep
|
||||
private native Object nativeGetSymbolScreenSpace();
|
||||
|
||||
@NonNull
|
||||
@Keep
|
||||
private native Object nativeGetIconOpacity();
|
||||
|
||||
Reference in New Issue
Block a user