feat: add STEP-093 runtime validation tooling
This commit is contained in:
@@ -729,7 +729,7 @@ jni::jboolean NativeMapView::setContinuousLayerRange(JNIEnv& env,
|
||||
|
||||
jni::Local<jni::Array<jni::String>> NativeMapView::getRetainedUnderlayDiagnostics(JNIEnv& env) {
|
||||
const auto snapshot = map->getRetainedUnderlayDiagnostics();
|
||||
const std::array<std::string, 20> values = {
|
||||
const std::array<std::string, 39> values = {
|
||||
snapshot.enabled ? "true" : "false",
|
||||
std::to_string(snapshot.build),
|
||||
std::to_string(snapshot.reuse),
|
||||
@@ -742,14 +742,33 @@ jni::Local<jni::Array<jni::String>> NativeMapView::getRetainedUnderlayDiagnostic
|
||||
snapshot.endLayerId,
|
||||
std::to_string(snapshot.startIndex),
|
||||
std::to_string(snapshot.endIndex),
|
||||
std::to_string(snapshot.continuousBegin),
|
||||
std::to_string(snapshot.continuousEndExclusive),
|
||||
snapshot.bottomPresent ? "true" : "false",
|
||||
snapshot.bottomCacheState,
|
||||
std::to_string(snapshot.bottomBuild),
|
||||
std::to_string(snapshot.bottomReuse),
|
||||
std::to_string(snapshot.bottomInvalidation),
|
||||
snapshot.bottomLastInvalidationReason,
|
||||
std::to_string(snapshot.bottomTextureCreate),
|
||||
std::to_string(snapshot.bottomCompositeCreate),
|
||||
std::to_string(snapshot.bottomResourceRelease),
|
||||
snapshot.topPresent ? "true" : "false",
|
||||
snapshot.topCacheState,
|
||||
std::to_string(snapshot.topBuild),
|
||||
std::to_string(snapshot.topReuse),
|
||||
std::to_string(snapshot.topInvalidation),
|
||||
snapshot.topLastInvalidationReason,
|
||||
std::to_string(snapshot.topTextureCreate),
|
||||
std::to_string(snapshot.topCompositeCreate),
|
||||
std::to_string(snapshot.topResourceRelease),
|
||||
snapshot.rangeFallback ? "true" : "false",
|
||||
snapshot.fastPathEligible ? "true" : "false",
|
||||
snapshot.fastPathActive ? "true" : "false",
|
||||
snapshot.fastPathFallbackReason,
|
||||
std::to_string(snapshot.fastPathHit),
|
||||
std::to_string(snapshot.fastPathMiss),
|
||||
std::to_string(snapshot.fullCpuFrame),
|
||||
};
|
||||
auto result = jni::Array<jni::String>::New(env, values.size());
|
||||
for (std::size_t index = 0; index < values.size(); ++index) {
|
||||
|
||||
@@ -18,18 +18,37 @@ public final class RetainedUnderlayDiagnostics {
|
||||
@NonNull public final String endLayerId;
|
||||
public final int startIndex;
|
||||
public final int endIndex;
|
||||
public final int continuousBegin;
|
||||
public final int continuousEndExclusive;
|
||||
public final boolean bottomPresent;
|
||||
@NonNull public final String bottomCacheState;
|
||||
public final long bottomBuild;
|
||||
public final long bottomReuse;
|
||||
public final long bottomInvalidation;
|
||||
@NonNull public final String bottomLastInvalidationReason;
|
||||
public final long bottomTextureCreate;
|
||||
public final long bottomCompositeCreate;
|
||||
public final long bottomResourceRelease;
|
||||
public final boolean topPresent;
|
||||
@NonNull public final String topCacheState;
|
||||
public final long topBuild;
|
||||
public final long topReuse;
|
||||
public final long topInvalidation;
|
||||
@NonNull public final String topLastInvalidationReason;
|
||||
public final long topTextureCreate;
|
||||
public final long topCompositeCreate;
|
||||
public final long topResourceRelease;
|
||||
public final boolean rangeFallback;
|
||||
public final boolean fastPathEligible;
|
||||
public final boolean fastPathActive;
|
||||
@NonNull public final String fastPathFallbackReason;
|
||||
public final long fastPathHit;
|
||||
public final long fastPathMiss;
|
||||
public final long fullCpuFrame;
|
||||
|
||||
RetainedUnderlayDiagnostics(@NonNull String[] values) {
|
||||
if (values.length != 20) {
|
||||
throw new IllegalArgumentException("Retained-range diagnostics require 20 values");
|
||||
if (values.length != 39) {
|
||||
throw new IllegalArgumentException("Retained-range diagnostics require 39 values");
|
||||
}
|
||||
enabled = Boolean.parseBoolean(values[0]);
|
||||
build = Long.parseLong(values[1]);
|
||||
@@ -43,20 +62,41 @@ public final class RetainedUnderlayDiagnostics {
|
||||
endLayerId = values[9];
|
||||
startIndex = Integer.parseInt(values[10]);
|
||||
endIndex = Integer.parseInt(values[11]);
|
||||
bottomPresent = Boolean.parseBoolean(values[12]);
|
||||
bottomBuild = Long.parseLong(values[13]);
|
||||
bottomReuse = Long.parseLong(values[14]);
|
||||
bottomInvalidation = Long.parseLong(values[15]);
|
||||
topPresent = Boolean.parseBoolean(values[16]);
|
||||
topBuild = Long.parseLong(values[17]);
|
||||
topReuse = Long.parseLong(values[18]);
|
||||
topInvalidation = Long.parseLong(values[19]);
|
||||
continuousBegin = Integer.parseInt(values[12]);
|
||||
continuousEndExclusive = Integer.parseInt(values[13]);
|
||||
bottomPresent = Boolean.parseBoolean(values[14]);
|
||||
bottomCacheState = values[15];
|
||||
bottomBuild = Long.parseLong(values[16]);
|
||||
bottomReuse = Long.parseLong(values[17]);
|
||||
bottomInvalidation = Long.parseLong(values[18]);
|
||||
bottomLastInvalidationReason = values[19];
|
||||
bottomTextureCreate = Long.parseLong(values[20]);
|
||||
bottomCompositeCreate = Long.parseLong(values[21]);
|
||||
bottomResourceRelease = Long.parseLong(values[22]);
|
||||
topPresent = Boolean.parseBoolean(values[23]);
|
||||
topCacheState = values[24];
|
||||
topBuild = Long.parseLong(values[25]);
|
||||
topReuse = Long.parseLong(values[26]);
|
||||
topInvalidation = Long.parseLong(values[27]);
|
||||
topLastInvalidationReason = values[28];
|
||||
topTextureCreate = Long.parseLong(values[29]);
|
||||
topCompositeCreate = Long.parseLong(values[30]);
|
||||
topResourceRelease = Long.parseLong(values[31]);
|
||||
rangeFallback = Boolean.parseBoolean(values[32]);
|
||||
fastPathEligible = Boolean.parseBoolean(values[33]);
|
||||
fastPathActive = Boolean.parseBoolean(values[34]);
|
||||
fastPathFallbackReason = values[35];
|
||||
fastPathHit = Long.parseLong(values[36]);
|
||||
fastPathMiss = Long.parseLong(values[37]);
|
||||
fullCpuFrame = Long.parseLong(values[38]);
|
||||
}
|
||||
|
||||
static RetainedUnderlayDiagnostics unavailable() {
|
||||
return new RetainedUnderlayDiagnostics(new String[] {
|
||||
"true", "0", "0", "0", "0", "unavailable", "false", "false", "", "", "-1", "-1",
|
||||
"false", "0", "0", "0", "false", "0", "0", "0"
|
||||
"-1", "-1", "false", "disabled", "0", "0", "0", "none", "0", "0", "0",
|
||||
"false", "disabled", "0", "0", "0", "none", "0", "0", "0", "false", "false",
|
||||
"false", "no-prepared-tree", "0", "0", "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +288,7 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.particle.ParticleCoreLayerValidationActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:description="@string/description_particle_core_layer_validation"
|
||||
android:exported="true"
|
||||
android:label="@string/activity_particle_core_layer_validation">
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.maplibre.android.testapp.activity.particle
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.InputType
|
||||
import android.util.Log
|
||||
import android.widget.Button
|
||||
@@ -28,6 +30,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
private lateinit var mapView: MapView
|
||||
private lateinit var maplibreMap: MapLibreMap
|
||||
private lateinit var status: TextView
|
||||
private lateinit var diagnostics: TextView
|
||||
private var active = true
|
||||
private var enabled = true
|
||||
private var maskMode = MASK_GLOBAL
|
||||
@@ -51,6 +54,21 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
private var navSeaPbfRenderEnabled = true
|
||||
private var navSeaPbfLayerVisibility = emptyList<NavSeaPbfLayerVisibility>()
|
||||
private var retainedCacheEnabled = true
|
||||
private var step093Mode = false
|
||||
private var step093Topology = Step093Topology.BOTTOM_CONTINUOUS_TOP
|
||||
private var step093Variant = Step093Variant.DEFAULT
|
||||
private var step093StartVisible = true
|
||||
private var step093EndVisible = true
|
||||
private var step093CameraPreset = 0
|
||||
private val step093Handler = Handler(Looper.getMainLooper())
|
||||
private val step093DiagnosticsPoll = object : Runnable {
|
||||
override fun run() {
|
||||
if (step093Mode && this@ParticleCoreLayerValidationActivity::maplibreMap.isInitialized) {
|
||||
refreshStep093Diagnostics(log = false)
|
||||
step093Handler.postDelayed(this, STEP093_DIAGNOSTICS_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
}
|
||||
private var realWeatherTuningMenu: PopupMenu? = null
|
||||
private var realWeatherMenuAnchor: android.view.View? = null
|
||||
private var openRealWeatherTuningAfterStyle = false
|
||||
@@ -88,6 +106,13 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
?: NavSeaPbfPosition.AFTER_CLIP
|
||||
navSeaPbfRenderEnabled = savedInstanceState?.getBoolean(STATE_NAVSEA_PBF_RENDER_ENABLED, true) ?: true
|
||||
retainedCacheEnabled = savedInstanceState?.getBoolean(STATE_RETAINED_CACHE_ENABLED, true) ?: true
|
||||
step093Mode = savedInstanceState?.getBoolean(STATE_STEP093_MODE, false) ?: false
|
||||
step093Topology = savedInstanceState?.getString(STATE_STEP093_TOPOLOGY)
|
||||
?.let { value -> Step093Topology.values().firstOrNull { it.name == value } }
|
||||
?: Step093Topology.BOTTOM_CONTINUOUS_TOP
|
||||
step093Variant = savedInstanceState?.getString(STATE_STEP093_VARIANT)
|
||||
?.let { value -> Step093Variant.values().firstOrNull { it.name == value } }
|
||||
?: Step093Variant.DEFAULT
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.i(
|
||||
TAG,
|
||||
@@ -98,6 +123,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
|
||||
mapView = findViewById(R.id.mapView)
|
||||
status = findViewById(R.id.validationStatus)
|
||||
diagnostics = findViewById(R.id.validationDiagnostics)
|
||||
mapView.addOnDidFailLoadingMapListener { errorMessage ->
|
||||
if (navSeaPbfMode || purePbfMode) {
|
||||
Log.e(TAG, "NAVSEA_PBF_STYLE_ERROR reason=$errorMessage")
|
||||
@@ -119,7 +145,8 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
updateNavSeaPbfButtonState()
|
||||
updatePbfModeButtonState()
|
||||
updateRetainedCacheButtonState()
|
||||
loadValidationStyle(active = active, enabled = enabled, reason = "INITIAL")
|
||||
if (step093Mode) loadStep093Style(configureBeforeStyle = false)
|
||||
else loadValidationStyle(active = active, enabled = enabled, reason = "INITIAL")
|
||||
}
|
||||
|
||||
findViewById<Button>(R.id.validationActive).setOnClickListener {
|
||||
@@ -251,6 +278,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
findViewById<Button>(R.id.validationMenuNavSeaPbf).setOnClickListener { showNavSeaPbfMenu(it) }
|
||||
findViewById<Button>(R.id.validationMenuPbfMode).setOnClickListener { showPbfModeMenu(it) }
|
||||
findViewById<Button>(R.id.validationMenuRetainedCache).setOnClickListener { showRetainedCacheMenu(it) }
|
||||
findViewById<Button>(R.id.validationMenuStep093).setOnClickListener { showStep093Menu(it) }
|
||||
findViewById<Button>(R.id.validationMenuMore).setOnClickListener { dismissRealWeatherTuning(); showMenu(it, "MORE", intArrayOf(R.id.validationActive, R.id.validationStatic, R.id.validationDisable, R.id.validationEnable, R.id.validationUniformEast, R.id.validationUniformNorth, R.id.validationVortex, R.id.validationTimeWindow, R.id.validationHostFieldSubmit, R.id.validationProductionInvalid, R.id.validationHostFieldDuplicate, R.id.validationHostFieldInvalid, R.id.validationAdvanceWindow, R.id.validationDuplicateWindow)) }
|
||||
}
|
||||
|
||||
@@ -264,8 +292,32 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
TOP("TOP")
|
||||
}
|
||||
|
||||
private enum class Step093Topology(val label: String, val bottom: Boolean, val top: Boolean) {
|
||||
BOTTOM_CONTINUOUS_TOP("A BOTTOM + CONTINUOUS + TOP", true, true),
|
||||
BOTTOM_CONTINUOUS("B BOTTOM + CONTINUOUS", true, false),
|
||||
CONTINUOUS_TOP("C CONTINUOUS + TOP", false, true),
|
||||
CONTINUOUS_ONLY("D CONTINUOUS ONLY", false, false),
|
||||
SINGLE_LAYER("E SINGLE-LAYER CONTINUOUS", true, true)
|
||||
}
|
||||
|
||||
private enum class Step093Variant {
|
||||
DEFAULT,
|
||||
CONTINUOUS_ADD,
|
||||
CONTINUOUS_REORDER,
|
||||
BOTTOM_ADD,
|
||||
BOTTOM_REORDER,
|
||||
TOP_ADD,
|
||||
TOP_REORDER,
|
||||
CROSS_BOTTOM,
|
||||
CROSS_CONTINUOUS,
|
||||
CROSS_TOP,
|
||||
START_MISSING,
|
||||
END_MISSING,
|
||||
FAST_PATH_FAIL_CLOSED
|
||||
}
|
||||
|
||||
private fun activateRealWeather(anchor: android.view.View?) {
|
||||
if (isPbfMatrixMode()) leaveRealWeatherMode()
|
||||
if (isPbfMatrixMode() || step093Mode) leaveRealWeatherMode()
|
||||
realWeatherMenuAnchor = anchor ?: findViewById(R.id.validationMenuRealWeather)
|
||||
if (realWeatherMode) {
|
||||
if (realWeatherTuningMenu == null) showRealWeatherTuning(realWeatherMenuAnchor!!) else dismissRealWeatherTuning()
|
||||
@@ -296,6 +348,8 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun leaveRealWeatherMode() {
|
||||
step093Mode = false
|
||||
step093Handler.removeCallbacks(step093DiagnosticsPoll)
|
||||
dismissRealWeatherTuning()
|
||||
weatherRuntime?.dispose()
|
||||
weatherRuntime = null
|
||||
@@ -381,6 +435,233 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun showStep093Menu(anchor: android.view.View) {
|
||||
PopupMenu(this, anchor).apply {
|
||||
Step093Topology.values().forEachIndexed { index, topology ->
|
||||
menu.add(0, index, index, topology.label)
|
||||
}
|
||||
menu.add(0, 10, 10, "MUTATION / FAST PATH")
|
||||
menu.add(0, 11, 11, "ENDPOINT / VISIBILITY")
|
||||
menu.add(0, 12, 12, "INVALID RANGE")
|
||||
menu.add(0, 13, 13, "CAMERA NEXT")
|
||||
menu.add(0, 14, 14, "READ DIAGNOSTICS")
|
||||
menu.add(0, 15, 15, "RESET DEFAULT A")
|
||||
setOnMenuItemClickListener { item ->
|
||||
when (item.itemId) {
|
||||
in Step093Topology.values().indices -> applyStep093Scene(Step093Topology.values()[item.itemId])
|
||||
10 -> showStep093MutationMenu(anchor)
|
||||
11 -> showStep093EndpointMenu(anchor)
|
||||
12 -> showStep093InvalidMenu(anchor)
|
||||
13 -> applyStep093CameraPreset()
|
||||
14 -> refreshStep093Diagnostics(log = true)
|
||||
15 -> applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP)
|
||||
}
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStep093MutationMenu(anchor: android.view.View) {
|
||||
val actions = arrayOf(
|
||||
"CONTINUOUS ADD", "CONTINUOUS REORDER", "BOTTOM ADD", "BOTTOM REORDER",
|
||||
"TOP ADD", "TOP REORDER", "CROSS → BOTTOM", "CROSS → CONTINUOUS",
|
||||
"CROSS → TOP", "FAST FAIL-CLOSED", "RESTORE DEFAULT"
|
||||
)
|
||||
PopupMenu(this, anchor).apply {
|
||||
actions.forEachIndexed { index, label -> menu.add(0, index, index, label) }
|
||||
setOnMenuItemClickListener { item ->
|
||||
val variant = when (item.itemId) {
|
||||
0 -> Step093Variant.CONTINUOUS_ADD
|
||||
1 -> Step093Variant.CONTINUOUS_REORDER
|
||||
2 -> Step093Variant.BOTTOM_ADD
|
||||
3 -> Step093Variant.BOTTOM_REORDER
|
||||
4 -> Step093Variant.TOP_ADD
|
||||
5 -> Step093Variant.TOP_REORDER
|
||||
6 -> Step093Variant.CROSS_BOTTOM
|
||||
7 -> Step093Variant.CROSS_CONTINUOUS
|
||||
8 -> Step093Variant.CROSS_TOP
|
||||
9 -> Step093Variant.FAST_PATH_FAIL_CLOSED
|
||||
else -> Step093Variant.DEFAULT
|
||||
}
|
||||
applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP, variant)
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStep093EndpointMenu(anchor: android.view.View) {
|
||||
val actions = arrayOf(
|
||||
"START VISIBLE ↔ HIDDEN", "END VISIBLE ↔ HIDDEN", "DELETE START", "RESTORE START",
|
||||
"DELETE END", "RESTORE END"
|
||||
)
|
||||
PopupMenu(this, anchor).apply {
|
||||
actions.forEachIndexed { index, label -> menu.add(0, index, index, label) }
|
||||
setOnMenuItemClickListener { item ->
|
||||
when (item.itemId) {
|
||||
0 -> toggleStep093Endpoint(start = true)
|
||||
1 -> toggleStep093Endpoint(start = false)
|
||||
2 -> applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP, Step093Variant.START_MISSING)
|
||||
3 -> applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP)
|
||||
4 -> applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP, Step093Variant.END_MISSING)
|
||||
5 -> applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP)
|
||||
}
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showStep093InvalidMenu(anchor: android.view.View) {
|
||||
val actions = arrayOf(
|
||||
"MISSING START", "MISSING END", "REVERSED", "CONFIGURE WHILE STYLE LOADING", "EMPTY ID", "RESTORE VALID"
|
||||
)
|
||||
PopupMenu(this, anchor).apply {
|
||||
actions.forEachIndexed { index, label -> menu.add(0, index, index, label) }
|
||||
setOnMenuItemClickListener { item ->
|
||||
if (!ensureStep093Scene()) {
|
||||
Log.i(TAG, "STEP093_ACTION scene initialized; repeat invalid-range action after READY")
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
when (item.itemId) {
|
||||
0 -> setStep093Range("step093-missing-start", STEP093_PARTICLE_LAYER_ID, "INVALID_MISSING_START")
|
||||
1 -> setStep093Range(STEP093_WEATHER_LAYER_ID, "step093-missing-end", "INVALID_MISSING_END")
|
||||
2 -> setStep093Range(STEP093_PARTICLE_LAYER_ID, STEP093_WEATHER_LAYER_ID, "INVALID_REVERSED")
|
||||
3 -> applyStep093Scene(
|
||||
Step093Topology.BOTTOM_CONTINUOUS_TOP,
|
||||
Step093Variant.DEFAULT,
|
||||
configureBeforeStyle = true
|
||||
)
|
||||
4 -> {
|
||||
val accepted = maplibreMap.setContinuousLayerRange("", STEP093_PARTICLE_LAYER_ID)
|
||||
Log.i(TAG, "STEP093_RANGE action=EMPTY_ID accepted=$accepted expected=false")
|
||||
refreshStep093Diagnostics(log = true)
|
||||
}
|
||||
5 -> setStep093Range(STEP093_WEATHER_LAYER_ID, STEP093_PARTICLE_LAYER_ID, "RESTORE_VALID")
|
||||
}
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureStep093Scene(): Boolean {
|
||||
if (step093Mode && styleReady) return true
|
||||
applyStep093Scene(Step093Topology.BOTTOM_CONTINUOUS_TOP)
|
||||
return false
|
||||
}
|
||||
|
||||
private fun applyStep093Scene(
|
||||
topology: Step093Topology,
|
||||
variant: Step093Variant = Step093Variant.DEFAULT,
|
||||
configureBeforeStyle: Boolean = false
|
||||
) {
|
||||
leaveRealWeatherMode()
|
||||
step093Mode = true
|
||||
step093Topology = topology
|
||||
step093Variant = variant
|
||||
step093StartVisible = true
|
||||
step093EndVisible = true
|
||||
timeWindowMode = true
|
||||
productionFeedMode = false
|
||||
hostSubmissionMode = true
|
||||
realWeatherMode = false
|
||||
pureParticleMode = false
|
||||
purePbfMode = false
|
||||
navSeaPbfMode = false
|
||||
active = true
|
||||
enabled = true
|
||||
retainedCacheEnabled = true
|
||||
maplibreMap.setRetainedUnderlayEnabled(true)
|
||||
updateRetainedCacheButtonState()
|
||||
loadStep093Style(configureBeforeStyle)
|
||||
}
|
||||
|
||||
private fun loadStep093Style(configureBeforeStyle: Boolean) {
|
||||
weatherRuntime?.dispose()
|
||||
weatherRuntime = null
|
||||
styleReady = false
|
||||
val epoch = ++styleLoadEpoch
|
||||
val range = step093Range()
|
||||
status.text = "STEP-093 · ${step093Topology.label} · ${step093Variant.name} · LOADING"
|
||||
maplibreMap.setStyle(Style.Builder().fromJson(step093StyleJson())) {
|
||||
if (!step093Mode || epoch != styleLoadEpoch) return@setStyle
|
||||
styleReady = true
|
||||
if (!configureBeforeStyle) maplibreMap.setContinuousLayerRange(range.first, range.second)
|
||||
submitHostValidationDataset()
|
||||
fitRealWeatherBounds()
|
||||
status.text = "STEP-093 · ${step093Topology.label} · ${step093Variant.name}"
|
||||
startStep093DiagnosticsPolling()
|
||||
refreshStep093Diagnostics(log = true)
|
||||
Log.i(
|
||||
TAG,
|
||||
"STEP093_SCENE_READY topology=${step093Topology.name} variant=${step093Variant.name} " +
|
||||
"range=${range.first}..${range.second}"
|
||||
)
|
||||
}
|
||||
if (configureBeforeStyle) {
|
||||
maplibreMap.setContinuousLayerRange(range.first, range.second)
|
||||
Log.i(TAG, "STEP093_RANGE action=CONFIGURE_WHILE_STYLE_LOADING start=${range.first} end=${range.second}")
|
||||
refreshStep093Diagnostics(log = true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun step093Range(): Pair<String, String> = if (step093Topology == Step093Topology.SINGLE_LAYER) {
|
||||
STEP093_PARTICLE_LAYER_ID to STEP093_PARTICLE_LAYER_ID
|
||||
} else {
|
||||
STEP093_WEATHER_LAYER_ID to STEP093_PARTICLE_LAYER_ID
|
||||
}
|
||||
|
||||
private fun setStep093Range(start: String, end: String, action: String) {
|
||||
val accepted = maplibreMap.setContinuousLayerRange(start, end)
|
||||
Log.i(TAG, "STEP093_RANGE action=$action accepted=$accepted start=$start end=$end")
|
||||
refreshStep093Diagnostics(log = true)
|
||||
}
|
||||
|
||||
private fun toggleStep093Endpoint(start: Boolean) {
|
||||
if (!ensureStep093Scene()) return
|
||||
val id = if (start) step093Range().first else step093Range().second
|
||||
val visible = if (start) !step093StartVisible else !step093EndVisible
|
||||
val accepted = maplibreMap.setStyleLayerVisibility(id, visible)
|
||||
if (start) step093StartVisible = visible else step093EndVisible = visible
|
||||
Log.i(TAG, "STEP093_VISIBILITY endpoint=${if (start) "start" else "end"} id=$id visible=$visible accepted=$accepted")
|
||||
refreshStep093Diagnostics(log = true)
|
||||
}
|
||||
|
||||
private fun applyStep093CameraPreset() {
|
||||
if (!ensureStep093Scene()) return
|
||||
step093CameraPreset = (step093CameraPreset + 1) % 4
|
||||
val position = when (step093CameraPreset) {
|
||||
1 -> CameraPosition.Builder().target(LatLng(31.0, 139.0)).zoom(3.5).bearing(0.0).tilt(0.0).build()
|
||||
2 -> CameraPosition.Builder().target(LatLng(25.0, 132.0)).zoom(4.5).bearing(55.0).tilt(0.0).build()
|
||||
3 -> CameraPosition.Builder().target(LatLng(37.0, 145.0)).zoom(5.0).bearing(120.0).tilt(45.0).build()
|
||||
else -> CameraPosition.Builder().target(LatLng(28.0, 135.0)).zoom(3.0).bearing(0.0).tilt(0.0).build()
|
||||
}
|
||||
maplibreMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 700)
|
||||
Log.i(TAG, "STEP093_CAMERA preset=$step093CameraPreset position=$position")
|
||||
}
|
||||
|
||||
private fun startStep093DiagnosticsPolling() {
|
||||
step093Handler.removeCallbacks(step093DiagnosticsPoll)
|
||||
step093Handler.post(step093DiagnosticsPoll)
|
||||
}
|
||||
|
||||
private fun refreshStep093Diagnostics(log: Boolean) {
|
||||
val snapshot = maplibreMap.retainedUnderlayDiagnostics
|
||||
val cacheCount = (if (snapshot.bottomPresent) 1 else 0) + (if (snapshot.topPresent) 1 else 0)
|
||||
diagnostics.text = buildString {
|
||||
append("Range cfg=${snapshot.rangeConfigured} valid=${snapshot.rangeValid} fallback=${snapshot.rangeFallback} reason=${snapshot.lastReason}\n")
|
||||
append("${snapshot.startLayerId}[${snapshot.startIndex}]..${snapshot.endLayerId}[${snapshot.endIndex}] C=[${snapshot.continuousBegin},${snapshot.continuousEndExclusive}) caches=$cacheCount\n")
|
||||
append("B ${snapshot.bottomPresent}/${snapshot.bottomCacheState} b/r/i=${snapshot.bottomBuild}/${snapshot.bottomReuse}/${snapshot.bottomInvalidation} res=${snapshot.bottomTextureCreate}/${snapshot.bottomCompositeCreate}/${snapshot.bottomResourceRelease} ${snapshot.bottomLastInvalidationReason}\n")
|
||||
append("T ${snapshot.topPresent}/${snapshot.topCacheState} b/r/i=${snapshot.topBuild}/${snapshot.topReuse}/${snapshot.topInvalidation} res=${snapshot.topTextureCreate}/${snapshot.topCompositeCreate}/${snapshot.topResourceRelease} ${snapshot.topLastInvalidationReason}\n")
|
||||
append("Fast e/a=${snapshot.fastPathEligible}/${snapshot.fastPathActive} h/m/full=${snapshot.fastPathHit}/${snapshot.fastPathMiss}/${snapshot.fullCpuFrame} ${snapshot.fastPathFallbackReason}")
|
||||
}
|
||||
if (log) {
|
||||
Log.i(TAG, "STEP093_DIAGNOSTICS ${diagnostics.text.toString().replace('\n', ' ')}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun dismissRealWeatherTuning() { realWeatherTuningMenu?.dismiss(); realWeatherTuningMenu = null }
|
||||
|
||||
private fun showRealWeatherTuning(anchor: android.view.View) {
|
||||
@@ -564,7 +845,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun enterPbfMatrix() {
|
||||
if (realWeatherMode) leaveRealWeatherMode()
|
||||
if (realWeatherMode || step093Mode) leaveRealWeatherMode()
|
||||
if (!isPbfMatrixMode()) {
|
||||
preRealWeatherVisuals = ParticleVisuals(particleCount, lineWidth, particleLength, particleOpacity, trailOpacity, trailFade)
|
||||
particleCount = REAL_WEATHER_PARTICLE_COUNT
|
||||
@@ -1277,6 +1558,10 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun statusText(): String {
|
||||
if (step093Mode) {
|
||||
return "STEP-093 · ${step093Topology.label} · ${step093Variant.name} · " +
|
||||
"CACHE ${if (retainedCacheEnabled) "ON" else "OFF"}"
|
||||
}
|
||||
val mask = when (maskMode) {
|
||||
MASK_OCEAN_A -> "OCEAN A"
|
||||
MASK_OCEAN_B -> "OCEAN B"
|
||||
@@ -1318,6 +1603,94 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
|
||||
private fun realWeatherHudValues(): String = "FPS ${realWeatherTargetFps.name.removePrefix("FPS_")} · P $particleCount · W ${"%.2f".format(lineWidth)} · L ${"%.4f".format(particleLength)} · O ${"%.2f".format(particleOpacity)} · T ${"%.2f".format(trailOpacity)} · F ${"%.2f".format(trailFade)}"
|
||||
|
||||
private fun step093StyleJson(): String {
|
||||
val sources = JSONObject()
|
||||
.put(PARTICLE_SOURCE_ID, JSONObject().put("type", "raster-array").put("host-field-submission", true))
|
||||
.put("step093-bottom-shape", step093GeoJsonSource("""{"type":"Polygon","coordinates":[[[112,0],[158,0],[158,56],[112,56],[112,0]]]}"""))
|
||||
.put("step093-semi-shape", step093GeoJsonSource("""{"type":"Polygon","coordinates":[[[134,8],[151,8],[151,49],[134,49],[134,8]]]}"""))
|
||||
.put("step093-opaque-shape", step093GeoJsonSource("""{"type":"Polygon","coordinates":[[[124,18],[136,18],[136,42],[124,42],[124,18]]]}"""))
|
||||
.put("step093-line-shape", step093GeoJsonSource("""{"type":"LineString","coordinates":[[115,6],[154,50],[154,6],[115,50]]}"""))
|
||||
|
||||
fun fill(id: String, source: String, color: String, opacity: Double) = JSONObject()
|
||||
.put("id", id).put("type", "fill").put("source", source)
|
||||
.put("paint", JSONObject().put("fill-color", color).put("fill-opacity", opacity))
|
||||
fun line(id: String, source: String, color: String, width: Double) = JSONObject()
|
||||
.put("id", id).put("type", "line").put("source", source)
|
||||
.put("paint", JSONObject().put("line-color", color).put("line-width", width).put("line-opacity", 0.95))
|
||||
|
||||
val layers = JSONArray()
|
||||
if (step093Topology.bottom) {
|
||||
layers.put(JSONObject().put("id", STEP093_BOTTOM_BACKGROUND_ID).put("type", "background")
|
||||
.put("paint", JSONObject().put("background-color", "#0b2942")))
|
||||
val bottomBase = fill(STEP093_BOTTOM_FILL_ID, "step093-bottom-shape", "#176b87", 0.72)
|
||||
val bottomExtra = fill(STEP093_BOTTOM_EXTRA_ID, "step093-semi-shape", "#2aa198", 0.18)
|
||||
if (step093Variant == Step093Variant.BOTTOM_REORDER) {
|
||||
layers.put(bottomExtra).put(bottomBase)
|
||||
} else {
|
||||
layers.put(bottomBase)
|
||||
if (step093Variant == Step093Variant.BOTTOM_ADD) layers.put(bottomExtra)
|
||||
}
|
||||
if (step093Variant == Step093Variant.CROSS_BOTTOM) {
|
||||
layers.put(fill(STEP093_CROSS_LAYER_ID, "step093-opaque-shape", "#9b59b6", 0.18))
|
||||
}
|
||||
}
|
||||
|
||||
if (step093Variant != Step093Variant.START_MISSING) {
|
||||
layers.put(
|
||||
JSONObject().put("id", STEP093_WEATHER_LAYER_ID).put("type", "weather-color")
|
||||
.put("source", PARTICLE_SOURCE_ID)
|
||||
.put("paint", JSONObject().put("weather-color-opacity", 0.32))
|
||||
)
|
||||
}
|
||||
if (step093Variant == Step093Variant.CONTINUOUS_ADD ||
|
||||
step093Variant == Step093Variant.CONTINUOUS_REORDER) {
|
||||
val first = fill(STEP093_CONTINUOUS_A_ID, "step093-semi-shape", "#ff00ff", 0.16)
|
||||
val second = fill(STEP093_CONTINUOUS_B_ID, "step093-opaque-shape", "#00ffff", 0.12)
|
||||
if (step093Variant == Step093Variant.CONTINUOUS_REORDER) layers.put(second).put(first)
|
||||
else layers.put(first).put(second)
|
||||
}
|
||||
if (step093Variant == Step093Variant.CROSS_CONTINUOUS) {
|
||||
layers.put(fill(STEP093_CROSS_LAYER_ID, "step093-opaque-shape", "#9b59b6", 0.18))
|
||||
}
|
||||
if (step093Variant == Step093Variant.FAST_PATH_FAIL_CLOSED) {
|
||||
layers.put(fill(STEP093_UNKNOWN_CONTINUOUS_ID, "step093-semi-shape", "#ff5500", 0.20))
|
||||
}
|
||||
if (step093Variant != Step093Variant.END_MISSING) layers.put(navSeaParticleLayer(active = true))
|
||||
if (step093Variant == Step093Variant.CROSS_TOP) {
|
||||
layers.put(fill(STEP093_CROSS_LAYER_ID, "step093-opaque-shape", "#9b59b6", 0.18))
|
||||
}
|
||||
|
||||
if (step093Topology.top) {
|
||||
val semi = fill(STEP093_TOP_SEMI_ID, "step093-semi-shape", "#ffd166", 0.42)
|
||||
val opaque = fill(STEP093_TOP_OPAQUE_ID, "step093-opaque-shape", "#ef476f", 1.0)
|
||||
val outline = line(STEP093_TOP_LINE_ID, "step093-line-shape", "#ffffff", 6.0)
|
||||
val extra = line(STEP093_TOP_EXTRA_ID, "step093-opaque-shape", "#00ff99", 3.0)
|
||||
if (step093Variant == Step093Variant.TOP_REORDER) {
|
||||
layers.put(outline).put(opaque).put(semi)
|
||||
} else {
|
||||
layers.put(semi).put(opaque).put(outline)
|
||||
if (step093Variant == Step093Variant.TOP_ADD) layers.put(extra)
|
||||
}
|
||||
}
|
||||
|
||||
return JSONObject()
|
||||
.put("version", 8)
|
||||
.put("name", "STEP-093 Continuous Range Runtime Validation")
|
||||
.put("sources", sources)
|
||||
.put("layers", layers)
|
||||
.toString()
|
||||
}
|
||||
|
||||
private fun step093GeoJsonSource(geometryJson: String): JSONObject = JSONObject()
|
||||
.put("type", "geojson")
|
||||
.put(
|
||||
"data",
|
||||
JSONObject()
|
||||
.put("type", "Feature")
|
||||
.put("properties", JSONObject())
|
||||
.put("geometry", JSONObject(geometryJson))
|
||||
)
|
||||
|
||||
private fun validationStyle(active: Boolean, enabled: Boolean, reason: String): String {
|
||||
val fixtureId = fixtureId()
|
||||
val nextFixtureId = if (timeWindowMode) {
|
||||
@@ -1396,11 +1769,11 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
override fun onStart() { super.onStart(); mapView.onStart() }
|
||||
override fun onStart() { super.onStart(); mapView.onStart(); if (step093Mode) startStep093DiagnosticsPolling() }
|
||||
override fun onResume() { super.onResume(); mapView.onResume() }
|
||||
override fun onPause() { mapView.onPause(); super.onPause() }
|
||||
override fun onStop() { mapView.onStop(); super.onStop() }
|
||||
override fun onDestroy() { weatherRuntime?.dispose(); weatherRuntime = null; mapView.onDestroy(); super.onDestroy() }
|
||||
override fun onStop() { step093Handler.removeCallbacks(step093DiagnosticsPoll); mapView.onStop(); super.onStop() }
|
||||
override fun onDestroy() { step093Handler.removeCallbacks(step093DiagnosticsPoll); weatherRuntime?.dispose(); weatherRuntime = null; mapView.onDestroy(); super.onDestroy() }
|
||||
override fun onLowMemory() { super.onLowMemory(); mapView.onLowMemory() }
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
@@ -1425,6 +1798,9 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
outState.putString(STATE_NAVSEA_PBF_POSITION, navSeaPbfPosition.name)
|
||||
outState.putBoolean(STATE_NAVSEA_PBF_RENDER_ENABLED, navSeaPbfRenderEnabled)
|
||||
outState.putBoolean(STATE_RETAINED_CACHE_ENABLED, retainedCacheEnabled)
|
||||
outState.putBoolean(STATE_STEP093_MODE, step093Mode)
|
||||
outState.putString(STATE_STEP093_TOPOLOGY, step093Topology.name)
|
||||
outState.putString(STATE_STEP093_VARIANT, step093Variant.name)
|
||||
super.onSaveInstanceState(outState)
|
||||
mapView.onSaveInstanceState(outState)
|
||||
}
|
||||
@@ -1458,9 +1834,26 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
private const val STATE_NAVSEA_PBF_POSITION = "particle_validation.navsea_pbf_position"
|
||||
private const val STATE_NAVSEA_PBF_RENDER_ENABLED = "particle_validation.navsea_pbf_render_enabled"
|
||||
private const val STATE_RETAINED_CACHE_ENABLED = "particle_validation.retained_cache_enabled"
|
||||
private const val STATE_STEP093_MODE = "particle_validation.step093_mode"
|
||||
private const val STATE_STEP093_TOPOLOGY = "particle_validation.step093_topology"
|
||||
private const val STATE_STEP093_VARIANT = "particle_validation.step093_variant"
|
||||
private const val PARTICLE_LAYER_ID = "particle-raster-core"
|
||||
private const val WEATHER_COLOR_LAYER_ID = "weather-color-real"
|
||||
private const val PARTICLE_SOURCE_ID = "particle-fixture"
|
||||
private const val STEP093_DIAGNOSTICS_INTERVAL_MS = 1000L
|
||||
private const val STEP093_WEATHER_LAYER_ID = WEATHER_COLOR_LAYER_ID
|
||||
private const val STEP093_PARTICLE_LAYER_ID = PARTICLE_LAYER_ID
|
||||
private const val STEP093_BOTTOM_BACKGROUND_ID = "step093-bottom-background"
|
||||
private const val STEP093_BOTTOM_FILL_ID = "step093-bottom-fill"
|
||||
private const val STEP093_BOTTOM_EXTRA_ID = "step093-bottom-extra"
|
||||
private const val STEP093_CONTINUOUS_A_ID = "step093-continuous-a"
|
||||
private const val STEP093_CONTINUOUS_B_ID = "step093-continuous-b"
|
||||
private const val STEP093_UNKNOWN_CONTINUOUS_ID = "step093-unknown-continuous"
|
||||
private const val STEP093_CROSS_LAYER_ID = "step093-cross-layer"
|
||||
private const val STEP093_TOP_SEMI_ID = "step093-top-semi"
|
||||
private const val STEP093_TOP_OPAQUE_ID = "step093-top-opaque"
|
||||
private const val STEP093_TOP_LINE_ID = "step093-top-line"
|
||||
private const val STEP093_TOP_EXTRA_ID = "step093-top-extra"
|
||||
private const val MASK_GLOBAL = 0
|
||||
private const val MASK_OCEAN_A = 1
|
||||
private const val MASK_OCEAN_B = 2
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<org.maplibre.android.maps.MapView android:id="@id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" />
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="#DD102030" android:orientation="vertical" android:padding="4dp">
|
||||
<TextView android:id="@+id/validationStatus" android:layout_width="match_parent" android:layout_height="42dp" android:gravity="center_vertical" android:maxLines="2" android:paddingLeft="4dp" android:paddingRight="4dp" android:textColor="@android:color/white" android:textSize="12sp" />
|
||||
<TextView android:id="@+id/validationDiagnostics" android:layout_width="match_parent" android:layout_height="92dp" android:fontFamily="monospace" android:gravity="center_vertical" android:maxLines="6" android:paddingLeft="4dp" android:paddingRight="4dp" android:text="STEP-093 diagnostics: open STEP 093" android:textColor="#FFDD88" android:textSize="9sp" />
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal">
|
||||
<Button android:id="@+id/validationMenuTime" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="TIME" />
|
||||
<Button android:id="@+id/validationMenuVisual" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="VIS" />
|
||||
@@ -12,6 +13,7 @@
|
||||
<Button android:id="@+id/validationMenuPbfMode" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="PBF MODE" android:textSize="9sp" />
|
||||
<Button android:id="@+id/validationMenuNavSeaPbf" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="NAVSEA PBF" android:textSize="9sp" />
|
||||
<Button android:id="@+id/validationMenuRetainedCache" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="CACHE ON" android:textSize="9sp" />
|
||||
<Button android:id="@+id/validationMenuStep093" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="STEP 093" android:textSize="9sp" />
|
||||
<Button android:id="@+id/validationMenuMore" style="@style/ParticleValidationButton" android:layout_width="0dp" android:layout_weight="1" android:text="MORE" />
|
||||
</LinearLayout>
|
||||
<!-- Existing action IDs are invisible menu targets; no permanent button grid. -->
|
||||
|
||||
@@ -44,14 +44,33 @@ MLN_EXPORT
|
||||
@property (nonatomic, copy, readonly) NSString *endLayerId;
|
||||
@property (nonatomic, readonly) NSInteger startIndex;
|
||||
@property (nonatomic, readonly) NSInteger endIndex;
|
||||
@property (nonatomic, readonly) NSInteger continuousBegin;
|
||||
@property (nonatomic, readonly) NSInteger continuousEndExclusive;
|
||||
@property (nonatomic, readonly) BOOL bottomPresent;
|
||||
@property (nonatomic, copy, readonly) NSString *bottomCacheState;
|
||||
@property (nonatomic, readonly) uint64_t bottomBuild;
|
||||
@property (nonatomic, readonly) uint64_t bottomReuse;
|
||||
@property (nonatomic, readonly) uint64_t bottomInvalidation;
|
||||
@property (nonatomic, copy, readonly) NSString *bottomLastInvalidationReason;
|
||||
@property (nonatomic, readonly) uint64_t bottomTextureCreate;
|
||||
@property (nonatomic, readonly) uint64_t bottomCompositeCreate;
|
||||
@property (nonatomic, readonly) uint64_t bottomResourceRelease;
|
||||
@property (nonatomic, readonly) BOOL topPresent;
|
||||
@property (nonatomic, copy, readonly) NSString *topCacheState;
|
||||
@property (nonatomic, readonly) uint64_t topBuild;
|
||||
@property (nonatomic, readonly) uint64_t topReuse;
|
||||
@property (nonatomic, readonly) uint64_t topInvalidation;
|
||||
@property (nonatomic, copy, readonly) NSString *topLastInvalidationReason;
|
||||
@property (nonatomic, readonly) uint64_t topTextureCreate;
|
||||
@property (nonatomic, readonly) uint64_t topCompositeCreate;
|
||||
@property (nonatomic, readonly) uint64_t topResourceRelease;
|
||||
@property (nonatomic, readonly) BOOL rangeFallback;
|
||||
@property (nonatomic, readonly) BOOL fastPathEligible;
|
||||
@property (nonatomic, readonly) BOOL fastPathActive;
|
||||
@property (nonatomic, copy, readonly) NSString *fastPathFallbackReason;
|
||||
@property (nonatomic, readonly) uint64_t fastPathHit;
|
||||
@property (nonatomic, readonly) uint64_t fastPathMiss;
|
||||
@property (nonatomic, readonly) uint64_t fullCpuFrame;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
|
||||
@@ -267,6 +267,13 @@ int processIsTranslated() {
|
||||
_endLayerId = @"";
|
||||
_startIndex = -1;
|
||||
_endIndex = -1;
|
||||
_continuousBegin = -1;
|
||||
_continuousEndExclusive = -1;
|
||||
_bottomCacheState = @"disabled";
|
||||
_bottomLastInvalidationReason = @"none";
|
||||
_topCacheState = @"disabled";
|
||||
_topLastInvalidationReason = @"none";
|
||||
_fastPathFallbackReason = @"no-prepared-tree";
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -278,14 +285,33 @@ int processIsTranslated() {
|
||||
_endLayerId = [NSString stringWithUTF8String:snapshot.endLayerId.c_str()];
|
||||
_startIndex = snapshot.startIndex;
|
||||
_endIndex = snapshot.endIndex;
|
||||
_continuousBegin = snapshot.continuousBegin;
|
||||
_continuousEndExclusive = snapshot.continuousEndExclusive;
|
||||
_bottomPresent = snapshot.bottomPresent;
|
||||
_bottomCacheState = [NSString stringWithUTF8String:snapshot.bottomCacheState.c_str()];
|
||||
_bottomBuild = snapshot.bottomBuild;
|
||||
_bottomReuse = snapshot.bottomReuse;
|
||||
_bottomInvalidation = snapshot.bottomInvalidation;
|
||||
_bottomLastInvalidationReason = [NSString stringWithUTF8String:snapshot.bottomLastInvalidationReason.c_str()];
|
||||
_bottomTextureCreate = snapshot.bottomTextureCreate;
|
||||
_bottomCompositeCreate = snapshot.bottomCompositeCreate;
|
||||
_bottomResourceRelease = snapshot.bottomResourceRelease;
|
||||
_topPresent = snapshot.topPresent;
|
||||
_topCacheState = [NSString stringWithUTF8String:snapshot.topCacheState.c_str()];
|
||||
_topBuild = snapshot.topBuild;
|
||||
_topReuse = snapshot.topReuse;
|
||||
_topInvalidation = snapshot.topInvalidation;
|
||||
_topLastInvalidationReason = [NSString stringWithUTF8String:snapshot.topLastInvalidationReason.c_str()];
|
||||
_topTextureCreate = snapshot.topTextureCreate;
|
||||
_topCompositeCreate = snapshot.topCompositeCreate;
|
||||
_topResourceRelease = snapshot.topResourceRelease;
|
||||
_rangeFallback = snapshot.rangeFallback;
|
||||
_fastPathEligible = snapshot.fastPathEligible;
|
||||
_fastPathActive = snapshot.fastPathActive;
|
||||
_fastPathFallbackReason = [NSString stringWithUTF8String:snapshot.fastPathFallbackReason.c_str()];
|
||||
_fastPathHit = snapshot.fastPathHit;
|
||||
_fastPathMiss = snapshot.fastPathMiss;
|
||||
_fullCpuFrame = snapshot.fullCpuFrame;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user