Compare commits
139 Commits
maplibre-p
...
bf7f6193e0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf7f6193e0 | ||
|
|
7cfad1c72f | ||
|
|
ea5bd393c6 | ||
|
|
40b79764ae | ||
|
|
69922b795a | ||
|
|
23f7b8a4d7 | ||
|
|
86906c8a6a | ||
|
|
a49dd936c4 | ||
|
|
2c6f673e54 | ||
|
|
c30add4d33 | ||
|
|
73db0356ac | ||
|
|
30d0e6665e | ||
|
|
a4b5f4eaa0 | ||
|
|
f8378fd711 | ||
|
|
e4c7af7c40 | ||
|
|
b433775348 | ||
|
|
2b4075b60b | ||
|
|
630ec65768 | ||
|
|
16a5d15f16 | ||
|
|
d3bf98bc55 | ||
|
|
0ce551ad37 | ||
|
|
6df21dac38 | ||
|
|
53a844e818 | ||
|
|
a4c6047d70 | ||
|
|
078ba40b76 | ||
|
|
6b48f905d2 | ||
|
|
7c5ed27b0b | ||
|
|
01863569fb | ||
|
|
64cf8f4435 | ||
|
|
d29e84c1a9 | ||
|
|
2780550b62 | ||
|
|
524aaf4af5 | ||
|
|
c4b481fd2c | ||
|
|
8a5214d92d | ||
|
|
e8b451fe70 | ||
|
|
95f0a45d6d | ||
|
|
baf9374318 | ||
|
|
1e7215e2a0 | ||
|
|
e9f84a8ec6 | ||
|
|
2e119961d9 | ||
|
|
750c14f527 | ||
|
|
4712e1752a | ||
|
|
5af91fe7a1 | ||
|
|
cd71640a84 | ||
|
|
1fdc5df625 | ||
|
|
2fca4a71a7 | ||
|
|
f081180bed | ||
|
|
159b0ad5f1 | ||
|
|
f3a44c7d5f | ||
|
|
b1239ac3b1 | ||
|
|
f49ffa68a1 | ||
|
|
5bb1a0e635 | ||
|
|
bd1cfe95b7 | ||
|
|
72d9369384 | ||
|
|
8c006ac83d | ||
|
|
0aab2bdc83 | ||
|
|
d0ced72351 | ||
|
|
be5b9080ed | ||
|
|
237a3e6608 | ||
|
|
0d13552bed | ||
|
|
91c2491b0e | ||
|
|
e67e4961b5 | ||
|
|
720d309364 | ||
|
|
b5c1c4879a | ||
|
|
82e8a18de7 | ||
|
|
4bc9d0ca56 | ||
|
|
ad5f92c48e | ||
|
|
05878d6623 | ||
|
|
45c4dca849 | ||
|
|
ee0b89e711 | ||
|
|
ddf20dec9f | ||
|
|
9d1f66c169 | ||
|
|
016fd1fff6 | ||
|
|
8fbb892a12 | ||
|
|
7eaff6e123 | ||
|
|
b001fd63c2 | ||
|
|
64715e4ce8 | ||
|
|
0dd475c22f | ||
|
|
66690b460e | ||
|
|
b3ec8edc87 | ||
|
|
8a5d88008c | ||
|
|
4908244d2d | ||
|
|
b89c8c8cb4 | ||
|
|
a9eaec6b65 | ||
|
|
c7506d6aff | ||
|
|
57d1981497 | ||
|
|
042f21da5c | ||
|
|
a33d3f00fb | ||
|
|
eca9e1db33 | ||
|
|
843cdec996 | ||
|
|
474d127bfb | ||
|
|
fed6dc019b | ||
|
|
0b342a1209 | ||
|
|
96e806931d | ||
|
|
e5d0fce32a | ||
|
|
be3f03b86e | ||
|
|
2919f71e39 | ||
|
|
6010a2e687 | ||
|
|
c3b588321b | ||
|
|
cbe4681ef1 | ||
|
|
1d0908bdaa | ||
|
|
96afb98b7f | ||
|
|
ef5ff9ac01 | ||
|
|
08f775e2ed | ||
|
|
a4670161a0 | ||
|
|
0c7fbe2b29 | ||
|
|
2a8ebc4906 | ||
|
|
06fcf13d42 | ||
|
|
f0bd259b53 | ||
|
|
2e13de25f4 | ||
|
|
65a3405370 | ||
|
|
550f64be22 | ||
|
|
836b862984 | ||
|
|
95a977e12e | ||
|
|
6485d28b3e | ||
|
|
d508e65692 | ||
|
|
743ed53794 | ||
|
|
a666f02633 | ||
|
|
9a9f831782 | ||
|
|
bd92c87d39 | ||
|
|
8be081ae83 | ||
|
|
49f80e95f3 | ||
|
|
d9664ee187 | ||
|
|
7f430aa624 | ||
|
|
b0388d186d | ||
|
|
ccb9af119e | ||
|
|
e2b01754b6 | ||
|
|
40be634126 | ||
|
|
f1905c5215 | ||
|
|
e626fc0fbd | ||
|
|
9ef0f1c790 | ||
|
|
25e4f6acbf | ||
|
|
a34723ff4a | ||
|
|
5e6fd6bb78 | ||
|
|
c8dad00be5 | ||
|
|
a6189feecb | ||
|
|
83ce54ed3e | ||
|
|
5bcdc704b8 | ||
|
|
15fcee54dc |
19
.github/workflows/android-ci.yml
vendored
19
.github/workflows/android-ci.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
outputs:
|
||||
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files.outputs.android_any_modified != 'true' }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
renderer: [opengl, vulkan]
|
||||
renderer: [opengl, vulkan, multiBackend]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: platform/android
|
||||
@@ -57,14 +57,14 @@ jobs:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN_ANDROID }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
- uses: ./.github/actions/setup-android-ci
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
@@ -169,6 +169,7 @@ jobs:
|
||||
case "${{ matrix.renderer }}" in
|
||||
opengl) echo "renderer=OpenGL" >> "$GITHUB_ENV" ;;
|
||||
vulkan) echo "renderer=Vulkan" >> "$GITHUB_ENV" ;;
|
||||
multiBackend) echo "renderer=MultiBackend" >> "$GITHUB_ENV" ;;
|
||||
*) echo "::error ::Unknown renderer '${{ matrix.renderer }}'"; exit 1 ;;
|
||||
esac
|
||||
|
||||
@@ -210,7 +211,7 @@ jobs:
|
||||
working-directory: test/android
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -255,7 +256,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -283,7 +284,7 @@ jobs:
|
||||
env:
|
||||
IS_LOCAL_DEVELOPMENT: false
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -316,7 +317,7 @@ jobs:
|
||||
C_COMPILER: aarch64-linux-android26-clang
|
||||
BINDGEN_TARGET: aarch64-linux-android26
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -390,7 +391,7 @@ jobs:
|
||||
|
||||
# automatically trigger android-release when code is pushed to main
|
||||
# and the platform/android/VERSION file has changed
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||
|
||||
- name: VERSION file changed
|
||||
|
||||
6
.github/workflows/android-device-test.yml
vendored
6
.github/workflows/android-device-test.yml
vendored
@@ -78,11 +78,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'maplibre' && github.event.workflow_run.conclusion == 'success'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
if: env.run_device_test == 'true'
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
|
||||
27
.github/workflows/android-release.yml
vendored
27
.github/workflows/android-release.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
run:
|
||||
working-directory: platform/android
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Validate and set version
|
||||
working-directory: .
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
|
||||
- name: Create release (draft)
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
tag_name: ${{ steps.prepare_release.outputs.version_tag }}
|
||||
name: ${{ steps.prepare_release.outputs.version_tag }}
|
||||
@@ -74,19 +74,20 @@ jobs:
|
||||
RENDERER:
|
||||
- vulkan
|
||||
- opengl
|
||||
- multiBackend
|
||||
BUILDTYPE:
|
||||
- Release
|
||||
- Debug
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
|
||||
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
@@ -118,7 +119,7 @@ jobs:
|
||||
"build/debug-symbols-maplibre-android-${{ matrix.RENDERER }}-${{ env.buildtype }}-$version_tag.tar.gz"
|
||||
|
||||
- name: Upload release assets (${{ matrix.RENDERER }}, ${{ matrix.BUILDTYPE }})
|
||||
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
tag_name: ${{ needs.android-create-release.outputs.version_tag }}
|
||||
fail_on_unmatched_files: true
|
||||
@@ -133,8 +134,12 @@ jobs:
|
||||
if [ "$renderer" = "opengl" ]; then
|
||||
./gradlew :MapLibreAndroid:publishOpengl${{ env.buildtype }}PublicationToMavenCentralRepository
|
||||
./gradlew :MapLibreAndroid:publishDefault${{ env.buildtype }}PublicationToMavenCentralRepository
|
||||
else
|
||||
elif [ "$renderer" = "vulkan" ]; then
|
||||
./gradlew :MapLibreAndroid:publishVulkan${{ env.buildtype }}PublicationToMavenCentralRepository
|
||||
elif [ "$renderer" = "multiBackend" ]; then
|
||||
./gradlew :MapLibreAndroid:publishMultibackend${{ env.buildtype }}PublicationToMavenCentralRepository
|
||||
else
|
||||
echo "::error ::Unknown renderer '$renderer'"; exit 1
|
||||
fi
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
|
||||
@@ -149,20 +154,20 @@ jobs:
|
||||
- android-build-and-upload-release
|
||||
steps:
|
||||
- name: Publish release (remove draft)
|
||||
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
tag_name: ${{ needs.android-create-release.outputs.version_tag }}
|
||||
name: ${{ needs.android-create-release.outputs.version_tag }}
|
||||
draft: false
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
|
||||
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
|
||||
10
.github/workflows/android-testapp-release.yml
vendored
10
.github/workflows/android-testapp-release.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
create-android-testapp-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
renderer: [opengl, vulkan]
|
||||
renderer: [opengl, vulkan, multibackend]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: platform/android
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN_ANDROID }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -68,11 +68,11 @@ jobs:
|
||||
needs: [android-build-testapp]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Finalize release (set draft=false)
|
||||
run: |
|
||||
|
||||
2
.github/workflows/cache-cleanup.yml
vendored
2
.github/workflows/cache-cleanup.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
14
.github/workflows/core-release.yml
vendored
14
.github/workflows/core-release.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -46,13 +46,13 @@ jobs:
|
||||
needs: [create-release]
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- run: brew install webp libuv
|
||||
- run: brew install webp libuv llvm
|
||||
|
||||
- uses: taiki-e/install-action@2ca9b94c269419b7b0c711c09d0b21c4e1d51145 # v2.83.1
|
||||
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
|
||||
with:
|
||||
tool: armerge@2
|
||||
|
||||
@@ -103,14 +103,14 @@ jobs:
|
||||
- renderer: vulkan
|
||||
runner: { os: ubuntu-24.04-arm, arch: arm64 }
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install dependencies
|
||||
run: .github/scripts/install-linux-deps
|
||||
|
||||
- uses: taiki-e/install-action@2ca9b94c269419b7b0c711c09d0b21c4e1d51145 # v2.83.1
|
||||
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
|
||||
with:
|
||||
tool: armerge@2
|
||||
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
- run: |
|
||||
git config --system core.longpaths true
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
||||
6
.github/workflows/gh-pages-android-api.yml
vendored
6
.github/workflows/gh-pages-android-api.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
|
||||
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
run: ./gradlew dokkaGenerate
|
||||
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
|
||||
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: platform/android/MapLibreAndroid/build/dokka/html
|
||||
|
||||
@@ -17,13 +17,13 @@ jobs:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Generate documentation
|
||||
run: make mkdocs-build
|
||||
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
|
||||
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: platform/android/site
|
||||
|
||||
4
.github/workflows/gh-pages-cpp-api.yml
vendored
4
.github/workflows/gh-pages-cpp-api.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
run: doxygen
|
||||
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
|
||||
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs/doxygen/html
|
||||
|
||||
12
.github/workflows/gh-pages-docc.yml
vendored
12
.github/workflows/gh-pages-docc.yml
vendored
@@ -15,15 +15,17 @@ on:
|
||||
|
||||
jobs:
|
||||
gh-pages-docc-build:
|
||||
if: ${{ github.ref_name == 'main' }}
|
||||
name: Build DocC Docs
|
||||
runs-on: macos-latest
|
||||
if: ${{ github.ref_name == 'main' }}
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
@@ -52,7 +54,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Download DocC docs artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -67,7 +69,7 @@ jobs:
|
||||
rm docs.zip
|
||||
|
||||
- name: Deploy DocC documentation (main) 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
|
||||
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: build/docs
|
||||
|
||||
6
.github/workflows/gh-pages-mdbook.yml
vendored
6
.github/workflows/gh-pages-mdbook.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
name: Deploy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Download book
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
path: artifacts/book
|
||||
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
|
||||
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: artifacts/book
|
||||
|
||||
14
.github/workflows/ios-ci.yml
vendored
14
.github/workflows/ios-ci.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
outputs:
|
||||
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files-yaml.outputs.ios_any_modified != 'true' }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
working-directory: platform/ios
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: false
|
||||
persist-credentials: false
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
if: github.ref == 'refs/heads/main' && vars.OIDC_AWS_ROLE_TO_ASSUME
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
@@ -236,7 +236,7 @@ jobs:
|
||||
runs-on: macos-14
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -269,7 +269,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: macos-26
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -304,7 +304,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
runs-on: macos-26
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -366,7 +366,7 @@ jobs:
|
||||
|
||||
# Trigger release on main if VERSION file changed
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
4
.github/workflows/ios-device-test.yml
vendored
4
.github/workflows/ios-device-test.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.repository_owner == 'maplibre' && github.event.workflow_run.conclusion == 'success'
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
files: "${{ matrix.test.xcTestFile }}, ${{ matrix.test.ipaFile }}"
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
|
||||
2
.github/workflows/ios-release-cocoapods.yml
vendored
2
.github/workflows/ios-release-cocoapods.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
working-directory: platform/ios
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
44
.github/workflows/ios-release.yml
vendored
44
.github/workflows/ios-release.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
working-directory: platform/ios
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
working-directory: platform/ios
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -104,13 +104,13 @@ jobs:
|
||||
working-directory: platform/ios
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
cat changelog_for_version.md
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
|
||||
- name: Release (GitHub) - Create Draft
|
||||
id: github_release
|
||||
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
name: ios-v${{ env.version }}
|
||||
files: |
|
||||
@@ -177,6 +177,22 @@ jobs:
|
||||
private-key: ${{ secrets.MAPLIBRE_NATIVE_BOT_PRIVATE_KEY }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
|
||||
- run: npm install
|
||||
working-directory: .
|
||||
|
||||
- name: Release (CocoaPods)
|
||||
shell: bash -leo pipefail {0} # so pod is found
|
||||
run: gh workflow run ios-release-cocoapods.yml --field version=${{ env.version }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish release (remove draft)
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
tag_name: ios-v${{ env.version }}
|
||||
name: ios-v${{ env.version }}
|
||||
draft: false
|
||||
|
||||
- name: Release (Swift Package Index)
|
||||
run: |
|
||||
echo "::add-mask::${{ steps.generate_token.outputs.token }}"
|
||||
@@ -192,22 +208,6 @@ jobs:
|
||||
"version":"${{ env.version }}",
|
||||
"download_url": "https://github.com/maplibre/maplibre-native/releases/download/ios-v${{ env.version }}/MapLibre.dynamic.xcframework.zip"}}'
|
||||
|
||||
- run: npm install
|
||||
working-directory: .
|
||||
|
||||
- name: Release (CocoaPods)
|
||||
shell: bash -leo pipefail {0} # so pod is found
|
||||
run: gh workflow run ios-release-cocoapods.yml --field version=${{ env.version }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish release (remove draft)
|
||||
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
||||
with:
|
||||
tag_name: ios-v${{ env.version }}
|
||||
name: ios-v${{ env.version }}
|
||||
draft: false
|
||||
|
||||
- name: Write release notifications
|
||||
if: github.repository_owner == 'maplibre'
|
||||
env:
|
||||
|
||||
4
.github/workflows/ios-testapp-release.yml
vendored
4
.github/workflows/ios-testapp-release.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: macos-26
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
test -f bazel-bin/platform/ios/app-swift/MapLibreApp.ipa
|
||||
|
||||
- name: Upload app to TestFlight
|
||||
uses: apple-actions/upload-testflight-build@1ad58030672057aa084b4e96beb6f7a8c627f9e6 # v5.2.1
|
||||
uses: apple-actions/upload-testflight-build@5e75ff58276689011512ba87a381d93dc67dbcf8 # v5.3.0
|
||||
with:
|
||||
app-path: bazel-bin/platform/ios/app-swift/MapLibreApp.ipa
|
||||
issuer-id: ${{ vars.APPSTORE_ISSUER_ID }}
|
||||
|
||||
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@@ -9,4 +9,4 @@ jobs:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6.2.0
|
||||
- uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0
|
||||
|
||||
16
.github/workflows/linux-ci.yml
vendored
16
.github/workflows/linux-ci.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
outputs:
|
||||
should_skip: ${{ github.event_name != 'workflow_dispatch' && steps.changed-files.outputs.linux_any_modified != 'true' }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -66,20 +66,20 @@ jobs:
|
||||
rust: true
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- name: Install dependencies
|
||||
run: .github/scripts/install-linux-deps
|
||||
|
||||
- uses: taiki-e/install-action@2ca9b94c269419b7b0c711c09d0b21c4e1d51145 # v2.83.1
|
||||
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
|
||||
with:
|
||||
tool: armerge@2
|
||||
|
||||
@@ -156,7 +156,7 @@ jobs:
|
||||
# CodeQL
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
category: "/language:cpp"
|
||||
|
||||
@@ -199,7 +199,7 @@ jobs:
|
||||
linux-coverage:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -215,7 +215,7 @@ jobs:
|
||||
${{ runner.os }}-bazel-
|
||||
path: ~/.cache/bazel
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
@@ -249,7 +249,7 @@ jobs:
|
||||
- linux-build-and-test
|
||||
- linux-coverage
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- if: github.event_name == 'pull_request'
|
||||
uses: ./.github/actions/save-pr-number
|
||||
|
||||
4
.github/workflows/macos-ci.yml
vendored
4
.github/workflows/macos-ci.yml
vendored
@@ -69,7 +69,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
@@ -106,7 +106,7 @@ jobs:
|
||||
name: wgpu
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
16
.github/workflows/macos-release.yml
vendored
16
.github/workflows/macos-release.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
working-directory: platform/macos
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
working-directory: .
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: xcframework
|
||||
path: |
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
working-directory: platform/macos
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
working-directory: .
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: xcframework-static
|
||||
path: |
|
||||
@@ -111,13 +111,13 @@ jobs:
|
||||
working-directory: platform/macos
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/download-artifact@v8
|
||||
|
||||
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v4
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
cat changelog_for_version.md
|
||||
|
||||
- name: Release (GitHub) - Create Draft
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
name: macos-v${{ env.version }}
|
||||
files: |
|
||||
@@ -167,7 +167,7 @@ jobs:
|
||||
draft: true
|
||||
|
||||
- name: Publish release (remove draft)
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
|
||||
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
|
||||
with:
|
||||
tag_name: macos-v${{ env.version }}
|
||||
name: macos-v${{ env.version }}
|
||||
|
||||
4
.github/workflows/node-ci.yml
vendored
4
.github/workflows/node-ci.yml
vendored
@@ -100,7 +100,7 @@ jobs:
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
/usr/sbin/update-ccache-symlinks
|
||||
|
||||
- name: Use Node.js from nvmrc
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: 'platform/node/.nvmrc'
|
||||
|
||||
|
||||
14
.github/workflows/node-release.yml
vendored
14
.github/workflows/node-release.yml
vendored
@@ -17,12 +17,12 @@ jobs:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Use Node.js from nvmrc
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: 'platform/node/.nvmrc'
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -159,7 +159,7 @@ jobs:
|
||||
/usr/sbin/update-ccache-symlinks
|
||||
|
||||
- name: Use Node.js from nvmrc
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: 'platform/node/.nvmrc'
|
||||
|
||||
@@ -297,12 +297,12 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Use Node.js from nvmrc
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: 'platform/node/.nvmrc'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
8
.github/workflows/pr-bloaty-ios.yml
vendored
8
.github/workflows/pr-bloaty-ios.yml
vendored
@@ -19,14 +19,14 @@ jobs:
|
||||
outputs:
|
||||
should_skip: ${{ steps.parent_workflow.outputs.was_skipped_or_cancelled }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
.nvmrc
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip == 'false'
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
if: vars.OIDC_AWS_ROLE_TO_ASSUME
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
|
||||
12
.github/workflows/pr-linux-tests.yml
vendored
12
.github/workflows/pr-linux-tests.yml
vendored
@@ -22,14 +22,14 @@ jobs:
|
||||
outputs:
|
||||
should_skip: ${{ steps.parent_workflow.outputs.was_skipped_or_cancelled }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
.nvmrc
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip == 'false'
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
if: github.ref == 'refs/heads/main' && vars.OIDC_AWS_ROLE_TO_ASSUME
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
@@ -139,7 +139,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_skip == 'false'
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
@@ -170,7 +170,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
if: github.ref == 'refs/heads/main' && vars.OIDC_AWS_ROLE_TO_ASSUME
|
||||
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6.2.2
|
||||
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ vars.OIDC_AWS_ROLE_TO_ASSUME }}
|
||||
|
||||
2
.github/workflows/qt-ci.yml
vendored
2
.github/workflows/qt-ci.yml
vendored
@@ -104,7 +104,7 @@ jobs:
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
path: source
|
||||
submodules: recursive
|
||||
|
||||
12
.github/workflows/rust-ci.yaml
vendored
12
.github/workflows/rust-ci.yaml
vendored
@@ -7,6 +7,10 @@ on:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: rustutils/
|
||||
@@ -23,9 +27,9 @@ jobs:
|
||||
- os: windows-latest
|
||||
- os: ubuntu-latest
|
||||
steps:
|
||||
- uses: taiki-e/install-action@2ca9b94c269419b7b0c711c09d0b21c4e1d51145 # v2.83.1
|
||||
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
|
||||
with: { tool: just }
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: just -v ci-test
|
||||
@@ -34,9 +38,9 @@ jobs:
|
||||
name: Rust tests MSRV (Minimal Supported Rust Version)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: taiki-e/install-action@2ca9b94c269419b7b0c711c09d0b21c4e1d51145 # v2.83.1
|
||||
- uses: taiki-e/install-action@ba47c86ac325773530516bb756137ac718732518 # v2.86.5
|
||||
with: { tool: just }
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Read crate metadata
|
||||
|
||||
6
.github/workflows/upload-coverage.yml
vendored
6
.github/workflows/upload-coverage.yml
vendored
@@ -12,14 +12,14 @@ jobs:
|
||||
outputs:
|
||||
should_run: ${{ !steps.parent_workflow.outputs.was_skipped_or_cancelled }}
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
.nvmrc
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
if: needs.pre_job.outputs.should_run == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
4
.github/workflows/validate-pr-title.yml
vendored
4
.github/workflows/validate-pr-title.yml
vendored
@@ -9,9 +9,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
|
||||
4
.github/workflows/validate-scripts.yml
vendored
4
.github/workflows/validate-scripts.yml
vendored
@@ -9,11 +9,11 @@ jobs:
|
||||
validate-scripts:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
|
||||
20
.github/workflows/windows-ci.yml
vendored
20
.github/workflows/windows-ci.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
- run: |
|
||||
git config --system core.longpaths true
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
- run: |
|
||||
git config --system core.longpaths true
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
sparse-checkout: |
|
||||
platform/windows/vendor
|
||||
@@ -118,19 +118,19 @@ jobs:
|
||||
- run: |
|
||||
git config --system core.longpaths true
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
||||
|
||||
- uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
- uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11
|
||||
|
||||
- name: Initialize sccache
|
||||
run: |
|
||||
@@ -167,7 +167,7 @@ jobs:
|
||||
# CodeQL
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
category: "/language:cpp"
|
||||
|
||||
@@ -255,7 +255,7 @@ jobs:
|
||||
git config --system core.longpaths true
|
||||
git config --system core.autocrlf input
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
@@ -279,11 +279,11 @@ jobs:
|
||||
libuv:p
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
- uses: mozilla-actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11
|
||||
|
||||
- name: Initialize sccache
|
||||
run: |
|
||||
@@ -308,7 +308,7 @@ jobs:
|
||||
# CodeQL
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
|
||||
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
|
||||
with:
|
||||
category: "/language:cpp"
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ MapLibre Native uses a monolithic repository that houses both core C++ code and
|
||||
|
||||
## Core cross-platform C++ code
|
||||
|
||||
In the repository, core C++ code is contained in the `include` and `src` directories. The former includes headers that are considered to make up the "public" core C++ API, while the latter includes `.cpp` implementation files and headers that are private to the implementation. Within both directories, files are nested under an `mbgl` directory, which has various subdirectories based on areas of functionality. Both public and private headers therefore can (and should) always be included with the form `#include <mbgl/___/___.hpp>`.
|
||||
In the repository, core C++ code is contained in the `include` and `src` directories. The former includes headers that are considered to make up the "public" core C++ API, while the latter includes `.cpp` implementation files and headers that are private to the implementation. Within both directories, files are nested under an `mbgl` directory, which has various subdirectories based on areas of functionality. Both public and private headers therefore can (and should) always be included with the form `#include <mln/___/___.hpp>`.
|
||||
|
||||
## Platform specific code
|
||||
|
||||
@@ -24,7 +24,7 @@ Code and build scripts belonging to platform SDKs are contained in the `platform
|
||||
## Other directories
|
||||
|
||||
- `benchmark` contains the performance tests built using https://github.com/google/benchmark/. The code under this directory builds the `mbgl-benchmark-test` executable to execute the benchmark tests.
|
||||
- The entry point of this executable is `platform/default/src/mbgl/benchmark/main.cpp -> benchmark/src/mbgl/benchmark/benchmark.cpp`.
|
||||
- The entry point of this executable is `platform/default/src/mln/benchmark/main.cpp -> benchmark/src/mln/benchmark/benchmark.cpp`.
|
||||
- iOS SDK runs benchmark test through a separate app named `BenchmarkApp`.
|
||||
- Android SDK does not have benchmark test.
|
||||
- `bin` contains the code for tools like `mbgl-cache`, `mbgl-offline`, and `mbgl-render`.
|
||||
@@ -142,4 +142,4 @@ To minimize data races and invalid memory access, we aim for zero shared memory
|
||||
|
||||
Invoking a task on another thread itself creates an ownership obligation: the responsibility for the work happening on the other thread. This ownership is represented by the invocation method returning `std::unique_ptr<AsyncTask>`. Destroying this object indicates that the result of the task is no longer required: the callback is guaranteed not to be called, and the work on the other thread may be aborted (if doing so is convenient).
|
||||
|
||||
All this is implemented by [Thread](https://github.com/mapbox/mapbox-gl-native/blob/master/src/mbgl/util/thread.hpp) and [RunLoop](https://github.com/mapbox/mapbox-gl-native/blob/master/include/mbgl/util/run_loop.hpp).
|
||||
All this is implemented by [Thread](https://github.com/mapbox/mapbox-gl-native/blob/master/src/mln/util/thread.hpp) and [RunLoop](https://github.com/mapbox/mapbox-gl-native/blob/master/include/mln/util/run_loop.hpp).
|
||||
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -29,6 +29,10 @@
|
||||
### 🐞 Bug fixes
|
||||
|
||||
- *...Add new stuff here...*
|
||||
- [core] Draw numbers and short uppercase codes upright in vertical CJK line labels ([#4565](https://github.com/maplibre/maplibre-native/issues/4565)), compat to [maplibre-gl-js#8205](https://github.com/maplibre/maplibre-gl-js/pull/8205).
|
||||
- [core] Fix `ImageSource` not rendering across world copies ([#4508](https://github.com/maplibre/maplibre-native/issues/4508)).
|
||||
- [core] Repaint data-driven symbol paint properties after feature-state updates.
|
||||
- [core] Accept alpha values in legacy comma-separated `hsl()` colors ([#4434](https://github.com/maplibre/maplibre-native/issues/4434)).
|
||||
- [core] Fix thread-unsafe headless OpenGL display singleton initialization [#4332](https://github.com/maplibre/maplibre-native/pull/4332)
|
||||
- [macos] Fix `mlt-cpp` and `mbgl-vendor-icu` not being included in the amalgamation
|
||||
- [core] Fix memory access violation exception in vector_tile_data.cpp [#632](https://github.com/maplibre/maplibre-native/pull/632)
|
||||
@@ -85,7 +89,7 @@
|
||||
|
||||
- [ios, macos] Allow specifying multiple fonts or font families for local font rendering ([#16253](https://github.com/mapbox/mapbox-gl-native/pull/16253))
|
||||
|
||||
By default, CJK characters are now set in the font specified by the `text-font` layout property. If the named font is not installed on the device or bundled with the application, the characters are set in one of the fallback fonts passed into the `localFontFamily` parameter of `mbgl::Renderer::Renderer()` and `mbgl::MapSnapshotter::MapSnapshotter()`. This parameter can now contain a list of font family names, font display names, and font PostScript names, each name separated by a newline.
|
||||
By default, CJK characters are now set in the font specified by the `text-font` layout property. If the named font is not installed on the device or bundled with the application, the characters are set in one of the fallback fonts passed into the `localFontFamily` parameter of `mln::Renderer::Renderer()` and `mln::MapSnapshotter::MapSnapshotter()`. This parameter can now contain a list of font family names, font display names, and font PostScript names, each name separated by a newline.
|
||||
|
||||
### 🐞 Bug fixes
|
||||
|
||||
@@ -139,7 +143,7 @@
|
||||
|
||||
- [core][tile mode] Fix variable placement for labels with the `icon-text-fit` property set ([#16382](https://github.com/mapbox/mapbox-gl-native/pull/16382))
|
||||
|
||||
The `symbolIntersectsTileEdges()` util in `mbgl::TilePlacement` now considers icon shift for the variable symbols with enabled icon-text-fit setting, thus providing more accurate results.
|
||||
The `symbolIntersectsTileEdges()` util in `mln::TilePlacement` now considers icon shift for the variable symbols with enabled icon-text-fit setting, thus providing more accurate results.
|
||||
|
||||
- [core] Correctly log a warning instead of crashing when a non-existent image is attempted to be removed. ([#16391](https://github.com/mapbox/mapbox-gl-native/pull/16391))
|
||||
|
||||
@@ -170,7 +174,7 @@
|
||||
- [android] Add jni binding for styleable snapshotter ([#16286](https://github.com/mapbox/mapbox-gl-native/pull/16286))
|
||||
|
||||
- [core] Ability to set generic layer properties using setProperty method ([#16324](https://github.com/mapbox/mapbox-gl-native/pull/16324))
|
||||
This change enables the following new keys for the `mbgl::Layer::setProperty()` API:
|
||||
This change enables the following new keys for the `mln::Layer::setProperty()` API:
|
||||
- "filter" invokes `setFilter()`
|
||||
- "minzoom" invokes `setMinZoom()`
|
||||
- "maxzoom" invokes `setMaxZoom()`
|
||||
@@ -252,7 +256,7 @@
|
||||
|
||||
- Fixed using of the `in` expression as a layer filter ([#16272](https://github.com/mapbox/mapbox-gl-native/pull/16272))
|
||||
|
||||
The bug was caused by `mbgl::style::conversion::isExpression()` always returning `false` for the `in` expression.
|
||||
The bug was caused by `mln::style::conversion::isExpression()` always returning `false` for the `in` expression.
|
||||
|
||||
### 🧩 Architectural changes
|
||||
|
||||
@@ -296,9 +300,9 @@
|
||||
|
||||
##### ⚠️ Breaking changes
|
||||
|
||||
- Changes to `mbgl::FileSourceManager::getFileSource()` ([#16238](https://github.com/mapbox/mapbox-gl-native/pull/16238))
|
||||
- Changes to `mln::FileSourceManager::getFileSource()` ([#16238](https://github.com/mapbox/mapbox-gl-native/pull/16238))
|
||||
|
||||
It returns now `mbgl::PassRefPtr<FileSource>` (previously was `std::shared_ptr<FileSource>`) in order to enforce keeping the strong reference to the returned object.
|
||||
It returns now `mln::PassRefPtr<FileSource>` (previously was `std::shared_ptr<FileSource>`) in order to enforce keeping the strong reference to the returned object.
|
||||
|
||||
Breaking code example:
|
||||
`auto fs = FileSourceManager::getFileSource(); fs->..`
|
||||
@@ -306,9 +310,9 @@
|
||||
Possible fix:
|
||||
`std::shared_ptr<FileSource> fs = `;
|
||||
|
||||
- The `mbgl::OnlineFileSource` class cannot be used directly ([#16238](https://github.com/mapbox/mapbox-gl-native/pull/16238))
|
||||
- The `mln::OnlineFileSource` class cannot be used directly ([#16238](https://github.com/mapbox/mapbox-gl-native/pull/16238))
|
||||
|
||||
Clients must use the parent `mbgl::FileSource` interface instead.
|
||||
Clients must use the parent `mln::FileSource` interface instead.
|
||||
|
||||
Breaking code example:
|
||||
`std::shared_ptr<OnlineFileSource> onlineSource = std::static_pointer_cast<OnlineFileSource>(FileSourceManager::get()->getFileSource(..));`
|
||||
|
||||
1840
CMakeLists.txt
1840
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
2480
bazel/core.bzl
2480
bazel/core.bzl
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ add_library(
|
||||
${PROJECT_SOURCE_DIR}/benchmark/parse/tile_mask.benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/parse/vector_tile.benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/renderer/group_layers.benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/src/mbgl/benchmark/benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/src/mln/benchmark/benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/storage/offline_database.benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/util/tilecover.benchmark.cpp
|
||||
${PROJECT_SOURCE_DIR}/benchmark/util/color.benchmark.cpp
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/map_options.hpp>
|
||||
#include <mbgl/gfx/headless_frontend.hpp>
|
||||
#include <mbgl/renderer/renderer.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mln/map/map.hpp>
|
||||
#include <mln/map/map_options.hpp>
|
||||
#include <mln/gfx/headless_frontend.hpp>
|
||||
#include <mln/renderer/renderer.hpp>
|
||||
#include <mln/style/style.hpp>
|
||||
#include <mln/style/image.hpp>
|
||||
#include <mln/storage/network_status.hpp>
|
||||
#include <mln/util/image.hpp>
|
||||
#include <mln/util/io.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/gfx/headless_frontend.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/map_observer.hpp>
|
||||
#include <mbgl/map/map_options.hpp>
|
||||
#include <mbgl/renderer/renderer.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/style/sources/geojson_source.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mln/gfx/headless_frontend.hpp>
|
||||
#include <mln/map/map.hpp>
|
||||
#include <mln/map/map_observer.hpp>
|
||||
#include <mln/map/map_options.hpp>
|
||||
#include <mln/renderer/renderer.hpp>
|
||||
#include <mln/storage/network_status.hpp>
|
||||
#include <mln/storage/resource_options.hpp>
|
||||
#include <mln/style/image.hpp>
|
||||
#include <mln/style/layers/symbol_layer.hpp>
|
||||
#include <mln/style/sources/geojson_source.hpp>
|
||||
#include <mln/style/style.hpp>
|
||||
#include <mln/util/image.hpp>
|
||||
#include <mln/util/io.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -124,7 +124,7 @@ static void API_renderStill_recreate_map_2(::benchmark::State& state) {
|
||||
}
|
||||
|
||||
static void API_renderStill_multiple_sources(::benchmark::State& state) {
|
||||
using namespace mbgl::style;
|
||||
using namespace mln::style;
|
||||
RenderBenchmark bench;
|
||||
HeadlessFrontend frontend{size, pixelRatio};
|
||||
Map map{frontend,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/function.hpp>
|
||||
#include <mbgl/style/conversion/property_value.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mln/style/conversion/json.hpp>
|
||||
#include <mln/style/conversion/function.hpp>
|
||||
#include <mln/style/conversion/property_value.hpp>
|
||||
#include <mln/style/conversion_impl.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mln;
|
||||
using namespace mln::style;
|
||||
|
||||
static std::string createFunctionJSON(size_t stopCount) {
|
||||
std::string stops = "[";
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/benchmark/stub_geometry_tile_feature.hpp>
|
||||
#include <mln/benchmark/stub_geometry_tile_feature.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/function.hpp>
|
||||
#include <mbgl/style/conversion/property_value.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mln/style/conversion/json.hpp>
|
||||
#include <mln/style/conversion/function.hpp>
|
||||
#include <mln/style/conversion/property_value.hpp>
|
||||
#include <mln/style/conversion_impl.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mln;
|
||||
using namespace mln::style;
|
||||
|
||||
static std::string createFunctionJSON(size_t stopCount) {
|
||||
std::string stops = "[";
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/benchmark/stub_geometry_tile_feature.hpp>
|
||||
#include <mln/benchmark/stub_geometry_tile_feature.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/property_value.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mln/style/conversion/json.hpp>
|
||||
#include <mln/style/conversion/property_value.hpp>
|
||||
#include <mln/style/conversion_impl.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mln;
|
||||
using namespace mln::style;
|
||||
|
||||
static std::string createFunctionJSON(size_t stopCount) {
|
||||
std::string stops = "[";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace mbgl {
|
||||
namespace mln {
|
||||
|
||||
int runBenchmark(int argc, char* argv[]);
|
||||
|
||||
} // namespace mbgl
|
||||
} // namespace mln
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <ios_test_runner.hpp>
|
||||
|
||||
#include <mbgl/benchmark.hpp>
|
||||
#include <mln/benchmark.hpp>
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mln/util/logging.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
@@ -22,13 +22,13 @@ bool TestRunner::startTest(const std::string& basePath) {
|
||||
argv.push_back(nullptr);
|
||||
|
||||
if (chdir(basePath.c_str())) {
|
||||
mbgl::Log::Error(mbgl::Event::General, "Failed to change the directory to " + basePath);
|
||||
mln::Log::Error(mln::Event::General, "Failed to change the directory to " + basePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
mbgl::Log::Info(mbgl::Event::General, "Start BenchmarkRunner");
|
||||
int status = mbgl::runBenchmark(static_cast<uint32_t>(argv.size()), argv.data());
|
||||
mbgl::Log::Info(mbgl::Event::General, "BenchmarkRunner finished with status: '%d'", status);
|
||||
mln::Log::Info(mln::Event::General, "Start BenchmarkRunner");
|
||||
int status = mln::runBenchmark(static_cast<uint32_t>(argv.size()), argv.data());
|
||||
mln::Log::Info(mln::Event::General, "BenchmarkRunner finished with status: '%d'", status);
|
||||
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/filter.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/benchmark/stub_geometry_tile_feature.hpp>
|
||||
#include <mln/style/filter.hpp>
|
||||
#include <mln/style/conversion/json.hpp>
|
||||
#include <mln/style/conversion/filter.hpp>
|
||||
#include <mln/style/conversion_impl.hpp>
|
||||
#include <mln/tile/geometry_tile_data.hpp>
|
||||
#include <mln/benchmark/stub_geometry_tile_feature.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
style::Filter parse(const char* expression) {
|
||||
style::conversion::Error error;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/algorithm/update_tile_masks.hpp>
|
||||
#include <mln/algorithm/update_tile_masks.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
class FakeTile {
|
||||
public:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mln/tile/vector_mvt_tile_data.hpp>
|
||||
#include <mln/util/io.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
static void Parse_VectorTile(benchmark::State& state) {
|
||||
auto data = std::make_shared<std::string>(
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
// Core function to benchmark
|
||||
#include <mbgl/renderer/group_by_layout.hpp>
|
||||
#include <mln/renderer/group_by_layout.hpp>
|
||||
|
||||
// For mock layer properties
|
||||
#include <mbgl/style/layer_properties.hpp>
|
||||
#include <mbgl/style/layers/fill_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/fill_layer_properties.hpp>
|
||||
#include <mbgl/style/layers/line_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/line_layer_properties.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mbgl/style/layers/circle_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/circle_layer_properties.hpp>
|
||||
#include <mbgl/util/immutable.hpp>
|
||||
#include <mln/style/layer_properties.hpp>
|
||||
#include <mln/style/layers/fill_layer_impl.hpp>
|
||||
#include <mln/style/layers/fill_layer_properties.hpp>
|
||||
#include <mln/style/layers/line_layer_impl.hpp>
|
||||
#include <mln/style/layers/line_layer_properties.hpp>
|
||||
#include <mln/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mln/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mln/style/layers/circle_layer_impl.hpp>
|
||||
#include <mln/style/layers/circle_layer_properties.hpp>
|
||||
#include <mln/util/immutable.hpp>
|
||||
|
||||
// For real style loading
|
||||
#include <mbgl/style/style_impl.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/layermanager/layer_manager.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/util/thread_pool.hpp>
|
||||
#include <mln/style/style_impl.hpp>
|
||||
#include <mln/storage/file_source.hpp>
|
||||
#include <mln/util/io.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
#include <mln/layermanager/layer_manager.hpp>
|
||||
#include <mln/renderer/render_layer.hpp>
|
||||
#include <mln/util/thread_pool.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mln;
|
||||
using namespace mln::style;
|
||||
|
||||
// Minimal FileSource stub for benchmark (doesn't actually fetch resources)
|
||||
class StubFileSource : public FileSource {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <mbgl/benchmark.hpp>
|
||||
#include <mln/benchmark.hpp>
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace mln {
|
||||
|
||||
int runBenchmark(int argc, char* argv[]) {
|
||||
::benchmark::Initialize(&argc, argv);
|
||||
@@ -10,4 +10,4 @@ int runBenchmark(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
} // namespace mln
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mln/tile/geometry_tile_data.hpp>
|
||||
#include <mln/util/feature.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
class StubGeometryTileFeature : public GeometryTileFeature {
|
||||
public:
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/storage/offline_database.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/storage/sqlite3.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mln/storage/offline_database.hpp>
|
||||
#include <mln/storage/resource.hpp>
|
||||
#include <mln/storage/response.hpp>
|
||||
#include <mln/storage/sqlite3.hpp>
|
||||
#include <mln/util/string.hpp>
|
||||
#include <mln/util/logging.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
@@ -18,14 +18,14 @@ public:
|
||||
|
||||
response.data = std::make_shared<std::string>(50 * 1024, 0);
|
||||
response.mustRevalidate = false;
|
||||
response.expires = mbgl::util::now() + 1h;
|
||||
response.expires = mln::util::now() + 1h;
|
||||
|
||||
resetAmbientTiles();
|
||||
resetRegion();
|
||||
}
|
||||
|
||||
void resetAmbientTiles() {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
db.clearAmbientCache();
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
}
|
||||
|
||||
void resetRegion() {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
auto regions = db.listRegions().value();
|
||||
if (!regions.empty()) {
|
||||
@@ -58,8 +58,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
mbgl::Response response;
|
||||
mbgl::OfflineDatabase db{":memory:", mbgl::TileServerOptions::DefaultConfiguration()};
|
||||
mln::Response response;
|
||||
mln::OfflineDatabase db{":memory:", mln::TileServerOptions::DefaultConfiguration()};
|
||||
|
||||
const unsigned tileCount = 100;
|
||||
int64_t regionID = 0;
|
||||
@@ -78,7 +78,7 @@ BENCHMARK_F(OfflineDatabase, DeleteRegion)(benchmark::State& state) {
|
||||
}
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, InsertTileRegion)(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
const Resource offline = Resource::tile(
|
||||
@@ -99,7 +99,7 @@ BENCHMARK_F(OfflineDatabase, ClearAmbientCache)(benchmark::State& state) {
|
||||
}
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, InsertTileCache)(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
const Resource ambient = Resource::tile(
|
||||
@@ -109,7 +109,7 @@ BENCHMARK_F(OfflineDatabase, InsertTileCache)(benchmark::State& state) {
|
||||
}
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, InsertBigTileCache)(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
Response big;
|
||||
big.data = std::make_shared<std::string>(util::DEFAULT_MAX_CACHE_SIZE / 100, 0);
|
||||
@@ -122,7 +122,7 @@ BENCHMARK_F(OfflineDatabase, InsertBigTileCache)(benchmark::State& state) {
|
||||
}
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, GetTile)(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
@@ -136,7 +136,7 @@ BENCHMARK_F(OfflineDatabase, GetTile)(benchmark::State& state) {
|
||||
}
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, AddTilesToFullDatabase)(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
Log::setObserver(std::make_unique<Log::NullObserver>());
|
||||
db.setMaximumAmbientCacheSize(50 * 1024 * 5);
|
||||
@@ -152,7 +152,7 @@ BENCHMARK_F(OfflineDatabase, AddTilesToFullDatabase)(benchmark::State& state) {
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, AddTilesToDisabledDatabase)
|
||||
(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
auto regions = db.listRegions().value();
|
||||
if (!regions.empty()) {
|
||||
@@ -171,7 +171,7 @@ BENCHMARK_F(OfflineDatabase, AddTilesToDisabledDatabase)
|
||||
|
||||
BENCHMARK_F(OfflineDatabase, GetTileFromDisabledDatabase)
|
||||
(benchmark::State& state) {
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
auto regions = db.listRegions().value();
|
||||
if (!regions.empty()) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mln/util/color.hpp>
|
||||
|
||||
static const std::vector<std::string> testStrings = {"#000000",
|
||||
"#FFFFFF",
|
||||
@@ -20,7 +20,7 @@ namespace {
|
||||
void ColorParse(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
for (const auto& str : testStrings) {
|
||||
auto result = mbgl::Color::parse(str);
|
||||
auto result = mln::Color::parse(str);
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/tile_coordinate.hpp>
|
||||
#include <mbgl/util/tile_cover.hpp>
|
||||
#include <mbgl/map/transform.hpp>
|
||||
#include <mln/util/geo.hpp>
|
||||
#include <mln/util/geometry.hpp>
|
||||
#include <mln/util/tile_coordinate.hpp>
|
||||
#include <mln/util/tile_cover.hpp>
|
||||
#include <mln/map/transform.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
static const LatLngBounds sanFrancisco = LatLngBounds::hull({37.6609, -122.5744}, {37.8271, -122.3204});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <mbgl/storage/file_source_manager.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mln/storage/file_source_manager.hpp>
|
||||
#include <mln/storage/resource.hpp>
|
||||
#include <mln/storage/resource_options.hpp>
|
||||
#include <mln/util/chrono.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
|
||||
#include <args.hxx>
|
||||
#include <mapbox/io/io.hpp>
|
||||
@@ -25,20 +25,20 @@ int main(int argc, char* argv[]) {
|
||||
args::ValueFlag<unsigned long> expiresValue(p, "expires", "Expires date, will use 'now' otherwise", {'e'});
|
||||
args::ValueFlag<unsigned long> modifiedValue(p, "modified", "Modified date, will use 'now' otherwise", {'m'});
|
||||
|
||||
std::unordered_map<std::string, mbgl::Resource::Kind> typeMap{{"glyphs", mbgl::Resource::Glyphs},
|
||||
{"image", mbgl::Resource::Image},
|
||||
{"source", mbgl::Resource::Source},
|
||||
{"sprite-image", mbgl::Resource::SpriteImage},
|
||||
{"sprite-json", mbgl::Resource::SpriteJSON},
|
||||
{"style", mbgl::Resource::Style},
|
||||
{"tile", mbgl::Resource::Tile}};
|
||||
std::unordered_map<std::string, mln::Resource::Kind> typeMap{{"glyphs", mln::Resource::Glyphs},
|
||||
{"image", mln::Resource::Image},
|
||||
{"source", mln::Resource::Source},
|
||||
{"sprite-image", mln::Resource::SpriteImage},
|
||||
{"sprite-json", mln::Resource::SpriteJSON},
|
||||
{"style", mln::Resource::Style},
|
||||
{"tile", mln::Resource::Tile}};
|
||||
|
||||
std::string typeHelp("One of the following (required):");
|
||||
for (const auto& key : typeMap) {
|
||||
typeHelp += " " + key.first;
|
||||
}
|
||||
|
||||
args::MapFlag<std::string, mbgl::Resource::Kind> typeFlag(
|
||||
args::MapFlag<std::string, mln::Resource::Kind> typeFlag(
|
||||
p, "type", typeHelp, {"type"}, typeMap, args::Options::Required);
|
||||
|
||||
args::Group tileIdGroup(p, "Coordinates (required for 'tile')", args::Group::Validators::AllOrNone);
|
||||
@@ -67,15 +67,15 @@ int main(int argc, char* argv[]) {
|
||||
exit(3);
|
||||
}
|
||||
|
||||
mbgl::Response response;
|
||||
mln::Response response;
|
||||
response.data = std::make_shared<std::string>(*file);
|
||||
response.etag = etagValue ? args::get(etagValue) : std::string();
|
||||
response.expires = expiresValue ? mbgl::Timestamp(mbgl::Seconds(args::get(expiresValue))) : mbgl::util::now();
|
||||
response.modified = modifiedValue ? mbgl::Timestamp(mbgl::Seconds(args::get(modifiedValue))) : mbgl::util::now();
|
||||
response.expires = expiresValue ? mln::Timestamp(mln::Seconds(args::get(expiresValue))) : mln::util::now();
|
||||
response.modified = modifiedValue ? mln::Timestamp(mln::Seconds(args::get(modifiedValue))) : mln::util::now();
|
||||
|
||||
mbgl::Resource resource(args::get(typeFlag), args::get(urlValue));
|
||||
mln::Resource resource(args::get(typeFlag), args::get(urlValue));
|
||||
|
||||
if (args::get(typeFlag) == mbgl::Resource::Tile) {
|
||||
if (args::get(typeFlag) == mln::Resource::Tile) {
|
||||
if (!xValueFlag || !yValueFlag || !zValueFlag) {
|
||||
std::cerr << "Error: -x, -y and -z must be provided for tiles" << '\n';
|
||||
exit(1);
|
||||
@@ -88,9 +88,9 @@ int main(int argc, char* argv[]) {
|
||||
.z = static_cast<int8_t>(args::get(zValueFlag))}};
|
||||
}
|
||||
|
||||
mbgl::util::RunLoop loop;
|
||||
std::shared_ptr<mbgl::FileSource> dbfs = mbgl::FileSourceManager::get()->getFileSource(
|
||||
mbgl::FileSourceType::Database, mbgl::ResourceOptions().withCachePath(args::get(cacheValue)));
|
||||
mln::util::RunLoop loop;
|
||||
std::shared_ptr<mln::FileSource> dbfs = mln::FileSourceManager::get()->getFileSource(
|
||||
mln::FileSourceType::Database, mln::ResourceOptions().withCachePath(args::get(cacheValue)));
|
||||
dbfs->forward(resource, response, [&loop] { loop.stop(); });
|
||||
loop.run();
|
||||
return 0;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/geojson.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
#include <mln/util/string.hpp>
|
||||
#include <mln/util/geojson.hpp>
|
||||
|
||||
#include <mbgl/storage/database_file_source.hpp>
|
||||
#include <mbgl/storage/file_source_manager.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
#include <mbgl/util/client_options.hpp>
|
||||
#include <mbgl/util/tile_server_options.hpp>
|
||||
#include <mln/storage/database_file_source.hpp>
|
||||
#include <mln/storage/file_source_manager.hpp>
|
||||
#include <mln/storage/resource_options.hpp>
|
||||
#include <mln/util/client_options.hpp>
|
||||
#include <mln/util/tile_server_options.hpp>
|
||||
|
||||
#include <args.hxx>
|
||||
|
||||
@@ -51,19 +51,19 @@ mapbox::geometry::geometry<double> parseGeometry(const std::string& json) {
|
||||
});
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, mbgl::Response::Error::Reason r) {
|
||||
std::ostream& operator<<(std::ostream& os, mln::Response::Error::Reason r) {
|
||||
switch (r) {
|
||||
case mbgl::Response::Error::Reason::Success:
|
||||
case mln::Response::Error::Reason::Success:
|
||||
return os << "Response::Error::Reason::Success";
|
||||
case mbgl::Response::Error::Reason::NotFound:
|
||||
case mln::Response::Error::Reason::NotFound:
|
||||
return os << "Response::Error::Reason::NotFound";
|
||||
case mbgl::Response::Error::Reason::Server:
|
||||
case mln::Response::Error::Reason::Server:
|
||||
return os << "Response::Error::Reason::Server";
|
||||
case mbgl::Response::Error::Reason::Connection:
|
||||
case mln::Response::Error::Reason::Connection:
|
||||
return os << "Response::Error::Reason::Connection";
|
||||
case mbgl::Response::Error::Reason::RateLimit:
|
||||
case mln::Response::Error::Reason::RateLimit:
|
||||
return os << "Response::Error::Reason::RateLimit";
|
||||
case mbgl::Response::Error::Reason::Other:
|
||||
case mln::Response::Error::Reason::Other:
|
||||
return os << "Response::Error::Reason::Other";
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ int main(int argc, char* argv[]) {
|
||||
exit(2);
|
||||
}
|
||||
|
||||
auto mapTilerConfiguration = mbgl::TileServerOptions::MapTilerConfiguration();
|
||||
auto mapTilerConfiguration = mln::TileServerOptions::MapTilerConfiguration();
|
||||
|
||||
std::string style = styleValue ? args::get(styleValue) : mapTilerConfiguration.defaultStyles().at(0).getUrl();
|
||||
std::cout << " Style: " << style << std::endl;
|
||||
@@ -138,7 +138,7 @@ int main(int argc, char* argv[]) {
|
||||
const bool includeIdeographs = includeIdeographsValue ? args::get(includeIdeographsValue) : false;
|
||||
const std::string output = outputValue ? args::get(outputValue) : "offline.db";
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
OfflineRegionDefinition definition = [&]() {
|
||||
if (geometryValue) {
|
||||
@@ -185,7 +185,7 @@ int main(int argc, char* argv[]) {
|
||||
int retCode = 0;
|
||||
std::cout << "Start Merge" << std::endl;
|
||||
inputSource.mergeOfflineRegions(
|
||||
*mergePath, [&](mbgl::expected<std::vector<OfflineRegion>, std::exception_ptr> result) {
|
||||
*mergePath, [&](mln::expected<std::vector<OfflineRegion>, std::exception_ptr> result) {
|
||||
if (!result) {
|
||||
std::cerr << "Error merging database: " << util::toString(result.error()) << std::endl;
|
||||
retCode = 1;
|
||||
@@ -264,7 +264,7 @@ int main(int argc, char* argv[]) {
|
||||
std::signal(SIGINT, [](int) { stop(); });
|
||||
|
||||
fileSource->createOfflineRegion(
|
||||
definition, metadata, [&](mbgl::expected<OfflineRegion, std::exception_ptr> region_) {
|
||||
definition, metadata, [&](mln::expected<OfflineRegion, std::exception_ptr> region_) {
|
||||
if (!region_) {
|
||||
std::cerr << "Error creating region: " << util::toString(region_.error()) << std::endl;
|
||||
loop.stop();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/map_options.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mln/map/map.hpp>
|
||||
#include <mln/map/map_options.hpp>
|
||||
#include <mln/util/image.hpp>
|
||||
#include <mln/util/run_loop.hpp>
|
||||
|
||||
#include <mbgl/gfx/backend.hpp>
|
||||
#include <mbgl/gfx/headless_frontend.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mln/gfx/backend.hpp>
|
||||
#include <mln/gfx/headless_frontend.hpp>
|
||||
#include <mln/style/style.hpp>
|
||||
|
||||
#include <args.hxx>
|
||||
|
||||
@@ -19,8 +19,10 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
args::ValueFlag<std::string> backendValue(argumentParser, "Backend", "Rendering backend", {"backend"});
|
||||
args::ValueFlag<std::string> apikeyValue(argumentParser, "key", "API key", {'t', "apikey"});
|
||||
args::ValueFlag<std::string> styleValue(argumentParser, "URL", "Map stylesheet", {'s', "style"});
|
||||
args::ValueFlag<std::string> outputValue(argumentParser, "file", "Output file name", {'o', "output"});
|
||||
args::ValueFlag<std::string> styleValue(
|
||||
argumentParser, "URL|file|-", "Map stylesheet (use '-' for stdin)", {'s', "style"});
|
||||
args::ValueFlag<std::string> outputValue(
|
||||
argumentParser, "file|-", "Output file name (use '-' for stdout)", {'o', "output"});
|
||||
args::ValueFlag<std::string> cacheValue(argumentParser, "file", "Cache database file name", {'c', "cache"});
|
||||
args::ValueFlag<std::string> assetsValue(
|
||||
argumentParser, "file", "Directory to which asset:// URLs will resolve", {'a', "assets"});
|
||||
@@ -69,7 +71,7 @@ int main(int argc, char* argv[]) {
|
||||
const double lon = lonValue ? args::get(lonValue) : 0;
|
||||
const double alt = altValue ? args::get(altValue) : 0;
|
||||
const double zoom = zoomValue ? args::get(zoomValue) : 0;
|
||||
const double fov = fovValue ? args::get(fovValue) : mbgl::util::rad2deg(mbgl::util::DEFAULT_FOV);
|
||||
const double fov = fovValue ? args::get(fovValue) : mln::util::rad2deg(mln::util::DEFAULT_FOV);
|
||||
const double bearing = bearingValue ? args::get(bearingValue) : 0;
|
||||
const double pitch = pitchValue ? args::get(pitchValue) : 0;
|
||||
const double roll = rollValue ? args::get(rollValue) : 0;
|
||||
@@ -87,9 +89,11 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
const bool debug = debugFlag ? args::get(debugFlag) : false;
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mln;
|
||||
|
||||
auto mapTilerConfiguration = mbgl::TileServerOptions::MapTilerConfiguration();
|
||||
auto mapTilerConfiguration = mln::TileServerOptions::MapTilerConfiguration();
|
||||
|
||||
std::string json;
|
||||
std::string style = styleValue ? args::get(styleValue) : mapTilerConfiguration.defaultStyles().at(0).getUrl();
|
||||
|
||||
util::RunLoop loop;
|
||||
@@ -115,11 +119,16 @@ int main(int argc, char* argv[]) {
|
||||
.withApiKey(apikey)
|
||||
.withTileServerOptions(mapTilerConfiguration));
|
||||
|
||||
if (style.find("://") == std::string::npos) {
|
||||
style = std::string("file://") + style;
|
||||
}
|
||||
if (style == "-") {
|
||||
json = std::string(std::istreambuf_iterator<char>(std::cin), std::istreambuf_iterator<char>());
|
||||
map.getStyle().loadJSON(json);
|
||||
} else {
|
||||
if (style.find("://") == std::string::npos) {
|
||||
style = std::string("file://") + style;
|
||||
}
|
||||
|
||||
map.getStyle().loadURL(style);
|
||||
map.getStyle().loadURL(style);
|
||||
}
|
||||
std::vector<double> bounds = args::get(boundsValue);
|
||||
if (bounds.size() == 4) {
|
||||
LatLngBounds boundingBox = LatLngBounds::hull(LatLng(bounds[0], bounds[1]), LatLng(bounds[2], bounds[3]));
|
||||
@@ -136,14 +145,19 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
map.setDebug(debug ? mbgl::MapDebugOptions::TileBorders | mbgl::MapDebugOptions::ParseStatus
|
||||
: mbgl::MapDebugOptions::NoDebug);
|
||||
map.setDebug(debug ? mln::MapDebugOptions::TileBorders | mln::MapDebugOptions::ParseStatus
|
||||
: mln::MapDebugOptions::NoDebug);
|
||||
}
|
||||
|
||||
try {
|
||||
std::ofstream out(output, std::ios::binary);
|
||||
out << encodePNG(frontend.render(map).image);
|
||||
out.close();
|
||||
std::string png = encodePNG(frontend.render(map).image);
|
||||
if (output == "-") {
|
||||
std::cout.write(png.data(), png.size());
|
||||
} else {
|
||||
std::ofstream out(output, std::ios::binary);
|
||||
out << png;
|
||||
out.close();
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
exit(1);
|
||||
|
||||
@@ -11,96 +11,93 @@ target_compile_definitions(
|
||||
)
|
||||
list(APPEND
|
||||
INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/mtl_fwd.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/tile_layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/mtl/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/particle_gpu_validation.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/retained_underlay_composite.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/symbol.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/mtl_fwd.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/tile_layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/mtl/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/particle_gpu_validation.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/retained_underlay_composite.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/shader_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/mtl/symbol.hpp
|
||||
)
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/mtl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/mtl/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/particle_gpu_validation.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/retained_underlay_composite.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/widevector.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/mtl/custom_layer_render_parameters.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/drawable_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/mtl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/mtl/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/particle_gpu_validation.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/retained_underlay_composite.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/mtl/widevector.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/style/layers/mtl/custom_layer_render_parameters.cpp
|
||||
)
|
||||
|
||||
find_library(METAL_FRAMEWORK Metal)
|
||||
if (METAL_FRAMEWORK)
|
||||
target_link_libraries(mbgl-core PRIVATE ${METAL_FRAMEWORK})
|
||||
endif()
|
||||
target_link_libraries(mbgl-core PRIVATE "-framework Metal")
|
||||
|
||||
@@ -11,143 +11,144 @@ target_compile_definitions(
|
||||
)
|
||||
list(APPEND
|
||||
INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/platform/gl_functions.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_manifest.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/shader_group_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/prelude.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/collision_box.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/collision_circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_outline.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_outline_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_outline_triangulated.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_extrusion_instanced.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_extrusion_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/fill_extrusion_pattern_instanced.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/retained_underlay_composite.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/line_gradient.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/line_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/line_sdf.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/location_indicator_textured.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/symbol_sdf.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/symbol_text_and_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/wide_vector.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/platform/gl_functions.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/shader_manifest.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/shader_group_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/prelude.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/background_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/collision_box.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/collision_circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_outline.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_outline_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_outline_triangulated.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_extrusion_instanced.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_extrusion_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/fill_extrusion_pattern_instanced.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/particle_gpu_validation.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/retained_underlay_composite.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/line_gradient.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/line_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/line_sdf.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/location_indicator_textured.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/symbol_sdf.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/symbol_text_and_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/wide_vector.hpp
|
||||
)
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/fence.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/fence.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/debugging_extension.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/debugging_extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/defines.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/draw_scope_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/enum.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/enum.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/framebuffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/object.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/object.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/renderbuffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/renderbuffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/resource_pool.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/resource_pool.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/state.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/timestamp_query_extension.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/timestamp_query_extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/value.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/value.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_array.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_array.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/platform/gl_functions.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/legacy/clipping_mask_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/legacy/program_base.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/legacy/program.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/legacy/programs.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/legacy/programs.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/fence.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/fence.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/debugging_extension.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/debugging_extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/defines.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/draw_scope_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/enum.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/enum.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/framebuffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/object.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/object.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/renderbuffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/renderbuffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/resource_pool.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/resource_pool.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/state.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/timestamp_query_extension.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/timestamp_query_extension.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/uniform.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/uniform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/value.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/value.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/vertex_array.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/vertex_array.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/platform/gl_functions.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/legacy/clipping_mask_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/legacy/program_base.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/legacy/program.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/legacy/programs.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/legacy/programs.hpp
|
||||
)
|
||||
|
||||
list(APPEND INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/background_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/circle_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/collision_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/custom_drawable_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/debug_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/fill_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/fill_extrusion_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/heatmap_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/heatmap_texture_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/hillshade_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/color_relief_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/hillshade_prepare_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/line_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/location_indicator_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/raster_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_defines.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/symbol_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/widevector_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/custom_drawable_layer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/custom_drawable_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/shader_program_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/buffer_allocator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/layer_group_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_buffer_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/vertex_attribute_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/background_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/circle_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/collision_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/custom_drawable_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/debug_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/fill_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/fill_extrusion_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/heatmap_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/heatmap_texture_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/hillshade_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/color_relief_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/hillshade_prepare_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/line_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/location_indicator_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/raster_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/shader_defines.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/symbol_layer_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/widevector_ubo.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/style/layers/custom_drawable_layer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/layermanager/custom_drawable_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/gl/shader_program_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/buffer_allocator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/drawable_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/drawable_gl_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/layer_group_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/uniform_buffer_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/gl/vertex_attribute_gl.hpp
|
||||
)
|
||||
list(APPEND SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/shader_info.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/gl/shader_program_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/buffer_allocator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/layer_group_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_buffer_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/vertex_attribute_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/shader_info.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/gl/shader_program_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/buffer_allocator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/drawable_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/drawable_gl_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/drawable_gl_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/layer_group_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/uniform_buffer_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/gl/vertex_attribute_gl.cpp
|
||||
)
|
||||
|
||||
@@ -12,93 +12,93 @@ target_compile_definitions(
|
||||
|
||||
list(APPEND
|
||||
INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/vulkan/custom_layer_init_parameters.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/layers/vulkan/custom_layer_render_parameters.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/descriptor_set.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/pipeline.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/tile_layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/vulkan/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/shader_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/symbol.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/widevector.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/style/layers/vulkan/custom_layer_init_parameters.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/style/layers/vulkan/custom_layer_render_parameters.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/descriptor_set.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/offscreen_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/pipeline.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/renderable_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/tile_layer_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/vulkan/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/shader_group.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/symbol.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/vulkan/widevector.hpp
|
||||
)
|
||||
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/layers/vulkan/custom_layer_render_parameters.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/descriptor_set.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/drawable_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/pipeline.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/renderable_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/vulkan/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/widevector.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/style/layers/vulkan/custom_layer_render_parameters.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/descriptor_set.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/drawable_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/pipeline.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/renderable_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/vulkan/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/vulkan/widevector.cpp
|
||||
)
|
||||
|
||||
@@ -17,99 +17,98 @@ target_include_directories(
|
||||
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/headless_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/draw_scope_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/wgsl_preprocessor.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/widevector.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/draw_scope_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/wgsl_preprocessor.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/background.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/circle.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/clipping_mask.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/collision.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/custom_geometry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/custom_symbol_icon.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/debug.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/fill.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/fill_extrusion.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/heatmap.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/heatmap_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/hillshade.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/hillshade_prepare.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/color_relief.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/line.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/location_indicator.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/raster.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/symbol.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/widevector.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/vertex_attribute.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/offscreen_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/tile_layer_group.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/layer_group.cpp
|
||||
)
|
||||
|
||||
list(APPEND
|
||||
INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/symbol.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/webgpu/widevector.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/webgpu/vertex_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/command_encoder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/context.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/drawable.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/dynamic_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/index_buffer_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/render_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/renderer_backend.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/shader_program.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/background.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/circle.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/clipping_mask.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/collision.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/common.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/custom_geometry.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/custom_symbol_icon.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/debug.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/fill.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/hillshade.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/hillshade_prepare.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/color_relief.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/line.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/location_indicator.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/raster.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/symbol.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/shaders/webgpu/widevector.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/upload_pass.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mln/webgpu/vertex_buffer_resource.hpp
|
||||
)
|
||||
|
||||
list(APPEND
|
||||
SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/shaders/webgpu/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/vertex_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/command_encoder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/context.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/dynamic_texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/index_buffer_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/render_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/renderer_backend.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/shaders/webgpu/shader_program.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/uniform_buffer.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/upload_pass.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mln/webgpu/vertex_buffer_resource.cpp
|
||||
)
|
||||
|
||||
# Include WebGPU vendor configuration (Dawn or wgpu)
|
||||
@@ -119,7 +118,13 @@ include(${PROJECT_SOURCE_DIR}/vendor/webgpu.cmake)
|
||||
if(MLN_WEBGPU_IMPL_DAWN)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/dawn.cmake)
|
||||
if(TARGET mbgl-vendor-dawn)
|
||||
target_link_libraries(mbgl-core PRIVATE mbgl-vendor-dawn)
|
||||
if(MLN_WEBGPU_EMDAWN)
|
||||
# Emdawn is a compiler/linker port rather than a conventional
|
||||
# library. Consumers must inherit its final-link options.
|
||||
target_link_libraries(mbgl-core PUBLIC mbgl-vendor-dawn)
|
||||
else()
|
||||
target_link_libraries(mbgl-core PRIVATE mbgl-vendor-dawn)
|
||||
endif()
|
||||
endif()
|
||||
elseif(MLN_WEBGPU_IMPL_WGPU OR MLN_WEBGPU_IMPL_FFI)
|
||||
# Include wgpu-native integration
|
||||
@@ -127,6 +132,11 @@ elseif(MLN_WEBGPU_IMPL_WGPU OR MLN_WEBGPU_IMPL_FFI)
|
||||
if(TARGET mbgl-vendor-wgpu)
|
||||
target_link_libraries(mbgl-core PRIVATE mbgl-vendor-wgpu)
|
||||
# Add WebGPU-Cpp implementation file (required for wgpu-native backend)
|
||||
list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/webgpu_cpp_impl.cpp)
|
||||
list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mln/webgpu/webgpu_cpp_impl.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Headless backend uses Dawn native / wgpu-native bootstrap; skip for emdawnwebgpu.
|
||||
if(NOT MLN_WEBGPU_EMDAWN)
|
||||
list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mln/webgpu/headless_backend.cpp)
|
||||
endif()
|
||||
|
||||
@@ -75,7 +75,7 @@ The shaders need a representation visible outside the toolkit and we need to cha
|
||||
|
||||
Individual shaders are represented by an object class with massive amounts of template logic and a minimum of in-line comments. They’re opaque from the outside and only controllable through vector tile data and styles.
|
||||
|
||||
The [render_raster_layer](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/layers/render_raster_layer.cpp), as an example, asks for the instantiation of (eventually) RasterProgram. Rather than having the source for the program, that then pokes into a compressed chunk of memory that contains the source, which is then uncompressed and fed into OpenGL for compilation.
|
||||
The [render_raster_layer](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/layers/render_raster_layer.cpp), as an example, asks for the instantiation of (eventually) RasterProgram. Rather than having the source for the program, that then pokes into a compressed chunk of memory that contains the source, which is then uncompressed and fed into OpenGL for compilation.
|
||||
|
||||
All of this makes sense in context, but is completely inaccessible outside the toolkit and rather incomprehensible when making changes.
|
||||
|
||||
@@ -134,9 +134,9 @@ Modern graphics pipelines use more than one pass to create a visual representati
|
||||
Without getting too deep into specifics, early rendering passes allow the developer to use the power of the rasterizer for their own data. Later rendering passes are typically used to decorate the map with effects.
|
||||
|
||||
#### The way it is now:
|
||||
The [low level rendering logic](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/renderer_impl.cpp) in the toolkit seems to only support one explicit rendering pass.
|
||||
The [low level rendering logic](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/renderer_impl.cpp) in the toolkit seems to only support one explicit rendering pass.
|
||||
|
||||
However, there is the [RenderPass](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/gl/render_pass.hpp) so some notion of this exists in the toolkit, but it's not clear how complete that is. It may depend on ordering to work things out, rather than the explicit command buffer filling and fences we would use in a more modern approach.
|
||||
However, there is the [RenderPass](https://github.com/maplibre/maplibre-native/blob/main/src/mln/gl/render_pass.hpp) so some notion of this exists in the toolkit, but it's not clear how complete that is. It may depend on ordering to work things out, rather than the explicit command buffer filling and fences we would use in a more modern approach.
|
||||
|
||||
In any case, we need this filled out more explicitly for the render targets.
|
||||
|
||||
@@ -205,7 +205,7 @@ In WhirlyGlobe we’ve always called out separate objects for drawing certain ki
|
||||
|
||||
Which is to say that Drawable is a good concept which can encapsulate a lot of complexity. So much so that it eventually encapsulates ALL the complexity, at least at that level of rendering. It’s a good interface between the things that construct geometry and the things that render geometry.
|
||||
|
||||
To keep the Drawable somewhat manageable, we added the concept of a Drawable Builder. This is an object that you throw geometry at in a somewhat disordered way and it emits Drawables when you’re done. MapLibre's [Buckets](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/bucket.hpp) are similar, but not quite the same. Perhaps they'll be adaptable. We'll see.
|
||||
To keep the Drawable somewhat manageable, we added the concept of a Drawable Builder. This is an object that you throw geometry at in a somewhat disordered way and it emits Drawables when you’re done. MapLibre's [Buckets](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/bucket.hpp) are similar, but not quite the same. Perhaps they'll be adaptable. We'll see.
|
||||
|
||||
Drawables and Builders have a subclass for each supported rendering SDK. One mistake we won’t bring over is using multiple inheritance for that. You’re welcome.
|
||||
|
||||
@@ -221,7 +221,7 @@ Builders will be used primarily by Layers to emit Drawables for rendering.
|
||||
|
||||
This is a big topic because it gets to the very heart of the critical changes we want to make to the toolkit. There are a couple of different categories that are revealing and we'll use some examples.
|
||||
|
||||
Most commonly there are *render layers*. These are individual classes that know how to render, for instance, the [fill layer](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/layers/render_fill_layer.cpp). You'll see a bunch of these that start with "render" and end with "layer".
|
||||
Most commonly there are *render layers*. These are individual classes that know how to render, for instance, the [fill layer](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/layers/render_fill_layer.cpp). You'll see a bunch of these that start with "render" and end with "layer".
|
||||
|
||||
What's going on here is that the toolkit has broken out a bunch of features from a tile, consolidated them together in a Bucket and then handed them off to a Layer to render. Sure enough, if you look in the render_*_layer you can see it doing just that.
|
||||
|
||||
@@ -230,7 +230,7 @@ Now it's not redoing the work of consolidation each frame, but it is doing a lot
|
||||
- This is more specific logic than we'd want to see in a rendering loop. Remember, this runs every frame.
|
||||
- If your data is not in tile form, it's going to be hard to render.
|
||||
|
||||
That last one is really interesting and we can find an example in MapLibre Native itself. Look to the [Render Location Indicator Layer](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/layers/render_location_indicator_layer.cpp). Here's where this approach trips up... rolls down the hill... into a pile of broken glass. You can feel the developers' pain in this module.
|
||||
That last one is really interesting and we can find an example in MapLibre Native itself. Look to the [Render Location Indicator Layer](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/layers/render_location_indicator_layer.cpp). Here's where this approach trips up... rolls down the hill... into a pile of broken glass. You can feel the developers' pain in this module.
|
||||
|
||||
If you're not familiar with real time rendering toolkits, I'll put it this way. Managing the logic for a location puck that updates every time the user moves should not involve direct OpenGL calls. It should be abstracted, at least a little.
|
||||
|
||||
@@ -319,7 +319,7 @@ Every real time rendering toolkit has a main rendering loop or something like it
|
||||
|
||||
On iOS this runs on the main thread and on Android this runs on its own separate thread. You might think the latter is better, but it has its own problems (gesture lag). In any case, MapLibre Native handles both just fine.
|
||||
|
||||
The toolkit's main rendering "loop" lives in [renderer_impl](https://github.com/maplibre/maplibre-native/blob/main/src/mbgl/renderer/renderer_impl.cpp) and it's worth a look. It serves as a central point to begin examining the real time rendering.
|
||||
The toolkit's main rendering "loop" lives in [renderer_impl](https://github.com/maplibre/maplibre-native/blob/main/src/mln/renderer/renderer_impl.cpp) and it's worth a look. It serves as a central point to begin examining the real time rendering.
|
||||
|
||||
As you might suspect, the rendering loop logic and implementation are heavily influenced by OpenGL.
|
||||
|
||||
|
||||
184
design-proposals/2025-07-05-custom-vector-source.md
Normal file
184
design-proposals/2025-07-05-custom-vector-source.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# Custom Vector Source
|
||||
|
||||
## Motivation
|
||||
|
||||
MapLibre Native currently supports two ways to provide vector tile data:
|
||||
|
||||
1. **URL-based sources** (`vector` source type) — tiles are fetched according to the protocol of the URL (`http://`,
|
||||
`file://`, etc.).
|
||||
2. **CustomGeometrySource** — accepts GeoJSON features programmatically, but internally re-encodes them into vector
|
||||
tiles, adding overhead and limiting control over the tile encoding.
|
||||
|
||||
This proposal comes from the need for an efficient and kotlin native way to asynchronously connect a tile data source
|
||||
similar to vector tile.
|
||||
CustomGeometrySource was considered, but it has some obvious drawbacks:
|
||||
|
||||
1. Tile requests are in the format of a bounding box — since it's not a tile X/Y/Z it is pretty unclear what logic it
|
||||
conforms to.
|
||||
1. Is it just a tile X/Y/Z but converted to geo bounds?
|
||||
2. Can it ever request data in a bounding box that is bigger than just one X/Y/Z tile
|
||||
3. Additional boilerplate of mapping geo bounds into tile X/Y/Z
|
||||
2. Internally CustomGeometrySource spawns a 4 thread threadpool and runs tasks one by one inside. It's a good old
|
||||
technique
|
||||
but Kotlin has things like coroutines which are a more ergonomic way to handle suspendable operations (like network
|
||||
requests).
|
||||
3. CustomGeometrySource operates over GeoJSON. So in case of a vector tiles like format it needs to be converted to
|
||||
GeoJSON and then internally it will be cut down into vector tile format back.
|
||||
|
||||
## Proposed Change
|
||||
|
||||
Introduce a new source type, `CustomVectorSource`, that lets the application deliver raw binary tile data (starting with
|
||||
MVT) directly to the rendering pipeline. The source participates in the standard tile loading lifecycle — the core
|
||||
requests tiles by `CanonicalTileID`, and the application responds asynchronously with encoded data or an error.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Platform layer (Kotlin) │
|
||||
│ │
|
||||
│ CustomVectorTileProvider.fetchTile(z, x, y) → TileData │
|
||||
│ ↕ (JNI / platform bridge) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Core C++ layer │
|
||||
│ │
|
||||
│ CustomVectorSource │
|
||||
│ ├── Options { fetchTileFunction, cancelTileFunction, │
|
||||
│ │ zoomRange } │
|
||||
│ ├── setTileData(CanonicalTileID, shared_ptr<string>, │
|
||||
│ │ TileDataFormat) │
|
||||
│ ├── setTileError(CanonicalTileID, exception_ptr) │
|
||||
│ └── invalidateTile(CanonicalTileID) │
|
||||
│ │
|
||||
│ CustomVectorTileLoader (Actor on Scheduler::GetBackground) │
|
||||
│ └── Receives fetch/cancel requests from tiles │
|
||||
│ │
|
||||
│ CustomVectorTile (extends Tile) │
|
||||
│ └── Parses MVT data via VectorTileData, delegates to │
|
||||
│ standard GeometryTileWorker for symbol/line/fill │
|
||||
│ layout │
|
||||
│ │
|
||||
│ RenderCustomVectorSource (extends RenderTileSetSource) │
|
||||
│ └── Standard tile pyramid rendering │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Existing rendering pipeline (unchanged) │
|
||||
│ GeometryTileWorker → Buckets → Drawables → GPU │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key Design Decisions
|
||||
|
||||
1. **Binary data, not GeoJSON.** For the Kotlin layer to send data to C++, it needs to be marshaled into some
|
||||
data format that can be passed across languages. One could come up with a new binary format, implement an encoder in
|
||||
Kotlin and a decoder in C++. But it turns out MVT is already such a format — just a binary blob that can be passed
|
||||
simply as a sized buffer. Existing infrastructure of `MVT` tile data is just reused as is.
|
||||
|
||||
2. **Actor-based concurrency.** `CustomVectorTileLoader` runs on a background thread via MapLibre's Actor system. The
|
||||
platform callback (fetch/cancel) is invoked on this thread; the platform layer is responsible for dispatching to its
|
||||
own preferred context (e.g., coroutines on Android).
|
||||
|
||||
3. **Cooperative cancellation.** When a tile is no longer needed (e.g., user panned away), the core calls
|
||||
`cancelTileFunction`. The platform layer can abort in-flight work.
|
||||
|
||||
4. **Standard tile pipeline reuse.** Once binary data arrives, it goes through the same `VectorTileData` →
|
||||
`GeometryTileWorker` path as HTTP-fetched vector tiles. No custom rendering code is needed.
|
||||
|
||||
5. **Extensible format enum.** `TileDataFormat` is an enum starting with `MVT`. Future formats (e.g., a hypothetical
|
||||
compact binary format) can be added without API changes. And obvious next candidate is `MLT` format support in
|
||||
CustomVectorSource.
|
||||
|
||||
### Threading Model
|
||||
|
||||
```
|
||||
Main thread: Source::update() → tile needs data
|
||||
↓
|
||||
Background Actor: CustomVectorTileLoader::fetchTile()
|
||||
↓
|
||||
Platform bridge: fetchTileFunction callback → platform code
|
||||
↓ (async, any thread)
|
||||
setTileData() → mailbox → CustomVectorTile::setData()
|
||||
↓
|
||||
GeometryTileWorker: parse MVT, create buckets (background pool)
|
||||
↓
|
||||
Main thread: Tile ready → render
|
||||
```
|
||||
|
||||
## API Modifications
|
||||
|
||||
### Core C++ (public header)
|
||||
|
||||
```cpp
|
||||
namespace mln::style {
|
||||
|
||||
enum class TileDataFormat : uint8_t { MVT = 0 };
|
||||
|
||||
using TileFunction = std::function<void(const CanonicalTileID&)>;
|
||||
|
||||
class CustomVectorSource final : public Source {
|
||||
public:
|
||||
struct Options {
|
||||
TileFunction fetchTileFunction;
|
||||
TileFunction cancelTileFunction;
|
||||
Range<uint8_t> zoomRange = {0, 18};
|
||||
};
|
||||
|
||||
CustomVectorSource(std::string id, const Options& options);
|
||||
|
||||
void setTileData(const CanonicalTileID&,
|
||||
const std::shared_ptr<const std::string>& data,
|
||||
TileDataFormat format = TileDataFormat::MVT);
|
||||
void setTileError(const CanonicalTileID&, std::exception_ptr error);
|
||||
void invalidateTile(const CanonicalTileID&);
|
||||
};
|
||||
|
||||
} // namespace mln::style
|
||||
```
|
||||
|
||||
### Android (Kotlin)
|
||||
|
||||
```kotlin
|
||||
interface CustomVectorTileProvider {
|
||||
suspend fun fetchTile(z: Int, x: Int, y: Int): TileData
|
||||
}
|
||||
|
||||
sealed class TileData {
|
||||
class Mvt(val data: ByteArray) : TileData()
|
||||
}
|
||||
|
||||
class CustomVectorSource(
|
||||
id: String,
|
||||
provider: CustomVectorTileProvider,
|
||||
scope: CoroutineScope,
|
||||
minZoom: Int = 0,
|
||||
maxZoom: Int = 18
|
||||
) : Source()
|
||||
```
|
||||
|
||||
The Android API uses Kotlin coroutines for async tile fetching. The `CoroutineScope` is caller-provided. Meaning
|
||||
`CustomVectorSource` can run on a threadpool but not limited to a threadpool. `CoroutineScope` abstracts it away.
|
||||
|
||||
### iOS / macOS
|
||||
|
||||
Not included in this initial implementation. The core C++ API is platform-agnostic and can be wrapped in Swift/Obj-C
|
||||
following the same pattern.
|
||||
|
||||
## Migration Plan and Compatibility
|
||||
|
||||
All changes are **additive**. No existing APIs are modified or removed. The new source type is opt-in — applications
|
||||
that don't use it are unaffected.
|
||||
|
||||
- A new `SourceType::CustomMVTVector` enum value is added to the core.
|
||||
- Existing `CustomGeometrySource` remains unchanged and is not deprecated.
|
||||
|
||||
## Rejected Alternatives
|
||||
|
||||
### Extend CustomGeometrySource to accept binary data
|
||||
|
||||
`CustomGeometrySource` is designed around GeoJSON features and internally manages geometry encoding. Bolting binary tile
|
||||
support onto it would conflate two different data models and complicate its already non-trivial implementation.
|
||||
|
||||
### Use a local file source with a custom URL scheme
|
||||
|
||||
This approach (e.g., `mbtiles://` or `custom://`) requires the application to write tile data to disk or implement a
|
||||
custom `FileSource`. It adds I/O overhead, doesn't support cooperative cancellation, and is harder to integrate with
|
||||
structured concurrency frameworks like Kotlin coroutines.
|
||||
104
docs/20_调查/Particle_V13_严格代码审查报告_v1.md
Normal file
104
docs/20_调查/Particle_V13_严格代码审查报告_v1.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Particle V13 严格代码审查报告
|
||||
|
||||
日期:2026-09-25(Asia/Tokyo)
|
||||
审查性质:Mac 仓库只读代码审查、历史任务/报告交叉核对、定向原生测试复跑。未修改业务源码、未执行设备 GPU runtime 或 profiler。
|
||||
|
||||
## 1. 审查基线和证据分级
|
||||
|
||||
- Mac:`/Users/tei/dev/MapLibreParticleLab`;分支:`particle/main`。
|
||||
- HEAD 与 `origin/particle/main` 一致:`ee0b89e711bf01335b3aa71d36def785cd97fec3`;工作树 clean。
|
||||
- V13 功能提交:`016fd1fff6a33cf795c10d4f5c5413d308383677`。发布版本:`13.4.1-particle.13`。
|
||||
- Integration 主线:`39ad8415fbdb76c1822460bb09f3a3f35fe141e0`。
|
||||
- 参照:`docs/40_任务/STEP-092...`、`STEP-093...`、`STEP-094...` 任务;对应 `docs/报告/` 与 `docs/50_Step记录/`;STEP-088/089/090 性能历史报告。
|
||||
- 本次独立复跑:Render Segment/Retained/Fast Path 43/43 PASS;Field/QBIN/Viewport Reseed 69/69 PASS;V13 RN package TypeScript PASS。
|
||||
- 当前 RN Test Host `npm run typecheck` **失败(exit 2)**:TS2307 无法解析 `@navsea/maplibre-particle-rn`,伴随 TS7006。Host package.json 仍指向 `.10`。此前 Codex 使用临时工作树依赖通过,不等于当前默认安装可重复验证。
|
||||
- STEP-094 报告记录 OpenGL、Metal 构建、Codegen、Android Validation APK 通过;**Android/iOS V13 runtime、GPU frame/visual、功耗与长时间运行仍 NOT RUN**。此报告不将历史 Android 性能测量冒充 V13 性能。
|
||||
|
||||
## 2. 审查结论
|
||||
|
||||
没有在已复跑的纯数据结构/协议测试中发现失败;但 V13 在高频渲染、Metal 多段重建、GPU 资源分配和真实运行态验收上存在明确风险。不能由 43 项纯 Native 测试和编译 PASS 推断任意 R/C 交错的 GPU 输出、跨平台性能已经验收。
|
||||
|
||||
### F01 — P1:完整 Diagnostics 深复制进入每帧热路径(源码确定)
|
||||
|
||||
证据:`src/mbgl/renderer/renderer_impl.cpp:206-208,500-505`;`src/mbgl/renderer/retained_underlay_runtime_state.hpp:243-254`。
|
||||
|
||||
`tryRenderParticleFastFrame()` 和 `render()` 调用 `renderSegmentSnapshot()`;该函数在互斥锁内复制完整 `RenderSegmentDiagnostics`(含 `styleLayers` 与每个 Segment 的重复 `layers`/字符串),再补几个状态字段。一次 fast frame 可能复制两次。与 pull-based 诊断的设计意图不一致。
|
||||
|
||||
修复:增加只读的轻量 hot-path 状态(enabled/configRevision/topologyRevision 等);完整快照只在外部 pull 时构造;快照构建/复制次数做计数,稳定 30/60 FPS 应接近零。
|
||||
|
||||
### F02 — P1:Metal Retained 构建逐段 GPU 同步等待(源码确定,运行影响待 profile)
|
||||
|
||||
证据:`renderer_impl.cpp:790-824`;`retained_underlay_cache.cpp:316-322`;`src/mbgl/mtl/command_encoder.cpp:29-31`;`src/mbgl/mtl/offscreen_texture.cpp:86-91`。
|
||||
|
||||
`finishBuild()->present(*offscreenTexture)->swap()` 内部 `commit()` 后 `waitUntilCompleted()`。一帧多个 Retained 段失效时,可能产生多次串行 CPU/GPU 同步。使用 Metal System Trace / GPU Capture 测量 `waitUntilCompleted` 时间和 command-buffer 数量,再设计保持依赖顺序的异步提交/跨 pass 协调;不可仅删除 wait 而不确保纹理可读。
|
||||
|
||||
### F03 — P1:缓存内容失效与 GPU 资源销毁耦合(源码确定)
|
||||
|
||||
证据:`retained_underlay_cache.cpp:203-209,241-255,364-374`。
|
||||
|
||||
`revisionChanged` 使 `invalidate()` 与 `releaseResources()` 一起发生,即使 viewport 未变、GPU context 有效,重建时仍需重新创建纹理和 composite group。普通 camera、source/tile、content revision 在多 Retained 段下会放大分配/销毁和相关同步。
|
||||
|
||||
修复:分离 `contentDirty` 与 `resourceInvalid`,同尺寸同 context 保留 allocation、重新 clear/build;context loss、尺寸不兼容、显式关闭/释放时才销毁。用 peak GPU bytes、textureCreate、resourceRelease、每帧 build/reuse 证明收益与正确性。
|
||||
|
||||
### F04 — P1:多缓存没有 GPU 内存预算(源码确定,OOM 影响待量化)
|
||||
|
||||
证据:`renderer_impl.cpp:506-524`;`retained_underlay_cache.cpp:241-251`;`mtl/offscreen_texture.cpp:20-55`;`gl/offscreen_texture.cpp:18-35`。
|
||||
|
||||
每个 Retained Segment 均拥有完整 viewport 的 RGBA + depth/stencil 离屏资源;总成本约随 retainedCount×width×height 增长。相邻 R-R 也各自独立,符合契约,但高像素 iPad 与多段场景缺乏实际 bytes/peak/budget 观测。先增加预算与失败时的安全 full-render fallback,切勿通过强制合并相邻 R-R 破坏 V13 契约。
|
||||
|
||||
### F05 — P1:V13 Test Host 默认安装不可复现(已复现失败)
|
||||
|
||||
证据:`integration/react-native/MapLibreParticleRNTestHost/package.json` 指向 `.10`;当前 `npm run typecheck` exit 2;报告也明确临时本地替换后已恢复旧依赖。
|
||||
|
||||
修复:将 Test Host 依赖和 lockfile 与已发布 `.13` 精确对应,重新安装并验证 V13 typecheck/codegen/iOS & Android bridge/真实运行;测试日志注明源包及 Native 精确版本。不得将临时链接环境结果写成默认环境 PASS。
|
||||
|
||||
### F06 — P1:多 Continuous 的 Particle Fast Path 固定 fallback(明确设计限制)
|
||||
|
||||
证据:`renderer_impl.cpp:45-57,198-287` 和 `particle_fast_path.hpp:110-140`,STEP-094 设计与报告。
|
||||
|
||||
N 个 Continuous 中只支持恰好一个的 Fast Path;R-C-R-C-R 场景总走 Full CPU。STEP-090 历史 A/B 场景 RenderThread 约为 fast ON 21.7% / OFF 97.0%,只是历史参考,不能直接视作 V13 数据。先采集 V13 多 C 的 CPU/GPU 帧时间与频率,再设计可组合的 multi-C fast path;绝不可为性能偷偷移动 Style Layer 或合并相邻段。
|
||||
|
||||
### F07 — P2:范围访问反复计算线性 ordinal(源码确定)
|
||||
|
||||
证据:`src/mbgl/renderer/render_orchestrator.hpp:156-180`,`std::distance(multimap.begin(), lower_bound(...))`。每个 Segment 的 opaque/translucent、build、upload/tweaker 路径可重复触发定位。
|
||||
|
||||
修复:在 LayerGroup topology 变化时预计算有序索引/ordinal;高频 render 只用稳定区间和 ordinal,避免多段场景重复 O(N) 前缀遍历。
|
||||
|
||||
### F08 — P2:多段失效粒度仍过宽(明确设计限制)
|
||||
|
||||
证据:`renderer_impl.cpp:565-646`;`render_orchestrator.cpp:156-158,1005-1018`。Layer Impl fingerprint 可局部失效;source/tile/image/glyph/placement 与聚合 `retainedSupported` 仍可能使全部 R fallback/build。应先用 `sourceId` 与 Segment 关联建立有证据的保守依赖关系,无法归属继续全局失效,不得牺牲安全。
|
||||
|
||||
### F09 — P2:Diagnostics 资源指标可能发生归属偏差(源码路径风险)
|
||||
|
||||
证据:`retained_underlay_runtime_state.hpp:173-240` 更新新 topology/entry;`renderer_impl.cpp:506-524` 随后 `clear()` 旧 caches;旧对象析构在 `retained_underlay_cache.cpp:364-374` 用旧 segmentIndex 报 release。不同 topology 的相同 index 可能指向新段,旧资源的释放计数可能归于新段或被 Continuous cache=null 丢弃。建议使用 cache generation/unique ID 归属,或在更换 diagnostics topology 前记录旧 generation 的 release;聚合 totals 与 per-generation 分离。
|
||||
|
||||
### F10 — P2:发布与协调状态资料漂移(核对事实)
|
||||
|
||||
Integration 的 `status/`、`compatibility/MATRIX.md` 仍描述 `.5` / iOS XCFramework 等旧状态,Mac 粒子仓库已发布 `.13`。应由粒子负责人维护正式兼容矩阵,区分“Particle 已发布”和“NavSea 已接入/验证”,不得仅根据旧矩阵断言 V13 不存在或已在 NavSea 生效。
|
||||
|
||||
## 3. 正确性与验证缺口
|
||||
|
||||
以下不是已证实的渲染 bug,而是必须在设备上验证的风险:
|
||||
|
||||
- V13 segmented pass 改变了 opaque/translucent、offscreen composite 的执行拆分;纯 resolver GTest 不覆盖 GPU blending/depth/stencil 与 Metal/OpenGL 的最终像素。
|
||||
- 必须覆盖 R-C-R、C-R-R、R-R-C、R-C-R-C-R、相邻 R-R 独立 cache、全 R、全 C,特别是透明航标/半透明颜色场与动态粒子叠加。
|
||||
- hidden boundary、invalid/recovery、Style layer insert/remove/reorder、Resize/Rotate/Pan/Zoom/Pitch、Context loss、Cache ON/OFF、Source/Tile mutation、切换 Plan 后的下一帧,均需要截图/帧采样和资源 counter 交叉验收。
|
||||
- STEP-093/094 报告已明确运行态 NOT RUN,因此不以原生编译 PASS 代替此项。
|
||||
|
||||
## 4. 推荐执行顺序(分批,降低反复安装成本)
|
||||
|
||||
A. **无需设备的修复**:先处理 F01 快照深复制、F05 Test Host 精确版本与复现、F07 ordinal、F09 诊断归属;增加纯 C++ 定向回归。每阶段只做对应范围,不把源文件无关改动混入。
|
||||
|
||||
B. **Metal 资源修复**:合并 F02/F03/F04,统一处理 GPU 对象分配与同步、资源预算;OpenGL/Metal 静态编译和 Native regression 先行;再一次集中到 iPhone/iPad 采集 GPU Frame Capture。
|
||||
|
||||
C. **正式运行态验收**:集中执行 topology、alpha/depth、invalid/recovery、30/60 FPS、稳定/变更、内存峰值、30 分钟以上长稳态;记录相同设备、相同 Style、相同视口的 V12/V13 或 V13 ON/OFF 成对指标,不外推历史数字。
|
||||
|
||||
D. **后续性能架构**:在基础正确性通过后,再研究多 Continuous Fast Path 和 source-to-segment 精确依赖。保持 Style Z-order 唯一顺序源、不合并同策略相邻段、不引入业务频率分类。
|
||||
|
||||
## 5. 最终判定边界
|
||||
|
||||
- 纯 Native tests:43/43 + 69/69 PASS;RN V13 package TS PASS。
|
||||
- Test Host 默认环境:FAIL(缺失模块 / `.10` 引用)。
|
||||
- 源码性能问题:F01/F02/F03/F07 的触发调用链得到静态确认;真实节省量仍需设备测量。
|
||||
- V13 Android/iOS GPU runtime、完整画面、内存和长时间性能:本次 NOT RUN;不声称生产级全量 PASS。
|
||||
- Mac Git:HEAD 与 origin 一致,工作树 clean;未修改粒子源码。
|
||||
436
docs/20_调查/RenderSegment多Retained段全局Placement门槛_粒子管理员审查说明_v1.md
Normal file
436
docs/20_调查/RenderSegment多Retained段全局Placement门槛_粒子管理员审查说明_v1.md
Normal file
@@ -0,0 +1,436 @@
|
||||
# RenderSegment 多 Retained 段全局 Placement 门槛——粒子管理员审查说明 v1
|
||||
|
||||
日期:2026-10-07
|
||||
性质:调查结论 / 修改目标 / 管理员审查输入,不是直接实施任务书。
|
||||
目标读者:Particle Shared Core / Renderer 维护者。
|
||||
|
||||
## 1. 本文要解决的问题
|
||||
|
||||
NavSea 当前已经能通过公开 `RendererRuntime.setRenderSegmentPlan()` 配置任意连续的 `RETAINED / CONTINUOUS` Segment,且 `.19 / .20` 的 RenderSegment 实现已经具备 source-local revision / readiness / cache diagnostics 等基础。
|
||||
|
||||
但 NavSea 真实运行验证发现:当存在多个 Retained Segment 时,一个与某 Retained Segment 无直接关系的全局 placement/fade 状态,仍可能把所有 Retained Segment 同时打回 fallback,导致多 Segment 不能发挥设计目标。
|
||||
|
||||
本文希望 Particle 管理员审查并决定:怎样把剩余的 placement/global fallback 门槛收敛到正确粒度,同时保持 fail-closed、Style Z-order、跨平台语义和 C-001 边界不变。
|
||||
|
||||
## 2. 正式边界
|
||||
|
||||
跨项目 Contract 仍为 `C-001`。
|
||||
|
||||
本问题属于 Particle Renderer 内部实现优化,目标上不要求新增 NavSea 私有 Native 通道,也不要求 Particle 理解 AIS、Route、Weather、Alarm 等 NavSea 业务语义。
|
||||
|
||||
NavSea 仍只负责:
|
||||
- 按 Style Z-order 选择 Segment 边界;
|
||||
- 通过稳定公开 API 提交 RenderSegmentPlan;
|
||||
- 读取 diagnostics;
|
||||
- 决定天气等业务能力何时显示。
|
||||
|
||||
Particle 仍负责:
|
||||
- Segment resolve / cache / invalidation / renderer execution;
|
||||
- placement / transition / fading / source dependency 的正确性;
|
||||
- GPU resource 和 stale-cache 安全;
|
||||
- Android / iOS 共用的 Shared Core 语义。
|
||||
|
||||
本修改若不改变公共 API、生命周期、错误语义或双方职责,不需要升级 Contract。
|
||||
|
||||
## 3. 当前 Mac 基线需要管理员先确认
|
||||
|
||||
本次只读检查发现:
|
||||
|
||||
- `/Users/tei/dev/MapLibreParticleLab`
|
||||
- branch: `particle/main`
|
||||
- HEAD: `750c14f52708d7dc93d8eb6ec2b21112185afd5c`
|
||||
- `/Users/tei/dev/MapLibreParticleLab-release-v19`
|
||||
- branch: `release/particle.19`
|
||||
- HEAD: `6b48f905d2d17a8271b6ff883e682db7bc45dcd3`
|
||||
- `/Users/tei/dev/MapLibreParticleLab-release-v20`
|
||||
- branch: `release/particle.20`
|
||||
- HEAD: `53a844e81849f254ba2d169c2d875dbd862cc7d5`
|
||||
- `/Users/tei/dev/MapLibreParticleLab-step101`
|
||||
- branch: `step101-render-orchestrator-teardown`
|
||||
|
||||
NavSea 当前实际消费的是 `.19` 行为;本次检查确认 `release/particle.19` 与 `release/particle.20` 在本文相关 placement gate 代码上相同。
|
||||
|
||||
注意:当前 `particle/main` 与 `release/particle.19/.20` 的 RenderSegment 执行细节存在差异,因此管理员开始修改前必须先明确正式修复基线,不要把 main 与 release 分支默认视为完全一致。
|
||||
|
||||
## 4. NavSea 当前为什么需要多 Segment
|
||||
|
||||
NavSea 当前为了避免旧的 retained fallback,采用保守的两段方案:
|
||||
|
||||
```text
|
||||
R0 [0,31) RETAINED
|
||||
C0 [31,114) CONTINUOUS
|
||||
```
|
||||
|
||||
C0 从 `rn-weather-color` 开始一直覆盖到 Style 尾部。
|
||||
|
||||
真实 diagnostics 已确认该 Continuous 尾段包含天气之后的大量运行时对象,包括 AIS / ownship / navigation / alarm 等 source/layer。
|
||||
|
||||
这能保护 R0 底图复用,但代价是:天气粒子需要持续 repaint 时,天气以上整个 Style 尾部都留在 Continuous 区域。
|
||||
|
||||
RenderSegment 的原始设计目标本来就是允许:
|
||||
|
||||
```text
|
||||
R0 → C0 → R1 → C1 → R2 ...
|
||||
```
|
||||
|
||||
并严格保持 Style Z-order,不把业务语义写进 Renderer。
|
||||
|
||||
## 5. NavSea 真实多段实验 A
|
||||
|
||||
第一次临时配置:
|
||||
|
||||
```text
|
||||
R0 [0,31)
|
||||
C0 [31,79)
|
||||
R1 [79,98)
|
||||
C1 [98,114)
|
||||
```
|
||||
|
||||
Native 接受该配置:
|
||||
|
||||
```text
|
||||
configured=true
|
||||
valid=true
|
||||
segmentCount=4
|
||||
retainedSegmentCount=2
|
||||
continuousSegmentCount=2
|
||||
coverageComplete=true
|
||||
fallback=false
|
||||
```
|
||||
|
||||
解析结果:
|
||||
|
||||
- R0: `background` → `place-labels-land-ja`
|
||||
- C0: `rn-weather-color` → `ownshipRangeLabelLayer`
|
||||
- R1: `routeLineActiveShadowLayer` → `planSimBoatLabelLayer`
|
||||
- C1: `crossCursorGotoLineLayer` → `chartDangerScanCenterLineLayer`
|
||||
|
||||
R1 当时依赖:
|
||||
- `navigationSource`
|
||||
- `ownshipTrackSource`
|
||||
- `planSimRouteSource`
|
||||
|
||||
结果 R1 为 `source-fading` fallback,`reuse=0`。
|
||||
|
||||
这个结果本身还不能证明 placement 问题,因为 R1 确实包含活动 source。
|
||||
|
||||
## 6. NavSea 真实多段实验 B:把 R1 收窄到 idle PlanSim
|
||||
|
||||
第二次把 R1 收窄为只有 PlanSim Route 的 10 个 layer:
|
||||
|
||||
```text
|
||||
R0 [0,31)
|
||||
C0 [31,88)
|
||||
R1 [88,98)
|
||||
C1 [98,114)
|
||||
```
|
||||
|
||||
R1:
|
||||
- start: `planSimRouteShadowLayer`
|
||||
- end: `planSimBoatLabelLayer`
|
||||
- dependent source: 仅 `planSimRouteSource`
|
||||
- 当时 PlanSim 为 idle。
|
||||
|
||||
5 秒早期诊断仍有 `source-fading`,所以继续等待到约 20 秒稳定态。
|
||||
|
||||
20 秒稳定态关键结果:
|
||||
|
||||
```text
|
||||
fadingSourceIds = []
|
||||
```
|
||||
|
||||
R0:
|
||||
```text
|
||||
sourceReady=true
|
||||
sourceStable=true
|
||||
cacheState=fallback
|
||||
build=0
|
||||
reuse=0
|
||||
invalidation=306
|
||||
lastInvalidationReason=static-placement
|
||||
finalDecision=fallback
|
||||
```
|
||||
|
||||
R1:
|
||||
```text
|
||||
sourceReady=true
|
||||
sourceStable=true
|
||||
cacheState=fallback
|
||||
build=1
|
||||
reuse=0
|
||||
invalidation=306
|
||||
lastInvalidationReason=static-placement
|
||||
finalDecision=fallback
|
||||
```
|
||||
|
||||
这说明稳定 source 已经不是阻塞因素;两个 Retained Segment 被同一个 `static-placement` 门槛同步打回 fallback。
|
||||
|
||||
## 7. release/particle.19 / .20 当前代码事实
|
||||
|
||||
### 7.1 per-segment source locality 已经存在
|
||||
|
||||
`.19 / .20` 在 `renderer_impl.cpp` 中会对每个 Retained Segment 单独计算:
|
||||
|
||||
- `retainedSegmentSourceState(begin,end)`
|
||||
- source-local revision
|
||||
- source `ready / stable`
|
||||
- `retainedSegmentIsStable(begin,end)`
|
||||
- `segmentSupportsCache[]`
|
||||
- 每个 cache 独立 `evaluate()`
|
||||
- 每段独立 diagnostics / finalDecision
|
||||
|
||||
`render_orchestrator.cpp` 中 `retainedSegmentSourceState()` 已通过 RenderSegment dependency 只检查该 Segment 相关 source 的 loaded / fading 状态。
|
||||
|
||||
这部分方向是正确的,不应回退到全局 source invalidation。
|
||||
|
||||
### 7.2 剩余 placement gate 仍是全局聚合
|
||||
|
||||
`.19 / .20` 的 `renderer_impl.cpp` 仍先对全部 Retained Segment 聚合:
|
||||
|
||||
```cpp
|
||||
bool retainedStaticUsesPlacement = false;
|
||||
...
|
||||
retainedStaticUsesPlacement =
|
||||
retainedStaticUsesPlacement ||
|
||||
orchestrator.retainedRangeUsesPlacement(...);
|
||||
|
||||
const bool retainedPlacementStable =
|
||||
!retainedStaticUsesPlacement ||
|
||||
(!renderTreeParameters.placementChanged &&
|
||||
renderTreeParameters.symbolFadeChange == 0.0f);
|
||||
```
|
||||
|
||||
然后每个 Segment 的 `segmentSupported` 又共同依赖同一个 `retainedPlacementStable`。
|
||||
|
||||
因此只要任一 Retained Segment 使用 placement,并且当前全局 frame 有 `placementChanged / symbolFadeChange`,所有 Retained Segment 都可能失去 cache eligibility。
|
||||
|
||||
### 7.3 full CPU mixed execution 已有基础,但仍有 globalLiveFallback
|
||||
|
||||
`.19 / .20` 已有 `visitRenderSegmentExecution(...)`,理论上可以:
|
||||
|
||||
```text
|
||||
R0 reuse
|
||||
C0 live
|
||||
R1 fallback/live
|
||||
C1 live
|
||||
R2 reuse
|
||||
```
|
||||
|
||||
但是进入该混合执行前仍有:
|
||||
|
||||
```cpp
|
||||
const bool globalLiveFallback =
|
||||
...
|
||||
!retainedPlacementStable ||
|
||||
orchestrator.retainedGlobalLightTransition();
|
||||
```
|
||||
|
||||
`!retainedPlacementStable` 会直接导致:
|
||||
|
||||
```text
|
||||
drawableOpaquePass(0, layerCount)
|
||||
drawableTranslucentPass(0, layerCount)
|
||||
```
|
||||
|
||||
即整帧退回全 live,绕过 per-segment mixed execution。
|
||||
|
||||
这与 NavSea 实验中 R0/R1 同时出现 `static-placement` fallback 的现象一致。
|
||||
|
||||
## 8. 希望管理员审查的核心修改目标
|
||||
|
||||
目标不是简单“关闭 placement 检查”。
|
||||
|
||||
目标是:
|
||||
|
||||
> 当 placement / symbol fade 只影响某些 Segment 时,不应让与其无关、且自身内容/依赖/相机均稳定的 Retained Segment 一起失效。
|
||||
|
||||
期望行为示例:
|
||||
|
||||
```text
|
||||
R0:不含 placement layer,source stable
|
||||
C0:Weather continuous
|
||||
R1:含 placement 或当前 placement unstable
|
||||
C1:AIS / Alarm continuous
|
||||
R2:不含 placement layer,source stable
|
||||
|
||||
期望:
|
||||
R0 = reuse
|
||||
C0 = live
|
||||
R1 = fallback/live
|
||||
C1 = live
|
||||
R2 = reuse
|
||||
```
|
||||
|
||||
而不是:
|
||||
|
||||
```text
|
||||
R1 placement unstable
|
||||
→ global retainedPlacementStable=false
|
||||
→ R0/R1/R2 全部失效
|
||||
→ 整帧 full live
|
||||
```
|
||||
|
||||
## 9. 建议管理员重点评估的实现方向
|
||||
|
||||
以下是审查建议,不是强制实现方案。
|
||||
|
||||
### 9.1 先把 placement eligibility 变成 per-retained-segment
|
||||
|
||||
对于每个 Retained Segment 分别判断:
|
||||
|
||||
- 该 Segment 是否实际 `usesPlacement`;
|
||||
- 该 Segment 的 layer transition / needsRepaint;
|
||||
- 该 Segment 的 source readiness / fading;
|
||||
- placement transition 是否确实会改变该 Segment 的最终像素;
|
||||
- 是否存在必须全局 fail-closed 的 placement 共享状态。
|
||||
|
||||
至少对于 **完全不含 placement layer 的 Retained Segment**,应评估是否有理由继续受全局 `placementChanged / symbolFadeChange` 阻塞。
|
||||
|
||||
### 9.2 审查 `globalLiveFallback` 中的 `!retainedPlacementStable`
|
||||
|
||||
建议确认是否可以:
|
||||
|
||||
- 从 globalLiveFallback 移除纯 placement 条件;
|
||||
- 让 placement 结果进入每段 `segmentSupported / decision`;
|
||||
- 真正使用现有 `visitRenderSegmentExecution()` 做 mixed retained/live。
|
||||
|
||||
真正全局的条件仍可保持全局,例如:
|
||||
- 3D;
|
||||
- Debug 模式;
|
||||
- MapMode 不支持;
|
||||
- sprite/image/global resource 未就绪;
|
||||
- global light transition(若确实会改变所有段);
|
||||
- context/resource 失效;
|
||||
- 无法证明安全的全局状态。
|
||||
|
||||
### 9.3 不要破坏已有 source-local 机制
|
||||
|
||||
`.19/.20` 已有 `retainedSegmentSourceState()` 与 dependency-scoped revision/readiness。
|
||||
|
||||
目标应是在此基础上继续收窄 placement/global gate,而不是重新把 source/tile mutation 退回“所有 Retained 一起 invalidate”。
|
||||
|
||||
### 9.4 placement 本身若无法简单 local 化,应明确分层
|
||||
|
||||
管理员需要判断 MapLibre placement 是否存在以下区别:
|
||||
|
||||
1. Segment 完全不使用 placement:理论上是否可忽略全局 placementChanged?
|
||||
2. Segment 使用 symbol placement,但其相关 source/layer 没变化:是否仍必须 invalidate?
|
||||
3. cross-source collision / shared collision index 是否会让某 Segment 的符号像素受其他 Segment placement 影响?
|
||||
4. `symbolFadeChange` 是全局时间量还是可以按 dependency/range 推导?
|
||||
5. 是否需要一个 per-segment placement revision/fingerprint,而不是 bool?
|
||||
|
||||
如果 2/3 无法安全局部化,也至少应优先解决第 1 类,让“无 placement Retained Segment”不被无关 placement 拖死。
|
||||
|
||||
## 10. 不能牺牲的正确性约束
|
||||
|
||||
任何优化都必须保持:
|
||||
|
||||
- Style Z-order 是唯一顺序事实;
|
||||
- Segment 不重新编号 Layer 的全局 ordinal;
|
||||
- opaque/translucent/depth 语义不变;
|
||||
- retained cache 不得显示 stale 像素;
|
||||
- Camera / viewport / pixelRatio 变化仍正确 invalidation;
|
||||
- Style reload / topology change 正确释放旧 cache;
|
||||
- Android / iOS 使用同一 Shared Core 语义;
|
||||
- 不把 AIS / Route / Weather 等业务名称写进 Renderer;
|
||||
- 不要求 NavSea 手工 invalidate Native cache;
|
||||
- 不新增“只为 NavSea 绕过 Renderer”的私有 API。
|
||||
|
||||
## 11. 建议新增/补强的 Core 测试
|
||||
|
||||
至少建议覆盖:
|
||||
|
||||
### Case A:无 placement 的 R0 + 有 placement 的 R1
|
||||
- R0 stable;
|
||||
- R1 发生 placement transition;
|
||||
- 期望 R0 继续 reuse;
|
||||
- R1 单独 fallback/live;
|
||||
- 最终 Z-order 正确。
|
||||
|
||||
### Case B:两个 Retained 都稳定
|
||||
- R0/R1 均 build 一次;
|
||||
- 后续 reuse 持续增长;
|
||||
- Continuous 段持续 live。
|
||||
|
||||
### Case C:单一 source fading
|
||||
- fading source 只属于 R1;
|
||||
- R1 fallback;
|
||||
- R0 不 invalidation。
|
||||
|
||||
### Case D:Continuous source 高频 mutation
|
||||
- mutation 只属于 C1;
|
||||
- R0/R1 retained revision 不变化;
|
||||
- cache 可继续 reuse。
|
||||
|
||||
### Case E:真正全局状态
|
||||
- global light transition、3D、Debug、context/resource failure 等;
|
||||
- 继续 fail-closed;
|
||||
- 不为追求 reuse 放宽安全边界。
|
||||
|
||||
### Case F:topology 变化
|
||||
- R-C-R-C → R-C;
|
||||
- 旧 retained texture/compositor 正确释放;
|
||||
- 不 composite stale resource。
|
||||
|
||||
## 12. Diagnostics 验收要求
|
||||
|
||||
修复后 diagnostics 必须能证明“局部失败不扩散”。
|
||||
|
||||
NavSea 重新做 R-C-R-C 真机测试时,至少需要看到类似:
|
||||
|
||||
```text
|
||||
R0:
|
||||
sourceReady=true
|
||||
sourceStable=true
|
||||
cacheState=reuse
|
||||
reuse 持续增长
|
||||
|
||||
R1:
|
||||
finalDecision=fallback
|
||||
lastFallbackReason=static-placement
|
||||
|
||||
C0/C1:
|
||||
正常 live
|
||||
```
|
||||
|
||||
关键验收不是 Fast Path hit。
|
||||
|
||||
多 Continuous Segment 本来就可以继续走 full CPU mixed renderer;即使 `fastPathHit=0`,只要稳定 Retained 段能够独立 reuse,优化就是有效的。
|
||||
|
||||
## 13. 与 NavSea 最新 Trace 的关系
|
||||
|
||||
`Trace-20261007T224751.json` 是 UDP + 天气 UI 的 DevTools Trace。
|
||||
|
||||
该 Trace 中约 11–13 秒和 21–23 秒出现两组很高的 JS 峰值;调用栈显示峰值主要落在 React root work 与 `WeatherForecastStrip / WeatherTable`,其中 `WeatherTable` 两次重 render 分别约 0.91s / 1.07s,AIS decoder 并不是这两个峰值的主要执行栈。
|
||||
|
||||
代码同时显示 `WeatherForecastStrip` 会订阅 `smoothGPS`,并用经纬度 `toFixed(2)` 形成天气采样位置 key;但当前尚未完成对这两次具体 WeatherTable render 触发源的一一证明,因此本文不把“约 10 秒”直接归因于 GPS 跨格或任何单一 NavSea 机制。
|
||||
|
||||
这些 JS/UI 峰值属于 NavSea 侧独立调查项,不应作为 Particle RenderSegment 修改的直接证据。
|
||||
|
||||
Particle 本次应以 **RenderSegment diagnostics 的 R0/R1 `static-placement` 同步 fallback** 为主要证据。
|
||||
|
||||
## 14. 管理员需要给出的结论
|
||||
|
||||
请管理员审查后明确回答:
|
||||
|
||||
1. `.19/.20` 当前全局 `retainedPlacementStable` 是否确实过度保守?
|
||||
2. 对“不含 placement layer”的 Retained Segment,是否可以安全解除全局 placementChanged/symbolFadeChange 阻塞?
|
||||
3. `globalLiveFallback` 是否应去掉 placement 条件,转为 per-segment decision?
|
||||
4. 若 placement 必须部分全局,最小安全局部化边界是什么?
|
||||
5. 正式修改应基于 `release/particle.20`、合并回 `particle/main`,还是先在独立工作树完成?
|
||||
6. 是否需要新 ADR/RFC?初步判断:若公共 API/C-001 语义不变,只是 Renderer 内部优化,可不新增跨项目 Contract;若管理员认为会改变 RenderSegment 公共语义,再交回 Integration 决定。
|
||||
|
||||
## 15. 当前 NavSea 状态
|
||||
|
||||
NavSea 临时 R-C-R-C 实验已经撤回。
|
||||
|
||||
当前恢复为原有保守方案:
|
||||
|
||||
```text
|
||||
R0 [0,31) RETAINED
|
||||
C0 [31,114) CONTINUOUS
|
||||
```
|
||||
|
||||
因此管理员可以先只做 Native/Core 审查,不需要 NavSea 同步修改。
|
||||
|
||||
等 Particle 给出明确方案和可验证版本后,再由 NavSea 重新选择真实 Style 边界并做 R-C-R-C / R-C-R-C-R 真机验证。
|
||||
285
docs/20_调查/STEP-095_V13独立严格代码与性能调查_v1.md
Normal file
285
docs/20_调查/STEP-095_V13独立严格代码与性能调查_v1.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# STEP-095 V13 独立严格代码与性能调查 v1
|
||||
|
||||
日期:2026-09-25(Asia/Tokyo)。性质:独立静态审查;只写指定中文文档,不修复源码,不运行构建、测试、codegen、安装或设备操作。
|
||||
|
||||
## 1. 执行摘要与结论边界
|
||||
|
||||
V13 的通用分段解析、Style 顺序及保守 Fast Path 门控有源码依据,但不能据此批准 GPU 正确性或性能。本轮先检查 V12→V13 diff、真实调用链和生命周期,再阅读旧报告逐项挑战。新增优先问题为:离屏目标切换未重置 CPU stencil 掩码记录;Metal depth/stencil 清除契约未完整下传;LayerGroup 抛错后 retained build 仍可能标成功;V4 PLAY 缺少生产时钟推进调用。前三项的实际像素、故障注入和设备行为仍需验证。
|
||||
|
||||
旧 F01/F02/F03/F04/F07 的成本路径成立,但没有本轮 profiler 数据证明热点排序、OOM 或收益。F06 多 Continuous 退出静态 CPU Fast Path、F08 保守全局失效属于显式设计限制。F09 可给出计数跨 topology 错归的具体链,但不证明 stale texture 被复用。F05 的 Host `.10`/native `.13` 错配成立,历史 TS2307 不能仅归因于版本号;F10 只证明协调文档滞后。
|
||||
|
||||
新增成本还包括 V4 全网格物化、UI 线程解码、普通粒子 Metal 离屏等待及 drawable 重建。未找到足以定 P0 的证据;不宣称不存在其他缺陷。调查内容完成,Git 交付结果见阶段记录的收尾条目。**V13 产品运行态不判 PASS:本轮所有构建、测试、设备、性能验证均 NOT RUN。** RDC 仍须独立复核和验证。
|
||||
|
||||
## 2. 冻结基线、环境与范围
|
||||
|
||||
| 项目 | 核实结果 |
|
||||
| --- | --- |
|
||||
| 机器/目录 | `Mac-mini-tei.lan`,Darwin x86_64;`/Users/tei/dev/MapLibreParticleLab` |
|
||||
| 分支/起始 HEAD | `particle/main`;`05878d662308b9a92c20c433c3cd2943d74ae718` |
|
||||
| 起始状态 | 工作树 clean;子模块未见偏离记录提交的标记 |
|
||||
| 远端 | cached origin 与实际 `git ls-remote` 都是上述 HEAD;origin 为 `https://git.eyaku.jp/tei/MapLibreParticleLab/` |
|
||||
| 冻结源码 | `ee0b89e711bf01335b3aa71d36def785cd97fec3` |
|
||||
| V13 功能/旧报告归档 | `016fd1fff6a33cf795c10d4f5c5413d308383677` / `45c4dca84928a57a2cf0226737c34cabd7fbfbfb` |
|
||||
| V12 比较点 | tag 解引用提交 `7eaff6e12360e26591dceb5e011129eeab7ba4c7` |
|
||||
| V13 tag | `.13` tag 对象 `bccbceddec70f7a2b6362bce653f9c577aa2db1d`,解引用为冻结源码,远端一致 |
|
||||
| manifest sourceCommit | `ddf20dec9fe9cd05b77274827b6825829500dd5a`;至冻结提交为发布元数据收尾,生产源码一致 |
|
||||
| 模型记录 | 用户在本次同一会话恢复指令中明确指定 `gpt-6-astra high`,与任务要求一致;这是当前会话的用户指定记录。未获得可独立核验的底层启动参数,不声称已独立验证实际模型/effort |
|
||||
|
||||
冻结源码至起始 HEAD 仅新增旧审查报告及 STEP-095 任务书;下文源码行号按冻结源码,与本轮起始工作树对应。V12→V13 整体 diff 为 45 文件、2393 行增加/203 行删除(含文档),主要新增 segment/parser/resolver、runtime diagnostics、renderer/orchestrator 调度与平台桥接,并非粒子数值 shader 的整体重写。
|
||||
|
||||
已读取 AGENTS、PARTICLE_BASELINE、项目规范、项目总则 README 所列当前有效规则及基线 v2,交叉阅读 STEP-088~094 的任务/设计/阶段/报告相关内容。总则仍含早期 `.3` 和 Linux 主线描述,本任务以 Mac `.13` 冻结点为准,不重写历史文档。官方 Core 基线 `18545ca10d296704b2cba675b182ff2c8da24588`,Android 官方 13.4.1、iOS 官方 6.28.0。
|
||||
|
||||
### 2.1 发布坐标(仅核对仓库记录)
|
||||
|
||||
来源:`release/maplibre-particle/release-manifest.json` 与 `release/maplibre-particle/ios/release-manifest.json`。
|
||||
|
||||
| 产物 | 坐标 | manifest 大小/SHA-256 |
|
||||
| --- | --- | --- |
|
||||
| RN | `@navsea/maplibre-particle-rn@13.4.1-particle.13`,MLRN 11.3.6 | 25,966 bytes;`3a726db06cb967fe56de77ca4a72feed98cd642a2d1b73fd51b1531d15ef7539` |
|
||||
| Android OpenGL | `cc.navsea.maplibre:android-sdk-particle-opengl:13.4.1-particle.13` | 169,786,873 bytes;`ddf1deced00cc963d1d625c73c68c449232602113a1490349e69100473dda82b` |
|
||||
| iOS Metal | `6.28.0-particle.13`,MapLibre XCFramework/SPM exactVersion | 8,418,198 bytes;`8d47d9f6d44479aff51299c213887bd9be204da320da4fd4fff15dd064930556` |
|
||||
|
||||
manifest 的 `PUBLISHED_PUBLIC_READBACK_PASS` 是 HISTORY。本轮没有下载、重算产物散列、重建或核实设备实际链接版本;文档提交不是新 V13 发布。
|
||||
|
||||
### 2.2 调用链和未覆盖范围
|
||||
|
||||
已沿 segment JSON/plan → runtime → orchestrator/renderer → cache → PaintParameters/GL/Metal target,及 canonical/QBIN/profile → Store/Clock/projection → RasterArraySource immutable Impl → WeatherColor/Particle RenderLayer → Field/State/Trail GPU 追踪;检查 Android Java/Kotlin/JNI、iOS ObjC++、RN typed API/JSON Spec、Host package/lock/plugin及 Integration 只读状态。阅读 resolver/cache/diagnostics/field/decoder/reseed 测试源码,不等同执行测试。
|
||||
|
||||
未逐行形式化验证全部官方 renderer/driver、Vulkan、业务 provider/HTTP/Route/ETA或所有并发交错;未使用设备、capture、sanitizer、fuzzer。此报告不是全仓无缺陷证明。
|
||||
|
||||
## 3. Finding 总表
|
||||
|
||||
D=源码可复核缺陷路径;C=源码确定成本;R=后果需运行验证;E=环境/文档偏差。置信度均指源码链而非事故发生概率。每项详细位置、修复与验收见后文。
|
||||
|
||||
| 编号 | 严重度/类别/置信度 | 触发与影响 | 旧报告关系 |
|
||||
| --- | --- | --- | --- |
|
||||
| N01 | P1/D+R/高 | 相同 tiles 跨 target,CPU stencil 映射复用,后段可能被裁掉 | 新增 |
|
||||
| N02 | P1/D+R/高 | Metal retained depth/stencil clear 未完整转换,模拟器 attachment 缺口 | 新增 |
|
||||
| N03 | P1/D+R/高 | group 绘制抛错被 catch,仍标 cache 成功,可能持续复用残图 | 新增 |
|
||||
| N04 | P1/D/高 | V4 只 PLAY 不继续 set time,生产时钟无推进调用 | 新增 |
|
||||
| N05 | P2/D/高 | JSON NUL/重复 strategy 被接受,严格解析失真 | 新增 |
|
||||
| N06 | P2/D+R/高 | 结构合法但数值非法的场先入库,物化失败后可用投影被置空 | 新增 |
|
||||
| N07 | P2/D/高 | 同 view 重复 attach,listener 和持有引用递增 | 新增 |
|
||||
| C01 | P1/C/高 | full diagnostics 锁内深复制进入 fast/render | F01 |
|
||||
| C02 | P1/C+R/高 | Metal retained build 与普通 State/Trail target 等待 | F02,新增扩大范围 |
|
||||
| C03 | P1/C/高 | 内容 dirty 释放同尺寸可复用 GPU allocation | F03 |
|
||||
| C04 | P1/C+R/高 | 多 R 全视口资源无总预算;Store 也缺 fieldKey 总预算 | F04,新增场预算 |
|
||||
| C05 | P2/C/高 | ordinal 线性前缀遍历,fast update 仍扫全部 items | F07,新增扫描 |
|
||||
| C06 | P1/C+R/高 | 同时间/mix-only 整网格物化;提交链可占用 UI | 新增 |
|
||||
| C07 | P2/C/高 | tick 重建 drawable/attributes/tweaker,窗口切换复制场 | 新增 |
|
||||
| O01 | P2/D/高 | 新 topology 先发布,旧 cache 析构向新 index 计数 | F09 |
|
||||
| E01 | P1/E/高 | Host RN `.10` 与 Android 插件 `.13` 错配 | F05 |
|
||||
| E02 | P3/E/高 | Integration 仍旧状态,实际接入 UNKNOWN | F10,降级 |
|
||||
|
||||
## 4. 新增正确性和生命周期发现
|
||||
|
||||
### N01:CPU stencil 记录跨 framebuffer 复用
|
||||
|
||||
证据:`src/mbgl/renderer/renderer_impl.cpp:798-847,938-945`;`src/mbgl/renderer/retained_underlay_cache.cpp:304-319`;`src/mbgl/renderer/paint_parameters.cpp:185-201,365-374`;`src/mbgl/gl/layer_group_gl.cpp:67-98`;`src/mbgl/mtl/tile_layer_group.cpp:118-119`。
|
||||
|
||||
最短链:同一个 PaintParameters → 第一个 R 清 stencil、写 mask 并记录 tileClippingMaskIDs → 第二个 R 新 target/清 stencil → tileIDsCovered 为真而跳过写 mask → draw 仍 Equal 非零 ID。CPU 记录属于前一 target,后一 GL target 实际为零。main buffer 清除后也未清 CPU 记录;updateStencilBufferAvailability 不是映射重置。
|
||||
|
||||
触发用例:同 vector source、同 tile 集合的两个 fill 分置相邻 R-R,首次都 build;或 R build 后同 tiles 的 C 绘入主目标。tile 集合变化可触发清记录,所以不是所有画面必坏。V13 任意 R-R 扩大暴露面,V12 多 target 也应回归,不能断言只由 V13 引入。
|
||||
|
||||
最小修复:target/pass 切换时明确失效 CPU mask/编号,或按 target generation 隔离,并保证 GPU clear 一致。验收:GL/Metal cache OFF 对照,同 source R-R/R-C-R 的首帧、rebuild、reuse 像素和 stencil capture。缺口源码已确认,实际像素 NEEDS_RUNTIME。
|
||||
|
||||
### N02:Metal depth/stencil 描述未完整下传
|
||||
|
||||
证据:`retained_underlay_cache.cpp:304-310` 请求 clearDepth=1、clearStencil=0;`src/mbgl/mtl/render_pass.cpp:13-38` 只转换 clearColor;`src/mbgl/mtl/offscreen_texture.cpp:32-83,139-148` 绑定附件但该路径未设置 depth/stencil clear/load/store。模拟器不创建 stencilTexture,也未将 combined depth/stencil texture 绑定 stencilAttachment;格式选择见 `src/mbgl/mtl/texture2d.cpp:99-104`。
|
||||
|
||||
触发:Metal retained tile/depth 绘制,尤其首次 target、simulator。源码确认契约缺口,但未测驱动默认内容/validation 行为,不宣称所有真机黑屏。isRenderable 仅验证 color,depth/stencil create 在 bind,早期就绪判断不能证明所有附件就绪。
|
||||
|
||||
最小修复:完整翻译 descriptor、正确绑定 combined attachment,并验证所有附件后允许 build;保持官方接入薄。验收:Metal API Validation、真机/模拟器 capture 核对 attachment/load/store/clear,故障注入验证安全 fallback。NEEDS_RUNTIME。
|
||||
|
||||
### N03:绘制异常未阻止 cache 发布为成功
|
||||
|
||||
证据:`src/mbgl/renderer/render_orchestrator.hpp:156-178` 的 visitor catch 只通知 observer;`renderer_impl.cpp:798-824` 随后无错误结果判断,finishBuild/markBuildSucceeded。
|
||||
|
||||
触发:R 的一个 layerGroup.render 抛错,observer 正常返回,其他 group 继续,残缺图像可变 valid 并在稳定帧 reuse。反例:资源准备阶段已有失败回退(`retained_underlay_cache.cpp:240-255`、`renderer_impl.cpp:662-677`),问题不等于所有资源失败都没有 fallback。
|
||||
|
||||
最小修复:build 汇总明确成功状态,失败 target 不发布/复用,可恢复错误进入完整渲染或约定安全失败。验收:第二个 group 故障注入,确认 successful build/reuse 不增长、无 stale composite、恢复和资源释放正确。NOT RUN。
|
||||
|
||||
### N04:V4 PLAY 没有生产时钟推进
|
||||
|
||||
证据:`src/mbgl/style/sources/raster_array_source.cpp:453-470`;`src/mbgl/particle/field/field_runtime.cpp:196-220`;`src/mbgl/renderer/layers/render_particle_validation_layer.cpp:1174-1189,1276-1278`。生产树 src/include/platform/packages 中 advanceForecastClock 仅见声明和定义,无调用。Android `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java:225-242`、iOS `platform/ios/src/MLNParticleFieldRuntime.mm:147-165` 的 wake 只 repaint。
|
||||
|
||||
最短链:设一次 requested time → PLAY 改 clock state → repaint/particle cadence → renderer 读取不变的 immutable projection.mix。粒子运动不能证明预报时间在播放。Host 每次显式 set time 可绕过,但不代表 PLAY 本身有效。
|
||||
|
||||
最小修复:在既有 map/source 所属线程接入唯一单调时钟,明确速度、pause/resume、后台和销毁语义,不建立第二套时间真相。验收:仅设一次时间,PLAY 的 .5/1/2 倍 mix、PAUSE、跨窗口和恢复;`test/particle/field_runtime.test.cpp:272-310` 手动 advance 单测不覆盖生产接线。本轮 NOT RUN。
|
||||
|
||||
### N05:Segment JSON NUL 截断与重复键
|
||||
|
||||
证据:`src/mbgl/renderer/render_segment_json.hpp:16-49`。Parse 用 C 字符串,strategy/startLayerId 用 GetString 未带 GetStringLength;`"RETAINED\u0000x"` 截成 `RETAINED`,`"boundary\u0000x"` 可解析到另一真实 ID。segment 两个重复 strategy 满足 MemberCount<=2,白名单不检唯一性,读取首值。
|
||||
|
||||
触发可由 primitive JSON/native 入口构造,TS typed API 不替代校验。普通未知 strategy/schema、missing/reversed 仍会 invalid/fallback。最小修复:长度感知解析/构造,拒绝 NUL/重复键,保持 invalid 清旧 plan 语义。验收:上述 payload、raw NUL 后缀、正常 unicode、未知字段、invalid→valid及两桥接错误归一化。NOT RUN。
|
||||
|
||||
### N06:数值非法的场在入库后才被拒绝物化
|
||||
|
||||
证据:`src/mbgl/particle/ingress/qbin_v2_decoder.cpp:41-73` 校验结构、CRC、scale/offset但不扫描 Float32 样本;`src/mbgl/particle/field/field_profile_validator.cpp:77-166` 匹配契约;`field_projection_materialization.cpp:38-67,97-135` 才检查解码数值;`raster_array_source.cpp:422-440,496-522` 先 submit,再物化,失败 next 对应投影为空。
|
||||
|
||||
触发:已有绑定字段,同时间更高 revision、CRC 正确、valid=1、样本 NaN/Inf 的 QBV2。结构/契约可接受,替换旧帧后物化失败,但 submit 返回 AcceptedInserted/AcceptedReplacedRevision。有限 scale 乘法溢出也应纳入验证。此处不声称 NaN 上传 GPU——物化拒绝正是反例;缺陷是 accepted/可渲染语义及旧状态保留脱节。
|
||||
|
||||
最小修复:明确 ingress 数值约束,入库前校验或事务式验证,保留合法无效 cell/通用未绑定 plane 语义。验收:好旧帧→坏高 revision,检查返回值、Store/投影保持、noData/validity、极值及恢复。NOT RUN。
|
||||
|
||||
### N07:Android attach listener 积累
|
||||
|
||||
证据:`packages/maplibre-particle-rn/android/src/main/java/org/navsea/maplibre/particle/weather/WeatherRuntimeBridgeModule.kt:30-63`。每 attach 新增捕获 concrete map 的 listener;显式 detach 只 dispose runtime,view detach 回调也不移除 listener。
|
||||
|
||||
同一个存活 view 重复 attach/detach,listener/引用及回调为 O(k)。未证明 view 回收后永久泄漏或 UAF;每次重新解析 view、没有全局 reactTag registry 是正面约束。最小修复:view/map 单一 listener、attach 幂等、明确 remove 生命周期。验收:同 view 100 次、换 view、卸载/后台恢复,listener/dispose/存活对象回基线。NOT RUN。
|
||||
|
||||
## 5. 性能、资源与观测
|
||||
|
||||
### C01:完整 diagnostics 深复制进入热路径
|
||||
|
||||
证据:`renderer_impl.cpp:198-208,500-505` → `retained_underlay_runtime_state.hpp:243-254` 锁内复制 styleLayers、segments.layers、字符串。成功 fast frame 可两次,不是所有帧固定两次。成本 O(L+S),锁竞争程度待测。修复:一致的轻量热快照与完整外部 pull 分开,不能无同步拆字段。验收:稳定 30/60 FPS 的完整快照次数应随外部 pull,测 alloc/frame、锁等待、CPU;无收益百分比。
|
||||
|
||||
### C02:Metal 等待不限于 retained rebuild
|
||||
|
||||
证据:`retained_underlay_cache.cpp:316-319` → `src/mbgl/mtl/command_encoder.cpp:29-31` → `mtl/offscreen_texture.cpp:86-91` commit/waitUntilCompleted,失效 R 逐段同步;稳定 reuse 没有 retained build wait。
|
||||
|
||||
新增链:`src/mbgl/renderer/render_target.cpp:71-119` 普通 target 也 present;`render_particle_validation_layer.cpp:1990-2111` tick 注册 State/Trail 写目标,初始化可能更多。因此 retained 稳定也可能有多个普通粒子 wait,属继承成本。修复前先 capture buffers、wait 栈及依赖,再设计有序异步提交,不能直接删 wait。验收:State A/B 无别名,Trail/composite 顺序与轨迹一致,CPU wait/GPU frame time 成对比较。NEEDS_RUNTIME。
|
||||
|
||||
### C03:内容失效与 allocation 销毁耦合
|
||||
|
||||
证据:`retained_underlay_cache.cpp:161-237` revisionChanged 同时 invalidate/release;`:240-255,365-374` 重建/释放 texture/compositor。触发为内容/相机等 revision 改变,不是稳定帧无条件分配。修复:contentDirty 与尺寸/context/格式的 resourceInvalid 分开,同尺寸有效 context 保留 allocation。验收:mutation、camera、resize、context loss 分开统计 build/create/release/peak;先保证 N01/N02 clear 正确。耗时收益待测。
|
||||
|
||||
### C04:多段 GPU 与多字段 CPU 无总预算
|
||||
|
||||
证据:`renderer_impl.cpp:506-524`;`retained_underlay_cache.cpp:240-255`;`src/mbgl/gl/offscreen_texture.cpp:18-35`、`mtl/offscreen_texture.cpp:20-55`。每 R 全视口 color/depth/stencil;RGBA8 color 理论下界 R×W×H×4 bytes,另有附件、alignment、主 framebuffer、State/Trail及延迟释放,不能把逻辑 release 当物理显存回收。
|
||||
|
||||
新增:`src/mbgl/particle/field/field_runtime.cpp:223-230` 对新 fieldKey 建 series;`include/mbgl/particle/field/field_runtime.hpp:115` 每 series 默认容量并非总 key/总 bytes 上限。QBIN 单文件64 MiB/解码32 MiB 上限也不约束累计持有量。
|
||||
|
||||
修复:map 预算、分配前溢出安全估算、超限明确 full-render/拒绝策略,不合并相邻 R、不淘汰仍绑定窗口。验收:R×viewport×字段数阶梯、allocation failure/context loss、30分钟以上 peak/回收。OOM/泄漏未证实,NEEDS_RUNTIME。
|
||||
|
||||
### C05:ordinal 前缀遍历和全层扫描
|
||||
|
||||
证据:`render_orchestrator.hpp:156-178` 的 multimap std::distance 是线性,S 次范围定位可能 O(S×G);`render_orchestrator.cpp:1202-1226` fast updateParticleLayers 仍遍历完整 items,非粒子只跳过 update;`:973-975` 按 retained 稳定性还可能扫 source fading。
|
||||
|
||||
修复:topology 改变时缓存 global ordinal/粒子列表,保持 generation 和原始全局深度编号。验收:固定粒子层扩大 L/G/S,测 CPU/调用次数并回归 reorder/delete。实际热点占比待测。
|
||||
|
||||
### C06:同时间/mix-only 仍全网格物化,UI 成本遗漏
|
||||
|
||||
证据:`raster_array_source.cpp:453-455,496-522` 在 sameProjection 前分别物化 color/particle;`field_runtime.cpp:196-200` 相同非零时间也返回 true;`field_projection_materialization.cpp:69-75,97-211` 分配/遍历 validity、T0/T1 scalar/vector。Wind 双绑定可重复同向量物化。mix 更新产生新 Impl/onSourceChanged,`render_orchestrator.cpp:361-365` 全局 SourceMutation 可进一步失效所有 R。
|
||||
|
||||
桥接:Android withMap UI 调度经 `platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp:1501-1517` 同步到 Source;iOS `packages/maplibre-particle-rn/ios/WeatherRuntimeBridge.mm:105-120,235-240` 的 withMap 与 `platform/ios/src/MLNParticleFieldRuntime.mm:222-252` 也同步提交 Core。预读取文件不等于 CRC/解码/物化已经离开 UI。成本随格点/plane 增长,实际卡顿/ANR未测。
|
||||
|
||||
修复:相同时间早退,按端点 identity/binding 共享不可变物化、mix 单独更新;若 worker 解码,owner-thread 发布必须带 map/source generation,禁止 worker 直接改 Source。局部失效必须先有完整依赖。验收:同时间、mix-only、跨窗口、双绑定、最大网格的 CPU/alloc/UI阻塞/upload/rebuild计数。NEEDS_RUNTIME。
|
||||
|
||||
### C07:tick 对象重建及端点复制
|
||||
|
||||
证据:`render_particle_validation_layer.cpp:826-904` clearDrawables 后新 attributes/builder/tweaker;`:1668-1669,1990-2111` 更新 target 注册及 State/Trail/composite;`:657` createOrUpdate UBO 不证明跨新 drawable 复用;`:1494-1499,1538-1563` 场端点切换复制数组。
|
||||
|
||||
反例:State/Trail textures 和共享顶点不是每 tick 全部重建,field 复制主要在窗口边界,不能称 CPU 每帧模拟全部粒子或无条件上传场。修复:稳定 drawable 保留,仅更新 uniforms/texture,端点共享不可变存储。验收:tick/bootstrap/reseed/resize/端点轮换分别测对象、UBO、upload和峰值。NOT RUN。
|
||||
|
||||
### O01:旧 cache release 记入新 topology
|
||||
|
||||
证据:`retained_underlay_runtime_state.hpp:173-240` 先发布新 entries;`renderer_impl.cpp:500-524` 再 clear 旧 cache;`retained_underlay_cache.cpp:120-122,365-374` 析构按旧 segmentIndex 计数;runtime `:256-272` 寻找当前 entry。
|
||||
|
||||
旧 index 0 的 R 换成新 R,旧 release 可记入新 R;新 index 为 C/越界时 per-segment 计数丢失。不证明 GPU 未释放或旧图复用。另 runtime `:198` root fallback 只表示 resolution invalid,不能覆盖 cache OFF/unsupported/resource fallback;消费方不可读成 GPU 当前 retained 成功。
|
||||
|
||||
修复:计数带 cache identity/generation,聚合历史与当前段分开,明确两类 fallback。验收:真 cache R-R→C-R、相同 index 换边界、disable/restore析构计数,纯手动 counter 测试不足。NOT RUN。
|
||||
|
||||
## 6. 环境发现和旧 F01~F10 复核
|
||||
|
||||
E01 定位:`integration/react-native/MapLibreParticleRNTestHost/package.json:12`、`package-lock.json:12,1765-1766` 为 `.10`,`plugins/withParticleNativeAndroid.js:9` 注入 `.13`,当前 package/native 为 `.13`。默认干净 Host 不能证明 V13 全链。旧 typecheck exit2/TS2307/TS7006 为 HISTORY;缺模块和旧 API 是不同原因,本轮未复跑。修复方向:后续单独对齐 package/lock/native resolved version,干净安装、typecheck/codegen及设备调用;不能把临时工作树链接 PASS 当默认包 PASS。本轮不改依赖。
|
||||
|
||||
E02 定位:只读 `/Users/tei/dev/navsea-particle-integration` HEAD `39ad8415fbdb76c1822460bb09f3a3f35fe141e0`,`compatibility/MATRIX.md` 与 `status/` 仍含 Sept18 `.5`、iOS 等待、RN NOT_STARTED。它与本仓 `.13` 是不同时点,真实 NavSea 接入 UNKNOWN。降 P3 文档项,建议负责人以接入 commit/包/设备证据更新,不改 Core 协议;本轮不改 Integration。
|
||||
|
||||
| 旧项/原结论 | 当前意见 | 修正和依据 | 补证 |
|
||||
| --- | --- | --- | --- |
|
||||
| F01 P1 深复制 | CONFIRMED | C01,成功 fast 可两次而非每帧必两次 | alloc/锁/CPU NOT RUN |
|
||||
| F02 P1 retained wait | CONFIRMED | C02,限定 build,补普通粒子 wait | 收益 NEEDS_RUNTIME |
|
||||
| F03 P1 dirty 释放 | CONFIRMED | C03,稳定 reuse 不重建 | 内容/resize/context分测 |
|
||||
| F04 P1 无预算 | CONFIRMED | C04,无预算不等于已 OOM | peak/压力 NEEDS_RUNTIME |
|
||||
| F05 P1 Host 不可复现 | QUALIFIED | E01,错配确定,旧 TS2307非本轮且不可仅归版本 | 干净安装 NOT RUN |
|
||||
| F06 P1 multi-C full CPU | QUALIFIED | 显式设计限制,建议 P2;不等于关闭 GPU retained reuse | 相同Style A/B NOT RUN |
|
||||
| F07 P2 ordinal 线性 | CONFIRMED | C05,优化定位不能改全局编号 | S/G基准 NOT RUN |
|
||||
| F08 P2 全局失效宽 | QUALIFIED | 保守设计,未证明 stale;未知依赖不能裁窄 | source/tile/glyph依赖 |
|
||||
| F09 P2 错归风险 | CONFIRMED | O01具体先换entries后旧析构链;不证明stale texture | 真cache生命周期 NOT RUN |
|
||||
| F10 P2 文档漂移 | QUALIFIED | E02降P3;不推定实际接入 | 负责人跨项目核对 |
|
||||
|
||||
没有为凑数将整个旧项标 DISPROVED;被否定的是“多C关闭所有GPU reuse”“计数错归证明旧纹理复用”“.10必然造成TS2307”“单测证明像素正确”等外推。旧报告未明确作这些断言之处,也不反向指控它作过。
|
||||
|
||||
## 7. 反例、边界和设计限制
|
||||
|
||||
1. `render_segment_plan.hpp:32-157` 采用完整 ordered IDs(含 hidden),边界存在且递增,全R/全C合法,相邻同策略不合并,V12经同模型映射;首段可省 startLayerId 是契约。普通 invalid 清 resolution、恢复重解析有依据。
|
||||
2. reorder 不是“仅added/removed所以遗漏”:`src/mbgl/renderer/style_diff.cpp:9-42` 序列差异体现移动,`render_orchestrator.cpp:318-329` 重建 orderedLayers,未报告无可达链的 reorder bug。
|
||||
3. `renderer.cpp:37-59` 在 full createRenderTree 前清 prepared tree,fast gate 检查 style/source 等输入;不能只见缓存引用便断言 UAF。context/destroy 极端交错仍需验证。
|
||||
4. `renderer_impl.cpp:798-918` 保留 opaque reverse/translucent forward 与 global ordinal,compositor premultiplied alpha/depth disabled 有源码依据。但不能推导所有分段像素等价,N01/N02仍为 gate;不凭空宣称所有 alpha 顺序错误。
|
||||
5. Cache OFF、不支持内容、资源准备失败已有普通路径;多 C 只退出 CPU fast,R可reuse。3D/debug/legacy/custom gate保守,不建议绕过求性能。
|
||||
6. QBIN有文件/plane/cell/decoded上限、CRC/bounds/长度检查,Clock有速度/整数溢出检查;FieldSeries按时间/revision处理重复/旧版本并shared持有窗口。未找到可证实的任意写/越界链;N06是数值发布语义。旧canonical adapter已有有限性检查,不能一概否定。
|
||||
7. State A/B、Trail、T0/T1和方向/速度各有路径;`render_particle_validation_layer.cpp:1671-1810` resize重建Trail、按zoom-out gesture决定reseed并保留其他状态,不代表orientation/zoom-out设备通过。nearest/linear采样及双端点validity需数值视觉基准,本轮未断言错误插值。
|
||||
8. 共享海陆mask尚无验收证据:`field_projection_materialization.cpp:77-92` snapshot displayDomain为GLOBAL;`render_particle_validation_layer.cpp:278-293,1314-1324` 有synthetic coastal mask路径。不能据此证明Wave/Tide/Current共用正式Land/Ocean Mask;陆地覆盖显示不等于mask。列为架构/接入证据缺口,不擅改协议。
|
||||
9. 桥接保持map-scoped,typed object经内部JSON,没有引入业务协议;普通invalid plan会关闭旧计划。符号接线不等于ABI/codegen或销毁竞态已测。
|
||||
|
||||
## 8. V12/V13 架构与成本比较
|
||||
|
||||
L=层数、G=LayerGroup数、S=段数、R=retained数、W/H=物理视口、P=格点。仅源码模型,不是测量。
|
||||
|
||||
| 维度 | V12 | V13 | 判断 |
|
||||
| --- | --- | --- | --- |
|
||||
| topology | 固定range,最多两个R | 任意独立R/C,相邻R不合并 | 扩大管理/资源上界,不自动提高FPS |
|
||||
| GPU复用 | 固定retained部分 | 每R独立 | Layer fingerprint局部化,全局依赖仍保守 |
|
||||
| CPU fast | 合格单连续区间 | 恰好一个C且gate满足 | 多C full CPU不等于GPU cache关闭 |
|
||||
| diagnostics | 旧统计结构 | 完整Style和重复段层列表 | C01 O(L+S)复制 |
|
||||
| 范围定位 | 固定数量 | S段前缀可能O(S×G) | 实际占比待测 |
|
||||
| retained资源 | 至多两组 | O(R×W×H) | 物理峰值与OOM未测 |
|
||||
| Metal等待 | 固定targets | 随失效R增加 | 普通State/Trail是继承成本 |
|
||||
| 场/粒子更新 | 已有物化/drawable | 多数继承 | C06/C07不全归因V13 |
|
||||
|
||||
STEP-090 fast ON 21.7%/OFF97.0% RenderThread仅历史特定实验,不外推V13。历史一次退出及随后短时未复现,既不证明泄漏也不证明长稳。必须同设备、Style、源数据、视口、刷新率/热状态配对,先像素正确再比CPU/GPU。
|
||||
|
||||
## 9. 测试证据与 RDC 验证矩阵
|
||||
|
||||
| 项目 | 历史 | 本轮 |
|
||||
| --- | --- | --- |
|
||||
| STEP-094 GL构建、8 suites/43 tests | 报告PASS | HISTORY/NOT RUN;纯状态解析不能验证GPU |
|
||||
| Field/QBIN/viewport69 tests、package TS | 旧审查PASS | HISTORY/NOT RUN |
|
||||
| Metal-only iPhoneOS编译 | STEP-094 PASS | HISTORY/NOT RUN;不验证附件/像素 |
|
||||
| Android APK、RN codegen | STEP-094 PASS,codegen用底层入口 | HISTORY/NOT RUN |
|
||||
| Host工作树替换TS及旧默认失败 | 两种不同依赖环境 | HISTORY/NOT RUN,可同时成立 |
|
||||
| 本轮静态/文档检查 | 不适用 | 已执行;Git结果见阶段收尾 |
|
||||
|
||||
以下所有运行项本轮均未执行。
|
||||
|
||||
| Gate | Android GL | iOS Metal真机/模拟器 | Vulkan/其他 | 证据要求 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| R/C/R-R/R-C-R/C-R-R/R-R-C/R-C-R-C-R | NOT RUN | NOT RUN | NOT RUN | cache OFF/ON截图、像素差、pass/ordinal |
|
||||
| 同source stencil、半透明fill/line/symbol | NOT RUN | NOT RUN | NOT RUN | 首帧/rebuild/reuse、depth/stencil capture |
|
||||
| hidden/reorder/delete/restore/invalid | NOT RUN | NOT RUN | NOT RUN | 下一帧无stale、revision与plan |
|
||||
| OFF/资源失败/draw失败/context loss | NOT RUN | NOT RUN | NOT RUN | 失败不可reuse,资源配对与恢复 |
|
||||
| PLAY/T0T1/坏数值/乱序/旧revision | NOT RUN | NOT RUN | NOT RUN | time/mix、返回码、旧窗口保持策略 |
|
||||
| pan/zoom-out/pitch/resize/orientation | NOT RUN | NOT RUN | NOT RUN | state/trail/reseed及无额外field提交 |
|
||||
| 30/60FPS,单C/多C、mutation | NOT RUN | NOT RUN | NOT RUN | CPU/GPU p50/p95/p99、miss/wait/alloc |
|
||||
| 预算/峰值/30分钟以上长稳 | NOT RUN | NOT RUN | NOT RUN | R×视口×字段阶梯、bytes/后台/卸载 |
|
||||
| attach/detach/双map/销毁中完成 | NOT RUN | NOT RUN | NOT RUN | owner thread、generation、listener |
|
||||
| 干净包版本/ABI/codegen | NOT RUN | NOT RUN | 不适用 | resolved包/散列/生成接口/实际调用 |
|
||||
|
||||
RDC先记录HEAD/manifest/tag/构建配置;以下是既有精确命令,本轮未执行。新增缺陷尚未补测试,旧过滤集PASS不能关闭本报告。
|
||||
|
||||
```sh
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner -j3
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='RenderSegmentPlan.*:RenderSegmentDiagnostics.*:ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='ParticleFieldRuntime.*'
|
||||
cmake --build build-ios --target ios-sdk-static -- -quiet
|
||||
```
|
||||
|
||||
Metal命令前确认构建目录MLN_WITH_METAL=ON、MLN_WITH_OPENGL=OFF;缺目录由RDC按规范配置,不复用未知缓存。RN先解决真实resolved `.13`前提,再按STEP-094/083现行入口typecheck/codegen。失败回传首个真实error、target、上下文和日志路径,成功仅exit/耗时/摘要。
|
||||
|
||||
## 10. 优先级与建议修复批次
|
||||
|
||||
只建议,不创建修复任务、不改源码。
|
||||
|
||||
| 批次 | 范围 | Gate/安全约束 |
|
||||
| --- | --- | --- |
|
||||
| A 正确性 | N01/N02/N03 target/Metal/失败发布,N04时钟另小提交 | 最小复现、故障注入、两平台OFF基线、PLAY端到端;不借机全面重构 |
|
||||
| B 无设备可先回归 | N05/N06/N07/O01/E01 | 纯测试/桥接由RDC执行;版本可复现,不代替A的GPU gate |
|
||||
| C CPU安全优化 | C01轻快照、C05ordinal/粒子列表、C06相同时间早退/端点复用 | 同步一致、Style唯一顺序、调用/分配次数证明 |
|
||||
| D GPU资源/同步 | C02/C03/C04/C07 | 先profile,再预算和allocation/content分离;明确buffer依赖,不能直接删wait |
|
||||
| E 较大架构 | multi-C fast、source依赖、异步大场、正式共享mask | 单独设计,未知依赖继续全局失效,不引入provider/HTTP业务调度 |
|
||||
|
||||
## 11. Git 与交付
|
||||
|
||||
仅四个允许路径:本文、`docs/50_Step记录/STEP-095_V13独立严格代码与性能审查_v1.md`、`docs/报告/STEP-095_V13独立严格代码与性能审查_Codex完成报告_v1.md`、根`粒子开发记录.md`末尾追加。创建前同主题输出不存在,使用v1,不覆盖旧报告。
|
||||
|
||||
起始HEAD `05878d662308b9a92c20c433c3cd2943d74ae718`。检查路径/引用/`git diff --check`后仅scoped staged/commit/push origin particle/main。实际SHA/message、push/remote/status及最终收尾提交自引用说明见阶段记录第4节;推送未完成前不写Git PASS。冻结源码至最终文档提交的差异只含既有两份文档及本轮四份文档,不含源码/shader/API/依赖/build/manifest/tag/产物。
|
||||
231
docs/20_调查/STEP-096_V13隔离盲审调查_v1.md
Normal file
231
docs/20_调查/STEP-096_V13隔离盲审调查_v1.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# STEP-096 V13 隔离盲审调查 v1
|
||||
|
||||
本报告仅使用 `/Users/tei/dev/MapLibreParticleV13Blind096` 内的当前规范、任务书与源码。发现由本轮独立阅读、追踪调用链及反例检查形成;未读取外部仓库、其他轮次审查、历史报告、会话日志、网页或既有审查结论。未构建、未执行测试、未运行设备、未修改源码。
|
||||
|
||||
## 1. 输入、结论边界与证据等级
|
||||
|
||||
- 合同:[STEP-096 任务书](../40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md)。已读取根 AGENTS、PARTICLE_BASELINE、项目规范目录、总则 README 指定的当前有效文件。
|
||||
- 唯一目录:`/Users/tei/dev/MapLibreParticleV13Blind096`。目标导出 SHA:`ee0b89e711bf01335b3aa71d36def785cd97fec3`,来源为任务书声明;本轮没有 Git 对象可供独立核验,未运行 Git。branch、当前 HEAD、Git clean/remote 状态均为 NOT AVAILABLE。
|
||||
- [release manifest](../../release/maplibre-particle/release-manifest.json#L4) 声明 particleRevision=13、sourceCommit=`ddf20dec9fe9cd05b77274827b6825829500dd5a`,RN/Android 为 `13.4.1-particle.13`,iOS 为 `6.28.0-particle.13`。manifest 的 sourceCommit 是产物来源声明,不能替代本次快照导出 SHA,也不能据此断言导出错误。
|
||||
- 当前基线总则仍包含 `.3` 发布坐标;本轮以快照源码及 `.13` manifest 描述实现。此为文档口径差异,未据此推断线上产物错误。manifest 的发布成功字样不是本轮公网回读证据。
|
||||
- 当前工作机器观察值为 `Mac-mini-tei.lan`;工作日期为 2026-09-25。实际 TUI 启动命令、screen 归属、模型配置及 reasoning 设置的独立启动记录均 NOT AVAILABLE;不访问目录外补证,不声称核实了 RDC 启动要求。
|
||||
|
||||
“确定缺陷”指限定触发条件下源码控制流或数值关系已闭合,不表示已复现用户事故。“源码确定成本”指可证明的调用、遍历、分配或等待,不表示 profiler 排序。“设计限制”指当前能力或上界不足。所有 GPU 画面、耗时、卡顿、OOM、崩溃、性能收益均 NEEDS_RUNTIME;所有构建和测试均 NOT RUN。未发现可由本轮证据成立的 P0。
|
||||
|
||||
## 2. 独立架构地图
|
||||
|
||||
| 路径 | 实际责任和所有权 | 审查定位 |
|
||||
|---|---|---|
|
||||
| RN RendererRuntime → 平台 bridge → Map/Renderer → RenderOrchestrator → segment plan | Host 提交策略配置;Style 层顺序仍是绘制顺序来源,策略在该顺序上划分区间 | [RN 入口](../../packages/maplibre-particle-rn/src/RendererRuntime.ts#L22)、[分段计划](../../src/mbgl/renderer/render_segment_plan.hpp)、[Renderer](../../src/mbgl/renderer/renderer_impl.cpp#L583) |
|
||||
| Renderer → RetainedUnderlayCache → gfx RenderPass/OffscreenTexture → GL/Metal | Renderer 持有各 retained 段缓存;缓存拥有离屏纹理/合成资源;同帧 PaintParameters 穿过多个目标 | [缓存生命周期](../../src/mbgl/renderer/retained_underlay_cache.cpp#L201)、[渲染调度](../../src/mbgl/renderer/renderer_impl.cpp#L798) |
|
||||
| RN FieldRuntime → Android/iOS bridge → WeatherRuntime/MLNParticleFieldRuntime → RasterArraySource | bridge 定位地图并派发;Source 持有 encoded store、绑定、forecast clock;发布不可变 Impl/投影供 RenderLayer 读取 | [RN API](../../packages/maplibre-particle-rn/src/FieldRuntime.ts)、[Source 提交](../../src/mbgl/style/sources/raster_array_source.cpp#L422) |
|
||||
| encoded ingress → QBIN V2/V3 → profile validator → EncodedFieldStore/FieldSeries → binding/window | magic 分派格式,校验结构和 profile;每个 fieldKey 保存时间序列;时间窗选取后物化数组 | [V3 解码](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp)、[profile](../../src/mbgl/particle/field/field_profile_validator.cpp)、[series](../../src/mbgl/particle/field/field_runtime.cpp#L144) |
|
||||
| projection → WeatherColorLayer / RasterParticleLayer → GL/Metal shader | 色场与粒子分层;颜色消费标量或向量幅值;粒子持有场纹理、State A/B、Trail A/B 和 drawable/tweaker | [物化](../../src/mbgl/particle/field/field_projection_materialization.cpp#L201)、[粒子更新](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1489)、[颜色更新](../../src/mbgl/renderer/layers/render_weather_color_layer.cpp#L205) |
|
||||
|
||||
正常路径存在实际保护:Style diff 处理增删/重排;无效分段与不支持场景可 fallback;稳定 retained 帧可复用;解码有结构、尺寸、CRC 等检查;同时间身份冲突和陈旧修订会拒绝;超出时间覆盖范围不会凭空外推。Source 使用共享不可变帧/投影,使读者可持有旧快照;粒子 tweaker 使用 weak_ptr,不能仅因资源与 drawable 互相引用的表象断言泄漏。
|
||||
|
||||
固定边界的实现情况:正式 Host 提交路径未要求 Native 承担 provider/manifest 下载;旧 fixture/local FileSource 路径应单独理解。RN 是控制入口,绘制仍在 Native Core。粒子模块有独立 field/ingress/render 层,但 Renderer/RenderOrchestrator 中也存在较多集成逻辑;没有上游对照输入,无法量化“薄接入”变更比例。Wave/Tide/Current 的共享地理掩码要求见 B09。GL 与 Metal 不能由共享 C++ 自动推出行为一致;Vulkan 完整粒子链未在本轮闭合。
|
||||
|
||||
## 3. 独立发现总表
|
||||
|
||||
编号按本轮源码证实顺序,排除的候选不占编号;优先级是建议处理顺序,不是实测事故等级。
|
||||
|
||||
| 编号 | 优先级 | 类型 | 置信度 | 发现及作用边界 |
|
||||
|---|---|---|---|---|
|
||||
| B01 | P1 | 确定缺陷 | 高 | 切换离屏/主目标未重置 tile stencil 的 CPU 覆盖记录 |
|
||||
| B02 | P1 | 确定缺陷 | 高 | Metal RenderPass 没有落实 gfx 的 clearDepth/clearStencil 请求 |
|
||||
| B03 | P2 | 源码确定成本 | 高 | Metal 每次离屏 present 显式等待 GPU 完成 |
|
||||
| B04 | P2 | 源码确定成本 | 高 | retained 内容失效同时释放同尺寸 GPU 资源 |
|
||||
| B05 | P2 | 源码确定成本 | 高 | 时间更新先全量物化场,再判断投影是否相同 |
|
||||
| B06 | P1 | 确定缺陷 | 高 | encoded PLAY 无生产路径推进 forecast clock |
|
||||
| B07 | P2 | 确定缺陷 | 高 | 8-bit 对称场编码不能表示零,产生有符号偏差 |
|
||||
| B08 | P2 | 确定缺陷 | 高 | Mercator 东向 U 位移缺少纬度修正因子 |
|
||||
| B09 | P2 | 设计限制 | 高 | 当前掩码为合成 fixture,未形成共享地理 Ocean Mask |
|
||||
| B10 | P2 | 源码确定成本 | 高 | 平台 UI 派发链同步解码并物化 encoded 数据 |
|
||||
| B11 | P2 | 设计限制 | 高 | encoded store 仅限制每序列帧数,无全局字节/key 上界 |
|
||||
| B12 | P2 | 确定缺陷 | 高 | retained 段绘制抛异常后仍可能标记缓存构建成功 |
|
||||
| B13 | P1 | 确定缺陷 | 高 | 粒子场更新门槛漏掉合法时间窗内的 V/有效性变化 |
|
||||
|
||||
### B01 — stencil 覆盖记录没有随渲染目标切换
|
||||
|
||||
**触发与调用链。** 多个 retained 段,或 retained 构建后主目标绘制,复用相同瓦片集合且需要 stencil 裁剪。[Renderer buildRetainedRange](../../src/mbgl/renderer/renderer_impl.cpp#L798) 共用 PaintParameters;[beginBuild](../../src/mbgl/renderer/retained_underlay_cache.cpp#L304) 创建清 stencil=0 的离屏 pass,GL 只更新 stencil 可用性;随后[主 pass](../../src/mbgl/renderer/renderer_impl.cpp#L839) 也清 stencil=0。[updateStencilBufferAvailability](../../src/mbgl/renderer/paint_parameters.cpp#L100) 不清覆盖表;[tileIDsCovered](../../src/mbgl/renderer/paint_parameters.cpp#L147) 和[早退](../../src/mbgl/renderer/paint_parameters.cpp#L185) 只看 tile ID,不看 attachment。下一目标仍会用[旧的 Equal stencil ID](../../src/mbgl/renderer/paint_parameters.cpp#L365)。[GL LayerGroup](../../src/mbgl/gl/layer_group_gl.cpp#L67) 正常调用掩码生成,也无法绕过这个早退。
|
||||
|
||||
**所有权、正常/错误/销毁。** 覆盖表属于同帧 PaintParameters,stencil 内容属于每个目标附件。下一帧重建 PaintParameters 不能修复同帧跨目标;[显式 clearStencil](../../src/mbgl/renderer/paint_parameters.cpp#L156) 会重置记录,但上述目标切换没有调用。资源创建失败有 fallback,与本问题不同;正常创建成功即可触发。在 GL 已清为 0 的新目标上,旧正 ID 与实际内容不一致的路径已证实。Metal 的清屏另受 B02 影响。
|
||||
|
||||
**反例与边界。** 同一 attachment 内复用覆盖记录是正确优化;瓦片集合改变可能重绘掩码;无裁剪图层、没有跨目标构建或全部退回主绘制的帧不满足条件。不能据此称所有 retained 帧都缺图,实际画面 NEEDS_RUNTIME。
|
||||
|
||||
**安全修复/最小验证。** 在目标/attachment 世代切换时失效掩码元数据及 ID 分配状态,保留同目标复用;不可在已绘制内容中途随意清 stencil。构造 R/C/R 和 R/R 共用瓦片的 fill/line 层,逐目标检查掩码写入及截图,与关闭 retained 对照;含稳定复用、相机变化、主目标后续 live 层。
|
||||
|
||||
### B02 — Metal 没有传递 depth/stencil 清屏语义
|
||||
|
||||
**触发与证据。** retained beginBuild 明确请求 depth=1、stencil=0;[Metal offscreen bind](../../src/mbgl/mtl/offscreen_texture.cpp#L62) 新建 descriptor 并挂接 color/depth/stencil 纹理。[Metal RenderPass 构造](../../src/mbgl/mtl/render_pass.cpp#L13) 只处理 clearColor,没有读取 clearDepth 或 clearStencil;[GL 对应构造](../../src/mbgl/gl/render_pass.cpp#L14) 把这些请求交给 clear。调用链为 Renderer → cache.beginBuild → gfx descriptor → Metal RenderPass → MTL descriptor,丢失发生在最后的转换。
|
||||
|
||||
**所有权与反例。** 附件属于 offscreen texture,pass/command encoder 管理本次命令。创建和销毁附件均不等于每次按请求清屏。主平台 descriptor 可自行配置清屏,不能证明新建离屏 descriptor 已正确配置;无 depth/stencil 的 pass 不受这两个字段影响。未使用外部 SDK 默认值推断确定黑屏,也未把未显式设置 StoreAction 直接定性为丢帧。模拟器 stencil attachment 分支另需设备验证。
|
||||
|
||||
**影响/修复/验证。** 确定的是 gfx 请求未落实,裁剪/深度表现 NEEDS_RUNTIME。统一转换各附件的 clear/load/store 语义,分别覆盖有无 clear 值、有无附件及模拟器组合格式。用非默认 depth/stencil clear 值做离屏后续比较测试,并核对 GPU capture;不得以 color 正常替代 depth/stencil 验证。
|
||||
|
||||
### B03 — Metal 离屏 present 中存在同步等待
|
||||
|
||||
**触发与链。** [RenderTarget::render](../../src/mbgl/renderer/render_target.cpp#L71) 在每个 target 绘制结束后 present;[Metal command encoder](../../src/mbgl/mtl/command_encoder.cpp#L29) 调 resource.swap;[OffscreenTexture::swap](../../src/mbgl/mtl/offscreen_texture.cpp#L86) commit 后执行 waitUntilCompleted,再重置命令缓冲。粒子稳态在[目标注册](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L2097) 中至少包含 StateWrite 和 TrailWrite,初始化还有额外读目标;retained 构建也有 present。
|
||||
|
||||
**所有权、边界和反例。** 等待保护命令/资源完成,是确定同步点,不是已测出的长时间阻塞。仅实际执行这些目标的帧计入;停绘、未激活层不计,retained 稳定复用不计新的 cache build 等待,GL 不经过此 Metal 函数。完成/销毁安全不能通过简单删 wait 保证。
|
||||
|
||||
**修复/最小验证。** 研究同队列命令依赖与完成回调持有资源,合并或延后提交,保留读写顺序及销毁保护。Metal capture 记录单粒子层每帧 command buffer、wait 次数和 CPU 等待时长,再测多粒子层、首帧、retained 重建及移除层;性能收益 NEEDS_RUNTIME。
|
||||
|
||||
### B04 — 内容失效与资源释放绑定
|
||||
|
||||
**触发与链。** 相机矩阵/内容 revision 改变而 viewport 尺寸不变。[Renderer revision 更新](../../src/mbgl/renderer/renderer_impl.cpp#L583) → [cache evaluate](../../src/mbgl/renderer/retained_underlay_cache.cpp#L201) → releaseResources → [prepareResources](../../src/mbgl/renderer/retained_underlay_cache.cpp#L244) 重新创建离屏资源。[releaseResources](../../src/mbgl/renderer/retained_underlay_cache.cpp#L365) 清掉纹理、合成组及资源键。
|
||||
|
||||
**正常/错误/销毁与反例。** 缓存对象持有资源,失效已实际释放所有权;稳定 valid 分支会 Reuse,不能称每帧都分配。viewport、格式、context 改变或最终销毁确需释放;资源创建异常已有 fallback。本 finding 针对同尺寸、同 context 的内容失效成本,不主张旧图继续有效。
|
||||
|
||||
**修复/验证。** 分开“内容有效性”和“附件可复用性”,保留匹配资源键的附件并重绘。固定 viewport 平移/缩放,对比 offscreen 创建次数、峰值显存、帧时间;再覆盖 resize/context 重建,防止错误跨 context 复用。成本路径已证实,分配耗时与收益 NEEDS_RUNTIME。
|
||||
|
||||
### B05 — 时间更新重复物化整个场
|
||||
|
||||
**触发与链。** Host 高频 setEncodedForecastTime,包括相同非零时间。[setRequestedForecastTime](../../src/mbgl/style/sources/raster_array_source.cpp#L453) → refreshV4RendererState;[clock setter](../../src/mbgl/particle/field/field_runtime.cpp#L196) 不因同值返回 false;[refresh](../../src/mbgl/style/sources/raster_array_source.cpp#L496) 先物化两类投影,再用 sameProjection 比较。[validity](../../src/mbgl/particle/field/field_projection_materialization.cpp#L69) 展开 bitset,[vectorSnapshot](../../src/mbgl/particle/field/field_projection_materialization.cpp#L105) 遍历向量;颜色 UV 与粒子各有自己的 T0/T1 物化。[sameProjection](../../src/mbgl/style/sources/raster_array_source.cpp#L65) 还会比较实际数组。
|
||||
|
||||
**所有权和反例。** 新数组在临时共享快照中,比较相同后可释放;发布新 Impl 时旧读者继续持有旧快照。无投影、无绑定、无法解出窗口会少做或跳过相关分支。相同内容可避免发布或 GPU 重传,故不等于每次都上传纹理;每个动画帧也不一定调用该时间 setter。完整性校验是必要成本,问题是同内容重复重建。
|
||||
|
||||
**成本/修复/验证。** N 个格点、两个时间面、颜色 UV 与粒子同时激活时,四份 vector+valid 基础数组约为 36N 字节的新逻辑存储,另有比较/校验遍历和旧快照重叠。缓存以完整不可变内容身份(含两分量、validity、grid、解释规则)为键,将 mix/time 与数组物化分离。统计同值时间、仅 mix 变化、跨窗、修订替换时的分配与上传次数;不得牺牲 B13 所需的完整身份。
|
||||
|
||||
### B06 — encoded PLAY 没有接入 forecast clock 推进
|
||||
|
||||
**触发与链。** 提交两帧、绑定、设置时间后,经公开 API 切 PLAY 并等待 repaint。[Source 播放设置及 advanceForecastClock](../../src/mbgl/style/sources/raster_array_source.cpp#L459) 中,播放设置只改 clock 状态,推进由独立方法完成。对 src/include/platform/RN 生产路径检索 advanceForecastClock 仅有[声明](../../include/mbgl/style/sources/raster_array_source.hpp#L240)和定义,没有调用方。Android [repaint timer](../../platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java#L225) 与 iOS [timer](../../platform/ios/src/MLNParticleFieldRuntime.mm#L147) 只触发重绘;粒子[读取 v4 mix/cadence](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1262) 不推进该 clock。
|
||||
|
||||
**正常/错误/销毁与反例。** clock 由 Source 所有;平台 timer 的生命周期清理不提供时间增量。[advance 实现](../../src/mbgl/particle/field/field_runtime.cpp#L209) 本身存在且处理溢出;[测试](../../test/source/raster_array_v4_host_api.test.cpp#L297) 直接手动调用,所以不能证明公开 PLAY 可自行推进。Host 持续设置 forecast time、C++ 调用方自行 advance、旧 sourceTimeline 路径均是反例;粒子在固定场中移动也不代表预报时刻在播放。
|
||||
|
||||
**修复/验证。** 为 encoded clock 指定唯一推进所有者和单调时钟来源,处理暂停/恢复、rate、地图移除、颜色单层及多层,避免每层重复推进。仅调用一次 setTime 和 PLAY,观察 requestedForecastTime/mix 随 elapsed 改变;暂停保持、恢复不跳跃、不同 rate 成比例,窗口末端行为明确。公开路径缺口可静态确定,运行表现 NEEDS_RUNTIME。
|
||||
|
||||
### B07 — 零值在 8-bit 场纹理中变成负值
|
||||
|
||||
**触发与证据。** 有效向量为零或接近抵消。[粒子编码](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L174) 用 uint8 转换 `(x / scale * 0.5 + 0.5) * 255`,scale 至少为 1;[颜色编码](../../src/mbgl/renderer/layers/render_weather_color_layer.cpp#L45) 同类处理;[GL 解码](../../shaders/particle_gpu_validation.fragment.glsl#L76) 还原为 `(channel * 2 - 1) * scale`,Metal [解码](../../include/mbgl/shaders/mtl/particle_gpu_validation.hpp#L48) 同理。x=0 被截为 127,解码为 `-scale/255`,两个零分量都带偏差,最小 scale=1 时向量长度也高于 1e-5 的近零阈值。
|
||||
|
||||
**边界和反例。** 场快照的 CPU float 正确不代表上传表示正确;无效点被 valid 分支拒绝,不计入这个有效零场问题。不同数值/缩放下误差相对大小不同;方向归一化可放大近零偏差。理论截断误差小于 `2*scale/255`,这是假定合法编码区间的算术界,不是 GPU 实测。重用或销毁纹理不会改变表示误差。
|
||||
|
||||
**修复/验证。** 选取可精确表达零的带符号编码或 float/half 表示,并评估纹理兼容性;仅改四舍五入仍无法让奇数 255 的对称映射精确表示零。以有效零场、微小速度、正负对消、纯东/北场做 GPU 解码读回和粒子位移检查,GL/Metal 同测。实际漂移像素/速度 NEEDS_RUNTIME。
|
||||
|
||||
### B08 — Mercator 东向位移少一个 sec(latitude)
|
||||
|
||||
**触发与链。** formal profile 使用 eastward/northward、m/s 的 U/V 语义,见[profile 校验](../../src/mbgl/particle/field/field_profile_validator.cpp#L25)。上传缩放在 shader 中还原后,[GL formal 位移](../../shaders/particle_gpu_validation.fragment.glsl#L169) 取 `dx=U*dt/C`、`dy=-V*dt/(C*cos(latitude))`;[Metal](../../include/mbgl/shaders/mtl/particle_gpu_validation.hpp#L133) 同样处理。这里 C 为地球周长,输入链未见对 U 预乘 sec(latitude)。
|
||||
|
||||
**推导、反例和边界。** Mercator x=λ/(2π)+0.5,而局部东向速度满足 dλ/dt=U/(R*cosφ),故 dx 应为 U*dt/(C*cosφ)。赤道、U=0 时不受此项影响;60° 纬度当前东向投影位移为应有值的一半。统一 visual time scale 不修复东西/南北相对畸变。此为固定输入语义下的数学缺陷,实际视觉速度、极区处理 NEEDS_RUNTIME;与资源销毁和错误 fallback 无关。
|
||||
|
||||
**修复/验证。** 在一致纬度与极区夹紧策略下对两个分量使用正确度量转换,保留既定视觉时间倍率。0°/45°/60° 的等物理速度东西向和南北向场,比较 CPU 解析预测与单步 GPU 位移;含符号、反向、极区边界与跨日期变更线。
|
||||
|
||||
### B09 — Ocean Mask 尚未形成正式共享地理输入
|
||||
|
||||
**触发与证据。** Wave/Tide/Current 需要 OCEAN_ONLY,或启用当前 mask 模式。[makeCoastalMaskFixture](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L281) 用格点坐标表达式生成合成海岸,formal 资源初始化[仍安装该 fixture](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1314)。物化[统一写 GLOBAL](../../src/mbgl/particle/field/field_projection_materialization.cpp#L77)。[顶点 shader](../../shaders/particle_gpu_validation.vertex.glsl#L56) 的 v_world 源自 quad 坐标,粒子合成[据此采样 mask](../../shaders/particle_gpu_validation.fragment.glsl#L262);[颜色分支](../../shaders/particle_gpu_validation.fragment.glsl#L113) 在该处理前返回。
|
||||
|
||||
**所有权、正常路径与反例。** mask 纹理由粒子资源拥有,随资源重建/销毁;缺少正式地理 mask 数据入口和两类层共享采样语义。默认关闭 mask 的 GLOBAL wind 不因此错误,Host 数据 nodata 也可能已有陆地缺测,但这不等价于独立共享 Land/Ocean Mask。不能把本限制扩展为所有风场不可用。
|
||||
|
||||
**修复/验证。** 由 Host 决定业务域策略,Core 接收明确地理坐标、网格和版本的共享掩码,两层统一采样;不把 provider/下载引入 Native。加载真实小型固定海岸 mask,平移、缩放、旋转后地理边界应固定;分别验证 Wind GLOBAL 与 Wave/Current OCEAN_ONLY,以及 nodata 叠加、删除与替换。当前设计缺口已证实,设备画面 NEEDS_RUNTIME。
|
||||
|
||||
### B10 — encoded 提交在 UI 派发链同步完成重工作
|
||||
|
||||
**触发与链。** RN 提交较大 QBIN。[Android bridge](../../packages/maplibre-particle-rn/android/src/main/java/org/navsea/maplibre/particle/weather/WeatherRuntimeBridgeModule.kt#L310) 经 runOnUiQueueThread 定位并调用 runtime;[Java submit](../../platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java#L97) → [JNI](../../platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp#L1501) 拷贝 bytes 并同步调用 Source。iOS [withMapForTag](../../packages/maplibre-particle-rn/ios/WeatherRuntimeBridge.mm#L105) 使用 UI block → [runtime submit](../../platform/ios/src/MLNParticleFieldRuntime.mm#L222) 拷贝并解码。V3 [CRC](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp#L66) 对字节做位循环,后续解码/校验/投影也在同步调用链内。
|
||||
|
||||
**边界、错误与反例。** Android 本地文件读取在 UI 派发之前,不能笼统写成全部文件 IO 都在 UI;小文件和 Duplicate 后的工作量不同,格式失败会提前返回。解码有大小上限,但允许的输入仍可较大。临时 bytes、decoded frame、Source 持久状态的所有权清楚;问题是所在线程及连续占用,并非已证明泄漏。未观测 ANR 或卡顿。
|
||||
|
||||
**修复/验证。** worker 只做不可变 bytes 解码/校验,带 map/style/source 世代令牌返回所有者线程提交;限制队列并处理取消、地图销毁和过时结果,不能把整个可变 Source 移到 worker。在中小/近上限输入、CRC 失败、连发及页面退出下记录 UI 区间耗时、峰值内存和错误回调。性能影响 NEEDS_RUNTIME。
|
||||
|
||||
### B11 — 每序列八帧不是全局内存预算
|
||||
|
||||
**触发与链。** 单 Source 连续提交不同有效 fieldKey。[EncodedFieldStore 成员](../../include/mbgl/particle/field/field_runtime.hpp#L151) 是 map 和 perSeriesCapacity=8;[submit](../../src/mbgl/particle/field/field_runtime.cpp#L223) 可为新 key 创建 series;[FieldSeries](../../src/mbgl/particle/field/field_runtime.cpp#L168) 只检查本序列容量。Source [提交](../../src/mbgl/style/sources/raster_array_source.cpp#L422) 不要求该 key 已绑定。V3 [输入上限](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp#L19) 限单帧 encoded/decoded bytes,不限 store 总量。
|
||||
|
||||
**所有权和反例。** store 持有共享帧,直到显式 clear/clearAll 或 Source 销毁;渲染读者可能延长旧快照寿命。单帧 decoded 上限 32 MiB 与八帧组合形成每序列最高 256 MiB 的逻辑上界,但不表示每个 profile 都能达到该值。key 数无总上界,不能据此保证 Source 总内存。Host 固定少量 key 并主动清理时可控;本轮没有 OOM 证据。
|
||||
|
||||
**修复/验证。** 在提交前计入全局 key/字节预算,包含共享去重与临时峰值;明确容量拒绝语义,保护当前绑定窗口,避免静默淘汰。循环提交多个合法 key,验证达到预算后稳定拒绝且现有窗口可用;clear 后可恢复,地图销毁后所有者释放,读者完成后最终释放。设计上界不足已证实,实际内存峰值 NEEDS_RUNTIME。
|
||||
|
||||
### B12 — 构建过程错误没有阻止 retained 缓存成功提交
|
||||
|
||||
**触发与链。** retained 范围内某 LayerGroup 在 render 时抛出被捕获的异常,observer 记录错误后正常返回。[RenderOrchestrator 遍历](../../src/mbgl/renderer/render_orchestrator.hpp#L156) 捕获异常并 onRenderError,不把失败状态返回调用方。[buildRetainedRange](../../src/mbgl/renderer/renderer_impl.cpp#L798) 在 opaque/translucent 遍历后继续 finishBuild、markBuildSucceeded;[成功标记](../../src/mbgl/renderer/retained_underlay_cache.cpp#L328) 使其可在后续稳定帧 Reuse。
|
||||
|
||||
**所有权、错误/销毁与反例。** 缓存持有可能只完成部分绘制的纹理,直到下次失效或销毁。资源准备阶段[有 catch/fallback](../../src/mbgl/renderer/retained_underlay_cache.cpp#L240),不属于本路径;无异常、observer 再抛出异常、随后 revision 立刻改变都不满足持续复用条件。此处只讨论同步可捕获 render 异常,不将异步 GPU 错误视作同一证据。
|
||||
|
||||
**修复/验证。** 让范围绘制返回成败或设置本次构建错误标记,失败不提交 valid 缓存,安全 fallback/下帧重试;保留 observer 通知,不引入每帧 GPU 等待作为错误检测。用一次性抛异常的假 LayerGroup 和正常返回的 observer,检查 BuildFailed、禁止 Reuse、下一帧成功恢复,再由 GL/Metal 场景验证画面。
|
||||
|
||||
### B13 — 粒子更新身份没有覆盖第二分量和有效性
|
||||
|
||||
**触发与可构造输入。** 同 fieldKey 的三个不同 validTime 帧使用相同 fieldID/generation/dataVersion,U 内容相同、V 依次变化(或 validity 变化),网格和 schema 兼容。此输入在[FieldSeries 新时间插入](../../src/mbgl/particle/field/field_runtime.cpp#L146) 合法:newerRevision 检查针对同一 timestamp,未要求不同时间递增 generation。窗口从 T0/T1 切到 T1/T2。
|
||||
|
||||
**完整调用链。** [materializeParticleProjection](../../src/mbgl/particle/field/field_projection_materialization.cpp#L201) 仅以 t0/t1FirstPlane 身份传给 baseSnapshot;[baseSnapshot](../../src/mbgl/particle/field/field_projection_materialization.cpp#L77) 用 fieldID+该身份组成 fieldID,保留 producer generation/dataVersion。[Source sameProjection](../../src/mbgl/style/sources/raster_array_source.cpp#L65) 比较实际数组,可正确发布新的 V/validity。但[粒子 sourceChanged](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1489) 只调用[fieldIdentityChanged](../../include/mbgl/particle/field/field_data_adapter.hpp#L111),其只比 generation/fieldID/dataVersion。两个槽身份都未变时,不进入内部 sameFieldGpuContent/纹理更新分支,继续使用旧场纹理。
|
||||
|
||||
**所有权、反例和边界。** Source 新投影存在、Renderer 仍持有旧 resources.field/nextField 及纹理,直到其他身份变化、重建或销毁。每时次主动递增 generation、U 也变化、初次资源创建都能触发更新;纯 mix 变化且窗口内容确实不变应保留纹理。此 finding 不指向颜色层:颜色投影的实际内容比较是反例,已排除“颜色仅看 U 而漏掉 V”的候选。
|
||||
|
||||
**修复/最小验证。** 粒子更新门槛使用包含 U/V、validity、grid 与解释语义的完整不可变内容身份;窗口时间状态单独更新,保持相同内容可复用。采用上述三帧并让 V/validity 可见地不同,seek 跨窗,检查 CPU 选窗、GPU 上传/复用判定及读回;增加不同时间同 generation、仅 V 改变、仅有效性改变、完全相同内容四组。错误门槛可静态证明,旧场画面 NEEDS_RUNTIME。
|
||||
|
||||
## 4. 反例检查及未成案候选
|
||||
|
||||
- **颜色投影身份:排除。** Source sameProjection → sameSnapshot → sameFieldGpuContent 会比较两分量/validity 实际数组;不能仅因第一 plane 参与 fieldID 就断言颜色不更新。B13 另有粒子特定的前置门槛证据。
|
||||
- **粒子资源强引用环:排除。** [ValidationDrawableTweaker](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L770) 持 weak_ptr;[layerRemoved](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1140) 移除目标。本轮未形成泄漏闭环。
|
||||
- **关闭缓存后辅助段状态残留:排除简单结论。** [synchronizeRetainedUnderlayState](../../src/mbgl/renderer/renderer_impl.cpp#L142) 覆盖段缓存同步;不能仅查主缓存 setter。
|
||||
- **纯重排未被处理:排除。** [Style diff](../../src/mbgl/renderer/style_diff.cpp#L19) 与[orchestrator 更新](../../src/mbgl/renderer/render_orchestrator.cpp#L318) 处理移除/添加并重建有序层;分段不是独立 Z-order 数据源。
|
||||
- **任意交错不受支持:排除笼统结论。** 单 continuous 段的 fast path 限制不等于普通 segmented path 不支持多段;[普通绘制](../../src/mbgl/renderer/renderer_impl.cpp#L938) 仍按计划遍历。透明混合、深度与遮挡整体等价性尚需运行验证。
|
||||
- **异常输入必然越界:未成案。** QBIN 有 MaxCells、字节预算、偏移/结构/CRC 检查,FieldSeries 有冲突/陈旧/兼容性拒绝。未完成形式化证明或 fuzz,不能声称完全安全,也未凭大输入符号制造越界 finding。
|
||||
|
||||
## 5. 性能与资源模型(静态模型,非 benchmark)
|
||||
|
||||
设视口为 W×H,retained 段数 K,格点数 N,活跃粒子层数 L,每层有效粒子数 P,encoded 字节数 E,fieldKey 数 F。
|
||||
|
||||
| 路径 | 静态成本模型 | 稳定路径/限制 |
|
||||
|---|---|---|
|
||||
| retained | 每段至少一张 RGBA8 颜色纹理约 4WH 字节,另加实际 depth/stencil 附件、对齐及 drawable;总量随 K 线性增长 | 稳定内容复用;Build 时绘制该段并合成;B04 增加同尺寸分配抖动 |
|
||||
| 粒子 | State A/B 随状态纹理面积增长,Trail A/B 随视口面积增长;积分和粒子绘制约随 P 增长,全屏衰减/合成随 WH 增长 | 初始化/重播种还有额外工作;不可只凭 particleCount 推断全部成本 |
|
||||
| Metal 提交 | 实际执行的粒子层稳态至少两次离屏同步点/层,加当帧 retained Build 数量及其他 target | 这是显式 wait 次数下界模型,不是每次都发生长等待;需 capture 核对实际启用分支 |
|
||||
| 时间 setter | 激活投影物化和数组相等比较为 O(N),颜色 UV+粒子约 36N 字节基础新数组 | 单纯 draw 并不必然调用 setter;不同 scalar/vector 绑定成本不同 |
|
||||
| QBIN | CRC 和解码大体随 E/样本数增长;提交链还会临时复制并可能物化 | 上限约束单帧;失败可以提前结束,不可套用最坏值到所有输入 |
|
||||
| encoded store | 每 key 最多八帧,但总量随 F 增长;另有 materialized snapshot、上传图像、在途旧读者 | 需要显式 clear;现有容量拒绝保护单序列,未构成全局预算 |
|
||||
|
||||
未取得 profiler、锁竞争、allocator、GPU capture 或设备温度数据。不提供热点排名、FPS、毫秒、节省比例或确定 OOM 阈值。查到同步等待和 UI 同步调用,不等于证明死锁;本轮未形成有闭环证据的锁死 finding。
|
||||
|
||||
## 6. 测试源码覆盖与缺口
|
||||
|
||||
阅读测试源码只表示理解其断言,以下全部 NOT RUN。
|
||||
|
||||
| 已阅读的代表性测试 | 能说明的设计意图 | 不能替代的验证 |
|
||||
|---|---|---|
|
||||
| [retained 状态测试](../../test/renderer/retained_underlay_cache.test.cpp#L116)、[失败测试](../../test/renderer/retained_underlay_cache.test.cpp#L479)、[segment 测试](../../test/renderer/retained_underlay_cache.test.cpp#L657) | Build/Reuse/Fallback、范围与交错计划 | 真实 attachment stencil、Metal 清屏、异常经 orchestrator 传递、透明/深度像素等价 |
|
||||
| [clock 测试](../../test/particle/field_runtime.test.cpp#L272)、[Host API clock](../../test/source/raster_array_v4_host_api.test.cpp#L297) | 手动 advance 的时间算法 | 平台 PLAY 是否接入生产推进者 |
|
||||
| [materialization 测试](../../test/source/raster_array_v4_host_api.test.cpp#L392)、[颜色幅值](../../test/source/raster_array_v4_host_api.test.cpp#L433) | 快照不变性、mix、重建计算 | GPU 8-bit 数值误差、B13 跨窗同 producer 身份、数组分配次数 |
|
||||
| [binding 测试](../../test/particle/field_binding.test.cpp#L84)、[V3 解码测试](../../test/particle/qbin_v3_decoder.test.cpp#L346) | 内容身份/选面、格式失败和边界 | 全 renderer 资源切换、UI 延迟、全局 key 预算及竞态销毁 |
|
||||
|
||||
未覆盖或未闭合:Vulkan/WebGPU 完整粒子实现、所有 Style 图层组合、真实设备 Metal simulator/device 差异、GPU 厂商驱动行为、平台业务调用频率、RN 安装/codegen/ABI、所有 error string 和 promise 回调分支、跨线程竞争注入、完整 fuzz、产物字节与 manifest 的对应关系。当前审查是有边界的静态追踪,不是逐行穷尽全仓或安全证明。
|
||||
|
||||
## 7. 后续可执行验证矩阵(交给 RDC,全部 NOT RUN)
|
||||
|
||||
本轮禁止执行以下构建/测试。RDC 在独立获准的验证阶段准备测试 runner 与设备;新增回归用例/修复属于后续代码任务,不能把下表当作本轮已提供可运行补丁。
|
||||
|
||||
| 项目 | 准备与执行动作 | 最小通过条件 |
|
||||
|---|---|---|
|
||||
| B01 | GL、Metal 各加载同瓦片 fill/line,策略 R/C/R、R/R、C/R/C;首帧/重建/复用逐帧对照关闭缓存 | attachment 切换均生成对应掩码,像素裁剪等价 |
|
||||
| B02 | 离屏附件预置非默认值,创建带 depth/stencil clear 的 pass,再以比较绘制检查;device/simulator 各一次 | clear 值与请求一致,无依赖未定义旧内容 |
|
||||
| B03/B04 | 1/2 粒子层、1/3 retained 段;固定视口平移 300 帧,记录 capture/分配/CPU 等待 | 给出次数、时长分布;资源复用变化有证据且无画面回归 |
|
||||
| B05 | 两时间面,固定时间重复 100 次、mix 小步变化 100 次,再跨窗和修订 | 输出物化/分配/上传次数;相同内容复用且变化可靠可见 |
|
||||
| B06 | 仅颜色、仅粒子、两者共存;setTime 一次后 PLAY、PAUSE、不同 rate | forecast time/mix 正确推进,每地图只推进一次 |
|
||||
| B07 | 有效零场、微值、正负对消、东西南北常量场,GPU 单步读回 | 零保持零,近零阈值一致,误差有明确预算 |
|
||||
| B08 | 0°/45°/60°,相同 m/s、相同 dt,比较解析 Mercator 位移 | U/V 投影度量一致,符号正确,极区有限值 |
|
||||
| B09 | 同一固定地理 mask 同时供颜色/粒子,平移缩放旋转,切 GLOBAL/OCEAN_ONLY | 两层海陆边界一致且固定在地理位置 |
|
||||
| B10 | 合法中小/近上限 QBIN、坏 CRC、连发、加载中移除地图 | UI 耗时可量化;回调一次;无过时提交/释放后访问 |
|
||||
| B11 | 多 key 连续提交直至预算,clear 后再提交 | 可预测拒绝、峰值有界、当前窗口不破坏、最终释放 |
|
||||
| B12 | 假 LayerGroup 首次抛异常,observer 记录后返回,下一帧正常 | 首次不得缓存成功;下一帧重试并恢复 |
|
||||
| B13 | 同 generation/dataVersion/U 的三时次,分别仅改 V、validity,再 seek 跨窗 | 新窗口 GPU 内容正确;完全相同内容仍可复用 |
|
||||
| 兼容 | 增删/重排/隐藏边界层,透明层交错、3D/custom fallback、resize/context 重建 | Style 顺序一致,fallback 可恢复,无残留目标 |
|
||||
|
||||
已有 C++ 定向测试的执行入口需使用平台生成的实际 runner;[test/CMakeLists](../../test/CMakeLists.txt#L1) 的 mbgl-test 是库,[macOS 配置](../../platform/macos/macos.cmake#L84) 定义 mbgl-test-runner。RDC 已构建并确认路径后可执行下列命令(本轮未执行;路径必须由 RDC 填写):
|
||||
|
||||
```sh
|
||||
RDC_TEST_RUNNER=/absolute/path/to/mbgl-test-runner
|
||||
"$RDC_TEST_RUNNER" --gtest_filter='Retained*:ContinuousLayerRange.*:RenderSegment*:ParticleFastPath.*:ParticleField*:ParticleQbin*:ParticleEncoded*:Source.RasterArrayV4*'
|
||||
```
|
||||
|
||||
这只运行现有匹配测试,不覆盖全部上述新增场景。RDC 应先确认 runner 的过滤输出确实命中测试,保存命令、exit code、测试数量和日志路径;设备场景记录设备/后端/版本、输入 fixture、截图或 capture。实际构建目录、签名、设备 ID、安装产物及历史日志均 NOT AVAILABLE,本轮不臆造构建命令或成功状态。
|
||||
|
||||
## 8. 分批建议与停止边界
|
||||
|
||||
1. **先补正确性闭环:** B01/B02 的目标附件状态、B06 的唯一时钟推进者、B13 的完整内容身份;加入最小回归后再做跨后端运行验证。B12 同批修复失败提交语义,避免错误缓存长期复用。
|
||||
2. **再统一数值与域语义:** B07/B08 的数值表示/投影度量,以及 B09 的共享地理掩码;用解析输入和小型固定 fixture 定量验收。
|
||||
3. **最后按测量做性能与预算:** B03/B04/B05/B10/B11,先记录同步、分配、线程耗时和峰值,再分别改命令提交、资源复用、物化缓存、工作线程和容量策略;避免多项同时修改而无法归因。
|
||||
|
||||
本轮仅交付三份中文盲审文档,不修改实现或测试。完成后停止,由 RDC 冻结三份原稿 SHA-256 和时间,再独立移交、追加开发记录并做正式仓库 scoped 提交及远端核验。本会话不参与解除盲态比较,不根据外部材料回写发现。
|
||||
|
||||
配套:[Step 记录](../50_Step记录/STEP-096_V13隔离盲审_v1.md) · [完成报告](../报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md)
|
||||
95
docs/30_设计/NavSea_PBF自动识别与轻量混淆跨平台方案设计_v1.md
Normal file
95
docs/30_设计/NavSea_PBF自动识别与轻量混淆跨平台方案设计_v1.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# NavSea PBF 自动识别与轻量混淆跨平台方案设计 v1
|
||||
|
||||
日期:2026-09-27
|
||||
状态:**规划 / DESIGN ONLY;未实现、未测试、未发布。**
|
||||
适用范围:NavSea 自有矢量海图 PBF,MapLibre Native Android / iOS 与 MapLibre GL JS Web。
|
||||
归属:MapLibre 资源加载适配层;**不是粒子、Weather Field 或 QBIN 格式变更**。
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
NavSea 计划对自己分发的 PBF 进行低成本字节混淆,避免直接下载后被普通 PBF/MBTiles 工具读取;客户端收到瓦片后恢复标准 PBF,继续使用原有 MapLibre 解析和渲染链。Web 版本也要消费同一份服务器资源。
|
||||
本方案明确只是增加直接复用数据的门槛,不承诺数字版权保护、防逆向或防止明文提取。客户端可被调试,解码后的 PBF 可在内存或缓存环节被截获;公开 Web 尤其如此。
|
||||
|
||||
**核心规则:检测到 NavSea 专用 Magic Header → 按版本解码;未检测到 → 维持 MapLibre 原有标准资源流程。** 不依据文件后缀决定是否解码,不修改标准 PBF 解析器,不建立第二套地图引擎。
|
||||
|
||||
## 2. 范围与不变项
|
||||
|
||||
- 只处理自有矢量瓦片资源;普通 PBF、第三方瓦片、Style JSON、Sprite、Glyph、图片以及 Weather/QBIN 不受影响。
|
||||
- 原有 URL 路径、Source/Layer、Style Z-order、粒子绘制、GPU、地图交互与正常 HTTP 重试行为不变。
|
||||
- 服务器可同时提供普通 PBF 与封装 PBF;三端遵守同一二进制契约,各自实现资源加载适配。
|
||||
- 只在有效响应体上进行格式识别;404、500、304、取消、空响应等继续走既有错误/缓存语义,不把错误页当 PBF 解码。
|
||||
- 本文是未来工作的设计草案;不指定当前源码已有某个具体 Hook,进入实施前须按当前 fork 做只读调查。
|
||||
|
||||
## 3. 封装结构草案
|
||||
|
||||
建议文件名仍为 `.pbf`,但编码后内容已不是标准 PBF,必须先解封装。以下 **16 字节头仅为待验证候选格式**,实施前冻结字节序、长度和兼容矩阵。
|
||||
|
||||
| 偏移 | 长度 | 字段 | 候选语义 |
|
||||
| --- | ---: | --- | --- |
|
||||
| 0 | 8 | Magic | ASCII `NSVTILE\0`,固定 8 字节 |
|
||||
| 8 | 1 | Version | `1` |
|
||||
| 9 | 1 | Codec | `1 = XOR-v1`;其他值拒绝 |
|
||||
| 10 | 1 | Flags | bit0 表示内部 GZIP,其余保留位须校验 |
|
||||
| 11 | 1 | HeaderLength | v1 固定 16,给后续扩展留入口 |
|
||||
| 12 | 4 | CRC32 | 解封装且内部解压后,标准 PBF 明文的 CRC32;约定字节序 |
|
||||
| 16… | 可变 | Payload | 经 XOR 混淆的原始 PBF 或内部 GZIP 字节 |
|
||||
|
||||
CRC32 只检测意外损坏或密钥不匹配的常见现象,**不是抗恶意篡改认证**。Magic 是类型标识,不是秘密,也不是加密强度来源。头部存在但格式、版本、长度、Flags、Codec 或校验不合法时,必须拒绝,不能退回普通 PBF。
|
||||
|
||||
## 4. 编码、识别、解码
|
||||
|
||||
服务器预处理一次:标准 PBF → 计算明文 CRC32 → 可选内部 GZIP → XOR → 添加 Header → 存储/CDN。对于已经是 GZIP 存储的原始瓦片,应先核对实际字节语义,再决定保留内部压缩还是重新封装,避免重复压缩。
|
||||
客户端:收到已按 HTTP 传输层规则处理的响应体 → 检查 Magic → 读取并验证头部 → XOR 还原 Payload → 按 Flags 内部解压 → 校验长度/CRC32 → 把标准 PBF 交给现有解析器。普通资源无 Magic 时完全返回既有处理链,不新增一次盲目 GZIP 解压。
|
||||
|
||||
**HTTP `Content-Encoding` 与封装内部 GZIP 必须分开。** XOR 后的压缩 Payload 不得冒充 HTTP gzip,否则网络库可能在 XOR 前尝试解压。封装可用 `Content-Type: application/octet-stream`,自定义 `X-NavSea-Tile-Encoding` 仅作辅助诊断;格式识别以响应体 Header 为准。HTTP 层若另行压缩整个封装,须确认客户端收到的是解开传输编码后的封装字节。
|
||||
|
||||
已声明为“必须受保护”的自有 Source 可另设严格策略:缺少 NavSea Header 也报错(fail-closed),防止服务端误发明文;普通/混合 Source 则执行“无头=原路径”。Source 保护策略与字节自动识别是不同层面,不得混为一谈。
|
||||
|
||||
## 5. 三个平台的接入边界
|
||||
|
||||
| 平台 | 未来接入方向 | 重要约束 |
|
||||
| --- | --- | --- |
|
||||
| Android | 在当前 fork 的 MapLibre HTTP 资源响应交给解析器前解封装 | 核对 OkHttp/Native 缓存与 Response 回调实际位置,避免双重解压或额外整份复制 |
|
||||
| iOS | 在当前 MapLibre Native 的对应资源响应路径解封装 | 以实际 iOS 网络资源实现为准,不假设 Android Java 修改会覆盖 iOS |
|
||||
| Web | MapLibre GL JS `addProtocol()` 负责 fetch、校验、解封装并返回标准 PBF `ArrayBuffer` | 自有瓦片 URL 经自定义 scheme 或 `transformRequest` 导向注册的协议;后者本身不能修改响应体 |
|
||||
|
||||
Web 必须核对 GL JS 版本及协议回调契约、Style/TileJSON 的 URL 重写、Worker/主线程负载、CORS 和取消信号;服务端需暴露必要响应头。第三方请求不接入解码器。三端共享格式测试向量,不共享平台相关 HTTP 实现。
|
||||
|
||||
## 6. 缓存、错误与日志
|
||||
|
||||
- CDN/HTTP 缓存以**封装字节**为对象;ETag、Content-Length、缓存键、版本及更新失效策略要与实际封装内容一致。
|
||||
- HTTP 304 没有新响应体;由现有缓存/重验证机制恢复对应实体,不能把空体交给解码器。按当前 Native/Web 路径调查 MapLibre 自有缓存究竟保存封装还是明文,不作默认安全保证。
|
||||
- 若业务要求离线缓存也不可直接导出标准 PBF,需单独设计落盘边界;仅 HTTP 层 XOR 不保证 MapLibre 离线库/内存缓存保存密文。
|
||||
- 解码前限制输入大小,解压后限制最大明文大小与压缩比,避免异常瓦片造成内存放大。数据损坏、版本不支持、密钥不匹配归类为独立 Codec 错误。
|
||||
- 将前述 HTTP URL 诊断与 Codec 诊断分开:`INVALID_URL`、`HTTP_ERROR`、`NETWORK_ERROR`、`UNSUPPORTED_TILE_CODEC`、`TILE_DECODE_FAILED`;只记录必要的 URL(敏感查询参数脱敏)、状态码、版本与长度,不输出密钥或明文 PBF;正常 200 不逐张刷日志,可限频。
|
||||
- 404/500、取消、超时、304、第三方瓦片和正常 200 行为均不因本功能改变。
|
||||
|
||||
## 7. 性能与安全预期
|
||||
|
||||
XOR 是 O(n) 的逐字节操作,优先服务器离线预编码、客户端原地处理,避免 React/JS Bridge 往返和多次完整 Buffer 拷贝。封装额外增加 Header 字节;“XOR 不改变 Payload 长度”不等于整体零额外字节。压缩应在 XOR 前进行,否则压缩收益可能明显恶化。
|
||||
Web 先评估主线程处理时长与地图交互,再决定是否使用 Worker;Android/iOS 关注实际缓存策略、内存峰值与线程阻塞。性能影响只能经真实 PBF 样本、冷/热缓存及拖动缩放实测后定论。
|
||||
|
||||
固定或循环 XOR 密钥可以被分析,已知格式和客户端代码会进一步降低逆向门槛;把算法放到 C++/WASM 或换成 AES 也无法阻止客户端截获已解码的明文。本方案定位为**轻量混淆**。若未来目标提高到防批量下载,应另行规划 HTTPS、授权、短期访问凭据、配额/限速、异常下载监测与必要的数据分发范围;不要把 XOR 描述成加密认证。
|
||||
|
||||
## 8. 未来实施阶段(本次均不执行)
|
||||
|
||||
| 阶段 | 工作 | 产出/闸门 |
|
||||
| --- | --- | --- |
|
||||
| A 只读调查 | 当前 fork Android/iOS HTTP、资源与磁盘缓存;GL JS 版本;服务器 PBF/GZIP、CDN、TileJSON/Style 路径 | 确认真实接入点、压缩语义和数据所有权 |
|
||||
| B 协议冻结 | 冻结 Header 字节序/CRC 覆盖、Codec、Flags、版本策略、普通/受保护 Source、Golden vectors | 三端可交叉解码同一 fixture |
|
||||
| C 服务端 | 离线编码工具、标准/封装样本、响应头及缓存策略 | 普通与封装资源同时可分发 |
|
||||
| D Android/iOS | 各自最小资源适配,保持解析器与业务接口不变 | 各平台原生样本验证;构建/实机由用户手工执行 |
|
||||
| E Web | 注册自定义协议、URL 路由、解码与取消/CORS | 自有/第三方混合地图正常 |
|
||||
| F 综合验收 | 性能、离线缓存、故障、日志、安全边界与回退 | 三端统一验收通过后再决定发布 |
|
||||
|
||||
验收矩阵至少覆盖:原始 PBF、标准 HTTP gzip、封装 RAW、封装内部 gzip、无头普通资源、受保护 Source 缺头、短头/错误 Magic/版本/Flags、错误 CRC/密钥、空瓦片、404/500/304、网络失败/取消、第三方瓦片、冷/热/离线缓存、跨平台 Golden Fixture、Web CORS 与长时间拖动缩放;不得以单张瓦片可显示作为最终通过。
|
||||
|
||||
## 9. 待实施前决策
|
||||
|
||||
1. 是否采用 XOR-v1 作为正式首版,还是只做试验;客户端密钥静态分发的风险是否接受。
|
||||
2. Magic/Header 的精确二进制布局、CRC 字节序、最大明文长度、Codec ID 和压缩 Flags 是否按本草案冻结。
|
||||
3. 哪些 NavSea Source 必须受保护;普通/混合资源的无头旁路范围。
|
||||
4. 离线缓存是否必须保存封装字节,以及 MapLibre 内建缓存如何满足该要求。
|
||||
5. Web URL 路由和跨域部署方案;第三方瓦片是否保持完全独立。
|
||||
|
||||
**本次结论:仅保留规划文档。没有新增 Codec、改动服务器资源、修改 MapLibre HTTP、引入密钥、触发构建/测试或宣布任何平台支持完成。**
|
||||
141
docs/30_设计/STEP-094_通用RenderSegment模型与Style分类Diagnostics设计_v1.md
Normal file
141
docs/30_设计/STEP-094_通用RenderSegment模型与Style分类Diagnostics设计_v1.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# STEP-094 通用 Render Segment 模型与 Style 分类 Diagnostics 设计 v1
|
||||
|
||||
## 1. 目标与边界
|
||||
|
||||
Renderer 只接收 Style 顺序和一组连续 Segment 定义。每个 Segment 的执行策略只有 `RETAINED` 或 `CONTINUOUS`;不引入 LOW/MEDIUM/HIGH,不识别 AIS、Route、Weather 等业务语义,不改变 Style Z-order,也不增加 Anchor/Marker Layer。
|
||||
|
||||
V12 的 Bottom Retained / Continuous / Top Retained 是本模型的兼容特例。新实现只有一套 resolved topology;旧 `setContinuousLayerRange()` 先转换为通用 Segment Plan,再进入同一 Renderer 路径。
|
||||
|
||||
## 2. 公共数据模型
|
||||
|
||||
Core 公共类型位于 `include/mbgl/renderer/render_segment.hpp`:
|
||||
|
||||
```text
|
||||
RenderSegmentPlan
|
||||
schemaVersion = 1
|
||||
segments[1..N]
|
||||
strategy = RETAINED | CONTINUOUS
|
||||
startLayerId = 第 1 段省略;后续段必填
|
||||
```
|
||||
|
||||
RN 公共类型位于 `packages/maplibre-particle-rn/src/types.ts`,`RendererRuntime.setRenderSegmentPlan(reactTag, plan)` 接收 typed object。TurboModule、Android/iOS package bridge 与 platform API 内部使用 schema-versioned JSON,JS 调用方不接触 raw JSON。
|
||||
|
||||
## 3. Config / Resolve 生命周期
|
||||
|
||||
1. map-scoped runtime state 保存 active config、`configSource` 和单调递增 `configRevision`。
|
||||
2. `setRenderSegmentPlan()` 将 active source 切到 `explicit-render-segment-plan`。
|
||||
3. `setContinuousLayerRange()` 将 active source 切到 `continuous-range-compat`,不会再并存第二套 Renderer topology。
|
||||
4. 没有显式配置时,既有 `startsRetainedDynamicRange()` 仅通过 `unconfigured/legacy` adapter 生成兼容 plan。
|
||||
5. RenderOrchestrator 只在 config、Style ready、Layer add/remove/change 时重新解析 boundary ID 和 diagnostics metadata;Particle 高频 Fast Path 不扫描/复制 Style 字符串,也不 stringify JSON。
|
||||
6. `topologyRevision` 只在 resolved strategy/begin/end 签名变化时递增。Visibility 变化更新 `visible`,不改变 topology revision。
|
||||
|
||||
显式 plan 合法条件:definitions 非空;第 0 段无 boundary;第 1..N-1 段 boundary 存在、非空且 index 严格递增;每段非空;完整覆盖 `[0, layerCount)`。失败时 segments 为空、`valid=false`、释放旧 cache 并走 full renderer;ordered `styleLayers` 仍可读取。
|
||||
|
||||
## 4. V12 Compatibility Mapping
|
||||
|
||||
旧闭区间 `[startLayerId,endLayerId]` 解析为:
|
||||
|
||||
```text
|
||||
startIndex > 0 -> RETAINED [0,startIndex)
|
||||
CONTINUOUS [startIndex,endIndex+1)
|
||||
endIndex+1 < styleLayerCount -> RETAINED [endIndex+1,layerCount)
|
||||
```
|
||||
|
||||
因此自然退化为 R-C-R、R-C、C-R 或 C。`configSource=continuous-range-compat`。旧 `getRetainedUnderlayDiagnostics()` 继续保留摘要;多段真实事实以新 API 为准。
|
||||
|
||||
## 5. Renderer 执行与 Cache Ownership
|
||||
|
||||
Resolved Segment 保留 Style 全局 `layerIndex` 和 LayerGroup 原 ordinal。Retained 构建继续使用 opaque reverse / translucent forward;Continuous 直接绘制同一全局 index 范围。`parameters.currentLayer` 和 `depthRangeSize` 不按 Segment 重新编号。
|
||||
|
||||
Renderer 按 resolved topology 动态创建 `retainedSegmentCaches[segmentIndex]`:
|
||||
|
||||
- RETAINED:独立 `RetainedUnderlayCache`、key、revision、texture、compositor 和 counters;
|
||||
- CONTINUOUS:对应 slot 为空,不创建 retained texture/FBO/compositor;
|
||||
- topology 改变:旧 cache 在 Renderer 线程释放,不能迁移或 composite stale resource;
|
||||
- GPU resource 仍由 `prepareResources()` lazy 创建,稳定 viewport 复用。
|
||||
|
||||
主 buffer 按 Segment 顺序执行:Retained composite 或 Continuous direct render。相邻同策略不会合并。
|
||||
|
||||
## 6. Invalidation
|
||||
|
||||
Layer immutable Impl identity 与全局 Style index 组成 retained Segment content fingerprint。Layer property/visibility 在某 retained Segment 内变化时,只推进该 Segment 的 content revision;其他 retained Segment 可继续 reuse。
|
||||
|
||||
以下仍保守 invalidate 全部 retained Segment:camera/viewport/pixel ratio、source/tile、image/sprite/glyph、placement/transition、context reset、debug/3D、style reload、resource/compositor failure。原因是当前 Core 没有足够稳定的通用 source-to-render-segment dependency graph;本 Step 不扩建该图。
|
||||
|
||||
## 7. Particle Fast Path
|
||||
|
||||
恰好一个 Continuous Segment、其内容满足既有 Particle-only 支持条件、所有实际 Retained cache 有效时,沿用 V12 Fast Path。缺少某个不存在的 retained cache 不构成 miss。
|
||||
|
||||
多个 Continuous Segment 暂不做高级 Fast Path:gate 以 `unsupported-continuous-layer` fail closed,进入正常 full CPU frame;Segment topology、cache 与 Z-order 不变。
|
||||
|
||||
## 8. Android / iOS / RN API
|
||||
|
||||
```text
|
||||
RN RendererRuntime
|
||||
setRenderSegmentPlan(reactTag, typedPlan)
|
||||
getRenderSegmentDiagnostics(reactTag)
|
||||
↓ schemaVersion=1 JSON transport
|
||||
WeatherRuntimeBridge(既有唯一 bridge)
|
||||
↓
|
||||
Android MapLibreMap / iOS MLNMapView
|
||||
↓
|
||||
mbgl::Map typed RenderSegmentPlan / RenderSegmentDiagnostics
|
||||
↓
|
||||
RetainedUnderlayRuntimeState + RenderOrchestrator + RendererImpl
|
||||
```
|
||||
|
||||
Android platform 内部 API 为 `setRenderSegmentPlan(String)` / `getRenderSegmentDiagnostics()`;iOS 为 `setRenderSegmentPlanJSON:` / `renderSegmentDiagnosticsJSON`。Core API 保持 typed。JSON/schema/strategy 非法时返回 REJECTED,同时把 active topology 置 invalid,避免继续复用旧 cache。
|
||||
|
||||
## 9. Diagnostics Schema
|
||||
|
||||
Snapshot 为 pull-based。顶层包含 enabled/configured/valid/configSource/configRevision/topologyRevision/counts/coverage/fallback/reason/Fast Path counters;`styleLayers[]` 始终按 Style 顺序;`segments[]` 包含 begin/end、实际 Layer 成员。Retained 的 `cache` 为 object;Continuous 的 `cache=null`,不会伪装为 disabled retained cache。
|
||||
|
||||
完整示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"enabled": true,
|
||||
"configured": true,
|
||||
"valid": true,
|
||||
"configSource": "explicit-render-segment-plan",
|
||||
"configRevision": 7,
|
||||
"topologyRevision": 4,
|
||||
"styleLayerCount": 6,
|
||||
"segmentCount": 4,
|
||||
"retainedSegmentCount": 3,
|
||||
"continuousSegmentCount": 1,
|
||||
"coverageComplete": true,
|
||||
"fallback": false,
|
||||
"lastReason": "none",
|
||||
"fastPathEligible": true,
|
||||
"fastPathActive": true,
|
||||
"fastPathFallbackReason": "none",
|
||||
"fastPathHit": 120,
|
||||
"fastPathMiss": 3,
|
||||
"fullCpuFrame": 4,
|
||||
"styleLayers": [
|
||||
{"layerIndex":0,"layerId":"background","layerType":"background","visible":true,"sourceId":null,"sourceLayer":null},
|
||||
{"layerIndex":1,"layerId":"water","layerType":"fill","visible":true,"sourceId":"chart","sourceLayer":"water"},
|
||||
{"layerIndex":2,"layerId":"rn-weather-color","layerType":"weather-color","visible":true,"sourceId":"rn-weather-fields","sourceLayer":null},
|
||||
{"layerIndex":3,"layerId":"rn-weather-particles","layerType":"raster-particle","visible":true,"sourceId":"rn-weather-fields","sourceLayer":null},
|
||||
{"layerIndex":4,"layerId":"land-area","layerType":"fill","visible":true,"sourceId":"chart","sourceLayer":"land"},
|
||||
{"layerIndex":5,"layerId":"ais-layer","layerType":"symbol","visible":true,"sourceId":"ais","sourceLayer":null}
|
||||
],
|
||||
"segments": [
|
||||
{"segmentIndex":0,"strategy":"RETAINED","configuredStartLayerId":null,"beginIndex":0,"endExclusive":2,"resolvedStartLayerId":"background","resolvedEndLayerId":"water","layerCount":2,"layers":[{"layerIndex":0,"layerId":"background","layerType":"background","visible":true,"sourceId":null,"sourceLayer":null},{"layerIndex":1,"layerId":"water","layerType":"fill","visible":true,"sourceId":"chart","sourceLayer":"water"}],"cache":{"cacheState":"reuse","contentRevision":19,"build":1,"reuse":120,"invalidation":0,"lastInvalidationReason":"none","textureCreate":1,"compositeCreate":1,"resourceRelease":0}},
|
||||
{"segmentIndex":1,"strategy":"CONTINUOUS","configuredStartLayerId":"rn-weather-color","beginIndex":2,"endExclusive":4,"resolvedStartLayerId":"rn-weather-color","resolvedEndLayerId":"rn-weather-particles","layerCount":2,"layers":[{"layerIndex":2,"layerId":"rn-weather-color","layerType":"weather-color","visible":true,"sourceId":"rn-weather-fields","sourceLayer":null},{"layerIndex":3,"layerId":"rn-weather-particles","layerType":"raster-particle","visible":true,"sourceId":"rn-weather-fields","sourceLayer":null}],"cache":null},
|
||||
{"segmentIndex":2,"strategy":"RETAINED","configuredStartLayerId":"land-area","beginIndex":4,"endExclusive":5,"resolvedStartLayerId":"land-area","resolvedEndLayerId":"land-area","layerCount":1,"layers":[{"layerIndex":4,"layerId":"land-area","layerType":"fill","visible":true,"sourceId":"chart","sourceLayer":"land"}],"cache":{"cacheState":"ready","contentRevision":22,"build":2,"reuse":80,"invalidation":1,"lastInvalidationReason":"layer-mutation","textureCreate":2,"compositeCreate":2,"resourceRelease":1}},
|
||||
{"segmentIndex":3,"strategy":"RETAINED","configuredStartLayerId":"ais-layer","beginIndex":5,"endExclusive":6,"resolvedStartLayerId":"ais-layer","resolvedEndLayerId":"ais-layer","layerCount":1,"layers":[{"layerIndex":5,"layerId":"ais-layer","layerType":"symbol","visible":true,"sourceId":"ais","sourceLayer":null}],"cache":{"cacheState":"reuse","contentRevision":11,"build":1,"reuse":40,"invalidation":0,"lastInvalidationReason":"none","textureCreate":1,"compositeCreate":1,"resourceRelease":0}}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
有效 snapshot 保证 Segment layers 拼接等于 styleLayers,Layer 不重号、不遗漏、不重复。RN Test Host 的按钮只在用户操作时配置/拉取并显示一次完整 JSON,不轮询、不逐帧打印。
|
||||
|
||||
## 10. 当前限制
|
||||
|
||||
- 多 Continuous 只保证正确 full renderer,不提供高级 Particle Fast Path。
|
||||
- Source/Tile mutation 尚无通用 dependency graph,仍全 retained invalidation。
|
||||
- Legacy diagnostics 只是兼容摘要,不能表达任意 N Segment。
|
||||
- OpenGL/Metal 编译、Native tests、Android codegen/Gradle 与设备运行由 RDC 独立验证后才能形成 PASS 事实。
|
||||
76
docs/30_设计/STEP-097_V13三轮问题去重与修复矩阵_v1.md
Normal file
76
docs/30_设计/STEP-097_V13三轮问题去重与修复矩阵_v1.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# STEP-097 V13 三轮问题去重与修复矩阵 v1
|
||||
|
||||
基线:Mac-mini-tei.lan;`particle/main`;起始 `720d309364628f85049cf9969d71c71e8dfacce9`,与查询时 `origin/particle/main` 一致;工作区干净。冻结 `.13` tag 指向 `ee0b89e71`。该 HEAD 相对任务书的 `b5c1c4879` 只新增 STEP-097 任务文档。Integration 本地 C-001/RFC-001 已只读;其远端是否最新尚未由 RDC 证实。所有构建、测试和运行验证:**NOT RUN**。
|
||||
|
||||
## 公共不变量
|
||||
|
||||
`fieldId/generation/validTime`、东向 U/北向 V、T0/T1/MIX、旧 T1→新 T0 复用、Style 全局 Z 顺序、每个 R 独立缓存、WeatherColor 与 Particle 分离、Host 拥有天气获取。无权改变 C-001 的公开生命周期、错误或数据所有权语义。
|
||||
|
||||
以下“入口”均为待执行回归,不能当作运行结果。源码状态随阶段更新;`WAITING_RDC_BUILD_AND_RUNTIME` 表示仅完成定位,尚未实现。
|
||||
|
||||
| # / 原编号 | 当前源码定位与最短触发 | 反例/安全约束 | 拟修文件与回归入口 | 状态 / commit / 平台待测 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 01 N01/B01 | `paint_parameters.cpp:185` tile 集合相同跨 R-R target 复用 CPU mask | 同一未清 stencil target 可复用 | PaintParameters、Renderer、RenderTarget 已在新目标重置;同 tiles R-R/R-C-R 像素入口尚缺 | WAITING_RDC_BUILD_AND_RUNTIME / `e67e4961b` / GL、Metal |
|
||||
| 02 N02/B02 | `mtl/render_pass.cpp:21` 仅 color clear;`offscreen_texture.cpp:67` 附件创建 | 无 depth/stencil 的 target 不可盲设附件 | Metal descriptor/combined 附件已修改;专用附件故障测试源码尚缺 | WAITING_RDC_BUILD_AND_RUNTIME / `e67e4961b` / Metal |
|
||||
| 03 N03/B12 | `render_orchestrator.hpp:156` catch;`renderer_impl.cpp:824` 仍 mark success | 失败后 full fallback、下帧重试 | visitor 错误标志与 fallback 已接入;异常注入测试源码尚缺 | WAITING_RDC_BUILD_AND_RUNTIME / `e67e4961b` / GL、Metal |
|
||||
| 04 N04/B06 | `Map::Impl::onUpdate()` 在 Continuous update 驱动每个 RasterArraySource;Source 使用 monotonic tick,并用 `forecastTickInProgress` 阻止同步 SourceObserver 重入二次推进 | 显式 setTime/PLAY/PAUSE/rate 由一个 Core clock owner 推进;平台 timer 只唤醒 | `map_impl.cpp`、RasterArraySource、Android/iOS WeatherRuntime;`RasterArrayV4ProductionClockTicksOnceForBothBindingsAndResetsOnCommands`、`RasterArrayV4ClockSourceNotificationReentryDoesNotAdvanceTwice` | CODE_IMPLEMENTED_STATIC_CHECKED / A2 源码提交 `f49ffa68a` / OpenGL 与 Metal host A2 定向 3/3 PASS;FZG1 V4 Golden PLAY/PAUSE/速率/clear/reload PASS;无 iOS runtime(用户豁免) |
|
||||
| 05 B13 | `sameFieldGpuContent()` 保持 revision/version 无关的 payload 相等;renderer GPU 槽位更新使用严格 `sameFieldGpuEndpoint()`;Source mix-only cache 使用 projection identity、binding、immutable frame 和 plane/validity storage pointer identity | mix-only 复用同一 T0/T1 snapshot;frame/revision、grid、validity、U/V、encoding 或 binding 改变则重物化并失效;invalid/clear fail-closed | `field_data_adapter.hpp`、projection materialization、RasterArraySource 与 renderer;Source cache 测试 + `ParticleGpuField.*` | CODE_IMPLEMENTED_STATIC_CHECKED / A2 源码提交 `f49ffa68a` / broad OpenGL 与 Metal host 各 121/121 PASS,A2 定向各 3/3 PASS;FZG1 stable mix 时 upload/reset 计数稳定;clear/reload 后合法增加 |
|
||||
| 06 B07 | 新增内部 signed RGBA8 编码,byte 128 明确表示零;GL/Metal shader 以 high precision 还原 byte | 不改公开 QBIN/FieldProfile encoding;量化误差与 sub-half-quantum 微速边界明确测试 | `particle_gpu_math.hpp`、GL/Metal shader 源及生成头、`particle_gpu_math.test.cpp` | CODE_IMPLEMENTED_STATIC_CHECKED / A2 源码提交 `f49ffa68a` / broad OpenGL 与 Metal host 各 121/121 PASS,含 signed zero、取消、NaN/invalid 与微速边界;两次 shader generator 幂等;无 iOS runtime |
|
||||
| 07 B08 | 统一 helper 与 GL/Metal 粒子位移路径都为 Mercator 东向 U、北向 V 应用相同 cos(latitude) metric,并夹紧极区分母 | 保持 U/V canonical m/s、V 北向为正、既有视觉时间倍率 | `particle_gpu_math.hpp`、renderer 与 GL/Metal shader 源及生成头;0°/45°/60° 四方向和极区测试 | CODE_IMPLEMENTED_STATIC_CHECKED / A2 源码提交 `f49ffa68a` / broad OpenGL 与 Metal host 各 121/121 PASS,含数学定向测试;Android FZG1 场景闭环通过;无 iOS runtime |
|
||||
| 08 N05 | 长度感知 JSON 解析,拒绝 NUL/重复键/非法 schema,invalid fail-closed | 清旧计划、合法恢复 | `render_segment_json.hpp`、双平台 bridge 与 GTest | CODE_IMPLEMENTED / B Core 定向 6/6、扩展 139/139 PASS;待 B Git,iOS runtime 未测 |
|
||||
| 09 N06 | FieldProfileValidator 在 Store commit 前检验有效数值及 scale/offset | validity=0/noData 合法;坏高 revision 不覆盖好帧 | FieldProfileValidator/Source GTest,修正旧 16-bit fixture | CODE_IMPLEMENTED / B Core 定向 6/6、扩展 139/139 PASS;待 B Git |
|
||||
| 10 N07 | View owner、generation guard、map destroy observer 源码已写 | 旧 map 回调不得影响新世代,监听须释放 | Kotlin/Java JUnit,真实 MapLibreMap.onDestroy | Android Native JUnit 2/2、Java 编译与 owner 隔离 JVM JUnit 4/4 PASS;BLOCKED_NATIVE_AAR_COMPATIBILITY:正式 `.13` 缺新 Map 方法,默认 RN consumer 不可配对编译,B 不判 PASS |
|
||||
| 11 F01/C01 | `renderer_impl.cpp:505` full diagnostics 快照 | 外部 pull schema 不变 | runtime/renderer;快照计数 | WAITING_RDC_BUILD_AND_RUNTIME / 待提交 / Core |
|
||||
| 12 F02/C02/B03 | Metal offscreen `swap()` 同步等待 | 不删不明依赖 wait | Metal;GPU capture | DEFERRED_DESIGN / 无 / Metal |
|
||||
| 13 F03/C03/B04 | cache revision 变化释放 texture | target clear 必须先正确 | cache;同尺寸重绘/resize | WAITING_RDC_BUILD_AND_RUNTIME / 待提交 / GL、Metal |
|
||||
| 14 F04/C04 | R 数 × viewport 独立附件内存 | 保留独立 R 与失败 fallback | cache;资源阶梯、失败注入 | DEFERRED_DESIGN / 无 / GL、Metal |
|
||||
| 15 C04/B11 | encoded Store 无总 key/byte 预算 | 不静默驱逐绑定窗口 | Store;容量/旧读者 | DEFERRED_DESIGN / 无 / Core |
|
||||
| 16 F07/C05 | `render_orchestrator.hpp:156` 每段前缀 distance | 全局 ordinal 与 Z 顺序不变 | orchestrator;重排/正反遍历 | WAITING_RDC_BUILD_AND_RUNTIME / 待提交 / Core |
|
||||
| 17 C06/B05/B10 | A2 已处理相同 immutable projection 的 mix-only 重物化;其余 diagnostics pull、ordinal 与 UI owner 世代发布仍属后续范围 | A2 mix-only 不再复制/比较整张浮点快照;不据此宣称 C 阶段整体完成 | A2 部分:RasterArraySource cache 定向测试及 FZG1;C 部分仍按原任务另行实施 | A2 mix-only 子项已验证 / 当前工作树 `5bb1a0e` / OpenGL、Metal host 定向 3/3 PASS;C 其余项目未开始 |
|
||||
| 18 C07 | drawable/tweaker tick 重建、端点复制 | 不保留 stale GPU 引用 | Particle renderer;tick/resize | DEFERRED_DESIGN / 无 / GL、Metal |
|
||||
| 19 F09/O01 | `runtime_state.hpp:230` 新 topology;旧 cache 析构按 index 计数 | 总量与当前 topology 分离 | runtime/cache 按 revision 过滤;新增 `OldCacheReleaseCannotChargeReplacementAtSameIndex` GTest | CODE_IMPLEMENTED_STATIC_CHECKED / `e67e4961b` / 2026-09-26 Core GTest 1/1 PASS,诊断组 5/5 PASS;GPU 资源验收仍待测 |
|
||||
| 20 F05/E01 | Test Host package/lock 已对齐正式 `.13`,SHA-256/SRI 核对一致 | RN/Native 必须精确同版,不改 `.13` 产物 | package/lock、release manifest、默认 RN 编译 | STATIC_VERSION_LOCK_PASS;B10 新 Native method 不在正式 `.13`,默认消费者仍阻塞 |
|
||||
| 21 F06 | `renderer_impl.cpp` multi-C 走 full CPU | 保留安全 fallback | 后续 A/B 设计 | DEFERRED_DESIGN / 无 / GL、Metal |
|
||||
| 22 F08 | source/tile 等全局失效 | 无依赖图前不缩窄 | 后续依赖设计 | DEFERRED_DESIGN / 无 / Core |
|
||||
| 23 F10/E02 | Integration status/compatibility 仍写 `.5` | 发布≠NavSea 支持 | 负责人协调证据请求 | DEFERRED_DESIGN / 无 / 跨项目 |
|
||||
| 24 STEP-095 §7/B09 | synthetic mask 非共享地理 mask | 不新建公开 mask API | C-001/RFC/ADR 协调 | DEFERRED_DESIGN / 无 / 跨项目 |
|
||||
|
||||
## 操作次数模型(静态,非性能实测)
|
||||
|
||||
- A1:跨 target 清除 CPU mask 为每次目标切换一次 O(1) 状态清理;当前同 tiles 可能零次重绘但产生错误像素。Metal clear 每个 pass 最多各一次附件 load 设置。异常后额外一次 full fallback,避免错误缓存跨帧复用。
|
||||
- A2:PLAY 由唯一 Map/Source clock 每次 update 推进一次;V4 mix-only 的投影重物化计数为 0(50 次 Source tick 定向测试),decoded endpoint 变化时 color/particle projection 各物化一次。FZG1 日志在单次 stable mix-only epoch 内 upload/reset 计数不变;clear/reload 会合法增加计数。以上是源码测试和该次设备记录,不构成普遍 GPU 性能结论。
|
||||
- B:JSON 严格校验 O(输入字节长度),有效数值验证 O(有效 cell × plane 数),View/map 每世代各至多一活跃监听;源码已实施,但正式 .13 Native ABI 不含新方法。无 GPU 性能实测。
|
||||
- C:预期 full diagnostics 深复制从每 render 次降到每外部 pull 次;ordinal 前缀从每段 O(G) 降到 topology 更新 O(G);同时间物化从 O(cell) 降为 O(1)。尚未实施。
|
||||
|
||||
## 2026-09-26 第 19 项实测更新
|
||||
|
||||
- RDC 使用 `0d13552be` 重编译并执行 GTest,第 19 项 1/1 PASS、RenderSegmentDiagnostics 全组 5/5 PASS;详见 `docs/报告/STEP-097_A1_第19项GTest运行验证报告_v1.md`。其他问题状态不因此变化,A1 仍为 PARTIAL。
|
||||
|
||||
## 2026-09-26 第 19 项 FZG1 设备辅助证据
|
||||
|
||||
- 基于相同生产源码的 APK 在 FZG1-2 通过覆盖安装和设备 SHA-256 校验。两轮拓扑循环、重排、缓存 OFF/ON、缺失边界回退与恢复的 20 张截图及 UI 诊断已保存;有效场景的 B/T 粗粒度 textureCreate-resourceRelease 均为 0 或 1。此证据只支持 Android 运行态冒烟,不替代此前旧 revision 归属的 GTest 1/1 PASS,也不能证明 GPU 无泄漏。详见 `docs/报告/STEP-097_A1_第19项FZG1运行验证报告_v1.md`。A1 仍因 01/02/03 未闭合保持 PARTIAL。
|
||||
|
||||
## 2026-09-26 A1 专用入口补充(待 RDC 执行)
|
||||
|
||||
- 01:Android Validation Activity 的 STEP-093 菜单新增 STEP-097 same-source stencil 子菜单;`Step097StencilFixture` 用一个本地 GeoJSON source 与四个 fill layer 生成 R-R、R-C-R、C-R-R,菜单可重载与读 segment 诊断,既有 CACHE ON/OFF 可切换。RDC 仍需首帧/重建/reuse 的实际像素截图与 cache 计数;此处仅是可操作 fixture,未实测。
|
||||
- 02:`mtl_retained_attachments.test.cpp` 检查实际离屏资源的 color/depth/stencil 绑定、simulator/x86 combined attachment、无 depth/stencil 时跳过 clear;生产 `RenderPass` 共用的 clear 辅助函数可检查 load/clear/store。设备资源创建失败与 encoder 失败的运行注入仍待 RDC 验证。
|
||||
- 03:`render_orchestrator_error.test.cpp` 注入正/反向范围 visitor 异常,核对 observer/failed 标志,并用 cache 状态机核对失败后继续 Build、成功重试后 Reuse。真实 GPU 绘制故障与完整 renderer fallback 仍待 RDC 注入验证。
|
||||
- 01/02/03 均保持 `WAITING_RDC_BUILD_AND_RUNTIME`;源码入口准备不等于编译或运行 PASS。19 的既有实测状态不变。
|
||||
|
||||
## 2026-09-26 A1 Android/Core 实测收口
|
||||
|
||||
- 01:same-source tiled fixture RR/RCR/CRR 两轮、rebuild/cache OFF/ON 共 18 点,屏幕中心与区域外采样两组像素均 18/18 一致;状态 valid=true/fallback=false,Android FZG1 实测通过。源码/测试提交 `d0ced7235`,编译修正 `8c006ac83`。
|
||||
- 02:Metal host runner 已编译,GTest 两个测试均因没有 Metal device SKIP;用户决定不执行 iOS 运行测试,记 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`,不得称 Metal 实测 PASS。
|
||||
- 03:`RenderOrchestratorError.*` 原生测试 2/2 PASS;真实 Android GPU fault injection 不在本次证据中。
|
||||
- 19:前述 Core 1/1 PASS、诊断组 5/5 PASS、FZG1 辅助测试均保留。A1 在 Android/Core 验收及 iOS 用户豁免口径下进入 A2;详细事实见 `docs/报告/STEP-097_A1_Android专项验收报告_v1.md`。
|
||||
|
||||
## 2026-09-26 A2 RDC 最终验证
|
||||
|
||||
- 04–07 已在同一 dirty 源码工作树完成实现与 RDC 独立验证。旧 `sameFieldGpuContent()` 测试断言修复后原 58 项 58/58 PASS;更新后的 broad filter OpenGL 与 Metal host 各 121/121 PASS,三项 A2 Source 定向测试两平台各 3/3 PASS。
|
||||
- 标准 Android Validation APK 为 OpenGL Debug/x86_64,61,753,803 bytes,SHA-256 `27bf4a6cc191bd86c4d1c10398478d81c2999edd61fe7242e40e5188516b0ca5`;安装到 FZG1-2 后设备 APK hash 相同。V4 Golden Wind test-only T0/T1 场景 17 张 PNG、24 个步骤、runner exit 0、ANR=0;PLAY 30 秒 UI 可响应,PAUSE 稳定,clear/reload 后再次 PLAY/PAUSE。
|
||||
- 日志按资源窗口分别记录:clear/reload 前 mix-only epoch `fieldUploadCount=6/resetCount=2` 稳定;explicit clear/reload 后计数合法增加,达到 `fieldUploadCount=10/resetCount=4`,此后 replay 稳定。不可把 clear/reload 期间的上传与 reset 写成零。
|
||||
- build source diff SHA-256 `18927a5f30a88f5c1c3a00e0017473dc33b04151c227e4baf52250dc4ad2e6a2` 与忽略目录中的 APK source snapshot 完全一致。未运行 iOS device runtime,按用户豁免记 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`;不得称 Metal host GTest 为 iOS PASS。A2 Android/Core 完成,B/C 未开始,整个 STEP-097 仍 PARTIAL。
|
||||
|
||||
## 2026-09-26 B 独立验证及阻塞
|
||||
|
||||
- RDC Core 定向 4/4、修正旧 16-bit fixture 后 broad 134/134 PASS;正式 .13 Android SDK 缺 B10 新 map destroy observer,默认 RN consumer 无法与该新源码配对。B PARTIAL,C 不启动;详见 B 独立报告。
|
||||
76
docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.md
Normal file
76
docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# STEP-098 QBIN V4 单帧与八帧滚动缓存设计
|
||||
|
||||
日期:2026-09-26
|
||||
状态:**已按接受的设计契约实现源码;Native 构建、定向测试与平台运行验收待 RDC 执行**。
|
||||
|
||||
## 1. 权威契约
|
||||
|
||||
- RFC-004:`/Users/tei/dev/navsea-particle-integration/rfc/RFC-004_QBIN_V4单帧首显与八帧滚动缓存.md`
|
||||
- ADR-001:`/Users/tei/dev/navsea-particle-integration/adr/ADR-001_QBIN_V4单帧与滚动缓存语义.md`
|
||||
- Contract C-002:`/Users/tei/dev/navsea-particle-integration/contracts/C-002_QBIN_V4单帧与滚动缓存.md`
|
||||
- COORD-005:`/Users/tei/dev/navsea-particle-integration/coordination/active/COORD-005/决议.md`
|
||||
- 读取时 Integration `main` / `origin/main` 均为 `1dd576d3304e267e53ed64d31f9711d2350ce10a`。四份文件为 ACCEPTED / DESIGN ONLY 或 IMPLEMENTATION_PENDING,不代表实现、设备或 V15 发布通过。
|
||||
- 原任务 v1 的旧 RFC-003 闸门和 `docs/报告/STEP-098_公共契约阻塞报告_v1.md` 属于此前状态。用户已确认旧 RFC-003/COORD-004 B 作废删除;本次不恢复、不改写任务书或旧报告。
|
||||
|
||||
八帧时间示例按 C-002 为 **13:00–20:00**。提交 21:00 后删除最早端 13:00。等距离时固定删除原最早端。
|
||||
|
||||
## 2. Core 存储与身份
|
||||
|
||||
`EncodedFieldStore` 按 `fieldKey` 保存独立 `FieldSeries`,默认每个序列容量 8。每个序列按 `validTimeMs` 严格升序存储;插入新帧使用 lower-bound 定位,不假定时间间隔。重复时间继续走 Duplicate、revision、stale、identity conflict 现有判定,不触发容量淘汰。
|
||||
|
||||
为同时支持新预报批次单帧首显和防止跨批次混插,分开处理两类兼容性:
|
||||
|
||||
- **同 key 共存兼容性**:grid、validity plane schema、所有 data plane 的数量与 schema 相同。不同 `fieldID`、QBIN `referenceTimeMs` 或解析 profile 的批次可以在序列中共存;否则有效的新日/新批次单帧可能无法进入序列。
|
||||
- **时间插值兼容性**:除共存 schema 相同外,`fieldID`、`referenceTimeMs`、`profileID` 和 `profileVersion` 必须全部相同。resolve 只在相邻时间端点满足这些条件时返回双帧;不同批次之间的时间返回 unavailable。Ingress 会把已验证的 profile 身份保留到解码帧,避免校验后丢失身份。
|
||||
|
||||
满额插入先复制现有有序序列,在候选序列上执行淘汰和新增端点 schema 校验。候选有效后才 swap 到正式序列;grid/plane schema 不兼容时返回既有 `RejectedIncompatible` 路径,不淘汰现有帧。对容量 8 的正常有效插入返回既有 `AcceptedInserted`;`RejectedCapacity` 枚举与 RN 字符串继续保留兼容,不用于正常满额滚动。
|
||||
|
||||
对提交时间 `n` 和原序列最早/最晚端点 `e/l`,淘汰较远端:`|n-e| >= |l-n|` 时淘汰原最早端,否则淘汰原最晚端。距离计算避免无符号时间相减下溢。该规则不读取 forecast clock,所以仍符合 RN 先 submit、后 setTime 的顺序。
|
||||
|
||||
## 3. 单帧、双帧与投影
|
||||
|
||||
- 精确匹配某个 `validTimeMs` 时 resolver 返回同一个不可变 frame 作为 T0/T1,`mix=0`。颜色和有合法 U/V 或方向分量的粒子可从该帧物化;标量帧仍不能通过向量绑定校验。
|
||||
- 非精确时间只在合法的相邻双帧 bracket 内插值,mix 按两端实际时间比例计算。落在窗口外、跨 batch/profile 边界或只有一帧但时间不匹配时返回 unavailable;不回退为最近帧。
|
||||
- 后续帧到达只更新实际变化的投影。新帧位于当前 bracket 外时保留 Source 的不可变物化 projection 与样本时刻;当前端点被淘汰后重新 resolve,原投影不可用则清除。
|
||||
- 单帧 materialization 只创建一个 `ParticleFieldSnapshot` 并让 T0/T1 共用它。Particle 和 WeatherColor 的首次资源安装也共享相同 endpoint 的 GPU texture/image/scale;GL 与 Metal 共用这段 renderer 代码及语义。设备资源实际行为仍须各平台独立验证。
|
||||
- 淘汰仅释放 Store 对已移除 frame 的引用。已发布 projection 或 GPU 更新仍持有共享 snapshot/texture 引用时,按 shared ownership 生命周期释放。
|
||||
|
||||
## 4. 内存观测范围
|
||||
|
||||
新增 `DecodedFieldFrame::decodedByteSize()`、`FieldSeries::decodedByteSize()` 与 `EncodedFieldStore::decodedByteSize()`,返回 validity bitset 加所有非 validity 原始 plane storage 的字节总和;共享 validity plane storage 不重复计数。该计数**不包含** profile/容器元数据、物化 Float32 snapshot、图像、GL/Metal texture、粒子 state 或 trail。
|
||||
|
||||
公式为单帧 `ceil(cellCount / 8) + Σ(plane payload bytes)`;序列与 Store 分别对帧及 key 求和。Native 定向测试代码覆盖滚动时每 key 保持 8 帧及此原始字节计数回落/清空,但本轮没有运行测试,也没有 CPU/GPU 峰值、32 帧总量或长期泄漏实测。8 帧不构成全局内存保证;不新增固定 MiB 上限或公开容量错误码。
|
||||
|
||||
## 5. API、职责与平台
|
||||
|
||||
RN TypeScript、Android Kotlin/JNI、iOS Objective-C++/Facade 保持 `submitEncodedField(...)` 与 `setEncodedForecastTime(...)` 两步调用及原有方法名、参数和结果名称;Codex 静态核对现有传递路径,本轮没有改 bridge。submit 不修改目标时钟,setTime 不下载数据。两调用仍非原子,不承诺无闪烁。
|
||||
|
||||
`DecodedFieldFrame` 增加内部解析 profile 身份字段及 decoded-byte 计数方法,改变该 C++ 数据结构的二进制布局;不改变 RN/Android/iOS bridge 的公开方法签名或结果枚举。Core 与两个平台必须使用同一源码重编;不得把既有 `.13` AAR 或旧发布物当作新 ABI 消费证据。
|
||||
|
||||
NavSea、Server、下载/cache/manifest、日期 UI、QBIN 格式、Rice 解码、V3、Style Z-order、provider、公开 RN API 均未改。
|
||||
|
||||
## 6. 定向测试映射
|
||||
|
||||
以下是本轮新增或扩展的测试代码覆盖,不代表已执行:
|
||||
|
||||
| 项目 | 测试入口 | 本轮代码覆盖 |
|
||||
| --- | --- | --- |
|
||||
| T01 | `ParticleFieldBinding.SingleFrameProjectsAtItsExactTimeAndUpgradesToInterpolation`;`Source.RasterArrayV4SingleExactFrameMaterializesAndSecondFrameEnablesInterpolation` | 单帧精确颜色/向量 projection、T0=T1、mix=0、第二帧中点升级;标量-only 无向量绑定 |
|
||||
| T02 | 同上 | 第二帧到达后返回双帧与 mix=0.5 |
|
||||
| T03 | `ParticleFieldRuntime.UnorderedSubmissionsAreSortedAndReferenceCyclesStaySeparate` | 乱序排序;wind/wave 分 key;跨 reference/profile 只可单帧解析 |
|
||||
| T04 | `ParticleFieldRuntime.FullWindowRollsBothDirectionsAndBreaksTiesAtEarliest`;`Source.RasterArrayV4RollingWindowPreservesAnUnchangedActivePair` | 满 8 后向未来提交、淘汰最早端并保持活动 pair |
|
||||
| T05 | `ParticleFieldRuntime.FullWindowRollsBothDirectionsAndBreaksTiesAtEarliest`;Source rolling 测试 | 满额向过去提交并淘汰最晚端 |
|
||||
| T06 | `ParticleFieldRuntime.FullWindowRollsBothDirectionsAndBreaksTiesAtEarliest` | 中部等距插入固定淘汰最早端、有序且 8 帧 |
|
||||
| T07 | `Source.RasterArrayV4StoresNewReferenceAndProfileAsSingleFrameWithoutCrossBatchMix` | 新 reference/profile 批次精确首显、补帧后同批插值、回到早批次单帧 |
|
||||
| T08 | `ParticleFieldRuntime.RevisionIdentityAndIndependentCadence`;既有 Source stale/revision cases | Duplicate、identity conflict、revision;既有 stale 路径保留。满额下 revision 不占槽由同一 Store 分支处理 |
|
||||
| T09 | `Source.RasterArrayV4HostApiRejectsKeepPublicProjectionStable`、`...RejectsNumericOverflowBeforeReplacingAcceptedRevision`、`ParticleFieldRuntime.RejectedFullWindowInsertDoesNotEvictAndKeysRemainIndependent` | 解码/profile/数值和 grid schema 拒绝路径、有效帧/投影/clock 零副作用。数据帧入 Store 前仍由现有 ingress 完成解码与 profile 校验 |
|
||||
| T10 | `ParticleFieldBinding.MixChangesSampleStateButNotContentIdentityOrStorage`、单帧升级 Source 测试 | 合法 bracket 的中间比例;精确端点以单帧语义表示 |
|
||||
| T11 | 既有 binding `WindowUnavailable` assertions;新单帧测试 | 非覆盖时间 unavailable,不用最近帧顶替 |
|
||||
| T12 | `Source.RasterArrayV4RollingWindowPreservesAnUnchangedActivePair` | 外围补帧/双向滚动不改变当前物化 projection 与 requested time |
|
||||
| T13 | `Source.RasterArrayV4EvictedActiveFrameClearsItsMaterializedProjection` | 当前单帧端点淘汰后 fail-closed 清除物化 projection |
|
||||
| T14 | `ParticleFieldRuntime.RejectedFullWindowInsertDoesNotEvictAndKeysRemainIndependent` | 两个 key 各自 8 帧,独立计数与字节 |
|
||||
| T15 | 单帧 binding/materialization 测试;GL/Metal renderer 资源安装源码 | T0/T1 共用物化 snapshot;renderer 首装共用 endpoint texture/image。GPU/context-loss 运行验证未覆盖 |
|
||||
| T16 | `ParticleFieldRuntime.RepeatedBidirectionalRollingAndClearStayBounded` | 120 次双向提交、每 key 8 帧边界、clear/clearAll 和 decoded bytes 归零 |
|
||||
| T17 | 现有 `FieldRuntime.ts`、`NativeWeatherRuntimeBridge.ts`、Android/iOS bridge 源码静态核对 | 旧 API、类型、方法名和两步语义未变;RN 自动化/双平台 consumer build 未运行 |
|
||||
|
||||
所有测试代码的执行状态均为 **NOT RUN**。完整执行状态与 RDC 命令见 STEP-098 完成报告。
|
||||
@@ -0,0 +1,249 @@
|
||||
# STEP-092 Continuous Range 可退化分段 Retained Cache — Codex 任务 v1
|
||||
|
||||
## 0. 目标
|
||||
在当前 MapLibreParticleLab / Particle V11 Renderer 上实现一个 explicit Continuous Range。
|
||||
正式架构定义:
|
||||
App 用正常 Style 定义唯一 Z-order,并指定两个现有 Style Layer ID 作为闭区间 Continuous Range;
|
||||
Renderer 将两个 ID 解析为连续 layerIndex,根据 Continuous Range 在 Style 中的位置自然形成 0~2 个 Retained Range Cache;
|
||||
最终可以是 1、2 或 3 个 Render Range,绝不是固定“三层三明治”。
|
||||
|
||||
本任务只支持一个 Continuous Range,不做多个 Range 或任意 N Segment Planner。
|
||||
|
||||
## 1. 环境与起始确认
|
||||
工作目录:/Users/tei/dev/MapLibreParticleLab
|
||||
目标分支:particle/main
|
||||
历史参考 HEAD:b29e564944197072a0effaec36ca95c48fe0649b,但不得据此强制回退。
|
||||
修改前必须:
|
||||
1. git fetch origin
|
||||
2. 确认当前分支、HEAD、origin/particle/main
|
||||
3. 记录起始 HEAD
|
||||
4. 检查 git status --short
|
||||
5. 不覆盖、不删除、不 reset/clean、不提交无关 dirty/untracked
|
||||
6. 若远端更新,以当前真实 origin/particle/main 为基线
|
||||
## 2. 唯一 Z-order 事实来源
|
||||
Style Layer 顺序是唯一 Z-order 事实来源:
|
||||
App/RN 负责业务语义和 Style Layer 顺序;
|
||||
MapLibre Style 保存正式 Z-order;
|
||||
C++ Renderer 只消费最终连续 layerIndex。
|
||||
Renderer 禁止硬编码 NavSea 业务 Layer ID(AIS/Alarm/Wind/Wave 等)。
|
||||
禁止建立 BOTTOM/CONTINUOUS/TOP 第二套 metadata 分类表。
|
||||
禁止增加 AnchorLayer、ContinuousStartLayer、ContinuousEndLayer、RenderAnchorLayer、空白 Marker Layer。
|
||||
|
||||
## 3. Continuous Range API 语义
|
||||
App 直接指定两个已有正常 Style Layer:
|
||||
startLayerId
|
||||
endLayerId
|
||||
公开语义为闭区间 [startLayerId, endLayerId]。
|
||||
Native 按当前 Style 解析成 startIndex/endIndex。
|
||||
合法条件必须是 startIndex <= endIndex。
|
||||
必须正式支持 startLayerId == endLayerId,单 Layer Continuous 完全合法。
|
||||
App/RN 不传数字 index,RN 不计算 layerIndex。
|
||||
|
||||
内部建议转半开区间:
|
||||
continuousBegin = startIndex
|
||||
continuousEndExclusive = endIndex + 1
|
||||
Bottom=[0,continuousBegin)
|
||||
Continuous=[continuousBegin,continuousEndExclusive)
|
||||
Top=[continuousEndExclusive,layerCount)
|
||||
Range 存在判断统一为 begin < endExclusive。
|
||||
## 4. 四种合法结构与 Cache 数量
|
||||
必须支持:
|
||||
1. Bottom + Continuous + Top → 2 retained caches
|
||||
2. Bottom + Continuous → 1 Bottom cache
|
||||
3. Continuous + Top → 1 Top cache
|
||||
4. Continuous only → 0 retained caches
|
||||
|
||||
Continuous only 当 startIndex==0 且 endIndex==layerCount-1,是完全合法状态,不是 error/fallback。
|
||||
不存在的 Range:
|
||||
不创建 cache;
|
||||
不分配 texture;
|
||||
不分配 framebuffer/render target;
|
||||
不 build;
|
||||
不 composite;
|
||||
不参与 cache-valid gate。
|
||||
|
||||
当前 RetainedUnderlayCache 应合理泛化为可复用 retained range cache 能力。
|
||||
具体命名服从当前源码,但不得固定创建 bottomCache+topCache 占位资源。
|
||||
Bottom/Top GPU 资源必须 lazy 创建。
|
||||
|
||||
## 5. Final Render 顺序
|
||||
如果 Bottom 存在:build/reuse/composite Bottom
|
||||
然后 render Continuous
|
||||
如果 Top 存在:build/reuse/composite Top
|
||||
顺序只能来自 Style,自然退化为 3/2/1 段。
|
||||
## 6. global layerIndex / pass 语义
|
||||
分 Range 后仍必须保持整个 Style 的:
|
||||
原始 layerIndex;
|
||||
原始 ordinal;
|
||||
parameters.currentLayer;
|
||||
depthRangeSize。
|
||||
不得给 Bottom/Continuous/Top 各自从 0 重新编号。
|
||||
Opaque 继续 reverse traversal;
|
||||
Translucent 继续 forward traversal。
|
||||
|
||||
## 7. Visibility
|
||||
Range topology 来自 Style/orderedLayers,不来自当前 visible/renderable Layers。
|
||||
hidden start/end 仍必须参与 Range index 解析。
|
||||
Layer ON/OFF 是内容变化,不是 Range topology 变化。
|
||||
例如 start=10 hidden、11 visible、end=12 hidden,Range 仍是 10..12,不得缩成 11..11。
|
||||
|
||||
## 8. Style mutation
|
||||
必须支持正常 Style mutation。
|
||||
Continuous 内新增/删除普通成员正常工作。
|
||||
Bottom/Top 内增删使对应实际存在 cache invalid/rebuild。
|
||||
同一 Range 内 reorder 使 cache 内容 invalid/rebuild。
|
||||
Layer 跨 Range 移动:重新解析 start/end index → topology revision → invalidate affected caches → invalidate fast prepared state → rebuild。
|
||||
startLayerId/endLayerId 自身删除:Range 立即 invalid,清除 stale cache/index/prepared state并安全 fallback。
|
||||
Layer 后续重新出现且顺序合法时可恢复 explicit Range。
|
||||
## 9. Top Cache 正确性
|
||||
Top retained texture 必须是透明 RGBA,并正确使用 premultiplied alpha。
|
||||
目标支持 Particle 属于 Continuous、land-area 属于 Top Retained 时,Top texture 正确覆盖 Particle。
|
||||
不得新增 LandMask RT、Wave/Tide mask system 或 Native land-mask 业务判断。
|
||||
land-area 仍只是普通 Style Z-order。
|
||||
|
||||
## 10. Legacy compatibility
|
||||
当前 WeatherColor/RasterParticle 可能通过 startsRetainedDynamicRange() 参与 legacy boundary。
|
||||
规则:
|
||||
explicit Continuous Range 已配置且有效 → STEP-092 Range 模式;
|
||||
未配置 explicit Range → 保持当前 legacy retained-underlay 行为。
|
||||
一旦 explicit Range 生效,startLayerId/endLayerId 是唯一 topology/boundary 来源。
|
||||
禁止 explicit Range 与 startsRetainedDynamicRange() 混合生成第二套 boundary。
|
||||
|
||||
## 11. RN / Native API
|
||||
在现有 RendererRuntime 增加稳定入口,目标语义:
|
||||
setContinuousLayerRange(reactTag,startLayerId,endLayerId)
|
||||
要求:ID 非空;允许相同;map-scoped;thread-safe;monotonic config revision;
|
||||
Range 修改触发 renderer update/invalidation。
|
||||
Android/iOS bridge 不理解业务;C++ 按当前 Style 解析 index。
|
||||
保留 setRetainedUnderlayEnabled() 与 getRetainedUnderlayDiagnostics() 兼容。
|
||||
## 12. Invalid / fallback
|
||||
至少处理:
|
||||
start 不存在;
|
||||
end 不存在;
|
||||
startIndex > endIndex;
|
||||
Style 未 ready;
|
||||
未配置 explicit range。
|
||||
要求:不 crash;不猜 index;不复用 stale index/cache/prepared state;
|
||||
不根据 Particle/WeatherColor 类型偷偷修正 explicit Range;
|
||||
安全进入 legacy/full renderer;
|
||||
diagnostics 说明 fallback 原因。
|
||||
Continuous-only 不是 invalid/fallback。
|
||||
|
||||
## 13. Particle-only CPU Fast Path
|
||||
现有 Particle-only CPU fast path 不得退化。
|
||||
三段:Bottom reuse → Continuous render → Top reuse
|
||||
只有 Bottom:Bottom reuse → Continuous render
|
||||
只有 Top:Continuous render → Top reuse
|
||||
0 cache:Continuous render
|
||||
不存在的 cache 不能成为 Fast Path miss 原因。
|
||||
Bottom 不存在时不得要求 bottomCache.valid=true;Top 同理。
|
||||
Fast gate 只检查实际存在 retained ranges。
|
||||
Continuous Range 本身必须通用,不依赖 RasterParticleLayer/Weather Layer ID。
|
||||
若 Continuous 中存在当前 Fast Path 无法证明安全的未知 Layer:Fast Path fail closed,走正常 full CPU frame,Range Z-order/cache 仍正确。
|
||||
不要为此重写整个 RenderGraph。
|
||||
## 14. Invalidation
|
||||
继续 correctness-first、偏保守模型,至少覆盖:
|
||||
camera/transform/viewport/resize/pixel ratio/style reload;
|
||||
layer add/remove/reorder/property;
|
||||
source mutation/tile update/drawable update;
|
||||
image/sprite/glyph;
|
||||
placement/symbol fade/transition;
|
||||
context reset/debug options/unsupported 3D/legacy ordering/resource/compositor failure。
|
||||
无法判断只影响 Bottom 还是 Top 时,可同时 invalidate 所有实际存在 retained caches。
|
||||
本任务不做复杂 dependency graph。
|
||||
topology 变化还要 invalid Range index resolution、retained prepared state、Particle fast prepared state。
|
||||
|
||||
## 15. Symbol / Placement
|
||||
Top 可能包含 symbol/label/Navigation/AIS/Alarm。
|
||||
correctness 优先。
|
||||
placement/symbol fade/transition 无法证明 reuse 安全时,invalidate/full fallback,稳定后 rebuild。
|
||||
不重写 Placement 系统。
|
||||
|
||||
## 16. Diagnostics
|
||||
至少增加/暴露:
|
||||
rangeConfigured, rangeValid,
|
||||
startLayerId,endLayerId,startIndex,endIndex,
|
||||
bottomPresent,bottomBuild,bottomReuse,bottomInvalidation,
|
||||
topPresent,topBuild,topReuse,topInvalidation,
|
||||
fallback,lastReason。
|
||||
bottomPresent=false 且 topPresent=false 可以只是 Continuous-only,不能自动判 error。
|
||||
Release 保持 pull-based,不增加 per-frame 高频日志。
|
||||
## 17. GPU 生命周期与双后端
|
||||
实际 retained texture 数量必须严格等于实际存在 retained ranges:
|
||||
Continuous only=0;
|
||||
Bottom+Continuous=1;
|
||||
Continuous+Top=1;
|
||||
三段=2。
|
||||
稳定 Continuous frame 不得每帧重建 retained texture/framebuffer/compositor resources。
|
||||
|
||||
Mac 上完成当前工程允许的精确 Native 验证。
|
||||
OpenGL 重点:Bottom/Top target 创建复用、Top RGBA/premultiplied alpha、0/1/2 cache 无空资源、Continuous-only、Fast Path。
|
||||
Metal 重点:同等 Range/cache topology、透明 Top composite、0/1/2 cache 生命周期、explicit Range/fallback 与 OpenGL 一致。
|
||||
不得用 Linux Core/OpenGL 构建替代 Mac 基线。
|
||||
若 Android 实机/Gradle/ADB 项未执行,报告必须明确列为“未执行 Android 项”,不得伪造通过。
|
||||
|
||||
## 18. Native directed tests(不加入 Jest)
|
||||
至少覆盖:
|
||||
start==end;
|
||||
start<end;
|
||||
start>end invalid;
|
||||
start missing;
|
||||
end missing;
|
||||
hidden start/end;
|
||||
Style reorder;
|
||||
start/end 删除;
|
||||
四种 Range 结构;
|
||||
Bottom empty/Top empty/both empty;
|
||||
不存在 Bottom 时不因 bottom cache missing 而 Fast Path miss;
|
||||
不存在 Top 时不因 top cache missing 而 Fast Path miss。
|
||||
还应验证:
|
||||
explicit Range 有效时不混用 legacy boundary;
|
||||
explicit Range invalid 不复用 stale cache;
|
||||
single-layer Continuous 正常;
|
||||
hidden endpoint 不改变 topology;
|
||||
reorder 后重新解析 index;
|
||||
endpoint 删除 fail safe;
|
||||
0/1/2 retained cache resource 数量与 topology 一致;
|
||||
Opaque/Translucent traversal 保持 global layerIndex 语义。
|
||||
|
||||
## 19. 明确不做
|
||||
不做:任意 N Segment Planner、多个 Continuous Range、LOW/MEDIUM/HIGH 分类、
|
||||
自动分析 Layer 更新频率、自动调整 Z-order、Anchor/Marker Layer、新 Style Layer 类型、
|
||||
NavSea AIS 专项优化、Weather provider、Route ETA、Native land-mask 业务、
|
||||
Wave/Tide 业务判断、第二套 Z-order、NavSea Layer ID 硬编码、
|
||||
复杂 per-source dependency graph、PBF 重构/重生成、通用 RenderGraph、
|
||||
Placement 重写、Particle 专属 Continuous 机制、Jest。
|
||||
如发现必须突破边界才能继续,停止扩大范围并记录阻塞。
|
||||
|
||||
## 20. 必做文档
|
||||
生成:
|
||||
docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md
|
||||
docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v1.md
|
||||
追加:粒子开发记录.md
|
||||
同主题已存在则递增版本,不覆盖旧文件;所有文档中文。
|
||||
完成报告必须包含:
|
||||
起始 HEAD、最终 HEAD、修改文件清单;
|
||||
C++ Renderer、RN API、Android API/bridge、iOS API/bridge;
|
||||
Range config 所有者、ID→layerIndex 解析位置机制;
|
||||
single-layer range、1/2/3 Render Range、0/1/2 retained cache;
|
||||
invalidation、legacy compatibility、Fast Path、diagnostics、GPU lifecycle;
|
||||
OpenGL、Metal、Native tests、未执行 Android 项、known limitations;
|
||||
commit SHA/message、push result、remote branch、origin/particle/main Final HEAD、最终 git status --short。
|
||||
|
||||
## 21. Git
|
||||
仅 scoped staging。
|
||||
禁止 git add -A、git add .、git reset --hard、git clean。
|
||||
不得触碰无关 dirty/untracked。
|
||||
结束前:git diff --check;核对变更;只 stage 本任务文件;scoped commit;push origin particle/main。
|
||||
push 后必须确认:
|
||||
git rev-parse HEAD
|
||||
git rev-parse origin/particle/main
|
||||
git status --short
|
||||
要求 HEAD == origin/particle/main。
|
||||
push 失败不得声明完成。
|
||||
|
||||
## 22. PASS Gate
|
||||
只有架构、四种 Range、0/1/2 cache、global layerIndex、Opaque/Translucent、Fast Path、
|
||||
diagnostics、RN/Android/iOS API、Native directed tests、OpenGL/Metal 规定验证、
|
||||
文档、scoped commit、push、远端 HEAD 一致全部满足,才可判 STEP-092 PASS。
|
||||
关键项无法完成必须明确 PARTIAL/BLOCKED 和原因,禁止伪造 PASS。
|
||||
652
docs/40_任务/STEP-093_ContinuousRange运行态综合验收_Codex任务_v1.md
Normal file
652
docs/40_任务/STEP-093_ContinuousRange运行态综合验收_Codex任务_v1.md
Normal file
@@ -0,0 +1,652 @@
|
||||
# STEP-093:Continuous Range 运行态综合验收
|
||||
|
||||
## 1. 任务目标
|
||||
|
||||
在 STEP-092 已完成并关闭的 Continuous Range / Retained Cache 架构基础上,进入真实 Renderer 运行态综合验收。
|
||||
|
||||
本任务不重新设计 STEP-092 架构,不引入新的 Z-order 体系,不重做 retained cache 结构。目标是通过可重复、可观察、可诊断的运行态场景,确认以下核心事实在真实渲染过程中成立:
|
||||
|
||||
1. Style Layer 顺序仍然是唯一 Z-order 真相。
|
||||
2. `[startLayerId, endLayerId]` 能稳定解析为一个 Continuous Range。
|
||||
3. Bottom / Continuous / Top 四种合法退化结构均能正确工作。
|
||||
4. 实际 retained cache 数量严格为 0 / 1 / 2,不存在的 range 不创建无意义 GPU 资源。
|
||||
5. Particle 连续播放时,稳定的普通 Style/PBF 内容能够命中 retained cache,而不是每帧重复完整绘制。
|
||||
6. Top range 能真实覆盖 Continuous 中的 Particle,验证最终画面顺序为:`Bottom → Continuous → Top`。
|
||||
7. Camera、viewport、style、layer/source 等变化发生时能够正确 invalidation、rebuild,并重新进入稳定 reuse。
|
||||
8. Fast Path 失败时必须安全退回 full CPU frame,但不得破坏 Continuous Range、retained cache 和 Z-order。
|
||||
9. Android/OpenGL 与 iOS/Metal 最终表现一致;若本阶段只能先完成 Android,则 iOS 可明确记录为后续待验收,不得虚报通过。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前基线
|
||||
|
||||
开始任务前必须先检查真实仓库,不得只依赖任务书中的 SHA。
|
||||
|
||||
预期起始基线:
|
||||
|
||||
- Repository: `MapLibreParticleLab`
|
||||
- Branch: `particle/main`
|
||||
- STEP-092 最终状态:`CLOSED / PASS(Mac Native 验证闭环)`
|
||||
- STEP-092 最终已知 HEAD:`8a5d88008c142e2a80e0ff602d228e0e67de2d83`
|
||||
- `HEAD == origin/particle/main`
|
||||
- 工作区应为 clean
|
||||
|
||||
STEP-092 已完成的关键内容包括:
|
||||
|
||||
- Continuous Range 显式配置;
|
||||
- Bottom / Continuous / Top 三段模型;
|
||||
- 四种合法退化拓扑;
|
||||
- 0 / 1 / 2 retained cache;
|
||||
- Bottom/Top retained cache;
|
||||
- Top 透明 RGBA + premultiplied alpha 合成;
|
||||
- Style mutation 后重新解析;
|
||||
- invalid explicit range 的安全 fallback;
|
||||
- Particle Fast Path 与 retained cache 的协同;
|
||||
- Android / iOS Bridge 接口;
|
||||
- OpenGL Native build;
|
||||
- iOS Metal-only native build;
|
||||
- 定向 Native tests 29/29 PASS。
|
||||
|
||||
本 STEP 不重新证明上述静态设计,而是证明它们在真实运行态画面与资源生命周期中成立。
|
||||
|
||||
---
|
||||
|
||||
## 3. 开始前必读
|
||||
|
||||
Codex 开始前必须读取:
|
||||
|
||||
1. 仓库根目录 `AGENTS.md`
|
||||
2. 当前粒子系统总规则 / 架构约束文档
|
||||
3. `docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v2.md`
|
||||
4. `docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v2.md`
|
||||
5. STEP-092 相关实现文件与 diagnostics 实现
|
||||
6. 当前 Android/iOS Particle Test App / validation 页面 / Host runtime 实现
|
||||
7. 当前可用的测试按钮、场景、日志和 diagnostics 展示入口
|
||||
|
||||
如实际仓库结构与本任务书描述不一致,以当前真实代码为准,并在报告中写明差异。
|
||||
|
||||
---
|
||||
|
||||
## 4. 本任务职责划分
|
||||
|
||||
### 4.1 Codex 负责
|
||||
|
||||
Codex 负责:
|
||||
|
||||
- 调查当前可用的运行态测试入口;
|
||||
- 为 STEP-093 补齐必要的 Test/Validation UI、场景切换、diagnostics 展示和最小测试辅助代码;
|
||||
- 只在确有必要时补充可观察性;
|
||||
- 修复在准备阶段发现的明确、局部、与 STEP-093 验收直接相关的问题;
|
||||
- 为 RDC / 用户准备清晰、可逐项执行的运行态验收入口;
|
||||
- 更新中文 STEP 记录、完成报告和开发记录;
|
||||
- 提交并 push 自己完成的代码与文档。
|
||||
|
||||
### 4.2 RDC / 用户负责
|
||||
|
||||
实际 Android / iOS 编译、安装、启动、真机或模拟器运行、视觉操作与最终画面确认由 RDC / 用户执行。
|
||||
|
||||
Codex 不得仅依据静态代码、日志或自己推测就把运行态测试标记为 PASS。
|
||||
|
||||
如果没有实际执行某个运行态场景,必须写为 `NOT RUN`、`WAITING_RUNTIME_VALIDATION` 或其他明确的未完成状态,不得写成 PASS。
|
||||
|
||||
---
|
||||
|
||||
## 5. 严格保护的 STEP-092 架构
|
||||
|
||||
本 STEP 禁止借“测试方便”修改以下既定架构:
|
||||
|
||||
1. Style 顺序是唯一 Z-order 真相。
|
||||
2. App/RN 只提供 `startLayerId`、`endLayerId`。
|
||||
3. Native 自行解析 index。
|
||||
4. Continuous Range 为闭区间 `[startLayerId, endLayerId]`。
|
||||
5. 内部:`continuousBegin = startIndex`,`continuousEndExclusive = endIndex + 1`。
|
||||
6. 三段:Bottom `[0, begin)`、Continuous `[begin, endExclusive)`、Top `[endExclusive, layerCount)`。
|
||||
7. `start == end` 合法。
|
||||
8. Continuous-only 合法,不是 fallback。
|
||||
9. 不允许加入 anchor / marker layer。
|
||||
10. 不允许增加第二套 BOTTOM / CONTINUOUS / TOP metadata 真相源。
|
||||
11. 不允许 Renderer 硬编码 NavSea/AIS/Alarm/Wind/Wave 等业务 Layer ID。
|
||||
12. Visibility 不改变 topology。
|
||||
13. explicit range 有效时不得再混用旧 `startsRetainedDynamicRange()` 作为 topology boundary。
|
||||
14. 不允许把普通 style layer 改造成新的特殊 layer type 来解决测试问题。
|
||||
15. 不做任意 N-range planner。
|
||||
16. 不做多个 Continuous Range。
|
||||
17. 不做频率分类系统。
|
||||
18. 不做 PBF 通用重构。
|
||||
19. 不做 RenderGraph 重构。
|
||||
20. 不加入 Jest。
|
||||
|
||||
---
|
||||
|
||||
# 6. STEP-093 必测场景
|
||||
|
||||
## 6.1 场景 A:Bottom + Continuous + Top
|
||||
|
||||
构造至少:Bottom 为普通 Style/PBF Layer,Continuous 为 Particle / Weather 动态 Layer,Top 为普通 Style/PBF Layer。
|
||||
|
||||
必须验证:
|
||||
|
||||
- explicit range valid;
|
||||
- Bottom present = true;
|
||||
- Top present = true;
|
||||
- retained cache 实际数量 = 2;
|
||||
- Bottom cache 可 build/reuse;
|
||||
- Top cache 可 build/reuse;
|
||||
- 最终画面顺序 `Bottom → Continuous → Top`;
|
||||
- Top 内容能够真实覆盖 Particle;
|
||||
- 无明显黑边、错误透明、旧 cache 或层序颠倒。
|
||||
|
||||
## 6.2 场景 B:Bottom + Continuous
|
||||
|
||||
Continuous 结束于当前 Style 最顶层。
|
||||
|
||||
必须验证:
|
||||
|
||||
- Bottom present = true;
|
||||
- Top present = false;
|
||||
- retained cache 实际数量 = 1;
|
||||
- 不得创建 Top texture/FBO/compositor;
|
||||
- 不存在的 Top 不得阻塞 Fast Path;
|
||||
- 画面顺序正确。
|
||||
|
||||
## 6.3 场景 C:Continuous + Top
|
||||
|
||||
Continuous 从当前 Style 最底层开始。
|
||||
|
||||
必须验证:
|
||||
|
||||
- Bottom present = false;
|
||||
- Top present = true;
|
||||
- retained cache 实际数量 = 1;
|
||||
- 不得创建 Bottom texture/FBO/compositor;
|
||||
- 不存在的 Bottom 不得阻塞 Fast Path;
|
||||
- Top 可正确覆盖 Particle。
|
||||
|
||||
## 6.4 场景 D:Continuous only
|
||||
|
||||
Continuous 覆盖全部 Style Layer。
|
||||
|
||||
必须验证:
|
||||
|
||||
- Bottom present = false;
|
||||
- Top present = false;
|
||||
- explicit range valid = true;
|
||||
- retained cache 实际数量 = 0;
|
||||
- 这是合法 Continuous-only,不得被识别为 fallback;
|
||||
- 不创建 retained texture/FBO/compositor;
|
||||
- Particle/continuous renderer 正常运行。
|
||||
|
||||
## 6.5 场景 E:Single-layer Continuous
|
||||
|
||||
设置 `startLayerId == endLayerId`。
|
||||
|
||||
必须验证:
|
||||
|
||||
- range valid;
|
||||
- startIndex == endIndex;
|
||||
- continuousEndExclusive == startIndex + 1;
|
||||
- 正常参与 Bottom/Top 切分;
|
||||
- 不得 fallback;
|
||||
- 不得被误认为空 range。
|
||||
|
||||
---
|
||||
|
||||
# 7. Z-order 核心视觉验收
|
||||
|
||||
这是 STEP-093 的最高优先级运行态验收。
|
||||
|
||||
必须构造一个肉眼可以清楚确认覆盖关系的场景:
|
||||
|
||||
1. Bottom 中放一个明显底图/填充层;
|
||||
2. Continuous 中运行 Particle;
|
||||
3. Top 中放一个能够明显覆盖 Particle 的普通 Style Layer。
|
||||
|
||||
优先使用已有普通 Style Layer;如果测试环境缺少合适图层,可添加纯测试用普通 Style Layer,但不得引入新的特殊 layer type 或业务硬编码。
|
||||
|
||||
建议 Top 验证至少覆盖:opaque fill、半透明 fill、line;如当前测试环境可行,再加入 symbol/text。
|
||||
|
||||
必须确认:
|
||||
|
||||
- Top 真正绘制在 Particle 上方;
|
||||
- Particle 不会穿透 opaque Top;
|
||||
- 半透明 Top 与 Particle 合成正确;
|
||||
- 无黑边;
|
||||
- 无颜色异常变暗;
|
||||
- 无错误双重 alpha;
|
||||
- 无 cache 旧内容残留。
|
||||
|
||||
---
|
||||
|
||||
# 8. Stable Frame / Cache Reuse 验收
|
||||
|
||||
在 Camera、viewport、Style、普通 PBF/source 内容都不变化,仅 Particle 持续动画时,必须观察:
|
||||
|
||||
- Bottom/Top retained cache build 后持续 reuse;
|
||||
- 不应每个 Particle frame 重建 retained cache;
|
||||
- 不应每 frame 重建 retained texture;
|
||||
- 不应每 frame 重建 FBO/offscreen texture;
|
||||
- 不应每 frame 重建 composite group;
|
||||
- Fast Path 在满足条件时能够持续命中;
|
||||
- diagnostics 能够区分 build / reuse / invalidation。
|
||||
|
||||
如果现有 diagnostics 无法证明资源生命周期,可增加最小 debug-only counter / reason 字段。禁止为了测试引入生产环境高频日志风暴。
|
||||
|
||||
---
|
||||
|
||||
# 9. Camera / Viewport invalidation
|
||||
|
||||
至少验证:Pan、Zoom、Rotate、Pitch、viewport resize/orientation 或等价尺寸变化,以及测试环境可实际触发时的 pixel ratio 变化。
|
||||
|
||||
每项检查:
|
||||
|
||||
- 旧 retained cache 被正确 invalidation;
|
||||
- 下一帧或正确时点 rebuild;
|
||||
- rebuild 后重新进入 reuse;
|
||||
- 不出现 stale cache;
|
||||
- 不出现错位;
|
||||
- 不出现黑屏;
|
||||
- 不出现 Particle 与地图不同步;
|
||||
- topology 不应无故改变。
|
||||
|
||||
---
|
||||
|
||||
# 10. Style Mutation / Topology 重新解析
|
||||
|
||||
必须提供可重复测试入口,至少覆盖:
|
||||
|
||||
### 10.1 Continuous 内部变更
|
||||
|
||||
添加 Layer、删除非 endpoint Layer、reorder Continuous 内部 Layer。
|
||||
|
||||
预期:重新解析必要状态;range 仍有效时保持正确 topology;cache 根据需要 invalidation;不产生第二套 Z-order。
|
||||
|
||||
### 10.2 Bottom 内变更
|
||||
|
||||
添加、删除、reorder,检查 Bottom cache invalidation / rebuild / reuse。
|
||||
|
||||
### 10.3 Top 内变更
|
||||
|
||||
添加、删除、reorder,检查 Top cache invalidation / rebuild / reuse。
|
||||
|
||||
### 10.4 Layer 跨边界移动
|
||||
|
||||
将某个普通 Layer 做有代表性的 Bottom → Continuous、Continuous → Top 或 Top → Bottom 跨 range 移动。
|
||||
|
||||
必须验证:
|
||||
|
||||
- ID → index 重新解析;
|
||||
- topology/cache/prepared state 正确 invalidation;
|
||||
- 新 Z-order 正确;
|
||||
- 不使用旧 index;
|
||||
- 不出现 stale cache。
|
||||
|
||||
---
|
||||
|
||||
# 11. Endpoint 删除与恢复
|
||||
|
||||
删除 start endpoint 时:explicit range 立即 invalid;不 crash;不猜测新 start;不继续使用 stale index/cache;进入既定安全 fallback;diagnostics 有明确 lastReason。
|
||||
|
||||
恢复 start endpoint 时:Native 能重新解析;explicit range 恢复 valid;正确重建需要的 cache;不需要重建整个 Map instance。
|
||||
|
||||
对 end endpoint 做同等验证。
|
||||
|
||||
---
|
||||
|
||||
# 12. Visibility 不改变 topology
|
||||
|
||||
对 start endpoint、end endpoint 或 Continuous 内普通 Layer 做 visible → hidden → visible。
|
||||
|
||||
必须验证:
|
||||
|
||||
- topology 仍以 Style 顺序解析;
|
||||
- startIndex/endIndex 不因 visibility 改变;
|
||||
- hidden endpoint 仍是 endpoint;
|
||||
- 不自动收缩 Continuous Range;
|
||||
- ON/OFF 只作为内容变化处理;
|
||||
- 如需 cache invalidation,应是内容 invalidation,不得变成新的 topology 规则。
|
||||
|
||||
---
|
||||
|
||||
# 13. Invalid Explicit Range
|
||||
|
||||
至少验证:
|
||||
|
||||
1. startLayerId 不存在;
|
||||
2. endLayerId 不存在;
|
||||
3. startIndex > endIndex;
|
||||
4. Style 尚未 ready 时配置;
|
||||
5. 空 ID / 未配置(按实际 API 合法性处理)。
|
||||
|
||||
预期:不 crash;不猜测;不复用 stale cache;不按 Layer 类型自动修正;进入明确安全 fallback;diagnostics 显示 invalid 原因;条件恢复后能够重新进入 explicit range。
|
||||
|
||||
---
|
||||
|
||||
# 14. Particle Fast Path
|
||||
|
||||
## 14.1 可命中场景
|
||||
|
||||
Continuous 内只保留当前 Fast Path 已支持的动态内容。
|
||||
|
||||
检查:Fast Path 可持续命中;Bottom/Top 的存在与否只影响实际存在的 retained cache;0 cache 的 Continuous-only 不得因为“没有 retained cache”而错误阻止 Fast Path。
|
||||
|
||||
## 14.2 Fail Closed 场景
|
||||
|
||||
在 Continuous 中加入当前 Fast Path 不支持的普通/未知 Continuous Layer。
|
||||
|
||||
必须验证:
|
||||
|
||||
- Fast Path 退回 full CPU frame;
|
||||
- 不 crash;
|
||||
- 不错误跳过该 Layer;
|
||||
- Continuous Range 本身保持 valid;
|
||||
- Bottom / Top retained cache Z-order 仍正确;
|
||||
- 不允许为了 Fast Path 强行把未知 Layer 移出 Continuous。
|
||||
|
||||
---
|
||||
|
||||
# 15. Top Alpha / Premultiplied Alpha 验收
|
||||
|
||||
必须重点看 Top retained cache 合成:transparent background、opaque fill、semi-transparent fill、line,以及可行时 symbol/text。
|
||||
|
||||
检查:透明区域正确露出 Particle;半透明区域正常叠加;opaque 区域完整覆盖;无黑色边缘;无 halo;无颜色被错误乘两次;无残影;OpenGL 与 Metal 设计保持一致。
|
||||
|
||||
---
|
||||
|
||||
# 16. 长时间运行与资源稳定性
|
||||
|
||||
在测试环境允许情况下进行持续运行测试,至少包括:Particle 连续播放、多次 Pan/Zoom/Rotate、多次 range 配置变化、endpoint 删除/恢复、visibility 切换、style mutation、再次稳定运行。
|
||||
|
||||
观察:
|
||||
|
||||
- 无持续 GPU resource 增长迹象;
|
||||
- retained texture/FBO 不因 stable frame 每帧新建;
|
||||
- 无明显内存持续增长;
|
||||
- 无黑屏;
|
||||
- 无闪屏;
|
||||
- 无 stale cache;
|
||||
- 无偶发层序颠倒;
|
||||
- 无 Particle 停止后恢复不了的问题。
|
||||
|
||||
如果当前工程缺少可靠 GPU memory 数字来源,不要求伪造数值;允许使用资源创建/释放 counter、diagnostics 和稳定运行现象作为当前阶段证据,并明确限制。
|
||||
|
||||
---
|
||||
|
||||
# 17. Diagnostics 要求
|
||||
|
||||
STEP-093 的测试入口必须能清楚观察至少以下信息:
|
||||
|
||||
### Range
|
||||
|
||||
- configured
|
||||
- valid
|
||||
- startLayerId
|
||||
- endLayerId
|
||||
- startIndex
|
||||
- endIndex
|
||||
- continuousBegin
|
||||
- continuousEndExclusive
|
||||
- fallback / lastReason
|
||||
|
||||
### Bottom
|
||||
|
||||
- present
|
||||
- cache state
|
||||
- build count
|
||||
- reuse count
|
||||
- invalidation count
|
||||
- last invalidation reason
|
||||
|
||||
### Top
|
||||
|
||||
- present
|
||||
- cache state
|
||||
- build count
|
||||
- reuse count
|
||||
- invalidation count
|
||||
- last invalidation reason
|
||||
|
||||
### Fast Path
|
||||
|
||||
- eligible / active
|
||||
- fallback reason
|
||||
- full CPU frame count 或等价诊断(若现有已有)
|
||||
- unknown continuous layer 导致 fail-closed 的可观察原因
|
||||
|
||||
如当前已有字段足够,不得重复造一套 diagnostics。
|
||||
|
||||
---
|
||||
|
||||
# 18. Test UI / Playground 要求
|
||||
|
||||
优先复用现有 Particle Test App / validation UI。
|
||||
|
||||
如果需要新增 STEP-093 面板,要求:
|
||||
|
||||
- 不影响生产 MapLibre API 语义;
|
||||
- 不引入 NavSea 业务逻辑;
|
||||
- 场景按钮命名明确;
|
||||
- 能一键切换四种 topology;
|
||||
- 能设置 single-layer range;
|
||||
- 能触发 invalid range;
|
||||
- 能隐藏/显示 endpoints;
|
||||
- 能删除/恢复 endpoint;
|
||||
- 能触发代表性的 reorder / cross-boundary move;
|
||||
- 能显示当前 diagnostics;
|
||||
- 能恢复默认测试场景。
|
||||
|
||||
测试 UI 本身不应成为复杂新框架。
|
||||
|
||||
---
|
||||
|
||||
# 19. Android 运行态验收
|
||||
|
||||
Android 作为本 STEP 首要完整运行态验收平台。
|
||||
|
||||
Codex 必须准备:
|
||||
|
||||
- 明确的 build/install/run 手工命令;
|
||||
- STEP-093 测试入口位置;
|
||||
- 每项场景的操作步骤;
|
||||
- 需要采集的日志/diagnostics;
|
||||
- PASS/FAIL 判定。
|
||||
|
||||
实际 Android Gradle / APK / ADB / 真机或模拟器操作由 RDC / 用户执行。
|
||||
|
||||
不得由 Codex 仅凭代码静态分析代替 Android 实机/模拟器结论。
|
||||
|
||||
---
|
||||
|
||||
# 20. iOS / Metal 运行态验收
|
||||
|
||||
Android 完整通过后,再进行 iOS / Metal 对等测试。
|
||||
|
||||
至少需要验证:四 topology、Single-layer Continuous、Top 覆盖 Particle、Stable cache reuse、Camera invalidation、endpoint missing/recovery、visibility、Fast Path fail-closed、Top alpha。
|
||||
|
||||
如果本 STEP 暂未执行 iOS runtime:
|
||||
|
||||
- 报告必须明确写 `WAITING_IOS_RUNTIME_VALIDATION`;
|
||||
- Android PASS 不得自动推导为 iOS PASS;
|
||||
- Metal native build PASS 也不能替代 Metal runtime rendering PASS。
|
||||
|
||||
---
|
||||
|
||||
# 21. 编译与测试原则
|
||||
|
||||
1. MapLibre Native 的 Android/iOS 开发与编译统一使用 Mac。
|
||||
2. 不安排 Linux Native 编译。
|
||||
3. noisy native build 遵循 Mac/Codex 全局构建输出节流规则。
|
||||
4. 不加入 Jest。
|
||||
5. 可运行已有 Native 精确测试;如代码变更影响 STEP-092 核心逻辑,应重跑相关现有 Native tests。
|
||||
6. 不为了“让测试绿”删除或弱化 STEP-092 已有覆盖。
|
||||
|
||||
---
|
||||
|
||||
# 22. 发现问题时的处理规则
|
||||
|
||||
### 22.1 小型、事实明确、局部问题
|
||||
|
||||
例如测试 UI 接线错误、diagnostics 漏展示、明确计数器错误、局部 invalidation reason 错误、编译错误、测试工具小缺陷,允许直接修复,并重新验收受影响项目。
|
||||
|
||||
### 22.2 架构级问题
|
||||
|
||||
如果发现需要修改 Continuous Range 数学定义、Style 顺序唯一 Z-order、0/1/2 retained cache 模型、renderer 大范围遍历结构、Fast Path 核心模型、第二套 layer metadata、新特殊 layer type、新 RenderGraph 或大规模 GPU cache redesign,必须停止当前修复扩张,先生成明确的“STEP-093 架构阻塞报告”,说明实际问题、复现方式、为什么 STEP-092 架构无法满足、建议方案和影响范围。
|
||||
|
||||
不得在运行态测试任务中擅自重构架构。
|
||||
|
||||
---
|
||||
|
||||
# 23. 验收矩阵
|
||||
|
||||
最终报告必须至少给出以下矩阵:
|
||||
|
||||
| 类别 | 场景 | Android | iOS/Metal | 关键证据 | 结论 |
|
||||
|---|---|---|---|---|---|
|
||||
| Topology | Bottom+Continuous+Top | | | | |
|
||||
| Topology | Bottom+Continuous | | | | |
|
||||
| Topology | Continuous+Top | | | | |
|
||||
| Topology | Continuous-only | | | | |
|
||||
| Range | Single-layer Continuous | | | | |
|
||||
| Z-order | Top covers Particle | | | | |
|
||||
| Cache | Stable reuse | | | | |
|
||||
| Invalidation | Pan/Zoom/Rotate/Pitch | | | | |
|
||||
| Mutation | Continuous internal mutation | | | | |
|
||||
| Mutation | Cross-range move | | | | |
|
||||
| Endpoint | start missing/recovery | | | | |
|
||||
| Endpoint | end missing/recovery | | | | |
|
||||
| Visibility | hidden endpoint topology | | | | |
|
||||
| Invalid | missing/reversed range | | | | |
|
||||
| Fast Path | eligible | | | | |
|
||||
| Fast Path | unknown layer fail-closed | | | | |
|
||||
| Alpha | Top premultiplied composite | | | | |
|
||||
| Stability | repeated operations / long run | | | | |
|
||||
|
||||
状态只允许使用清楚枚举,例如:PASS、FAIL、NOT RUN、BLOCKED、WAITING_ANDROID_RUNTIME_VALIDATION、WAITING_IOS_RUNTIME_VALIDATION。
|
||||
|
||||
---
|
||||
|
||||
# 24. STEP-093 完成条件
|
||||
|
||||
只有满足下面条件,才允许把 STEP-093 标记为 `CLOSED / PASS`:
|
||||
|
||||
1. Android 运行态核心矩阵实际执行并通过;
|
||||
2. 四种 topology 实际验证;
|
||||
3. Single-layer Continuous 实际验证;
|
||||
4. Top 覆盖 Particle 实际验证;
|
||||
5. 0/1/2 cache 与 diagnostics 一致;
|
||||
6. Stable reuse 实际验证;
|
||||
7. Camera invalidation → rebuild → reuse 实际验证;
|
||||
8. endpoint missing/recovery 实际验证;
|
||||
9. visibility 不改变 topology 实际验证;
|
||||
10. invalid range fallback 实际验证;
|
||||
11. Fast Path eligible + fail-closed 实际验证;
|
||||
12. Top alpha 无明显错误;
|
||||
13. 发现的阻塞性缺陷已解决并回归;
|
||||
14. 文档与 Git 收尾完整;
|
||||
15. `HEAD == origin/particle/main`;
|
||||
16. 工作区 clean。
|
||||
|
||||
如果 Android 已全部通过但 iOS 尚未运行,可记录为:`ANDROID CLOSED / PASS + IOS WAITING_RUNTIME_VALIDATION`。不得把未运行的平台写成 PASS。
|
||||
|
||||
---
|
||||
|
||||
# 25. 必做输出
|
||||
|
||||
本任务所有需要 ChatGPT/RDC 后续审查的文件必须由 Codex 在任务中实际生成,不得在结束后临时补要。
|
||||
|
||||
## 25.1 STEP 记录
|
||||
|
||||
生成:
|
||||
|
||||
`docs/50_Step记录/STEP-093_ContinuousRange运行态综合验收_v1.md`
|
||||
|
||||
如果同名主题已有版本,递增为 v2/v3……,不得覆盖旧版。
|
||||
|
||||
内容至少包括:起始 Git 基线、调查到的实际测试入口、新增/修改内容、Android/iOS 实际执行状态、验收矩阵、问题与修复、未执行项、当前状态、下一步。
|
||||
|
||||
## 25.2 Codex 完成报告
|
||||
|
||||
生成:
|
||||
|
||||
`docs/报告/STEP-093_ContinuousRange运行态综合验收_Codex完成报告_v1.md`
|
||||
|
||||
同主题已有版本时递增版本号。
|
||||
|
||||
报告至少包含:任务目标、修改文件、测试入口、diagnostics、build/test 实际结果、Android runtime 实际结果、iOS runtime 实际结果、PASS/FAIL/WAITING 状态、Git commit、push、Final HEAD、origin/particle/main、git status、未执行事项、风险与已知限制。
|
||||
|
||||
## 25.3 开发记录
|
||||
|
||||
追加:
|
||||
|
||||
`粒子开发记录.md`
|
||||
|
||||
只追加,不覆盖历史内容。
|
||||
|
||||
---
|
||||
|
||||
# 26. Git 规则
|
||||
|
||||
严格遵守项目 Git 规则:
|
||||
|
||||
- 只提交本任务相关文件;
|
||||
- 禁止 `git add -A`;
|
||||
- 禁止 `git add .`;
|
||||
- 禁止 `git reset --hard`;
|
||||
- 禁止 `git clean`;
|
||||
- 不触碰无关 dirty/untracked;
|
||||
- 功能代码与文档可按合理 scoped commit 拆分;
|
||||
- push 到 `origin/particle/main`;
|
||||
- push 后确认 `HEAD == origin/particle/main`;
|
||||
- 最终确认 `git status --short`;
|
||||
- push 失败不得标记任务完成。
|
||||
|
||||
---
|
||||
|
||||
# 27. Codex 执行终态规则
|
||||
|
||||
Codex 本轮结束时必须给出真实状态,而不是默认写 PASS。
|
||||
|
||||
建议状态:
|
||||
|
||||
- `IMPLEMENTED / WAITING_RUNTIME_VALIDATION`
|
||||
- `PARTIAL / WAITING_ANDROID_RUNTIME_VALIDATION`
|
||||
- `ANDROID PASS / WAITING_IOS_RUNTIME_VALIDATION`
|
||||
- `CLOSED / PASS`
|
||||
- `BLOCKED`
|
||||
- `FAILED`
|
||||
|
||||
如果只是完成测试工具与代码准备,而 RDC/用户尚未真正运行 Android,则只能标记等待运行态验收。
|
||||
|
||||
---
|
||||
|
||||
# 28. 明确不做
|
||||
|
||||
STEP-093 不做:
|
||||
|
||||
- 任意 N-range planner;
|
||||
- 多 Continuous Range;
|
||||
- frequency class 自动分类;
|
||||
- 自动 Z-order;
|
||||
- anchor/marker layer;
|
||||
- 第二套 BOTTOM/CONTINUOUS/TOP metadata;
|
||||
- NavSea AIS 专用优化;
|
||||
- Alarm 专用优化;
|
||||
- Weather provider;
|
||||
- Route ETA;
|
||||
- LandMask 业务系统;
|
||||
- Wave/Tide 业务系统;
|
||||
- PBF 通用重构;
|
||||
- RenderGraph 大改;
|
||||
- 新粒子算法;
|
||||
- 粒子视觉美化;
|
||||
- unrelated performance tuning;
|
||||
- Jest。
|
||||
|
||||
---
|
||||
|
||||
# 29. 最终核心判定
|
||||
|
||||
STEP-093 最终不是检查“按钮能不能点”,而是验证 STEP-092 的核心架构在真实渲染中确实成立:
|
||||
|
||||
> 普通地图内容可以被合理拆成 Bottom / Top retained cache,Particle 所在 Continuous Range 保持高频实时绘制;Style 顺序仍然决定最终 Z-order;不存在的 retained range 不产生资源;缓存只在需要时失效,并在稳定状态持续复用。
|
||||
|
||||
只要这个结论还没有通过真实运行态证据建立,STEP-093 就不能写成最终 `CLOSED / PASS`。
|
||||
599
docs/40_任务/STEP-094_通用RenderSegment分段渲染与Style分类诊断_Codex任务_v1.md
Normal file
599
docs/40_任务/STEP-094_通用RenderSegment分段渲染与Style分类诊断_Codex任务_v1.md
Normal file
@@ -0,0 +1,599 @@
|
||||
# STEP-094 通用 Render Segment 分段渲染与 Style 分类诊断 — Codex 任务 v1
|
||||
|
||||
## 0. 任务目标
|
||||
|
||||
从已冻结的 Particle V12 `Bottom Retained / Continuous / Top Retained` 单 Continuous Range 模型,演进到最终通用模型:
|
||||
|
||||
```text
|
||||
Style Z-order
|
||||
↓
|
||||
连续 layerIndex
|
||||
↓
|
||||
若干连续 Render Segment
|
||||
↓
|
||||
每个 Segment 的执行策略仅为:
|
||||
CONTINUOUS 或 RETAINED
|
||||
```
|
||||
|
||||
Style 顺序继续是唯一 Z-order 事实来源。Renderer 不理解 LOW / MEDIUM / HIGH,也不理解 AIS、Route、地图、Weather 等业务语义。
|
||||
|
||||
本 STEP 同时必须建立新的 pull-based Segment Diagnostics,能够取回“当前 Style → Segment → Layer”的真实分类快照,供后续人工判断 Segment 划分是否合理。
|
||||
|
||||
## 1. 当前冻结基线
|
||||
|
||||
工作目录:`/Users/tei/dev/MapLibreParticleLab`
|
||||
目标分支:`particle/main`
|
||||
|
||||
当前已知 V12 冻结基线:
|
||||
- HEAD:`7eaff6e12360e26591dceb5e011129eeab7ba4c7`
|
||||
- Commit:`release: finalize unified particle.12`
|
||||
- Tag:`maplibre-particle/rn/13.4.1-particle.12`
|
||||
- `HEAD == origin/particle/main`
|
||||
- 工作区 clean
|
||||
|
||||
开始前必须重新执行 fetch/status/HEAD 检查,以实际仓库为准。禁止 reset/clean,禁止回退、移动、覆盖 V12 Tag。STEP-094 是 V12 之后的新开发,不修改 V12 已发布事实。
|
||||
|
||||
必须先读取:
|
||||
- 根目录 `AGENTS.md`
|
||||
- `ARCHITECTURE.md`
|
||||
- STEP-092 / STEP-093 任务、Step 记录与完成报告
|
||||
- V12 当前 Continuous Range、Retained Cache、Fast Path、Android/iOS/RN bridge 实现
|
||||
- 当前 `RendererRuntime.ts`、`types.ts`、`NativeWeatherRuntimeBridge.ts`
|
||||
|
||||
## 2. 最终架构原则
|
||||
|
||||
1. Style Layer 顺序是唯一 Z-order 真相。
|
||||
2. 整个 Style 必须按连续 layerIndex 被完整划分为 1..N 个 Render Segment。
|
||||
3. 每个 Segment 只声明 `RETAINED` 或 `CONTINUOUS`。
|
||||
4. 允许多个 RETAINED、多个 CONTINUOUS,且可按 Style 顺序任意交错。
|
||||
5. 相邻同策略 Segment 不得自动合并。
|
||||
6. 每个 RETAINED Segment 独立拥有 cache / revision / invalidation / rebuild / GPU resource。
|
||||
7. CONTINUOUS Segment 不创建 retained texture/FBO/compositor。
|
||||
8. Renderer 不自动分析 Layer 更新频率,不自动调整 Z-order。
|
||||
9. App 通过 Style 顺序 + Segment boundary 表达分类。
|
||||
10. 不建立 LOW/MEDIUM/HIGH 第二套业务分类。
|
||||
11. 不硬编码 NavSea Layer ID。
|
||||
12. 不增加空白 Anchor / Marker Layer。
|
||||
|
||||
V12 三明治只是本模型的一个特例:`RETAINED → CONTINUOUS → RETAINED`。
|
||||
|
||||
## 3. 命名约束
|
||||
|
||||
MapLibre 现有代码已经大量使用 shader/bucket 的 `Segment` / `SegmentVector`。本任务禁止新增裸名称 `Segment` 造成语义冲突。
|
||||
|
||||
新模型命名必须明确属于 Renderer execution topology,例如:
|
||||
- `RenderSegmentStrategy`
|
||||
- `RenderSegmentDefinition`
|
||||
- `RenderSegmentPlan`
|
||||
- `ResolvedRenderSegment`
|
||||
- `RenderSegmentDiagnostics`
|
||||
- `RetainedSegmentCache`
|
||||
|
||||
具体文件名可按当前代码结构调整,但必须避免与 geometry/shader Segment 混淆。
|
||||
|
||||
## 4. Segment Plan 公共语义
|
||||
|
||||
推荐公共模型:
|
||||
|
||||
```text
|
||||
RenderSegmentDefinition
|
||||
strategy: RETAINED | CONTINUOUS
|
||||
startLayerId?: string
|
||||
```
|
||||
|
||||
规则:
|
||||
- definitions 至少 1 个。
|
||||
- 第 0 个 Segment 从 Style index 0 开始,`startLayerId` 必须省略/为空。
|
||||
- 第 1..N-1 个 Segment 必须提供非空 `startLayerId`。
|
||||
- startLayerId 必须引用当前 Style 中已经存在的普通 Layer。
|
||||
- Native 根据当前 Style 解析真实 layerIndex。
|
||||
- App/RN 不传数字 index。
|
||||
|
||||
例如:
|
||||
|
||||
```text
|
||||
[
|
||||
{ strategy: RETAINED },
|
||||
{ strategy: CONTINUOUS, startLayerId: "rn-weather-color" },
|
||||
{ strategy: RETAINED, startLayerId: "land-area" },
|
||||
{ strategy: RETAINED, startLayerId: "ais-layer" }
|
||||
]
|
||||
```
|
||||
|
||||
解析后:
|
||||
- Segment 0 = `[0, index(rn-weather-color))`
|
||||
- Segment 1 = `[index(rn-weather-color), index(land-area))`
|
||||
- Segment 2 = `[index(land-area), index(ais-layer))`
|
||||
- Segment 3 = `[index(ais-layer), layerCount)`
|
||||
|
||||
Segment 2/3 虽然都是 RETAINED,也必须保持两个独立 cache,不得合并。
|
||||
|
||||
这种定义保证整个 Style 完整覆盖;插入普通 Layer 后依据 Style 位置自然进入对应 Segment;最顶端新增 Layer自动属于最后一个 Segment。
|
||||
|
||||
## 5. Plan 合法性与 resolve
|
||||
|
||||
有效计划必须满足:
|
||||
- Style ready;
|
||||
- 所有 boundary Layer 存在;
|
||||
- boundary index 严格递增;
|
||||
- 无重复 boundary;
|
||||
- 每个 resolved Segment 非空;
|
||||
- 最终覆盖 `[0, layerCount)`;
|
||||
- 不重叠、不留 gap。
|
||||
|
||||
hidden / visibility=none 的 boundary Layer 仍参与 topology。Visibility 变化不得改变 Segment membership。
|
||||
|
||||
以下情况 plan invalid:
|
||||
- boundary missing;
|
||||
- boundary 顺序反转或重复;
|
||||
- Style 未 ready;
|
||||
- 空 definitions;
|
||||
- 非法 strategy;
|
||||
- JSON/schema 非法。
|
||||
|
||||
invalid 时不得 crash、不得猜 boundary、不得复用 stale cache。必须释放/隔离失效 topology 的 retained resource,安全走 full renderer,并在 diagnostics 给出明确 reason。Style 后续恢复合法时允许自动重新 resolve。
|
||||
|
||||
必须有 monotonic `configRevision`。Style add/remove/reorder 后重新 resolve;实际 begin/end 变化时推进 `topologyRevision`。Visibility 变化不得推进 topologyRevision。
|
||||
|
||||
## 6. Renderer 执行模型
|
||||
|
||||
Resolved Segment 按 Style 顺序执行:
|
||||
|
||||
```text
|
||||
for segment in resolvedSegments:
|
||||
RETAINED -> build/reuse cache -> composite
|
||||
CONTINUOUS -> direct render
|
||||
```
|
||||
|
||||
逻辑上按 Segment 顺序组合,但实际实现必须继续满足 MapLibre 原有 RenderPass 语义。
|
||||
|
||||
必须保持:
|
||||
- 全 Style 原始 global layerIndex;
|
||||
- 原始 ordinal;
|
||||
- `parameters.currentLayer`;
|
||||
- `depthRangeSize`;
|
||||
- Opaque reverse traversal;
|
||||
- Translucent forward traversal。
|
||||
|
||||
禁止每个 Segment 从 0 重新编号,禁止为了 Segment 模型重新排序 Style Layer。
|
||||
|
||||
## 7. RETAINED Segment 独立 Cache
|
||||
|
||||
每个 RETAINED Segment 必须拥有独立:
|
||||
- cache state;
|
||||
- content revision;
|
||||
- build/reuse/invalidation count;
|
||||
- last invalidation reason;
|
||||
- texture/compositor create count;
|
||||
- resource release count。
|
||||
|
||||
GPU resource 必须 lazy 创建。CONTINUOUS Segment 绝不能因为占位而创建 retained texture。
|
||||
|
||||
Plan/topology 改变后,不能证明安全复用的旧 cache 必须释放并重建;stale segment cache 绝不能错误 composite。本 STEP 不要求复杂 cache migration,correctness-first。
|
||||
|
||||
## 8. Invalidation 粒度
|
||||
|
||||
目标是 Segment 级 invalidation。
|
||||
|
||||
能够明确定位影响 Segment 时,只 invalidate 受影响 RETAINED Segment;其他 RETAINED Segment 保持 valid/reuse。
|
||||
|
||||
LayerMutation 若明确属于某 Segment,应只使该 Segment dirty。Source/Tile mutation 若能从现有 RenderLayer/Source 关系安全确定影响的多个 Segment,应 invalidate 对应集合。
|
||||
|
||||
若无法可靠确定影响范围,允许保守 invalidate 全部 RETAINED Segment。本 STEP 不建立复杂通用 dependency graph。
|
||||
|
||||
camera/transform/viewport/resize/pixel ratio、style reload、image/sprite/glyph、placement/symbol fade/transition、context reset、debug options、unsupported 3D、resource/compositor failure 等无法证明局部安全时可 invalidate 全部 retained。
|
||||
|
||||
完成报告必须区分“已实现的 segment-local invalidation”和“仍采用全 retained invalidation 的原因”。
|
||||
|
||||
## 9. Cache ON/OFF
|
||||
|
||||
现有 Cache ON/OFF 总开关继续有效。
|
||||
|
||||
Cache OFF:
|
||||
- Segment Plan 仍然 resolve;
|
||||
- Diagnostics 仍能看到 Style/Segment/Layer 分类;
|
||||
- RETAINED Segment 不错误复用 retained GPU cache;
|
||||
- Renderer 安全走非 retained 路径。
|
||||
|
||||
Cache ON:
|
||||
- 每个 RETAINED Segment 独立 build/reuse;
|
||||
- CONTINUOUS Segment 直接绘制。
|
||||
|
||||
关闭所有 CONTINUOUS Layer 的 visibility 不得删除 Segment topology。
|
||||
|
||||
## 10. V12 兼容入口
|
||||
|
||||
不得破坏现有:
|
||||
- `setRetainedUnderlayEnabled()`
|
||||
- `setContinuousLayerRange(startLayerId,endLayerId)`
|
||||
- `getRetainedUnderlayDiagnostics()`
|
||||
|
||||
新内部实现应尽量只有一套 Segment topology。
|
||||
|
||||
`setContinuousLayerRange(start,end)` 应作为 compatibility adapter,转换成等价 RenderSegmentPlan:
|
||||
- start 前存在 → RETAINED
|
||||
- start..end → CONTINUOUS
|
||||
- end 后存在 → RETAINED
|
||||
|
||||
自然退化成 V12 原有 1/2/3 Range。
|
||||
|
||||
旧 API 与新 Segment Plan 不得同时形成两套 Renderer topology。最后一次显式 topology 配置必须只有一个 active plan,并从 diagnostics 可见 `configSource`。
|
||||
|
||||
旧 `getRetainedUnderlayDiagnostics()` 保留兼容摘要;新的多 Segment 事实以新 Diagnostics API 为准。
|
||||
|
||||
## 11. 新 RN / Native API
|
||||
|
||||
新增稳定公共语义:
|
||||
|
||||
```text
|
||||
RendererRuntime.setRenderSegmentPlan(reactTag, plan)
|
||||
RendererRuntime.getRenderSegmentDiagnostics(reactTag)
|
||||
```
|
||||
|
||||
建议 TS:
|
||||
|
||||
```text
|
||||
RenderSegmentStrategy = "RETAINED" | "CONTINUOUS"
|
||||
|
||||
RenderSegmentDefinition = {
|
||||
strategy: RenderSegmentStrategy
|
||||
startLayerId?: string
|
||||
}
|
||||
|
||||
RenderSegmentPlan = {
|
||||
schemaVersion: 1
|
||||
segments: readonly RenderSegmentDefinition[]
|
||||
}
|
||||
```
|
||||
|
||||
RN public API 必须是 typed object。TurboModule ABI 可使用 JSON string 作为 plan/snapshot 内部传输,避免可扩展嵌套数组变成脆弱 parallel arrays。若采用 JSON,必须有 schemaVersion 与严格校验;public TS 不暴露 raw JSON。
|
||||
|
||||
必须沿当前真实链路扩展:
|
||||
`RendererRuntime → NativeWeatherRuntimeBridge/TurboModule → Android/iOS package bridge → MapLibre platform API → Core Renderer state`。
|
||||
|
||||
不得新建第二套独立 RN bridge。
|
||||
|
||||
## 12. Segment Diagnostics — 强制要求
|
||||
|
||||
这是 STEP-094 的强制验收项,不是附加日志。
|
||||
|
||||
新增 pull-based `getRenderSegmentDiagnostics()`,必须能够取回当前真实 Style 的:
|
||||
1. Style 全 Layer 顺序;
|
||||
2. 当前 resolved Segment 顺序;
|
||||
3. 每个 Segment 的 strategy;
|
||||
4. 每个 Segment 的 begin/end;
|
||||
5. 每个 Segment 内实际包含的 Layer;
|
||||
6. 每个 RETAINED Segment 的 cache 状态与统计。
|
||||
|
||||
Diagnostics 只能按需读取。禁止 per-frame 打印完整 Style/Segment/Layer,禁止每帧构造大 JSON/大字符串。
|
||||
|
||||
## 13. Diagnostics Snapshot 最低字段
|
||||
|
||||
顶层至少:
|
||||
|
||||
```text
|
||||
schemaVersion
|
||||
enabled
|
||||
configured
|
||||
valid
|
||||
configSource
|
||||
configRevision
|
||||
topologyRevision
|
||||
styleLayerCount
|
||||
segmentCount
|
||||
retainedSegmentCount
|
||||
continuousSegmentCount
|
||||
coverageComplete
|
||||
fallback
|
||||
lastReason
|
||||
fastPathEligible
|
||||
fastPathActive
|
||||
fastPathFallbackReason
|
||||
fastPathHit
|
||||
fastPathMiss
|
||||
fullCpuFrame
|
||||
```
|
||||
|
||||
`configSource` 至少区分:
|
||||
- `explicit-render-segment-plan`
|
||||
- `continuous-range-compat`
|
||||
- `unconfigured/legacy`(若仍存在)
|
||||
|
||||
必须提供完整 ordered `styleLayers[]`,用于 plan invalid 时仍可人工分析 Style。
|
||||
|
||||
## 14. Style Layer Diagnostics
|
||||
|
||||
每个 `styleLayers[]` / Segment 内 `layers[]` 至少返回:
|
||||
|
||||
```text
|
||||
layerIndex
|
||||
layerId
|
||||
layerType
|
||||
visible
|
||||
```
|
||||
|
||||
如当前 Style/Core 可低成本稳定取得,还应返回:
|
||||
- `sourceId`
|
||||
- `sourceLayer`
|
||||
|
||||
不适用时可为空/null,禁止伪造。Layer Diagnostics 只描述通用 Style 信息,禁止加入 AIS/Route/Wind 等业务判断。
|
||||
|
||||
## 15. 每个 Segment Diagnostics
|
||||
|
||||
每个 Segment 至少:
|
||||
|
||||
```text
|
||||
segmentIndex
|
||||
strategy
|
||||
configuredStartLayerId
|
||||
beginIndex
|
||||
endExclusive
|
||||
resolvedStartLayerId
|
||||
resolvedEndLayerId
|
||||
layerCount
|
||||
layers[]
|
||||
```
|
||||
|
||||
如果 `strategy=RETAINED`,还必须有:
|
||||
|
||||
```text
|
||||
cacheState
|
||||
contentRevision
|
||||
build
|
||||
reuse
|
||||
invalidation
|
||||
lastInvalidationReason
|
||||
textureCreate
|
||||
compositeCreate
|
||||
resourceRelease
|
||||
```
|
||||
|
||||
如果 `strategy=CONTINUOUS`,不得伪装成 disabled retained cache。retained-only 字段应为 null/not-applicable,或由 TS discriminated union 排除。
|
||||
|
||||
## 16. Diagnostics 一致性
|
||||
|
||||
当 plan valid:
|
||||
- `styleLayers.length == styleLayerCount`
|
||||
- Segment 按 segmentIndex/beginIndex 严格递增
|
||||
- 所有 `segment.layers[]` 拼接后必须与 `styleLayers[]` 完全一致
|
||||
- 每个 Style Layer 必须且只能属于一个 Segment
|
||||
- `segment.layerCount == segment.layers.length`
|
||||
- `coverageComplete=true`
|
||||
|
||||
当 plan invalid:
|
||||
- 仍尽可能返回当前 ordered styleLayers
|
||||
- segments 可为空或只返回已安全解析部分,但必须 `valid=false`
|
||||
- 禁止把猜测结果标成 valid
|
||||
|
||||
## 17. DEBUG 使用目标
|
||||
|
||||
必须能取回类似:
|
||||
|
||||
```text
|
||||
Segment 0 RETAINED [0..18)
|
||||
background
|
||||
water
|
||||
coastline
|
||||
|
||||
Segment 1 CONTINUOUS [18..20)
|
||||
rn-weather-color
|
||||
rn-weather-particles
|
||||
|
||||
Segment 2 RETAINED [20..27)
|
||||
land-area
|
||||
navigation-marks
|
||||
route
|
||||
|
||||
Segment 3 RETAINED [27..30)
|
||||
ais
|
||||
radar
|
||||
alarm
|
||||
```
|
||||
|
||||
此信息只用于人工分析 Style 分类是否合理。Renderer 不根据 Debug 结果自动重新分类。
|
||||
|
||||
设计文档必须给出至少一个完整 JSON/TS snapshot 示例。
|
||||
|
||||
## 18. Particle Fast Path
|
||||
|
||||
V12 已有 Particle Fast Path 不得无声退化。
|
||||
|
||||
至少保证:
|
||||
- 对“恰好一个 CONTINUOUS Segment + 其余为 RETAINED”的 V12 等价拓扑,且 Continuous 内容满足现有支持条件时,现有 Fast Path 能继续工作。
|
||||
- 不存在某个 retained cache 时不得成为 miss 原因。
|
||||
|
||||
对于多个 CONTINUOUS Segment,若当前 Fast Path 无法安全支持,允许 fail closed:
|
||||
- `fastPathActive=false`
|
||||
- 明确 fallback reason
|
||||
- 正常 full CPU frame
|
||||
- Segment topology / retained cache / Z-order 仍正确
|
||||
|
||||
禁止为了 STEP-094 一次性重写整个 RenderGraph 或实现所有 N-Continuous Fast Path 优化。
|
||||
|
||||
## 19. Style Mutation
|
||||
|
||||
必须验证:
|
||||
- Segment 内新增/删除/reorder Layer
|
||||
- boundary 前后插入 Layer
|
||||
- boundary Layer hidden
|
||||
- boundary Layer 删除/重新出现
|
||||
- boundary reorder 导致 plan invalid
|
||||
- plan 更新后恢复
|
||||
|
||||
普通 Layer 插入 Segment 内后应自然成为该 Segment 成员,不要求 App 给每个 Layer 单独注册频率 metadata。
|
||||
|
||||
相邻 RETAINED Segment 即使策略相同,也必须依靠显式 boundary 保持独立。
|
||||
|
||||
## 20. GPU 生命周期
|
||||
|
||||
实际 retained GPU resource 数量应与当前 resolved plan 中 RETAINED Segment 数量一致,允许 lazy 未创建状态,但不得为 CONTINUOUS Segment 分配 retained target。
|
||||
|
||||
Plan topology 变化后 stale resource 必须正确 release。稳定帧不得重复创建 retained texture/FBO/compositor。OpenGL 与 Metal 行为必须一致。
|
||||
|
||||
## 21. Native Directed Tests(不加入 Jest)
|
||||
|
||||
本任务明确不加入 Jest。
|
||||
|
||||
至少覆盖:
|
||||
1. 单 RETAINED Segment 覆盖全 Style
|
||||
2. 单 CONTINUOUS Segment 覆盖全 Style
|
||||
3. V12 等价 R-C-R
|
||||
4. C-R-R
|
||||
5. R-R-C
|
||||
6. R-C-R-C-R 多段交错
|
||||
7. 相邻 R-R 不自动 merge
|
||||
8. hidden boundary 不改变 topology
|
||||
9. boundary missing / duplicate / 顺序非法
|
||||
10. Style 内插入 Layer 后 membership 正确
|
||||
11. boundary 删除后 fail safe、恢复后重新 resolve
|
||||
12. retained resource 数量匹配 RETAINED Segment 数
|
||||
13. CONTINUOUS 无 retained resource
|
||||
14. Cache OFF 时 topology diagnostics 仍完整
|
||||
15. V12 `setContinuousLayerRange` 兼容映射
|
||||
16. global layerIndex / Opaque / Translucent 语义不变
|
||||
17. 多 CONTINUOUS Fast Path 安全 fallback
|
||||
|
||||
Diagnostics tests 额外验证:
|
||||
- styleLayers 顺序精确
|
||||
- segments 顺序精确
|
||||
- 每个 Segment 的 layers 成员精确
|
||||
- 拼接 segment.layers == styleLayers
|
||||
- layerIndex 不重编号
|
||||
- layerId/layerType/visible 正确
|
||||
- sourceId/sourceLayer(若实现)正确
|
||||
- invalid plan 仍能取得 ordered styleLayers
|
||||
- snapshot pull 不产生 per-frame 日志
|
||||
|
||||
## 22. 平台与 RN 验证
|
||||
|
||||
Core/C++:
|
||||
- 执行规定的 Mac 原生精确编译与 Native tests
|
||||
- OpenGL / Metal
|
||||
- 编译输出遵循全局 build-output-throttle
|
||||
|
||||
Android:
|
||||
- 完成源码、JNI/Kotlin/Java/RN bridge 修改
|
||||
- Android Gradle 编译由用户手工执行,不由 Codex 运行
|
||||
- 报告列明“未执行 Android 编译/实体机”直到用户验证
|
||||
|
||||
iOS:
|
||||
- 只面向 iPhone/iPad arm64 真机架构
|
||||
- 不要求 Simulator slice
|
||||
- 可执行当前工程已有的 Mac/iOS arm64 精确编译验证
|
||||
- 不伪造实体机运行 PASS
|
||||
|
||||
## 23. 最小 Debug/Validation 入口
|
||||
|
||||
在当前已有 Particle validation/Test Host 体系中补一个最小 pull 入口:
|
||||
- Fetch Segment Diagnostics
|
||||
- 展示或输出一次完整 snapshot
|
||||
- 能看到 Segment 列表和每个 Segment 的 Layer 列表
|
||||
|
||||
不得增加持续轮询,不得把大 snapshot 每帧写日志。若现有 UI 已有 diagnostics panel,优先复用。
|
||||
|
||||
## 24. 性能要求
|
||||
|
||||
Segment topology/style diagnostic 数据只在 config/style topology 或相关 debug metadata 变化时更新,或在显式 diagnostics pull 时做必要轻量组装。
|
||||
|
||||
禁止因为 Particle 30/60fps:
|
||||
- 每帧扫描/复制完整 Style Layer 字符串
|
||||
- 每帧 JSON stringify
|
||||
- 每帧创建 Segment diagnostics 大对象
|
||||
- 每帧 Logger 输出 topology
|
||||
|
||||
高频 render path 只消费预解析的轻量 segment ranges/cache state。
|
||||
|
||||
## 25. 明确不做
|
||||
|
||||
本 STEP 不做:
|
||||
- LOW/MEDIUM/HIGH 枚举或自动频率分类
|
||||
- Renderer 识别 NavSea 业务 Layer
|
||||
- 自动调整 Style Z-order
|
||||
- Anchor/Marker Layer
|
||||
- 复杂通用业务 dependency graph
|
||||
- Weather provider / Route ETA / AIS 专项 renderer
|
||||
- PBF 重生成
|
||||
- 通用 RenderGraph 重写
|
||||
- 自动合并同策略 Segment
|
||||
- 多 Continuous 的高级 Fast Path 优化
|
||||
- per-frame Segment debug log
|
||||
- Jest
|
||||
|
||||
如发现必须突破这些边界才能保证 correctness,停止扩大范围并在报告明确 BLOCKED/PARTIAL。
|
||||
|
||||
## 26. 必做文档
|
||||
|
||||
新增:
|
||||
- `docs/30_设计/STEP-094_通用RenderSegment模型与Style分类Diagnostics设计_v1.md`
|
||||
- `docs/50_Step记录/STEP-094_通用RenderSegment分段渲染与Style分类诊断_v1.md`
|
||||
- `docs/报告/STEP-094_通用RenderSegment分段渲染与Style分类诊断_Codex完成报告_v1.md`
|
||||
|
||||
追加:
|
||||
- `粒子开发记录.md`
|
||||
|
||||
同主题已有文件则递增版本,不覆盖历史。所有文档中文。
|
||||
|
||||
设计文档必须包含最终 Segment 数据模型、config/resolve 生命周期、V12 compatibility mapping、cache ownership、invalidation、Fast Path 边界、Android/iOS/RN API、Diagnostics schema、完整 Style→Segment→Layer snapshot 示例。
|
||||
|
||||
## 27. 完成报告必须记录
|
||||
|
||||
- 起始 HEAD / 最终 HEAD
|
||||
- 修改文件清单
|
||||
- RenderSegment config API
|
||||
- boundary Layer ID → layerIndex 解析
|
||||
- N Segment 遍历
|
||||
- retained cache ownership/resource lifecycle
|
||||
- segment-local 与 global invalidation
|
||||
- V12 compatibility / Fast Path
|
||||
- Diagnostics schema
|
||||
- styleLayers / segment.layers 验证
|
||||
- RN/Android/iOS bridge
|
||||
- OpenGL / Metal
|
||||
- Native test 数量与结果
|
||||
- 未执行 Android/实体机项目
|
||||
- known limitations
|
||||
- commit SHA/message
|
||||
- push result / remote branch
|
||||
- origin/particle/main Final HEAD
|
||||
- 最终 `git status --short`
|
||||
|
||||
## 28. Git 规则
|
||||
|
||||
仅 scoped staging。禁止 `git add -A`、`git add .`、`git reset --hard`、`git clean`,不得删除/覆盖无关 dirty/untracked。
|
||||
|
||||
结束前必须:
|
||||
1. `git diff --check`
|
||||
2. 核对 diff
|
||||
3. 只 stage 本任务文件
|
||||
4. scoped commit
|
||||
5. push `origin particle/main`
|
||||
6. fetch/确认远端
|
||||
|
||||
最终要求:
|
||||
```text
|
||||
HEAD == origin/particle/main
|
||||
git status --short 无本任务残留
|
||||
```
|
||||
|
||||
push 失败不得声称完成。
|
||||
|
||||
## 29. PASS Gate
|
||||
|
||||
只有以下全部成立才可判 STEP-094 PASS:
|
||||
- Style Z-order 仍唯一
|
||||
- 1..N 连续 Segment 完整覆盖
|
||||
- RETAINED/CONTINUOUS 可任意交错
|
||||
- 相邻同策略 Segment 不自动合并
|
||||
- 每个 RETAINED Segment 独立 cache/revision/invalidation/resource
|
||||
- V12 Continuous Range 兼容
|
||||
- V12 等价 Fast Path 不无声退化
|
||||
- 新 Diagnostics 能真实返回 Style→Segment→Layer
|
||||
- diagnostics pull-based、无 per-frame 大开销
|
||||
- Android/iOS/RN API 完整
|
||||
- Native directed tests 通过
|
||||
- 规定编译验证完成
|
||||
- 文档完成
|
||||
- scoped commit/push 完成
|
||||
- HEAD 与远端一致
|
||||
|
||||
关键项未完成必须明确 PARTIAL/BLOCKED,禁止伪造 PASS。
|
||||
109
docs/40_任务/STEP-095_V13独立严格代码与性能审查_Codex任务_v1.md
Normal file
109
docs/40_任务/STEP-095_V13独立严格代码与性能审查_Codex任务_v1.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# STEP-095 V13 独立严格代码与性能审查 — Codex 任务 v1
|
||||
|
||||
## 0. 工作性质与模型
|
||||
- 本任务是独立、严格、全链路、以源码为最终证据的只读代码/性能调查,不是修复任务,也不是批准已有报告。
|
||||
- 执行环境:Mac-mini-tei.lan,仓库 /Users/tei/dev/MapLibreParticleLab,分支 particle/main。
|
||||
- 运行模型:gpt-6-astra,reasoning effort=high;由外部启动命令实际指定,报告记录实际模型。
|
||||
- 最终交付物必须为中文,具体源码符号、文件路径、命令、证据可保留英文。
|
||||
- 不以“编译通过”“定向单元测试通过”“已有 Codex 报告 PASS”推断 GPU 运行态、安全性、性能或跨平台一致性已经通过。
|
||||
|
||||
## 1. 源码冻结基线
|
||||
- 被审查的 V13 代码提交:ee0b89e711bf01335b3aa71d36def785cd97fec3。
|
||||
- V13 核心功能提交:016fd1fff6a33cf795c10d4f5c5413d308383677。
|
||||
- V13 发布标识:RN 13.4.1-particle.13;iOS 6.28.0-particle.13;以实际 manifest/tag/API 核实,不假设已在 NavSea 接入。
|
||||
- 前置独立审查归档提交:45c4dca84928a57a2cf0226737c34cabd7fbfbfb。
|
||||
- 审查前读取 AGENTS.md、PARTICLE_BASELINE.md、docs/00_项目规范/、docs/00_项目总则/README.md 与其中标记的当前有效总则。
|
||||
- 同步检查 git branch、HEAD、origin/particle/main、working tree、release manifest 和相关 tag;记录所有偏差。
|
||||
- 本任务自身新增文档提交不改变上述被审查的源码 commit;核查源码时固定以该提交为事实基线。
|
||||
|
||||
## 2. 审查独立性:先源码,后已有报告
|
||||
- 首先依据 Git V12→V13 改动、当前调用链及实际代码独立扫描,不从旧报告结论直接生成 findings。
|
||||
- 然后阅读 docs/20_调查/Particle_V13_严格代码审查报告_v1.md,逐项复核 F01–F10:确认、修正、否定或标记需动态验证。
|
||||
- 不能复制上一份报告来冒充独立 review。需要发现旧报告遗漏、误判、证据不足及其他模块的潜在风险。
|
||||
- 交叉阅读 STEP-088~094 的任务、设计、Step 记录、Codex 报告及相关发布/验证事实。
|
||||
- 当任务书与代码冲突,分别说明“设计意图”和“实际实现”;不能把历史数据冒充 V13 测量。
|
||||
- 可以读取 Integration repo 的 contract/status/compatibility,但不得修改该仓库;发现跨平台契约问题只提升级建议。
|
||||
|
||||
## 3. 强制审查范围 A:Renderer 与 V13 Segment
|
||||
- 通用 RenderSegment plan、JSON parser/resolver、配置切换、missing/reorder/hidden boundary、valid/invalid/recovery。
|
||||
- Style 全局 Z-order、layerIndex、LayerGroup ordinal、opaque reverse、translucent forward、depth/stencil/blending、debug/legacy/3D 与 offscreen composite 的一致性。
|
||||
- 任意 R/C 交错:全 R、全 C、R-C-R、C-R-R、R-R-C、R-C-R-C-R、相邻 R-R;缓存 OFF 和资源失败的 full fallback。
|
||||
- Retained cache 独立生命周期、build/reuse/invalidate/release、topology generation、content fingerprint、diagnostics counters 的归属。
|
||||
- V12 连续区间兼容映射、单 Continuous Fast Path、多个 Continuous 安全 fallback,注意 silent fallback 与正常渲染的真实成本。
|
||||
- 特别核查 Segment pass 分割后的 alpha/depth/stencil 语义、source/layer mutation 与下一帧 stale GPU object 风险。
|
||||
## 4. 强制审查范围 B:GPU、粒子和时间场
|
||||
- OpenGL 与 Metal OffscreenTexture、Framebuffer、Texture、render pass、commit/present/wait、resource destroy/context loss;区分通用 Core 与平台实现。
|
||||
- 是否存在 CPU/GPU 同步等待、重复 GPU allocation、每帧 upload/UBO/drawable 重建、纹理引用失效和资源峰值。
|
||||
- Particle State A/B、Trail、Field T0/T1/MIX、spatial sampling、forecast/playback、zoom-out reseed、viewport bounds 和 resize/orientation。
|
||||
- Wind/Wave/Current/Rain 等 canonical FieldProfile;V3/V4 encoded/decoded field、QBIN decoder、projection/materialization、binding/validity/missing data。
|
||||
- 检查异常或损坏输入、极大网格/时间、浮点 NaN/Inf、整数溢出、文件/缓冲区生命周期、重复/乱序/过期 field、安全失败和内存占用。
|
||||
- 需要从 Source→Runtime→RenderLayer→Renderer→GPU 按真实调用链追踪,不接受只搜索名称的浅层判断。
|
||||
|
||||
## 5. 强制审查范围 C:高频、线程和 Host API
|
||||
- 每帧 CPU 分配/深复制/锁竞争/字符串或 JSON 构造、LayerGroup 遍历复杂度、静态 CPU Fast Path 命中与错过原因。
|
||||
- style/source/tile/image/glyph/placement 失效范围是否正确,segment-local 与全局 revision 的边界是否一致。
|
||||
- map-scoped lifetime、prepared RenderTree、Runtime/renderer/control state 的并发、线程归属、异步回调、销毁后引用和重复 attach/detach。
|
||||
- Android Java/Kotlin/JNI 与 iOS ObjC++/Metal 的桥接接口、错误归一化、RN TurboModule typed API、ABI/codegen 与版本锁。
|
||||
- Test Host 的依赖及 lockfile、构建结果的可复现性、release manifest/npm/AAR/XCFramework 的版本一致性。
|
||||
- 不将业务 provider、HTTP、Route/ETA 带入 Shared Core;不建议建立新的隐藏私有桥接或第二套协议。
|
||||
|
||||
## 6. 强制审查问题清单
|
||||
- 是否存在 V13 上线后能够导致画面层级错误、透明度/遮挡错误、丢帧、黑屏、闪烁、过期 cache composite、GPU/CPU 泄漏、崩溃或错误数据的实际源码路径?
|
||||
- 非法配置是否真正 fail closed?同一 index 换不同 Segment 时旧 cache/diagnostics 归属是否错误?
|
||||
- Retained contentDirty 是否被误当作 GPU allocation invalid?Metal 逐 cache wait 是否可证实?需要哪些 profiler 证据才能决定修改?
|
||||
- 高频 Fast Path 是否复制 full diagnostics、扫描 Style 或反复线性搜索?有无更重的热点在既有报告中遗漏?
|
||||
- 多段 retained 是否存在全 viewport depth/stencil 过度分配;是否有峰值预算、安全回退及 resource accounting?
|
||||
- source/tile 局部更新是否引起不必要全 retained rebuild?若建议局部化,必须给出不破坏 correctness 的依赖证据。
|
||||
- 单 Continuous 与多 Continuous 的 Frame 处理在相同真实 Style 下有什么可测的差异?不能外推 STEP-090 历史 A/B 数字。
|
||||
- release、Test Host、RN/iOS/Android 版本与实际产物是否能被独立复现?尚未测试的必须标 NOT RUN。
|
||||
|
||||
## 7. 审查方法
|
||||
1. 建立 V12→V13 变更与模块地图,阅读入口、类型定义、状态机、调用方和析构路径。
|
||||
2. 针对每个怀疑的问题制作最短触发条件和源码调用链;尝试找反例,禁止只因为名称相似就报告漏洞。
|
||||
3. 按已证实缺陷、源码确定的成本、真实运行影响待验证、显式设计限制、文档/环境偏差分类。
|
||||
4. 为每条 finding 写严重度 P0/P1/P2/P3、置信度、源文件精确行范围、触发场景、影响、最小安全修复方向和验收方法。
|
||||
5. 独立比较上一份 F01–F10,标为 CONFIRMED / QUALIFIED / DISPROVED / NEEDS_RUNTIME,说明依据和新增发现。
|
||||
6. 对潜在收益只给复杂度/估算表达和建议基准测试,不提供无 profiler 支持的 FPS/CPU/GPU 节省百分比。
|
||||
7. 所有未亲自执行的测试必须标 HISTORY / NOT RUN;已有报告的 PASS 只能列为历史证据,不替代当前独立执行。
|
||||
|
||||
## 8. 运行与修改边界
|
||||
- 禁止修改任何生产源码、shader、公共 API、构建配置、package/lockfile、release manifest、tag、发布产物或 Integration 文件。
|
||||
- 禁止运行耗时 CMake/Xcode/Gradle 编译、安装、设备操作和大型测试;由 RDC/用户另行验证。
|
||||
- 允许只读 git show/log/diff、文件检索、源码静态分析和查看既有日志、测试源码、报告。
|
||||
- 如判断必须借助 profiler、真机或编译才可定论,写精确验证方案而不是擅自实施。
|
||||
- 仅允许新增本 STEP 中文调查/Step/完成报告,按规定追加根目录粒子开发记录;不要顺手修复发现的问题。
|
||||
## 9. 完成报告格式(必须实际落盘)
|
||||
- 执行摘要:哪些是确定缺陷、哪些是性能成本、哪些只能动态验证;不能只给结论口号。
|
||||
- 基线与范围:审查 commit、分支、release manifest、审查的主要文件/代码路径、未覆盖范围。
|
||||
- Finding 总表:编号、严重度、证据类别、问题、触发、影响、代码定位、修复方向、验证方法。
|
||||
- 逐条完整分析:至少包含最短可复核调用链及确认或推翻依据;新问题与旧报告重复项区分。
|
||||
- V13 与 V12 架构/性能成本比较:不确定的写待测;不要虚构性能数值。
|
||||
- F01~F10 独立复核矩阵:原结论、当前意见、依据、是否需补充/修正。
|
||||
- 缺失测试与运行态矩阵:GPU correctness、CPU/GPU frame time、allocation/peak memory、30/60 FPS、长时间稳定性、各平台状态。
|
||||
- 优先级清单:分 correctness gate、无需设备的安全优化、GPU 资源/同步、较大架构改造。
|
||||
- 具体建议的下一轮 Codex 修复批次(只建议,不创建修复任务,不改源码)。
|
||||
- Git:起始/最终 HEAD、docs-only diff 清单、commit SHA/message、push 结果、remote HEAD、最终 status。
|
||||
- 结论状态:调查 PASS/PARTIAL/BLOCKED 与 V13 产品运行态是否通过必须分开。
|
||||
|
||||
## 10. 必做输出和固定路径
|
||||
- 调查主文档:docs/20_调查/STEP-095_V13独立严格代码与性能调查_v1.md。
|
||||
- 阶段记录:docs/50_Step记录/STEP-095_V13独立严格代码与性能审查_v1.md。
|
||||
- Codex 完成报告:docs/报告/STEP-095_V13独立严格代码与性能审查_Codex完成报告_v1.md。
|
||||
- 追加:根目录 粒子开发记录.md,短而具体地记录本次调查变化、现状及下一步,不覆盖历史。
|
||||
- 若同主题相同文件已经存在,改用递增版本号并在报告写明,不覆盖旧报告。
|
||||
- 以上文件全部中文;任何报告必须明确区分事实、推断和待验证。
|
||||
|
||||
## 11. Git 收尾
|
||||
- 先确保用户现有 dirty/untracked 不被覆盖;只有本任务新增/追加文档允许 staged。
|
||||
- 不执行 git reset --hard、git clean、force push、tag 移动或向 upstream push。
|
||||
- 对所有新增文档进行路径、目录、内容、交叉引用检查;git diff --check。
|
||||
- 仅 git add 上述具体文档和本次追加的开发记录;scoped commit 后 push origin particle/main。
|
||||
- push 失败或 HEAD 与远端不一致时,不得写 PASS;明确失败与恢复建议。
|
||||
- 记录源代码相对于原 V13 源码提交没有改变,禁止把 docs-only commit 误写成新 V13 软件发布。
|
||||
- 最终由 RDC 独立检查报告证据、Git 与任务边界,Codex 不自行宣布正式产品验收。
|
||||
|
||||
## 12. 停止条件
|
||||
- 无法确认当前 commit、源代码状态与所审查发布版本对应时,停止并报告 BLOCKED。
|
||||
- 遇到跨项目协议变更/需要修改业务源码时,只形成接口阻塞或修复建议,不扩大任务。
|
||||
- 证据不足时明确 NEEDS_RUNTIME,不应为了凑数量虚构问题。
|
||||
- 重大 P0 或明确破坏性问题优先直接写进报告,但本任务仍只读,不自动修复。
|
||||
59
docs/40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md
Normal file
59
docs/40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# STEP-096 V13 隔离盲审 — Codex 任务 v1
|
||||
|
||||
## 0. 工作性质与隔离目标
|
||||
|
||||
这是针对已冻结 V13 源码的全新、只读、源码优先的代码与性能审查。发现必须来自当前隔离目录内的源代码和规范,不允许从任何既有审查结论、聊天记录或外部仓库导入问题清单。不得为凑数量制造 finding。
|
||||
|
||||
- 执行模型:全新 Codex TUI 会话,`gpt-6-astra`,reasoning effort=`high`;RDC 负责实际启动与记录,Codex 报告仅记录能核实的启动事实。
|
||||
- 唯一工作目录:`/Users/tei/dev/MapLibreParticleV13Blind096`。
|
||||
- 目标源码版本:`ee0b89e711bf01335b3aa71d36def785cd97fec3`;由 RDC 从该 Git 对象导出**无 .git 元数据**的源码快照。当前隔离目录不是主仓库、不是 Git worktree;不得在此运行 git,也不得用其他路径反查仓库历史。
|
||||
- 唯一任务说明:本文件。用户和外部 RDC 将在审查开始前检查隔离树不含已有调查、阶段记录、完成报告、任务历史或开发日志。
|
||||
- 禁止访问隔离目录之外的所有源码、文档、Git metadata、会话日志、终端回放、网页、连接器、用户历史或其他 AI 输出;不要尝试恢复缺失文档。对任何未在快照内的证据写 NOT AVAILABLE。
|
||||
- 不得读取、搜索或比较其他轮次的审查材料;**本任务只有盲审,不包含解除盲态后的交叉比较。** 完成后的文件由 RDC 先冻结散列,再独立移交正式仓库。
|
||||
|
||||
## 1. 只读入口与事实层级
|
||||
|
||||
先读取隔离目录的 `AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/00_项目规范/`、`docs/00_项目总则/README.md`、其中列出的当前有效总则和本任务。隔离快照故意不提供历史 Step、调查/完成报告;读取要求在盲审范围内以当前有效规范和实际源码为准,不得向目录外补读。规范包含历史发布坐标时,以本快照的 release manifest、源码和目标 SHA 为实现事实,区别说明规范意图与实际代码。
|
||||
|
||||
允许读取:隔离树内的 C++/GL/Metal/Android/iOS/RN 代码、头文件、shader、构建配置、测试源码、release manifest,以及当前有效规范/架构设计。历史测试输出和运行日志不可用;阅读测试源码不等于执行测试。不得浏览 `docs/20_调查`、`docs/50_Step记录`、`docs/报告`、既有历史任务或开发日志(这些输入在隔离树内也应不存在)。不引用主仓库的当前 HEAD 作为 V13 源码 SHA。
|
||||
|
||||
## 2. 审查目标与探索方法
|
||||
|
||||
从目录和公开 API 识别实际架构,自行建立模块和调用链地图;不要按照预设缺陷名称凑检索结果。对每个候选问题至少追踪入口、状态所有权、调用方、正常路径、错误路径、销毁路径,并寻找反例。分别审查:
|
||||
|
||||
1. Style 顺序和分段解析/更新/绘制语义;任意连续渲染策略交错、透明/深度/裁剪及缓存一致性。
|
||||
2. Renderer→gfx→OpenGL/Metal 的目标、命令、资源和生命周期;稳定/变化帧、失败恢复、尺寸变化及上下文切换。
|
||||
3. GPU 粒子、颜色场、时空插值与场数据链;输入合法性、数值边界、时间状态和显示状态。
|
||||
4. Source/Runtime/Field/QBIN、数据快照、线程与内存所有权;重复、乱序、异常或极大输入与 fail-closed。
|
||||
5. Android/iOS/RN 的公开 API、错误传播、生命周期和版本/产物引用;区分源码可证事实与安装环境需要的验证。
|
||||
6. 高频执行成本:CPU、锁、分配、遍历、复制、GPU 同步/资源、UI 线程以及资源上界。查找实际热点路径,但没有 profiler 不得断言运行时热点排序或节省百分比。
|
||||
7. 兼容与工程边界:既有行为、上游薄接入、Style Z-order 唯一事实来源;业务下载/HTTP/provider 属于 Host,不进入 Native。
|
||||
|
||||
如同一问题已有安全 fallback、缓存稳定复用或数据校验,必须写出反例和限制,而不是仅报告表面上可疑的符号。源代码路径和行号必须在隔离快照内真实存在。
|
||||
|
||||
## 3. 每条 finding 的证据契约
|
||||
|
||||
- 按发现顺序自行编号 `B01`、`B02`……;不要采用其他报告的任何编号。
|
||||
- 列:P0/P1/P2/P3、类型(确定缺陷/源码确定成本/设计限制/环境或文档偏差/需运行验证)、置信度、触发条件、最短源码调用链与精确路径/行号、反例、影响边界、安全修复方向、最小验证方案。
|
||||
- 区分“代码中的风险路径已经证实”和“用户画面、GPU、CPU、OOM、崩溃、性能收益已经实测”;后者本轮一概不可假定。
|
||||
- 如果推断尚缺关键调用链,降为 HYPOTHESIS/NEEDS_RUNTIME,不以 P0/P1 明确事故冒充。
|
||||
- 不要求 finding 数量、也不要求与任何报告相同;实际不存在证据就明确无此类 finding。
|
||||
- 不复制包含商业/个人机密的数据;路径与定位信息足够即可。
|
||||
|
||||
## 4. 验证边界与停止条件
|
||||
|
||||
本任务只允许静态读取、轻量文件搜索、源码/语法/引用自检。禁止生产代码、测试代码、shader、manifest、package/lock、工具链改动;禁止 CMake/Xcode/Gradle、Codegen、Jest、设备、安装、性能测试、发布、Git 写入。历史构建/测试结果没有暴露,不得编造。所有未运行门槛标 `NOT RUN`,运行效果标 `NEEDS_RUNTIME`。如必须依赖平台设备、profiler 或竞态注入,写可执行验证矩阵,停止在证据边界。
|
||||
|
||||
只能写以下三份中文文件,写完确认三份存在、正文和相对链接有效、所引用路径/行号有效、无错误引用和行尾空格后退出:
|
||||
|
||||
1. `docs/20_调查/STEP-096_V13隔离盲审调查_v1.md`:架构地图、独立 finding 总表与证据、反例、风险、性能模型、未覆盖范围、运行验证矩阵、分批建议。开头明确声明仅使用隔离输入。
|
||||
2. `docs/50_Step记录/STEP-096_V13隔离盲审_v1.md`:状态、输入版本、检查范围、只读工作过程、结果、三份文件清单、未运行验证、阻塞与下一步。
|
||||
3. `docs/报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md`:执行结果 PASS/PARTIAL/BLOCKED(仅表示盲审文档交付)、finding 索引、证据质量、输入限制、构建测试 NOT RUN、源码未变、交付/移交方案。
|
||||
|
||||
本隔离树无 Git metadata,**不要在报告内伪造 Git commit/push/remote/clean 状态**。正式仓库移交、`粒子开发记录.md` 追加、四个文件的 scoped commit/push、最终 SHA 和远端核对均由 RDC 在盲审文件冻结之后执行。Codex 不得自行打开正式仓库进行移交,避免在写稿前接触比较材料。
|
||||
|
||||
## 5. 盲审冻结与移交验收(由 RDC 执行,不是 Codex 自行执行)
|
||||
|
||||
Codex 停止后,RDC 验证隔离树的文件清单,计算三份原始报告 SHA-256 并记录时间;冻结后不得由同一会话基于其他资料重写 finding。随后独立把三份报告完整复制到正式 `particle/main` 同路径,追加根目录 `粒子开发记录.md`,执行引用、边界、git diff --check、scoped commit、push `origin particle/main`、远端 HEAD/clean 核查。禁止修改已冻结正文,若必须校正移交元数据,应写入独立移交记录,不得改写发现表。
|
||||
|
||||
文档交付 PASS 不等于 V13 Android/iOS GPU 运行态或性能 PASS。若 Codex 无法访问输入、丢失上下文或额度阻断,停止、保留已成品并标 PARTIAL/BLOCKED;不得使用其他会话已有审查结果补齐。
|
||||
153
docs/40_任务/STEP-097_V13三轮审查问题合并修复_Codex任务_v1.md
Normal file
153
docs/40_任务/STEP-097_V13三轮审查问题合并修复_Codex任务_v1.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# STEP-097 V13 三轮审查问题合并修复 — Codex 任务 v1
|
||||
|
||||
状态:**计划 / 待执行**。本文件只定义后续代码修复任务;创建本文件不代表任何缺陷已经修复、编译通过或 V13 运行验收通过。
|
||||
|
||||
## 0. 目标、基线及本轮决策
|
||||
|
||||
目标:对 V13 三轮源码调查的问题去重、复核、按安全依赖顺序修改;保留全部原始编号和证据归属,不以“多份报告都说有问题”取代源码验证。先消除渲染与天气数据的正确性风险,再处理输入安全、Host 生命周期和可证明的热路径成本。保留通用连续 Render Segment、Style Z-order 唯一顺序、每个 RETAINED 独立 cache;不得退回旧 Bottom/Continuous/Top 固定三明治模型。
|
||||
|
||||
本次用户决定:**暂不执行 V13 正式运行态确认**。本任务结束的最高状态只能是 \`IMPLEMENTED / WAITING_RDC_BUILD_AND_RUNTIME_VALIDATION\`;不能写 Android/iOS GPU、FPS、长期稳定性、正式发布或 NavSea 接入 PASS。本任务不要求 Codex 编译、安装、操控设备或执行性能测试。运行态集中验证清单由 Codex准备,之后单独授权执行,避免小变动引发多次 Android 编译/安装。
|
||||
|
||||
实际源码基线以执行时 \`particle/main\`、\`origin/particle/main\` 和 clean worktree 为准;编写任务书时 HEAD 为 \`b5c1c4879a9d36608242e788afab5012bd9388f2\`,V13 软件冻结源码为 \`ee0b89e711bf01335b3aa71d36def785cd97fec3\`,功能提交 \`016fd1fff6a33cf795c10d4f5c5413d308383677\`。当前 \`.13\` 软件已发布,所有修复在后续开发提交中完成,**不得原地覆盖、移动或重新发布 \`.13\` 的 tag/manifest/产物**。若起始 HEAD 已前进,先核实源代码差异并报告,不用旧行号机械覆盖。
|
||||
|
||||
审查输入,必须逐份读取:
|
||||
1. \`docs/20_调查/Particle_V13_严格代码审查报告_v1.md\`(F01–F10,含历史实测)。
|
||||
2. \`docs/20_调查/STEP-095_V13独立严格代码与性能调查_v1.md\`(N01–N07、C01–C07、O01、E01/E02)。
|
||||
3. \`docs/20_调查/STEP-096_V13隔离盲审调查_v1.md\`(B01–B13;**已冻结的独立盲审原文,不得因修复结果修改其 findings**)。
|
||||
4. STEP-094、095、096 的任务/Step/完成报告与 release manifest,按真实性区分历史 PASS 与本轮 NOT RUN。
|
||||
|
||||
开始前读根 \`AGENTS.md\`、\`PARTICLE_BASELINE.md\`、\`docs/00_项目规范/\`、\`docs/00_项目总则/README.md\` 指定的四份有效总则。通过 RDC 确认 \`navsea-particle-integration\` 已同步到最新 \`main\`,并只读检查 \`README.md\`、\`WORKFLOW.md\`、\`coordination/TEAM_MODEL.md\`、\`contracts/\`、\`rfc/\`、\`adr/\`、\`status/\`、\`compatibility/\`。创建任务时 Integration main 为 \`39ad8415fbdb76c1822460bb09f3a3f35fe141e0\`,C-001 / RFC-001 为既有合同,不把其中历史 \`.5\` 误认为当前软件发布 \`.13\`。本任务**不修改 Integration、NavSea 仓库**,新增跨项目公共语义须先有协调/RFC/ADR/Contract 决定。
|
||||
|
||||
## 1. 去重修复总表与执行分类
|
||||
|
||||
状态枚举:\`CODE_FIX\`=本任务可实施;\`CONDITIONAL\`=只有满足设计/证据门槛才动;\`DESIGN_ONLY\`=不作为既有缺陷盲改;\`COORDINATION\`=需跨项目负责人协调。Codex 应将表中每项逐条写入实施矩阵,落实文件、测试入口、commit、实际状态;确认某项不成立也必须提供反证,不能直接删除。
|
||||
|
||||
| 合并问题 | 三轮原编号 | 初始分类 | 目标与安全边界 |
|
||||
| --- | --- | --- | --- |
|
||||
| 01 跨 render target 的 stencil CPU/GPU 状态失配 | N01 / B01 | CODE_FIX | target/pass 世代一致;首帧、R-R/R-C-R、cache ON/OFF |
|
||||
| 02 Metal depth/stencil clear 与附件不完整 | N02 / B02 | CODE_FIX | 全部 RenderPass descriptor/combined attachment;不得只改颜色 |
|
||||
| 03 LayerGroup render 异常后缓存错误标成功 | N03 / B12 | CODE_FIX | 失败不得 \`markBuildSucceeded\` 或 reuse;允许安全恢复 |
|
||||
| 04 encoded PLAY 缺失唯一 production clock 驱动 | N04 / B06 | CODE_FIX | map/source owner 单一单调推进;无双重 tick |
|
||||
| 05 GPU 粒子场身份未覆盖 V/validity | B13 | CODE_FIX | 两时间端点完整内容身份;正确复用和局部上传 |
|
||||
| 06 8-bit 零向量偏差 | B07 | CONDITIONAL | 修复零表达和编码/解码一致性,不引入未验证的格式破坏 |
|
||||
| 07 Mercator 东向位移缺纬度系数 | B08 | CODE_FIX | U/V 相同物理单位下正确度量,保留既定时间倍率 |
|
||||
| 08 JSON 嵌入 NUL/重复键被接受 | N05 | CODE_FIX | 长度感知解析;非法计划清旧状态、fail-closed |
|
||||
| 09 坏数值场先入库、物化失败替换好投影 | N06 | CODE_FIX | 事务式校验/发布;允许合法 no-data/validity=0 |
|
||||
| 10 Android 重复 attach listener 积累 | N07 | CODE_FIX | 幂等 attach/detach、移除监听、对象释放 |
|
||||
| 11 热路径完整 Diagnostics 深复制 | F01 / C01 | CODE_FIX | 内部轻快照与对外完整 pull 分离,线程一致性 |
|
||||
| 12 Metal retained/普通 State/Trail 同步等待 | F02 / C02 / B03 | CONDITIONAL | 先记录同步点/依赖;不可直接删除 wait |
|
||||
| 13 内容 dirty 导致相同尺寸 GPU allocation 重建 | F03 / C03 / B04 | CODE_FIX | contentDirty 与 resourceInvalid 分离;清屏正确性先通过 |
|
||||
| 14 retained GPU 资源无总预算 | F04 / C04 | CONDITIONAL | 安全估算、分配失败完整 fallback;独立 R 不合并 |
|
||||
| 15 encoded store 缺总 key/byte 预算 | C04 / B11 | CONDITIONAL | 保留绑定窗口和旧读者;若拒绝结果需新公共语义则停止 |
|
||||
| 16 ordinal 前缀 O(S×G)/fast 扫全层 | F07 / C05 | CODE_FIX | topology generation 缓存索引,不能改变全局顺序 |
|
||||
| 17 相同 time/mix-only 重物化和 UI 同步处理 | C06 / B05 / B10 | CODE_FIX(异步部分 CONDITIONAL) | 先幂等和不可变端点复用;owner-thread 安全发布 |
|
||||
| 18 drawable/tweaker 重建与窗口端点复制 | C07 | CONDITIONAL | 只改可证明稳定的对象生命周期,避免新 stale 引用 |
|
||||
| 19 旧 cache 的 release 记入新 topology | F09 / O01 | CODE_FIX | identity/generation 归属、历史/当前计数分离 |
|
||||
| 20 Test Host RN \`.10\` / native \`.13\` 错配 | F05 / E01 | CODE_FIX | 默认 package/lock 与插件精确锁定;不把旧 TS 报错误归因 |
|
||||
| 21 多 Continuous 退出 CPU Fast Path | F06 | DESIGN_ONLY | 保留安全 full CPU fallback,后续真实 A/B 再立项 multi-C |
|
||||
| 22 source/tile 等保守全局失效 | F08 | DESIGN_ONLY | 没有完整依赖证明不得缩窄,后续 profiling/依赖设计 |
|
||||
| 23 Integration compatibility/status 历史口径 | F10 / E02 | COORDINATION | 向粒子负责人提交接入证据请求,不擅改或声称 NavSea 支持 |
|
||||
| 24 正式共享地理 Ocean Mask 尚未形成 | STEP-095 §7 / B09 | COORDINATION | 跨 Host/Shared Core/双平台显示契约需单独 RFC/ADR,不用合成 fixture 冒充正式实现 |
|
||||
|
||||
注意:B13 与 N06 **不是同一缺陷**;GPU 内容身份遗漏与 encoded ingress 事务发布必须分别修复和验证。B07/B08 是粒子数值正确性,不等于 V13 分段回归。所有 P1/P2 是调查建议优先级,不是运行事故证明。
|
||||
|
||||
## 2. 固定顺序与不可跨越的检查点
|
||||
|
||||
严格按 \`基线复核 → A正确性 → B输入/生命周期 → C安全性能 → D交付\` 串行进行。前一阶段没有明确代码完成和静态检查结果,禁止推进下一阶段;失败、进程超时、状态未知不能当作成功。任一阶段发现需要更改冻结公共 API、QBIN/FieldProfile 语义或破坏跨平台 ABI,**停在该问题**,记录接口阻塞和建议,不自行加入 Adapter/Normalizer、隐藏通道或不兼容 fallback。不得为了凑齐总表自动进行大架构重构。
|
||||
|
||||
### 阶段 0:基线与定点反证
|
||||
|
||||
1. 确认 branch/HEAD/origin、dirty/untracked、submodule、manifest、V13 tag;对照三轮行号回读实际源码,建立 \`问题→当前源码→最短复现→反例→修复文件→目标回归\` 表。
|
||||
2. 确认 GL/Metal/RN/Test Host 的实际入口和平台条件,核对是否已有后续修改解决某项;有明确反证者记 \`NOT_REPRODUCIBLE_ON_CURRENT_HEAD\` 并附定位,不重复修复。
|
||||
3. 固定公开语义:\`fieldId/generation/validTime\`、U 东向/V 北向、T0/T1/MIX 与 OLD_T1→NEW_T0 reuse、Style Z-order、每个 R 独立 cache、颜色与粒子分离、天气获取由 Host 所有。必要的内部对象身份可以新增,禁止创造第二套公共场协议。
|
||||
4. 在 \`docs/30_设计/STEP-097_V13三轮问题去重与修复矩阵_v1.md\` 先写入逐项状态和安全不变量;后续随源码实现持续更新。这不是重新撰写第四轮审查。
|
||||
|
||||
### 阶段 A1:Renderer 正确性(01/02/03/19)
|
||||
|
||||
- **01 stencil**:明确记录属于当前 render target/pass,切换附件时重置/分代 CPU mask/ID 记录;GPU clear 与 CPU 映射同世代。保留同一 target 中安全的 tile mask 复用,不能中途全局清掉仍需使用的 stencil。针对相同 tiles 的 R-R、R-C-R、C-R-R、首次 build/rebuild/reuse/cache OFF 加最小可执行回归入口。
|
||||
- **02 Metal**:从 gfx RenderPass descriptor 到 MTL descriptor 完整传递 color/depth/stencil 的 load/clear/store;正确处理 combined depth-stencil 和 device/simulator 附件存在性,创建失败显式不发布可用缓存。不能只依赖默认 loadAction 或 color isRenderable。补 descriptor/附件状态与 fallback 可观察测试入口;不宣称 iOS runtime PASS。
|
||||
- **03 错误缓存**:使 layer-group 绘制失败结果贯穿 opaque/translucent、observer、finishBuild;部分绘制不得发布为 valid,不得在下一帧 reuse。正常 fallback/retry 能恢复;保留已有资源准备失败回退,不吞异常或改成进程崩溃。
|
||||
- **19 计数归属**:cache 创建/析构使用稳定 identity + topology generation,旧资源 release 不记入同 index 的新段;聚合统计与当前 topology 统计分离。连续模式切换、R→C、相同 index 换边界均有验证入口。诊断错误不夸大为纹理本体泄漏。
|
||||
- 本阶段有任何 stencil/Metal/异常正确性未闭合时,**不得开始资源复用/异步 GPU 性能改造**。
|
||||
|
||||
### 阶段 A2:Field/粒子正确性(04/05/06/07)
|
||||
|
||||
- **04 PLAY**:只允许一个 map/source owner 推进 forecast clock,基于单调时间处理 PLAY/PAUSE、速度、恢复前后台、clear/destroy;平台 timer 仅调度/唤醒,不允许 WeatherColor 与 Particle 各推进一次。只 setTime 一次后 PLAY 自动移动 time/mix;保持 Host 显式 setTime 路径语义。
|
||||
- **05 B13**:在两个端点的 GPU 更新门槛覆盖 U、V、validity、grid、encoding/解释语义及来源版本;generation、fieldID、dataVersion 不能代替完整内容身份。只变 mix 不应上传场,真正跨窗时旧 T1→新 T0 安全复用,只上传需要的新端点,不能每 tick 重建;无效/旧 revision 不可污染有效窗口。
|
||||
- **06 B07**:先确认当前 GL/Metal 纹理格式、GPU 精度与 CPU/shader 编解码约束;以零、微风、正负抵消及 NaN/validity fixture 定量约束误差。选择可准确表达零的**内部**表示或明确等效方案,GL/Metal 统一;如果必须改变公共 encoding、需要不支持的图形格式或改变已发布输入 ABI,则不强行实施,记录 \`BLOCKED_FORMAT_DECISION\`。
|
||||
- **07 B08**:按 eastward U / northward V m/s 推导 Web Mercator 度量,对 U/V 一致应用纬度修正、符号、极区夹紧和既有 visual time scale。建立 0°/45°/60°、东/西/南/北及极区有限值的解析对照;不得更改 Host 输入向量单位。
|
||||
|
||||
### 阶段 B:输入与平台生命周期(08/09/10/20)
|
||||
|
||||
- **08 N05**:JSON strategy/startLayerId 必须使用长度感知字符串;拒绝内嵌 NUL、重复键、未知 schema/strategy、缺失/逆序边界。无效配置 fail-closed、旧计划清除与恢复语义保持,Android/iOS/RN 错误归一化不分叉。
|
||||
- **09 N06**:在已解码 frame 真正替换 Store 前,按既有 profile/validity/no-data 语义验证有效 cell 的有限 U/V 和 scale/offset 运算不溢出;事务式提交,失败返回明确错误并保留好旧帧、投影及 GPU 显示。不把合法 validity=0 或规范允许的 noData 当成错误;不同时间/高 revision 的合法行为不改变。
|
||||
- **10 N07**:同 View 重复 attach/detach 幂等;map listener 有明确 remove/dispose owner 和 map/destroy 世代。测试入口覆盖 100 次复用、切 view、销毁中的异步回调,不产生悬挂访问或多重 dispose。
|
||||
- **20 E01**:核实真实发布坐标、Host \`package.json\` 和 lockfile、plugin 注入的 Native 版本;将**默认** Test Host 消费组合对齐经核对的 \`.13\` 精确配对,不将临时 node_modules/本地软链当作成功。若需要 install/codegen/Gradle,则准备 RDC/用户命令并标 \`NOT RUN\`;不发布、不覆盖现有 \`.13\` 产物、不改 NavSea。
|
||||
|
||||
### 阶段 C:有边界的性能与资源(11–18)
|
||||
|
||||
严格先做只读热点/资源依赖记录,再实施不会改变正确性和公共契约的优化,优先把同一阶段兼容变更集中,避免每个小点都要求一次 Android APK。
|
||||
|
||||
1. **11 轻量 Diagnostics**:内部 fast/render 热路径只取同一 generation 的轻量一致状态;完整 Style/Segments 深复制仅在外部 pull 时构造。避免用若干无同步原子值组成不一致快照;低频 pull schema 兼容。
|
||||
2. **16 ordinal/扫描**:预计算 global ordinal 和粒子/待更新 group 列表,topology/style reorder 后失效重建;保持 opaque reverse、translucent forward、隐藏层及全局 Z-order,不能用局部 ordinal 替代全局编号。
|
||||
3. **17 物化与 UI**:相同 requestedTime 和相同不可变端点早退;mix-only 仅更新 mix,复用完整内容 identity(U/V/validity/grid/encoding),与 B13 修复共用身份。双 binding 共享安全的不可变端点,不能跨 generation 复用旧数据。Android/iOS 解码和 CRC 若转 worker,必须保存 map/source 世代、owner-thread 事务发布、有限队列、取消和 destroy race;若涉及跨平台公共异步返回语义或不能证明生命周期,先完成同步路径早退,异步部分标 \`DEFERRED_DESIGN\`。
|
||||
4. **13 retained allocation**:仅在 A1 的 target clear/错误语义已经正确后,分离内容 dirty 与资源 key invalid;同尺寸、同 gfx context/format 可清除重绘;resize/context loss/关闭明确释放。相邻 R-R 仍是独立 cache。
|
||||
5. **14/15 预算**:显式估算 retained color+depth/stencil+pending 与 fieldStore key/byte 上界,处理整数溢出和在途旧快照。无法分配必须走原设计的安全 fallback 或拒绝;不得静默丢弃仍绑定窗口。若新增拒绝状态无法用现有 public error contract 表达,保留安全上界/诊断并提交接口阻塞,禁止私改 RN/Native 双方错误语义。
|
||||
6. **18 Drawable**:仅在能证明版本/target/UBO 生命周期正确时保留可复用 drawable/tweaker、减少 field endpoint 深复制;区分 tick、reseed、resize、context loss 与窗口轮换。未能证明不产生 stale resources 时不做大重构。
|
||||
7. **12 Metal wait**:仅盘点 retained build、State/Trail 等实际同步点、命令和资源依赖,准备 Metal capture/性能基准。未经设备/renderer 验证**不得直接删 \`waitUntilCompleted\`、改成无法证明安全的异步 present**。可在现有顺序中去除明确重复且不改变依赖的等待,但须提供静态资源所有权证据;否则标 \`DEFERRED_PROFILE_AND_RUNTIME\`。
|
||||
|
||||
## 3. 本任务明确不进行的架构/协调事项
|
||||
|
||||
- **F06 multi-C**:保留既有安全 full CPU fallback 和 GPU retained reuse,不为达到指标改变 Style 顺序或暗中合并 C/R;新的可组合 multi-C fast path 单独设计、后续 A/B 验证。
|
||||
- **F08 精细失效**:保留 source/tile/glyph/image/placement 的保守全局 invalidation,直到存在完整依赖与变更序列回归;不因性能冲动将其裁窄。
|
||||
- **B09 Ocean Mask**:现有 synthetic fixture 不是正式共享地理 Mask。本任务只形成 Host→Shared Core→两层消费及跨平台一致性需求、最小数据边界和阻塞报告,交粒子负责人按 Integration C-001/RFC/ADR 决定;**不借任务顺便建立新的公开 mask API、导入 provider 或让 MapLibre 理解 NavSea 业务**。
|
||||
- **F10/E02**:只输出“需 Integration 更新 Compatibility/Status”的事实与建议,并提供当前软件版本与真正验证状态;不修改 Integration 文档或宣称 NavSea 已支持。
|
||||
- 不扩大为 renderer 全架构重写、QBIN 格式版本升级、RN 第二套桥、全量新主题、NavSea业务变动、新软件版本发布或复原旧三明治设计。
|
||||
|
||||
## 4. 验证准备、执行责任与验收矩阵
|
||||
|
||||
Codex 负责按实际代码添加**现有框架下必要的定向 C++/平台测试源码或最小 fixture**、静态核对、命令和期望结果;仅有调用说明但没有针对关键回归的测试入口,不能把相应问题标代码完成。可按现有项目测试结构写回归,但本任务**不包含 Jest,也不运行 Jest**。不修改旧断言来掩盖真实失败,不删除测试、不降低测试门槛。
|
||||
|
||||
| 验证集合 | 必备情形/最低证据 |
|
||||
| --- | --- |
|
||||
| Renderer A1 | 同 source/same tiles R-R/R-C-R、主/离屏 stencil;Metal clear/load/store、combined attachment;异常后禁止 reuse;R→C/拓扑更换计数 |
|
||||
| Field A2 | 一次 setTime 后 PLAY/PAUSE/rate;T0/T1 boundary reuse;同 identity 仅 V 或 validity 变化;零/微速量化、0°/45°/60° Mercator |
|
||||
| 输入 B | NUL/重复键/invalid→valid;好旧场→坏高 revision 且旧场保留;重复 attach/销毁;Host 默认版本与 lockfile |
|
||||
| CPU C | pull-only diagnostics、reorder/ordinal、相同时间/仅 mix、窗口换端点、UI owner 世代安全 |
|
||||
| 资源 C | mutation vs resize vs context loss、allocation fail、R×viewport×fieldKey 阶梯、清理恢复、GL/Metal resource ownership |
|
||||
| 集中运行态(后续) | Android OpenGL + iOS Metal 各自像素/数值/时间/资源复现;30/60 FPS、p50/p95/p99、峰值/长稳、方向/缩放、状态恢复;按平台独立记录 |
|
||||
|
||||
**现在不执行** CMake、Xcode、Gradle、Codegen、Test Host install、APK/AAR、ADB、安装、真实设备、GPU capture、profiler、NavSea 集成或正式 V13 运行确认。Codex 结束时给出可复制的 RDC 验证命令(以本仓现有 runner/build 入口为准);Android Win11 手工 Gradle/ADB 和 iOS 设备验证依后续授权,不在本任务自动触发。不得把 STEP-094 历史 43/43、旧报告 69/69 或任何已发布 manifest PASS 写成本任务结果。
|
||||
|
||||
RDC 在每个代码批次之后独立审查文件/静态 diff;未来获授权再集中编译/运行,而不是在本轮分阶段频繁请求重装 APK。未来完整 Android 编译应遵守 \`tools/particle_android_validation/build_validation_apk.sh\` 当前权威流水线与用户手工运行安排。Metal 修改必须留给 Mac 同 commit 验证,Android 结果不得替 iOS PASS。
|
||||
|
||||
## 5. 允许修改与明确禁止
|
||||
|
||||
允许(仅与已复核问题直接相关,实际存在的路径以源码核对为准):
|
||||
- \`src/mbgl/renderer/\`、\`src/mbgl/gl/\`、\`src/mbgl/mtl/\`、\`include/mbgl/\`、所需 gfx backend;
|
||||
- \`src/mbgl/particle/\`、\`src/mbgl/style/sources/raster_array_source.cpp\`、\`src/mbgl/renderer/layers/\`、对应 GL/Metal shader及其标准生成源;
|
||||
- Android Java/Kotlin/JNI、iOS ObjC++、RN 公共实现及 Test Host 本任务限域依赖文件;
|
||||
- 对应定向测试源码/fixture、下述交付文档和开发记录。
|
||||
涉及 shader generator 必须改其权威源而非只手改自动生成产物,并附原生成/校验命令由 RDC 后续执行。
|
||||
|
||||
禁止:修改 Integration、NavSea、项目总则、旧三份调查/任务/报告、已发布 manifest/tag/tgz/AAR/XCFramework、无关 package/lock、官方上游基线;禁止 \`git reset --hard\`、\`git clean\`、force push、push upstream;禁止把公开 API/FieldProfile/QBIN breaking 变更悄悄塞进修复。不能自行把 V13 版本重命名为下一发布版,下一版本号属于独立发布任务。
|
||||
|
||||
## 6. 必做输出与报告路径
|
||||
|
||||
执行时必须建立、更新且全部中文:
|
||||
1. \`docs/30_设计/STEP-097_V13三轮问题去重与修复矩阵_v1.md\`:保留表中全部 24 行、旧编号、实际源码定位、修复/不修理由、源码状态、测试入口、commit、平台影响、运行待测项。分阶段附可量化的变更前/后操作次数模型,不虚构 FPS/内存收益。
|
||||
2. \`docs/50_Step记录/STEP-097_V13三轮审查问题合并修复_v1.md\`:阶段 0/A1/A2/B/C/D 检查点、状态、实际改动、阻塞、下一步。每一阶段结束后追加短而具体的事实,未完成不得勾选。
|
||||
3. \`docs/60_测试/STEP-097_V13修复后集中验证清单_v1.md\`:按 Android GL、iOS Metal、通用 Core/测试入口、后续 GPU 性能分层记录**尚未执行**的精确命令、fixtures、预期输出和复核责任。
|
||||
4. \`docs/报告/STEP-097_V13三轮审查问题合并修复_Codex完成报告_v1.md\`:按规定详列开始/结束 HEAD、每批提交、文件清单、各问题状态、跨项目阻塞、静态检查实际命令和结果、所有构建/运行 \`NOT RUN\`、软件发布 \`NOT RUN\`、下一步集中 RDC 验证。
|
||||
5. 在根目录 \`粒子开发记录.md\` **仅追加**实际进展;不得覆盖历史。
|
||||
6. 若实际触发跨 Contract 阻塞,额外写 \`docs/报告/STEP-097_公共接口阻塞报告_v1.md\`,明确现有 C-001/RFC-001、拟议语义、为什么无法安全局部修、Android/iOS/NavSea 各自责任;本地只记录并提升级建议,不假装协调决定已被接受。
|
||||
|
||||
完成状态只能细分为 \`CODE_IMPLEMENTED_STATIC_CHECKED\`、\`DEFERRED_DESIGN\`、\`BLOCKED_CONTRACT\`、\`NOT_REPRODUCIBLE_WITH_EVIDENCE\`、\`WAITING_RDC_BUILD_AND_RUNTIME\`;没有执行的验证永远写 \`NOT RUN\`,产品级 \`PASS\` 禁用。
|
||||
|
||||
## 7. Git 收尾与停止条件
|
||||
|
||||
在当前 \`particle/main\` 上执行,先保护所有已有 dirty/untracked;只 stage 本任务变更。按 A1、A2、B、C 各自边界形成 scoped commit,文档随阶段更新;阶段失败不能越过到下一阶段,不可混入不相关工作。每个成功阶段允许 push \`origin particle/main\` 供 RDC 直接核对,失败必须确认进程/状态并修复,不能以 timeout 当作已失败后盲目重复 push。最终 \`git diff --check\`、提交内容、远端 HEAD、clean status 明确记录。push 失败不得宣称交付完成;提交并不代表运行验收。
|
||||
|
||||
触发以下任一条件则停止相应实现并生成阻塞事实:需要新增/改变公共契约而无 Integration 决定;必须升级工具链/MapLibre;不能证明跨 GL/Metal 正确或资源所有权;修复需要删除已有功能/测试或强制绕过安全 fallback;当前 HEAD 与所需源码不符且不能安全合并;既有用户改动会被覆盖;任一关键问题没有明确退出条件。必要时整任务停在已完成的 scoped checkpoint,报告 PARTIAL,不靠继续扩大代码量冒充完成。
|
||||
|
||||
交付后由 RDC 独立审查并按后续授权集中执行构建、回归和设备验收。**本任务不发布下一版软件,不提前关闭 V13 GPU 运行态。**
|
||||
141
docs/40_任务/STEP-098_QBIN_V4单帧首显与八帧滚动缓存_Codex任务_v1.md
Normal file
141
docs/40_任务/STEP-098_QBIN_V4单帧首显与八帧滚动缓存_Codex任务_v1.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# STEP-098:QBIN V4 单帧首显与按 fieldKey 独立的八帧滚动缓存 — Codex 任务 v1
|
||||
|
||||
状态:**任务书 / 待契约闸门通过后执行**。本任务书不代表代码已经修改、编译或双平台运行验收通过。
|
||||
|
||||
## 0. 目标与执行环境
|
||||
|
||||
本任务落实已讨论的目标模型:**单帧可独立显示;第二帧到达后支持正常时间插值;后续时间片在 Native 内部进入每个 fieldKey 独立的、按 validTime 升序排序的固定 8 帧滚动缓存。** 满 8 帧提交新的合法时间片时应自动淘汰,不应因正常满额返回 `REJECTED_CAPACITY`。
|
||||
|
||||
当前用户维护和修改的源码以 **Mac** 为准:`/Users/tei/dev/MapLibreParticleLab`,分支 `particle/main`。编写本任务书时 Mac HEAD / origin HEAD 均为 `0d13552bed84f427dd43cae9856391bd26622179`。执行前重新查询 Git 事实,不以该 SHA 或本文行号覆盖后续提交;不要拿 Linux 旧工作树代替 Mac 代码。任务 MD 的目标归档位置为 `docs/40_任务/STEP-098_QBIN_V4单帧首显与八帧滚动缓存_Codex任务_v1.md`;不要创建 `docs/任务/`。
|
||||
|
||||
本阶段以 **Shared Core 公共语义和现有 RN V4 公共接口**为实施目标,不在 NavSea/Weather Server 中实施下载策略;Android 与 iOS 使用同一共享语义,平台专项编译/实体机验收分别另行完成。不得因 Mac 为编辑机而建立 iOS 专属 Core 行为。
|
||||
|
||||
### 固定边界
|
||||
|
||||
- RN:负责获取预报目录、QBIN 文件、本地下载缓存、用户选择的预报时间、异步命令 latest-wins 和 UI。RN 已提供 `FieldRuntime.submitEncodedField(...)`、`FieldRuntime.setEncodedForecastTime(...)`,**先 await 前者成功,再 await 后者**;无需新增组合提交 API。
|
||||
- Shared Core/Native:负责 QBIN 校验、存储、每 fieldKey 内排序/淘汰/复用、单帧/双帧解析、颜色与粒子投影、GPU 资源正确性。
|
||||
- 不增加 Native→RN 索取数据回调;Native 不接入 provider、HTTP、manifest、下载、缓存文件管理或 NavSea 业务语义。
|
||||
- 不修改 QBIN 文件格式、Rice 解码语义、现有公开方法签名、Style Z-order 或 V3 路径,不在 JS 伪造第二帧,也不在 Host 手动清空 8 帧来实现正常拖动。
|
||||
|
||||
## 1. 首要闸门:Integration 公共契约
|
||||
|
||||
1. 先经 RDC 检查并同步 `/Users/tei/dev/navsea-particle-integration` 的最新 `origin/main`(`git fetch origin main` + 确认可 fast-forward;尊重现有本地改动)。读取该仓库 `README.md`、`WORKFLOW.md`、`coordination/TEAM_MODEL.md`、`contracts/`、`rfc/`、`adr/`、`status/`、`compatibility/`、`coordination/active/COORD-004/` 和 `instructions/PARTICLE_PROJECT_INSTRUCTIONS.md`。
|
||||
2. 编写本任务书时 Integration HEAD 为 `318f8ccf911ac3136c3086a1d14e61f83e2d4bce`;`RFC-003_编码场两帧首显与增量补帧语义.md` 仍处于 DRAFT,其第一条要求至少两帧、满额返回容量拒绝,与本任务新目标**明确冲突**。本任务书不是已经接受的跨平台 RFC。
|
||||
3. **开始改公共源码前,必须由粒子负责人/Integration 按既定流程正式更新 RFC-003、COORD/Contract 或 ADR,接受下述单帧和滚动淘汰语义,明确 Android/iOS 共用。** Codex 不得自行把 DRAFT 当 ACCEPTED,也不得静默更改 Integration 文档替代负责人决定。
|
||||
4. 如果执行时仍没有已接受且不冲突的正式依据:先在 `docs/报告/STEP-098_公共契约阻塞报告_v1.md` 写出当前 SHA、冲突条目、拟实施语义与所需协调决策,**停止功能修改及 push**,状态记为 `BLOCKED_CONTRACT`,交回粒子负责人。不得绕过闸门做 Android/iOS 两套实现。
|
||||
5. 若 Integration 已更新且批准,记录精确文档路径、版本与 commit SHA,后续实现以正式版本为准;如正式结论与本文不同,应停止并回报,不自行择一。
|
||||
|
||||
## 2. 开始前必须核对的 Mac 实际基线
|
||||
|
||||
先读根项目规范、`PARTICLE_BASELINE.md`(如存在)、`docs/00_项目规范/`、`docs/00_项目总则/README.md` 指定总则、与 STEP-097 的正在实施范围。读取并建立文件/函数对照表:
|
||||
|
||||
- `include/mbgl/particle/field/field_runtime.hpp`、`src/mbgl/particle/field/field_runtime.cpp`:`FieldSeries`、`EncodedFieldStore`、`resolve`、容量及 revision/identity。
|
||||
- `src/mbgl/particle/field/field_binding.cpp`、`src/mbgl/particle/field/field_projection_materialization.cpp`:单/双帧投影、独立绑定和物化。
|
||||
- `src/mbgl/style/sources/raster_array_source.cpp` 及相关头文件:`submitEncodedField`、`setRequestedForecastTime`、`refreshV4RendererState`、现有 projection equality/notification。
|
||||
- `src/mbgl/renderer/layers/render_weather_color_layer.cpp`、`render_particle_validation_layer.cpp` 及 shader/texture 资源:单帧/双帧下颜色、粒子、轨迹和 GPU 复用。
|
||||
- `packages/maplibre-particle-rn/src/FieldRuntime.ts`、`NativeWeatherRuntimeBridge.ts`、Android Kotlin bridge/JNI、iOS `WeatherRuntimeBridge.mm`/`MLNParticleFieldRuntime.mm`:确认两个现有公开调用完整传递结果。
|
||||
- `test/particle/field_runtime.test.cpp`、`test/particle/field_binding.test.cpp`、`test/source/raster_array_v4_host_api.test.cpp` 及现有 Renderer 定向验证入口。
|
||||
|
||||
编写任务书时源码事实:`FieldSeries::submit` 对第 9 个不同时间直接 `RejectedCapacity`;`resolve` 对 `frames.size()<2` 返回空;`submitEncodedField` 已会刷新投影但不修改 forecast time。以上仅供定位,若新 HEAD 有变化应以实际代码为准。若 STEP-097 仍在改相同的 runtime/projection/Renderer 文件,先确认依赖顺序,不得并行覆盖或回滚已完成的修复;尤其保留 STEP-097 的输入校验、forecast clock、GPU 身份、资源生命周期等新修正。
|
||||
|
||||
## 3. 正式目标语义
|
||||
|
||||
### 3.1 缓存所有权、容量与排序
|
||||
|
||||
- `EncodedFieldStore` 按 `fieldKey` 分别持有 `FieldSeries`。`wind`、`wave`、`rain`、`tide` 使用不同 key 时分别最多 8 帧;同 key 的多个 Layer/Binding 共享该序列。不能把四类天气合为“全局 8 帧”。
|
||||
- 每帧按 `frameContentIdentity.validTimeMs` **升序**保存,提交顺序不影响排序;不得假设固定一小时/三小时间隔。
|
||||
- 已有相同 `validTime`:先走现有 Duplicate、identity conflict、stale、合法 revision 替换语义;不额外占一个槽,不因为满额淘汰别的帧。
|
||||
- 不同时间且不足 8 帧:先完整校验,按时间有序插入。
|
||||
- 不同时间且已满 8 帧:在成功通过解码、profile、grid/plane、身份和相邻兼容性校验后,选择淘汰一帧并原子提交新有序集合。正常满额替换成功返回现有 `ACCEPTED_INSERTED`(或正式合同要求的**既有**成功语义),不返回 `REJECTED_CAPACITY`。为了 TypeScript/ABI 向后兼容可以保留旧结果枚举,但正常容量=8的有效插入路径不再产生它;不可偷偷更名公共结果。
|
||||
- 淘汰只作用于正在提交的 `fieldKey`,不影响其他天气种类、Bindings、requestedForecastTime、V3 数据或 Style。
|
||||
|
||||
### 3.2 双向淘汰,按新提交帧时间取中心
|
||||
|
||||
由于既定调用顺序是先 `submitEncodedField()`、后 `setEncodedForecastTime()`,**提交阶段不能依赖尚未下发的新目标时间**。本版使用“新提交帧 validTime 为中心,淘汰时间距离最远的端点”的确定性规则;新帧本身必须留下。对于已升序的满额序列,只在最早端或最晚端候选之间选择;若距离相同,按正式合同规定稳定决胜,允许优先避免淘汰当前显示端点,但不可牺牲新提交帧。不得永远只删除最旧帧。
|
||||
|
||||
必须覆盖:
|
||||
|
||||
- 原有示意 `13:00 ... 21:00` 共 8 帧;提交 `22:00` → 删除最早端 `13:00`,插入 `22:00`,最终仍 8 帧。
|
||||
- 已向后滚动后提交 `12:00` → 删除最远的最晚端,重新保留 `12:00`;向过去拖动同样成立。
|
||||
- 已满时提交位于内部的新时刻 → 仍保持有序、8 帧和确定的端点淘汰。
|
||||
- 今天跳到后天某一时刻 → 接收该时刻 QBIN,而不是要求 RN 先清空旧窗口或填齐 8 帧。之后逐帧提交,Native 自行滚动。
|
||||
- 乱序提交、Duplicate、同时间新 revision 不应造成意外淘汰。
|
||||
- 插入不兼容数据或解码失败时,**零淘汰、零 Store/Projection/Clock 修改**;不得先删除旧帧再验证。
|
||||
|
||||
### 3.3 单帧首显与双帧升级
|
||||
|
||||
- 当请求时间精确对应某个已验证 `validTime`,即使整个 Store 只有一帧,或它与其余 7 帧相隔很远无法形成合理双帧窗口,也应能够显示该帧:颜色为这一帧的值;有有效 U/V(或规范允许的方向向量)时粒子可持续运动,**天气时间不变不等于粒子停止**;仅标量帧不能伪装成可平流向量。
|
||||
- 单帧在运行时具有真实单端点语义。可在内部使用同一 Snapshot 作为 T0/T1、`mix=0` 来复用现有双纹理 shader,但不得向 RN 要求伪造第二个 QBIN 或捏造第二个不同 validTime;优先共享解码结果、物化 Snapshot 和 GPU 纹理,避免同一单帧无意义地双份常驻。
|
||||
- 第二帧补入后,如果目标时间被合法的相邻端点覆盖,则自动升级为双帧插值,保持既有 `T0/T1/MIX`,端点、mix 与实际预报时间对应;如果并未覆盖,保持合法单帧或 fail-closed,不能强行把不相关的旧帧插值进去。
|
||||
- 目标时间落在两帧之间且有合法覆盖时执行正常时间插值;目标时间既不精确匹配可用单帧、也没有合法双帧覆盖时返回明确 unavailable,不使用“最近旧帧”冒充该时刻。RN 若选择最近预报帧首显,必须以该帧实际 `validTime` 作为已显示时刻;用户日历选中时间与实际显示时间不可混称。例如用户初始选择 13:30,只有最近的 12:00 QBIN 时,RN 可先提交该帧并调用现有 `setEncodedForecastTime(12:00)` 显示 12:00 静态预报,仍将 13:30 保留为业务层待完成目标;等 15:00 帧到达后再设置 `setEncodedForecastTime(13:30)` 进入插值。不得在 Native 悄悄修改 `requestedForecastTime`,也不得将临时 12:00 画面标成 13:30 的插值天气。
|
||||
- 不能把跨 dataset/reference/Profile 的帧混合成一个时间序列;沿用已有权威身份契约。不凭固定时间间隔猜测有效帧,也不能用任意远离的旧时间片推断新的天气。若当前元数据不足以明确区分“同一批次的合法双端点”与“跨批次伪兼容”,作为契约阻塞项报告,不能自行新造隐含协议。
|
||||
- 明确 `fieldKey` 之间可有不同 validTime 覆盖。颜色与粒子在同一全局请求时刻分别 resolve,各自可处于单帧、双帧或 unavailable;不得因一个 fieldKey 无数据清空其他 key 的合法投影。
|
||||
|
||||
### 3.4 两个现有 RN API 的行为不变
|
||||
|
||||
正常时间轴操作为:
|
||||
|
||||
1. RN 从本地缓存或服务器取得对应 QBIN,先 `await FieldRuntime.submitEncodedField(...)`。
|
||||
2. 仅在 `ACCEPTED_INSERTED`、`ACCEPTED_REPLACED_REVISION` 或可确认的 `DUPLICATE` 等成功结果后,`await FieldRuntime.setEncodedForecastTime(reactTag, targetTimeMs)`。
|
||||
3. Native 的 submit **不擅自修改目标时间**,setTime 不触发网络下载。已缓存时间直接 setTime 即可;无需每次重新 submit。
|
||||
4. 两调用非原子,可能在两次调用之间短暂显示旧时间、单帧或暂时不可用,**不可对外保证无闪烁**。不得把旧时刻天气伪标为新目标。RN 侧 latest-wins、目标版本和展示状态属于后续 Host 接入范围;本任务不私改 NavSea。
|
||||
5. 不新增 `submitAndSetTime`、Native→RN 数据请求事件、逐帧删除 RN API 或新的 provider 参数;保留现有 `clearEncodedField()` / `clearAllEncodedFields()` 作为显式重置能力,而不是正常滚动手段。
|
||||
|
||||
### 3.5 Renderer 与资源安全
|
||||
|
||||
- 正常向前/向后补帧且当前已选 pair 和 mix 未变化时,避免无条件 rebuild、重复 GPU 上传、清空 trail 或发布无意义 Source revision;复用 existing `sameProjection`/GPU content identity。
|
||||
- 单帧→双帧、双帧窗口变化和 revision 更新必须正确刷新,shader 无非法 T1/null;若相同 Snapshot 对应 T0/T1,避免重复上传同一内容。支持 GL/Metal 共享语义,不能只修 Android Renderer。
|
||||
- 淘汰旧帧不能销毁仍被当前 projection/GPU 更新流程持有的不可变 Snapshot;通过正常引用计数和资源所有权安全释放。切换不同窗口时遵守现有 trail/particle reset 规则,不错误承诺跨任意远跳跃保留轨迹。
|
||||
- 坏帧不允许覆盖已验证的好投影;生命周期关闭、clear、style reload、map 销毁与异步提交有明确所有权,不使旧请求重新点亮已 OFF 的画面。
|
||||
|
||||
### 3.6 内存边界
|
||||
|
||||
- 8 帧是**每 fieldKey 的数量上限**,不是无限制内存保证。每个 decoded frame 由原始 Plane 字节、validity bitset 和元数据构成;参与显示的端点另有 Float32 物化数组、图像、纹理和粒子/trail 资源。不得错误地用压缩 QBIN 大小表示运行内存。
|
||||
- 不在本任务未经批准添加任意固定全局 MiB 上限或第二套容量公开错误码。为风/浪/雨/潮各 8 帧、单端点/双端点和跳跃替换提供 CPU/GPU 常驻及峰值测量入口或现有计数;记录可计算的 decoded byte 占用、资源复用/释放及最坏边界风险。
|
||||
- 评估单帧 T0=T1 情况下重复物化/重复上传;保证淘汰与资源 release 后无持续增长。若测量显示 32 帧和显示资源会触及移动端内存风险,报告下一步“全局字节预算/多 fieldKey 优先级”设计建议,**不可把内存申请失败伪装成正常 REJECTED_CAPACITY**。
|
||||
|
||||
## 4. 实施顺序与测试矩阵
|
||||
|
||||
阶段 A:只读复核与契约闸门 → 阶段 B:Core Store 滚动淘汰及单帧 resolver → 阶段 C:Binding、物化、Renderer 单/双帧和资源复用 → 阶段 D:已有 RN Bridge 端到端语义检查 → 阶段 E:文件、报告、Git 收尾。前一阶段未明确通过不进入后一阶段;命令 timeout/进程未知不能算通过。发生公共 ABI、QBIN、profile、dataset 身份或无法证实跨平台一致性的阻塞时停止扩大范围。
|
||||
|
||||
至少具备以下定向验证;优先扩展既有 C++ 源级测试和可复用 Test Host 场景,不新建无关测试框架:
|
||||
|
||||
| 编号 | 场景 | 必须得到的结果 |
|
||||
|---|---|---|
|
||||
| T01 | 只有一帧,target=validTime | 投影合法;色场可显示;有 U/V 时粒子可动;实际时刻正确 |
|
||||
| T02 | 首帧后补入第二帧,target 在两者中间 | 单帧→双帧,MIX 正确;不用伪造第二帧 |
|
||||
| T03 | 8 帧未满乱序提交 | 按 validTime 升序;各 key 相互隔离 |
|
||||
| T04 | 满 8 帧,向未来提交新帧 | 淘汰最早端、保留新帧,计数仍 8,无正常容量拒绝 |
|
||||
| T05 | 满 8 帧,向过去提交新帧 | 淘汰最晚端、保留新帧,计数仍 8 |
|
||||
| T06 | 满 8 帧,提交中间时刻 | 确定性端点淘汰;排序/唯一性不变 |
|
||||
| T07 | 今天→后天单帧→后续补帧→返回今天 | 新时刻单帧可用,后续升级双帧;旧数据需 RN 重交时可正常滚动,不越界、不混批 |
|
||||
| T08 | Duplicate、同时间合法新 revision、stale、identity conflict | 保留现有判定;重复/替换不淘汰其他时刻 |
|
||||
| T09 | 错 QBIN、Profile/Grid/Plane 不兼容、无效向量 | 拒绝且 Store、forecast clock、原投影不被破坏 |
|
||||
| T10 | 目标时间位于已缓存相邻两帧之间 | 正常插值,mix 首/中/末精确 |
|
||||
| T11 | 目标不被合法帧覆盖也不精确匹配 | unavailable,不把最近帧冒充目标时间 |
|
||||
| T12 | 新帧在当前 pair 外围、当前投影不变 | requestedTime、当前 pair/mix 保持;避免无意义资源重建 |
|
||||
| T13 | 新帧改变当前 bracket,或当前端点被淘汰 | 正确更新;不沿用失效旧 GPU 数据、错误轨迹 |
|
||||
| T14 | `wind` 满额后提交 `wave`;同 key Color+Particle | 独立 8 帧;其他 key 不受影响;同 key 不复制 Store |
|
||||
| T15 | 单/双端点 Materialization/GL/Metal 资源 | 单帧无需两份独立 QBIN/CPU/GPU 内容;复用、release 与上下文丢失恢复正确 |
|
||||
| T16 | 连续 100+ 次双向滚动、反复 clear、切 Runtime | 帧上限不破、无持续内存增长和悬挂引用 |
|
||||
| T17 | RN 两步调用成功与失败分支 | 既有 API/TypeScript/Android/iOS bridge 类型兼容,失败不继续 setTime;不新增公开 API |
|
||||
|
||||
注意:Native 静态/定向测试只能证明对应源码路径,不等于手机 GPU 首帧或 NavSea UI 通过。对尚未执行的 Android/iOS 真机、滚动拖动、跨天回退、内存峰值必须标 `NOT RUN / WAITING_USER_VALIDATION`。
|
||||
|
||||
## 5. 修改范围与明确禁止项
|
||||
|
||||
允许根据当前真实源码在上述 Shared Core/Source/Renderer 及对应现有测试文件做必要的最小修改;仅在证明是既有 API 传递障碍时修改 Android/iOS bridge,保持方法签名和结果语义。可在 `docs/30_设计/` 记录淘汰不变量与单帧/双帧选择表,在 `docs/50_Step记录/` 记录实施进度。
|
||||
|
||||
禁止:修改 NavSea、Server、天气 provider、下载缓存、Manifest、日历 UI;重新生成 PBF、修改 Style Z-order、强行更改 QBIN/QBV3 格式;新建第二套 FieldStore/Timeline、额外 JS Normalizer/Wrapper、私有 Native 通道、自动请求 RN 数据、提交单帧伪造第二份不同时间、给四类天气合用 8 帧、让正常满额仍返回容量拒绝。不允许顺带完成 STEP-097 的未授权项,也不允许覆盖现有发布 tag/manifest 或把源码通过称为正式发布通过。
|
||||
|
||||
## 6. 构建、交付与 Git
|
||||
|
||||
- 本次编译、Gradle/Pod/Xcode 构建、APK/IPA 安装、ADB/设备操作及实际 GPU 验收由用户人工执行。Codex 可做源码、`git diff --check`、格式/静态检查及环境许可的低成本 C++ 定向测试;**不得擅自启动完整 Android/iOS 编译或设备操作**,也不得把未运行项目写成 PASS。
|
||||
- 准备一份 Windows 11 可直接执行的 Android 手动验证清单,ADB 命令如需涉及当前虚拟机必须显式 `adb -s 192.168.200.139 ...`;iOS 只列 Mac 用户手工构建/设备验收条件。合并一轮验证 T01–T17,不为单个按钮或日志要求反复重装。
|
||||
- 必做输出:`docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.md`、`docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md`、`docs/报告/STEP-098_QBIN_V4单帧与八帧滚动缓存_Codex完成报告_v1.md`。目录不存在先创建;同主题报告已存在则递增版本,不覆盖旧报告。全部中文。
|
||||
- 报告明确记录:当前 HEAD、获接受的 Integration 协议版本/commit、真实改动列表、API/ABI 是否变化、每项 T01–T17 执行状态、`REJECTED_CAPACITY` 新语义、单帧显示实际范围、CPU/GPU 内存测量与未验证项、下一步 Android/iOS/Host 责任。最多只能报告 `IMPLEMENTED / WAITING_PLATFORM_RUNTIME_VALIDATION`;契约闸门未过则 `BLOCKED_CONTRACT`。
|
||||
- 完成可实施阶段且检查通过后,只提交本次任务相关变更到 **Mac 当前项目 `particle/main`**,并 push 到公开 `origin/particle/main`。提交前检查未跟踪/用户既有文件,不得 `git add -A` 混入无关变更;先核验 `origin` 是否前进,冲突时停下处理而非强推。完成报告必须写最终 commit hash、commit message、push 结果和远端 branch/HEAD;push 失败不能声称完成。若被契约闸门阻塞,不提交或 push 功能代码。
|
||||
|
||||
## 7. 最终验收口径
|
||||
|
||||
用户能在 RN 维持两个现有 API 和顺序:第一帧即显示其真实有效时间;第二帧具备合法覆盖时升级插值;后续任意顺序提交,Native 每 key 自动保持最多 8 帧。向未来提交淘汰最早,向过去提交淘汰最晚;正常已满不会 `REJECTED_CAPACITY`;四类天气互不挤占。无效帧零副作用、时间语义不造假、Core 不掌握下载/日历。Renderer 不因正常补帧无谓清屏或持续泄漏。Android 和 iOS 分别通过用户实际设备验证后,才能由 Integration 更新兼容性及正式状态。
|
||||
690
docs/40_任务/STEP-100_SourceScoped_RenderSegment局部失效_Codex任务_v2.md
Normal file
690
docs/40_任务/STEP-100_SourceScoped_RenderSegment局部失效_Codex任务_v2.md
Normal file
@@ -0,0 +1,690 @@
|
||||
# STEP-100 Source → RenderSegment 局部 Revision / Invalidation / Readiness 与独立 Fallback — Codex 任务 v2
|
||||
|
||||
## 0. 任务性质
|
||||
|
||||
这是 STEP-099 之后的正式修复任务。
|
||||
|
||||
STEP-099 已经完成纯诊断并 CLOSED / PASS,已确认 V17 的核心问题:
|
||||
|
||||
1. 动态 GeoJSON Source/Tile mutation 会推进 global retained content revision;
|
||||
2. 即使 R0 不依赖该 GeoJSON,R0 retained cache 仍跟着 invalid/build;
|
||||
3. GeoJSON 更新期间约 200 ms 的 transient `isLoaded=false` 会通过 global `RenderOrchestrator::isLoaded()` 把整个 retained path 拉成 `style-not-loaded`;
|
||||
4. 当前 renderer 还存在 `useRetainedRanges` all-or-none gate:一个 RETAINED Segment fallback 时,会使其他本来可安全 reuse 的 RETAINED Segment 一起退出 retained path;
|
||||
5. STEP-099 diagnostics 已能正确给 source mutation 计算 `affectedSegmentIndices`,但该依赖关系仍只是诊断,不参与正式 invalidation。
|
||||
|
||||
本任务目标是把 **Source/Tile 变化对 RETAINED Segment 的影响正式局部化**。
|
||||
|
||||
本任务不是 V18 发布任务。Codex 只负责实现与源码级说明;Android/iOS 构建、APK、ADB、设备测试、最终 Git push、V18 release 由 RDC/ChatGPT 在 Codex 完成后独立执行。
|
||||
|
||||
未经用户明确要求,本任务 **不加入、不运行 Jest**。
|
||||
|
||||
---
|
||||
|
||||
## 1. 冻结基线
|
||||
|
||||
工作目录:
|
||||
|
||||
`/Users/tei/dev/MapLibreParticleLab-step100`
|
||||
|
||||
分支:
|
||||
|
||||
`step100-segment-local-source-invalidation`
|
||||
|
||||
开始基线必须重新核对,当前预期:
|
||||
|
||||
- `origin/particle/main`
|
||||
- HEAD:`c4b481fd2c5b5da20d31f6ae54011f0552d7dbd0`
|
||||
- STEP-099 implementation:`8a5214d92dd2f8899db76d2194da42999fa0c87d`
|
||||
- V17 frozen tag:`maplibre-particle/rn/13.4.1-particle.17`
|
||||
- V17 frozen commit:`e8b451fe70054107773e82484c80e90df3889147`
|
||||
|
||||
禁止修改、移动、覆盖 V17 tag / release worktree。
|
||||
|
||||
STEP-100 是 V17 之后的新开发,最终只有 RDC 验收通过后才允许进入 V18 发布。
|
||||
|
||||
开始前必须读取:
|
||||
|
||||
- 当前仓库实际 HEAD / status / diff;
|
||||
- 全局 Codex AGENTS;
|
||||
- `ARCHITECTURE.md`(若存在);
|
||||
- STEP-092 / 094 / 099 的任务、Step 记录、完成报告;
|
||||
- 当前:
|
||||
- `renderer_impl.cpp`
|
||||
- `render_orchestrator.*`
|
||||
- `retained_underlay_cache.*`
|
||||
- `retained_underlay_runtime_state.hpp`
|
||||
- `render_segment.*`
|
||||
- STEP-099 diagnostics 与 Android fixture;
|
||||
- 当前 RenderSegment / retained cache / particle fast path tests。
|
||||
|
||||
不得凭历史印象修改。
|
||||
|
||||
---
|
||||
|
||||
## 2. 最终架构原则
|
||||
|
||||
长期 RenderSegment 模型继续保持通用模型:
|
||||
|
||||
```text
|
||||
Style Z-order
|
||||
↓
|
||||
R / C / R / C / R / ...
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- R = RETAINED
|
||||
- C = CONTINUOUS
|
||||
|
||||
本任务只用 **R-C-R** 做最小验证,不把 R-C-R 固化成最终架构。
|
||||
|
||||
必须保持:
|
||||
|
||||
1. Style layer 顺序是唯一 Z-order 真相;
|
||||
2. Renderer 不理解 AIS / Route / Weather / GeoJSON 等业务名;
|
||||
3. Source → Segment 依赖由当前实际 Style / RenderLayer / Source 关系推导;
|
||||
4. 一个 Source 可依赖多个 Segment;
|
||||
5. source-less layer 不制造假 dependency;
|
||||
6. unknown/global dependency 必须 fail closed;
|
||||
7. 相邻 Segment、多个 C、多个 R 的通用模型不能被破坏;
|
||||
8. 本任务不实现 multi-continuous Fast Path。
|
||||
|
||||
---
|
||||
|
||||
## 3. 本任务必须实现的核心目标
|
||||
|
||||
### 3.1 Source/Tile mutation 局部化
|
||||
|
||||
假设:
|
||||
|
||||
```text
|
||||
R0 depends [staticSource]
|
||||
C depends [particleField]
|
||||
R1 depends [dynamicGeoJson]
|
||||
```
|
||||
|
||||
当:
|
||||
|
||||
```text
|
||||
dynamicGeoJson mutation
|
||||
```
|
||||
|
||||
正式 renderer 必须达到:
|
||||
|
||||
```text
|
||||
R0:
|
||||
content/revision 不因该 source mutation 改变
|
||||
cache 不 invalid
|
||||
cache 不 rebuild
|
||||
持续 reuse
|
||||
|
||||
R1:
|
||||
revision/invalidation 正常变化
|
||||
按需要 build/reuse/fallback
|
||||
|
||||
C:
|
||||
正常 continuous render
|
||||
```
|
||||
|
||||
禁止继续出现:
|
||||
|
||||
```text
|
||||
dynamicGeoJson mutation
|
||||
↓
|
||||
global revision 变化
|
||||
↓
|
||||
R0 + R1 一起 rebuild
|
||||
```
|
||||
|
||||
### 3.2 保留 global revision 兼容信号
|
||||
|
||||
STEP-100 不要求删除现有 global `retainedUnderlayContentRevision`。
|
||||
|
||||
为了保持:
|
||||
|
||||
- diagnostics;
|
||||
- 现有 fast-path correctness;
|
||||
- 旧 API / compatibility;
|
||||
- conservative fallback;
|
||||
|
||||
允许并推荐继续维护 global revision。
|
||||
|
||||
但 **RETAINED Segment cache 的正式内容 revision / invalidation 不能再只依赖这个 global source/tile revision**。
|
||||
|
||||
当前 `retainedUnderlayRevisionTracker` 同时消费 global content revision 与 `renderTreeParameters.loaded`。STEP-100 必须明确拆成两种用途:
|
||||
|
||||
```text
|
||||
global retained revision / tracker
|
||||
-> compatibility / Fast Path / diagnostics
|
||||
|
||||
segment-local retained content state
|
||||
-> full CPU renderer 的每个 RETAINED Segment Build / Reuse / Fallback
|
||||
```
|
||||
|
||||
**Segment-local cache content state 禁止继续直接消费:**
|
||||
|
||||
- global source/tile content revision;
|
||||
- global `renderTreeParameters.loaded`。
|
||||
|
||||
否则即使 source-scoped revision 已实现,R0 仍会被无关 GeoJSON transient unloaded 或 global revision 连带失效。
|
||||
|
||||
允许 global revision / global tracker继续按原逻辑变化;禁止为了让测试 PASS 而停止 global revision 增长或放宽 Fast Path。
|
||||
|
||||
### 3.3 per-RETAINED-Segment readiness
|
||||
|
||||
不得修改任何 Source `isLoaded()` 定义。
|
||||
|
||||
不得修改:
|
||||
|
||||
```cpp
|
||||
renderTreeParameters->loaded = updateParameters->styleLoaded && isLoaded();
|
||||
```
|
||||
|
||||
这个 global loaded 仍作为 MapLibre 现有全局兼容事实。
|
||||
|
||||
但 retained segment 的 cache Build/Reuse/Fallback 必须有自己的安全 readiness 判断。
|
||||
|
||||
最低语义:
|
||||
|
||||
- Style 本身未 ready:fail closed;
|
||||
- image manager / sprite / glyph 等无法安全定位到单 Segment 的全局前置条件未 ready:fail closed;
|
||||
- Segment 已知依赖的 source 中任一缺失或 `isLoaded()==false`:仅该 Segment fail closed;
|
||||
- Segment 已知依赖的 source `hasFadingTiles()==true`:仅该 Segment视为 unstable;
|
||||
- **不被该 Segment 引用的 source unloaded 或 fading,不得让该 Segment cache fallback/rebuild**;
|
||||
- `retainedRangeIsStable(begin,end)` 的 source fading 检查必须按该 range 的真实 source dependency 缩小,不能继续遍历全部 `renderSources` 作为 full-CPU retained gate;
|
||||
- Fast Path 原有 global fading gate 保持不变;
|
||||
- source ID 无法解析、dependency 缺失或真正无法证明安全时 fail closed。
|
||||
|
||||
必须区分:
|
||||
|
||||
1. **已知 Source dependency**;
|
||||
2. **symbol/global prerequisite**(glyph/image/placement 等);
|
||||
3. **真正 unknown dependency**。
|
||||
|
||||
STEP-099 的 `unknownDependencies` 目前会把 symbol 相关条件标为 unknown。STEP-100 不得机械地把“存在 symbol”解释成永久 fallback;symbol 所需 glyph/image/placement 应作为明确的 global prerequisite/fail-closed 条件处理。
|
||||
|
||||
因此 T3 中一个:
|
||||
|
||||
```text
|
||||
no layer
|
||||
enabled=false
|
||||
isLoaded=false
|
||||
```
|
||||
|
||||
的 RasterArray source 可以继续让 global `RenderOrchestrator::isLoaded()==false`,但不得因此让与它无依赖关系的 R0/R1 cache 全部 `style-not-loaded`。
|
||||
|
||||
本 Step 的运行态硬验收范围是 **MapMode::Continuous**(粒子正式实时渲染模式)。当前非 Continuous / still 路径如果在 global unloaded 时提前返回,本 Step 不强行改变其兼容语义;完成报告必须明确该适用范围。
|
||||
|
||||
### 3.4 RETAINED Segment 独立决策
|
||||
|
||||
当前 V17 路径存在类似:
|
||||
|
||||
```text
|
||||
useRetainedRanges = all retained segments supported
|
||||
```
|
||||
|
||||
的 all-or-none 语义。
|
||||
|
||||
STEP-100 必须改为每个 RETAINED Segment 独立拥有:
|
||||
|
||||
- readiness/support decision;
|
||||
- Build / Reuse / Fallback;
|
||||
- content/source revision;
|
||||
- invalidation reason。
|
||||
|
||||
如果:
|
||||
|
||||
```text
|
||||
R0 = Reuse
|
||||
R1 = Fallback
|
||||
```
|
||||
|
||||
则本帧必须允许:
|
||||
|
||||
```text
|
||||
R0 composite cached texture
|
||||
C live render
|
||||
R1 live render fallback
|
||||
```
|
||||
|
||||
而不是退化为“整个 Style 全部 live render”。
|
||||
|
||||
如果某 retained cache 自身 build 失败,应优先只 fallback 该 Segment;只有无法证明局部安全的 context/global resource failure 才允许全 retained fail closed。
|
||||
|
||||
---
|
||||
|
||||
## 4. Source-scoped revision 设计要求
|
||||
|
||||
Codex 必须基于当前代码选择最小、稳定设计,并在完成报告说明实际方案。
|
||||
|
||||
推荐方向但不强制具体类名:
|
||||
|
||||
- 为 Source/Tile mutation 维护 source-scoped monotonic revision;
|
||||
- keyed by stable sourceId,但必须处理 source 删除后同 ID recreate,不能让新 source 错误继承可复用的旧 cache identity;可用 generation/epoch 或保留单调 tombstone 语义实现;
|
||||
- source diff、feature-state mutation、tile changed 等所有当前会进入 Source/Tile retained content invalidation 的正式路径都必须覆盖;
|
||||
- 能定位 sourceId 的 mutation 只推进对应 source revision;无法定位 sourceId 的 mutation继续 global fail closed;
|
||||
- Segment content revision 由:
|
||||
- 该 Segment 的 dependent source revisions;
|
||||
- 当前 Segment layer fingerprint / layer mutation;
|
||||
- 必须全局影响 retained 的 global revision 类别;
|
||||
- topology / camera / viewport 等既有安全条件
|
||||
共同决定。
|
||||
|
||||
Source/Tile mutation 不应推进“所有 Segment 都消费的 retained cache revision”。
|
||||
|
||||
必须避免:
|
||||
|
||||
- 用屏幕位置猜 dependency;
|
||||
- 在 renderer 中硬编码 source/layer ID;
|
||||
- 从 STEP-099 diagnostics JSON 反向驱动正式 renderer;
|
||||
- 建立 diagnostics 与 production 两套互相漂移的 dependency 真相。
|
||||
|
||||
如果需要提取 production-grade dependency helper,应让 diagnostics 和正式逻辑共享同一只读推导源。正式 renderer 不得从 diagnostics JSON 或 `RetainedUnderlayRuntimeState` 反向取 dependency。
|
||||
|
||||
Source-scoped revision 属正式 correctness state,不得沿用 STEP-099 diagnostics 的“best-effort 记录失败可忽略”语义。正式 revision/dependency state 若无法可靠更新,必须 conservative global invalidation/fail closed。
|
||||
|
||||
---
|
||||
|
||||
## 5. Global mutation 仍可保守处理
|
||||
|
||||
本任务只要求 **Source/Tile mutation** 与明确 Source readiness 局部化。
|
||||
|
||||
以下无法安全局部化的事件,本轮允许继续 invalidate/fail closed 全 retained:
|
||||
|
||||
- context reset;
|
||||
- style reload / topology change;
|
||||
- image mutation;
|
||||
- glyph mutation;
|
||||
- sprite/image manager 全局 readiness;
|
||||
- placement / symbol fade / glyph/image/sprite 全局状态;
|
||||
- camera / transform / viewport / resize / pixel ratio;
|
||||
- debug mode;
|
||||
- 3D / unsupported / legacy ordering;
|
||||
- 无法定位 dependency 的 mutation;
|
||||
- 真正 unknown/global dependency。
|
||||
|
||||
注意:**Source 自身的 loaded / fading 不属于这里的 global fail-closed 项**;若 source dependency 可定位,必须按 Segment 局部判断。Fast Path 的 global source/fading gate除外,本轮保持原状。
|
||||
|
||||
完成报告必须列出:
|
||||
|
||||
- 已局部化的 mutation 类型;
|
||||
- 仍为 global 的 mutation 类型;
|
||||
- 为什么保守处理。
|
||||
|
||||
---
|
||||
|
||||
## 6. Fast Path 本轮严格不改
|
||||
|
||||
STEP-099 已确认 Fast Path 仍有 global gates:
|
||||
|
||||
- global update signature(sources/layers/images 等);
|
||||
- global content revision;
|
||||
- global fade;
|
||||
- pendingChanges;
|
||||
- placement/light/non-particle transition/repaint;
|
||||
- annotation mutation;
|
||||
- topology/boundary/revision/cache validity;
|
||||
- `singleContinuousSegment`。
|
||||
|
||||
STEP-100 **禁止修改这些 gate 的语义**。
|
||||
|
||||
允许:
|
||||
|
||||
- Source mutation 后 Fast Path miss;
|
||||
- transient source readiness 时 Fast Path fail closed;
|
||||
- full CPU renderer 被调用。
|
||||
|
||||
但进入 full CPU renderer 后,必须能做到:
|
||||
|
||||
```text
|
||||
R0 retained cache reuse
|
||||
R1 rebuild/fallback
|
||||
```
|
||||
|
||||
这正是本任务验收目标。
|
||||
|
||||
Multi-continuous Fast Path 明确不在本任务。
|
||||
|
||||
---
|
||||
|
||||
## 7. Render 顺序与混合 Build/Reuse/Fallback
|
||||
|
||||
实现 per-segment mixed decisions 时必须保持原 MapLibre 绘制语义:
|
||||
|
||||
- Style Z-order;
|
||||
- global layerIndex;
|
||||
- opaque reverse traversal;
|
||||
- translucent forward traversal;
|
||||
- currentLayer;
|
||||
- depthRangeSize;
|
||||
- legacy item 不双绘;
|
||||
- debug overlay 不重复;
|
||||
- retained texture composite 不改变 segment 顺序。
|
||||
|
||||
推荐的逻辑行为:
|
||||
|
||||
```text
|
||||
for segment in Style order:
|
||||
RETAINED + Build:
|
||||
build cache
|
||||
composite cache
|
||||
RETAINED + Reuse:
|
||||
composite cache
|
||||
RETAINED + Fallback:
|
||||
live render only this range
|
||||
CONTINUOUS:
|
||||
live render this range
|
||||
```
|
||||
|
||||
实际代码可按现有 RenderPass 安全实现,不要求机械照搬伪代码。
|
||||
|
||||
必须特别检查:
|
||||
|
||||
- 一个 R fallback 不得导致另一个 R live redraw;
|
||||
- resource prepare 在 Build 前失败时,必须先把该 Segment 本帧 decision 改为 Fallback,再进入主 buffer 绘制;
|
||||
- retained build 中途失败时,必须 invalidate/标记该 Segment失败并把该 Segment 本帧 decision 改为 Fallback,禁止 composite 旧纹理;
|
||||
- 如果失败意味着 context / shared GPU state 已不可信,允许全局 fail closed;
|
||||
- fallback range 的 legacy items 只绘一次,不得因 per-segment 主循环重复 render;
|
||||
- debug overlay 全帧只绘一次;
|
||||
- Segment 间 Opaque/Translucent 语义不得被破坏;
|
||||
- 相邻 R、多个 C、透明叠加与 legacy scene 不能因 mixed execution 出现漏绘/双绘。
|
||||
|
||||
推荐执行顺序:先完成各 Segment resource prepare 与必要离屏 Build;再 clear 主 buffer;最后按 Style Segment 顺序逐段选择 cached composite 或 live range render。
|
||||
|
||||
---
|
||||
|
||||
## 8. Diagnostics 必须继续可证明局部性
|
||||
|
||||
保留 STEP-099 diagnostics,并 additive 增加足够字段,使 RDC 能验证正式行为。
|
||||
|
||||
每个 RETAINED Segment 至少应能观察:
|
||||
|
||||
- dependentSourceIds;
|
||||
- segment readiness / support;
|
||||
- segment-local source/content revision 或等价可证明值;
|
||||
- Build / Reuse / Fallback 的**最终本帧 execution decision**;
|
||||
- build/reuse/fallback/invalidation count;
|
||||
- last invalidation/fallback reason。
|
||||
|
||||
Source mutation 继续输出:
|
||||
|
||||
- sourceId;
|
||||
- sequence/reason/action;
|
||||
- affectedSegmentIndices。
|
||||
|
||||
要求:
|
||||
|
||||
```text
|
||||
step099-dynamic mutation
|
||||
affected=[R1]
|
||||
R0 revision unchanged
|
||||
R0 cache reuse++
|
||||
R0 build unchanged
|
||||
R0 invalidation unchanged
|
||||
```
|
||||
|
||||
Diagnostics 仍是 pull/event low-frequency,不允许逐帧高频 spam。
|
||||
|
||||
---
|
||||
|
||||
## 9. Android Test App
|
||||
|
||||
复用 STEP-099,不另建独立 App。
|
||||
|
||||
至少保留并完善:
|
||||
|
||||
### T1 STATIC
|
||||
|
||||
验证静态 R-C-R:
|
||||
|
||||
- loaded settle;
|
||||
- R0/R1 build 一次后稳定 reuse;
|
||||
- 不产生持续 rebuild。
|
||||
|
||||
### T2 GEOJSON_1HZ
|
||||
|
||||
两个 GeoJSON source 交错,各约 1 Hz。
|
||||
|
||||
重点:
|
||||
|
||||
- global loaded transient false window 可以继续存在;
|
||||
- 只引用某 source 的 retained Segment 才允许因该 source mutation 改变;
|
||||
- 无关 retained Segment build/invalidation 不得跟随增长。
|
||||
|
||||
### T3 PERMANENT_UNREADY
|
||||
|
||||
保留一个:
|
||||
|
||||
- no layer;
|
||||
- enabled=false;
|
||||
- isLoaded=false;
|
||||
- no field submission
|
||||
|
||||
的 RasterArray source。
|
||||
|
||||
预期:
|
||||
|
||||
- global renderOrchestratorLoaded 仍可为 false;
|
||||
- 但无关 R0/R1 retained cache 不应因它持续 `style-not-loaded` fallback;
|
||||
- 能安全判断依赖的 retained Segment应继续 build/reuse。
|
||||
|
||||
### T4 R-C-R(主验收)
|
||||
|
||||
必须保持清晰依赖:
|
||||
|
||||
```text
|
||||
R0 -> dedicated static source only
|
||||
C -> WeatherColor/Particle field
|
||||
R1 -> dedicated dynamic GeoJSON source
|
||||
```
|
||||
|
||||
运行动态 GeoJSON 约 1 Hz。
|
||||
|
||||
必须调整 fixture,避免 STEP-099 中 R1 再复用 R0 的 static source:
|
||||
|
||||
- R0 static source 只出现在 R0;
|
||||
- R1 dynamic source 只出现在 R1;
|
||||
- 若 MapLibre 内建 annotation source/layer 自动进入 R1,必须在 diagnostics 中列明,并保证验收窗口内 annotation 不发生 mutation;
|
||||
- 不允许用业务 ID 特判 renderer。
|
||||
|
||||
RDC 验收区间必须支持“settled baseline → 60 s pure dynamic-source mutation window → final”对比。每个 aggregate sample 同时记录 mutation source/sequence、各 Segment local revision、readiness、最终 execution decision 与 cache counters。
|
||||
|
||||
---
|
||||
|
||||
## 10. STEP-100 硬验收标准
|
||||
|
||||
### A. R0 locality
|
||||
|
||||
T4 settle 后记录 baseline。
|
||||
|
||||
随后至少 60 s dynamic GeoJSON:
|
||||
|
||||
- R0 `buildDelta == 0`
|
||||
- R0 `invalidationDelta == 0`
|
||||
- R0 `reuseDelta > 0`
|
||||
- R0 segment-local revision/content state 不因 R1 dynamic source mutation 改变
|
||||
- 即使某采样点 global `renderOrchestratorLoaded=false`,只要 R0 自身 prerequisites/dependencies ready,R0 final decision 仍可为 Reuse
|
||||
|
||||
如果为了安全出现明确 global event,应在日志中可解释并重新选择纯动态 mutation 区间;不能把 global event 混入后声称 PASS。
|
||||
|
||||
### B. R1 reacts
|
||||
|
||||
同一时间窗:
|
||||
|
||||
- R1 必须能观察到 source mutation;
|
||||
- R1 revision / build / invalidation / fallback 中至少有与动态 source 对应的实际变化;
|
||||
- `affectedSegmentIndices` 必须只包含真实依赖 Segment。
|
||||
|
||||
### C. global revision compatibility
|
||||
|
||||
- global `retainedUnderlayContentRevision` 允许并预期继续增长;
|
||||
- 不能通过停止 global revision 增长来制造 R0 PASS。
|
||||
|
||||
### D. readiness locality
|
||||
|
||||
T2 transient unloaded 或 T3 permanent unrelated unloaded 时:
|
||||
|
||||
- global loaded 可 false;
|
||||
- R0 不得仅因无关 source 的 unloaded 而 invalid/rebuild/fallback;
|
||||
- R0 cache 必须继续可复用。
|
||||
|
||||
### E. correctness
|
||||
|
||||
- 无 crash / ANR;
|
||||
- 无 stale cache composite;
|
||||
- 无 Segment Z-order 错乱;
|
||||
- 无 fallback range 双绘;
|
||||
- Cache OFF 仍安全走 live renderer;
|
||||
- plan invalid 仍 fail closed。
|
||||
|
||||
任一硬门槛失败,STEP-100 不得宣布 PASS,不得进入 V18。
|
||||
|
||||
---
|
||||
|
||||
## 11. Native 非 Jest 测试要求
|
||||
|
||||
Codex 必须新增或扩展现有 C++ 测试源码,至少覆盖:
|
||||
|
||||
1. source A mutation 只改变依赖 A 的 Segment revision;
|
||||
2. source A 被多个 Segment 共享时,对应多个 Segment 都变化;
|
||||
3. unrelated Segment revision 不变;
|
||||
4. source-less Segment 不制造 dependency;
|
||||
5. unknown/global dependency fail closed;
|
||||
6. unrelated source unloaded 不使安全 Segment readiness false;
|
||||
7. dependent source unloaded 使对应 Segment readiness false;
|
||||
8. R0 Reuse + R1 Fallback 的 mixed decision;
|
||||
9. 单 Segment build failure 不 composite stale cache;
|
||||
10. query diagnostics 不改变 revision/cache state;
|
||||
11. global non-source invalidation 仍影响所有 retained;
|
||||
12. source 删除后同 ID recreate 不误复用旧 Segment cache identity;
|
||||
13. dependent source fading 只影响对应 Segment;unrelated source fading 不影响安全 Segment;
|
||||
14. Cache OFF / invalid plan 行为不回归;
|
||||
15. 至少有一组能证明实际 mixed render 没有漏绘/双绘的 renderer-level draw-count、pixel 或现有等价测试入口;不能只用 decision unit test 代替。
|
||||
|
||||
不得修改测试断言去适应错误实现。
|
||||
|
||||
---
|
||||
|
||||
## 12. 允许修改范围
|
||||
|
||||
允许:
|
||||
|
||||
- RenderOrchestrator source mutation/readiness bookkeeping;
|
||||
- RenderSegment dependency production helper;
|
||||
- Renderer retained per-segment revision/readiness/decision;
|
||||
- RetainedUnderlayCache/RuntimeState 为局部状态增加必要字段;
|
||||
- additive diagnostics JSON/TS;
|
||||
- Android Validation Test App STEP-099 fixture/log;
|
||||
- 相关 Native C++ tests;
|
||||
- STEP-100 Step 记录/完成报告/开发记录。
|
||||
|
||||
禁止:
|
||||
|
||||
- NavSea;
|
||||
- Integration;
|
||||
- V17 tag/release worktree;
|
||||
- Source `isLoaded()` 定义;
|
||||
- Particle field/provider/network;
|
||||
- Fast Path gate semantic;
|
||||
- `singleContinuousSegment`;
|
||||
- multi-continuous Fast Path;
|
||||
- 自动改变 Style Z-order;
|
||||
- provider/business-specific source/layer ID;
|
||||
- unrelated cleanup/refactor;
|
||||
- Jest。
|
||||
|
||||
---
|
||||
|
||||
## 13. Codex 执行边界
|
||||
|
||||
Codex 本轮负责:
|
||||
|
||||
1. 读取实际源码和任务书;
|
||||
2. 实现代码;
|
||||
3. 编写 Native 非 Jest 测试源码;
|
||||
4. 更新 Android Test App 验证入口;
|
||||
5. 执行轻量静态检查,如 `git diff --check`;
|
||||
6. 生成中文完成报告。
|
||||
|
||||
Codex **不得执行**:
|
||||
|
||||
- Android Gradle / APK;
|
||||
- ADB / 安装 / 实机;
|
||||
- Xcode / iOS device;
|
||||
- V18 release;
|
||||
- tag;
|
||||
- push;
|
||||
- Jest。
|
||||
|
||||
本轮 Codex 完成报告固定:
|
||||
|
||||
`docs/报告/STEP-100_SourceScoped_RenderSegment局部失效_Codex完成报告_v1.md`
|
||||
|
||||
Step 记录固定:
|
||||
|
||||
`docs/50_Step记录/STEP-100_SourceScoped_RenderSegment局部失效_v1.md`
|
||||
|
||||
完成报告必须写清:
|
||||
|
||||
- 实际 Codex model / reasoning effort;
|
||||
- start HEAD;
|
||||
- 修改文件;
|
||||
- 生产设计;
|
||||
- source revision/readiness 规则;
|
||||
- mixed retained decision 规则;
|
||||
- Fast Path 明确未改;
|
||||
- 测试源码新增情况;
|
||||
- 实际执行 / NOT RUN;
|
||||
- 风险与 RDC 验收点;
|
||||
- 未 commit / 未 push(如果确实如此)。
|
||||
|
||||
Codex 不 commit、不 push。由 RDC 验证通过后统一 Git 收尾。
|
||||
|
||||
---
|
||||
|
||||
## 14. RDC / ChatGPT 后续独立验收
|
||||
|
||||
Codex 返回后由 RDC 负责:
|
||||
|
||||
1. source/diff 审计;
|
||||
2. Native Mac 编译;
|
||||
3. Native focused + broad related C++ tests;
|
||||
4. Android x86_64 OpenGL validation APK 单次构建;
|
||||
5. Mac ADB 直连 FZG1-2;
|
||||
6. 自动跑 T1/T2/T3/T4;
|
||||
7. 解析 R0/R1 build/reuse/invalidation/revision/readiness;
|
||||
8. 确认硬验收标准 A~E;
|
||||
9. 若失败,回到 STEP-100 修复,不发布;
|
||||
10. 若全部 PASS,完成 STEP-100 Git push;
|
||||
11. 再按现有统一发行流程升级到:
|
||||
`maplibre-particle/rn/13.4.1-particle.18`
|
||||
12. V18 build/release/public artifact 验证通过后才宣布 V18 发布完成。
|
||||
|
||||
---
|
||||
|
||||
## 15. 停止条件
|
||||
|
||||
Codex 遇到以下任一情况必须停止并报告,不得扩大范围:
|
||||
|
||||
- 要修改 Source `isLoaded()` 才能继续;
|
||||
- 需要放宽 Fast Path gate;
|
||||
- 必须改变 singleContinuous / multi-continuous;
|
||||
- production dependency 无法可靠从现有 Style/RenderLayer/Source 推导;
|
||||
- per-segment fallback 会破坏 RenderPass/Z-order 且无法在当前范围安全解决;
|
||||
- 发现需要 NavSea/Integration 配合;
|
||||
- 需要业务 layer/source ID;
|
||||
- 需要改变 V17 release。
|
||||
|
||||
---
|
||||
|
||||
## 16. 本任务最终原则
|
||||
|
||||
STEP-100 的目标不是让“全局世界看起来 loaded”。
|
||||
|
||||
目标是:
|
||||
|
||||
> **即使某个 GeoJSON Source 正在变化或短暂 unready,只要 R0 与它没有依赖关系,R0 retained cache 就必须继续安全 reuse,不能被迫一起刷新。**
|
||||
|
||||
Fast Path 是否还能 miss,是后续独立问题。
|
||||
|
||||
只有这一点经过 Native + Android R-C-R 实测成立,才允许进入 V18 发布。
|
||||
405
docs/40_任务/STEP-101_RenderOrchestrator销毁生命周期修复_Codex任务_v1.md
Normal file
405
docs/40_任务/STEP-101_RenderOrchestrator销毁生命周期修复_Codex任务_v1.md
Normal file
@@ -0,0 +1,405 @@
|
||||
# STEP-101 RenderOrchestrator teardown 生命周期修复 — Codex 任务 v1
|
||||
|
||||
## 0. 任务目的
|
||||
|
||||
修复 Particle V18 Android 在正常 Renderer teardown / MapView reset 时发生的 Native SIGABRT。
|
||||
|
||||
现场已在 NavSea Android x86_64 设备稳定复现:
|
||||
|
||||
```text
|
||||
Fatal signal 6 (SIGABRT)
|
||||
thread: RenderThread 11
|
||||
|
||||
FORTIFY:
|
||||
pthread_mutex_lock called on a destroyed mutex
|
||||
|
||||
libmaplibre.so
|
||||
std::__ndk1::mutex::lock()
|
||||
...
|
||||
mbgl::android::MapRenderer::resetRenderer()
|
||||
```
|
||||
|
||||
V17 正常,V18 接入后稳定在启动约 9~11 秒触发。
|
||||
|
||||
本任务只修 Particle Native 生命周期;禁止在 NavSea 增加绕路、private wrapper、禁止阻止正常 MapView reset。
|
||||
|
||||
未经用户明确要求:不加入、不执行 Jest。
|
||||
|
||||
---
|
||||
|
||||
## 1. 冻结基线
|
||||
|
||||
工作树:
|
||||
|
||||
`/Users/tei/dev/MapLibreParticleLab-step101`
|
||||
|
||||
分支:
|
||||
|
||||
`step101-render-orchestrator-teardown`
|
||||
|
||||
起点必须是:
|
||||
|
||||
`origin/particle/main = d29e84c1a90daeea104b389d28b000c4f017d08d`
|
||||
|
||||
即正式 V18 Final HEAD。
|
||||
|
||||
V18 已发布,不得覆盖、重发或移动:
|
||||
|
||||
- `maplibre-particle/rn/13.4.1-particle.18`
|
||||
- Android `13.4.1-particle.18`
|
||||
- iOS `6.28.0-particle.18`
|
||||
|
||||
修复通过后由 RDC/ChatGPT 发布新不可变版本 V19。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已知根因证据
|
||||
|
||||
V18 STEP-100 新增:
|
||||
|
||||
```cpp
|
||||
RenderSegmentRevisionBook retainedSegmentRevisions;
|
||||
mutable std::mutex readinessDiagnosticsMutex;
|
||||
uint64_t readinessEventSequence;
|
||||
std::unordered_map<std::string, SourceReadinessEventState> sourceReadinessEvents;
|
||||
RenderMutationDiagnostics lastReadinessMutation;
|
||||
```
|
||||
|
||||
多个 RenderSource / Tile observer callback 会进入:
|
||||
|
||||
```cpp
|
||||
advanceRetainedSourceRevision(...)
|
||||
recordReadinessMutation(...)
|
||||
onTileChanged(...)
|
||||
onTileAction(...)
|
||||
buildReadinessDiagnostics(...)
|
||||
retainedSegmentSourceState(...)
|
||||
```
|
||||
|
||||
并 lock:
|
||||
|
||||
```cpp
|
||||
readinessDiagnosticsMutex
|
||||
```
|
||||
|
||||
V18 当前成员声明中:
|
||||
|
||||
```text
|
||||
renderSources
|
||||
renderLayers
|
||||
...
|
||||
retainedSegmentRevisions
|
||||
...
|
||||
readinessDiagnosticsMutex
|
||||
sourceReadinessEvents
|
||||
...
|
||||
threadPool
|
||||
```
|
||||
|
||||
C++ 成员按声明反序析构,因此 readiness state / mutex 会早于 renderSources 销毁。
|
||||
|
||||
而 RenderSource 在创建时:
|
||||
|
||||
```cpp
|
||||
renderSource->setObserver(this);
|
||||
```
|
||||
|
||||
observer 指向 RenderOrchestrator。
|
||||
|
||||
当前 `RenderOrchestrator::~RenderOrchestrator()` 只:
|
||||
|
||||
1. contextLost 时标记 layer;
|
||||
2. `threadPool.waitForEmpty()`;
|
||||
|
||||
没有在 readiness state 仍有效时显式 detach RenderSource observer / 清理 renderSources。
|
||||
|
||||
因此 V18 存在明确生命周期危险:
|
||||
|
||||
```text
|
||||
readinessDiagnosticsMutex destroyed
|
||||
↓
|
||||
renderSources still destroying/alive
|
||||
↓
|
||||
late tile/source callback
|
||||
↓
|
||||
RenderOrchestrator::onTile*
|
||||
↓
|
||||
lock destroyed mutex
|
||||
↓
|
||||
FORTIFY SIGABRT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 修复原则
|
||||
|
||||
不要只依赖调整成员声明顺序。
|
||||
|
||||
本任务应建立显式 teardown contract:
|
||||
|
||||
```text
|
||||
RenderOrchestrator destructor begins
|
||||
↓
|
||||
stop / drain deferred scheduler work
|
||||
↓
|
||||
detach observer from every RenderSource
|
||||
↓
|
||||
destroy/clear renderSources while all orchestrator state is still alive
|
||||
↓
|
||||
only then continue member teardown
|
||||
```
|
||||
|
||||
同时 `RenderSource::setObserver(nullptr)` 必须安全恢复到 NullObserver。
|
||||
|
||||
目标是即使未来成员声明顺序变化,Source callback 也不能在 owner teardown 后访问 RenderOrchestrator。
|
||||
|
||||
---
|
||||
|
||||
## 4. 必做实现
|
||||
|
||||
### 4.1 RenderSource nullptr observer 语义
|
||||
|
||||
当前:
|
||||
|
||||
```cpp
|
||||
void RenderSource::setObserver(RenderSourceObserver* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
```
|
||||
|
||||
改成与 Style Source / Layer 一致的安全语义:
|
||||
|
||||
```cpp
|
||||
observer = observer_ ? observer_ : &nullObserver;
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- constructor 仍默认 NullObserver;
|
||||
- `setObserver(nullptr)` 是合法 detach;
|
||||
- onTileChanged / onTileError / onTileAction 不需要加 null 分支;
|
||||
- 不吞掉正常有 observer 时的回调。
|
||||
|
||||
必须加非 Jest C++ 回归测试验证 nullptr detach 后 callback 不 crash、不调用旧 observer。
|
||||
|
||||
### 4.2 RenderOrchestrator 显式 teardown
|
||||
|
||||
在 `RenderOrchestrator::~RenderOrchestrator()` 中,在 readiness mutex/state 仍确定存活时:
|
||||
|
||||
1. 保留现有 contextLost layer handling;
|
||||
2. 等待已有 deferred work 完成;
|
||||
3. 对所有 `renderSources` 执行 observer detach;
|
||||
4. 显式 `renderSources.clear()`;
|
||||
5. 必要时对 glyph/image observer 也做已有 API 支持的 detach,但不要扩大范围;
|
||||
6. 不允许 teardown callback 再进入 RenderOrchestrator source callback。
|
||||
|
||||
顺序必须结合当前 TaggedScheduler / RenderSource / TilePyramid 的真实生命周期检查,而不是机械照抄上述编号。
|
||||
|
||||
如果存在“clear renderSources 本身可能产生新的 scheduler work”,需要设计第二次 drain 或更安全顺序,并在报告解释。
|
||||
|
||||
### 4.3 生命周期状态可选保护
|
||||
|
||||
如果仅 detach + explicit clear 仍无法证明并发安全,允许增加最小 teardown flag,例如 atomic bool,但只作为二次防线。
|
||||
|
||||
禁止用 flag 代替 observer detach。
|
||||
|
||||
禁止 catch FORTIFY;destroyed mutex abort 不是 C++ exception。
|
||||
|
||||
---
|
||||
|
||||
## 5. 不得修改
|
||||
|
||||
- STEP-100 Source→Segment locality 语义;
|
||||
- per-segment revision;
|
||||
- per-segment readiness;
|
||||
- mixed Build/Reuse/Fallback;
|
||||
- Fast Path gate;
|
||||
- singleContinuousSegment;
|
||||
- Source::isLoaded;
|
||||
- Style Z-order;
|
||||
- provider/network;
|
||||
- NavSea;
|
||||
- MapRenderer::resetRenderer 正常生命周期;
|
||||
- Android Activity 为避免 reset 而加 workaround。
|
||||
|
||||
---
|
||||
|
||||
## 6. 必做测试
|
||||
|
||||
### 6.1 Native 非 Jest
|
||||
|
||||
至少覆盖:
|
||||
|
||||
1. RenderSource 默认 NullObserver 可安全接 callback;
|
||||
2. setObserver(real) 正常转发;
|
||||
3. setObserver(nullptr) 后不再调用旧 observer;
|
||||
4. detach 后 onTileChanged / onTileError / onTileAction 安全;
|
||||
5. RenderOrchestrator teardown 有至少一个含 RenderSource 的场景;
|
||||
6. source callback 与 teardown 边界不访问已销毁 readiness state;
|
||||
7. STEP-100 locality 相关 focused tests 不回归。
|
||||
|
||||
如果现有测试设施不方便直接构造完整 RenderOrchestrator teardown,允许提取最小可测试 teardown helper,但禁止为了测试重构大范围生产结构。
|
||||
|
||||
### 6.2 Android Test App
|
||||
|
||||
在现有 ParticleCoreLayerValidationActivity / Validation App 增加专门 STEP-101 teardown 场景。
|
||||
|
||||
场景必须真实触发 Native Renderer teardown,而不是只 clear field。
|
||||
|
||||
至少提供:
|
||||
|
||||
```text
|
||||
T1 RESET_ONCE
|
||||
T2 RESET_LOOP_20
|
||||
T3 RESET_WITH_DYNAMIC_GEOJSON
|
||||
T4 RESET_WITH_DIAGNOSTICS
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- recreate/destroy MapView 或等价真实 renderer.reset;
|
||||
- 每轮等待足够让 source/tile work 进入正常运行;
|
||||
- T3 同时保持动态 GeoJSON/source mutation;
|
||||
- T4 在 reset 前调用一次 RendererRuntime diagnostics,模拟 NavSea probe 时序;
|
||||
- 20 次循环无 SIGABRT / crash / ANR;
|
||||
- reset 后新 renderer 能继续正常显示 / 获取 diagnostics。
|
||||
|
||||
不得通过延迟 reset、禁用 observer、关闭 GeoJSON 来逃避问题。
|
||||
|
||||
---
|
||||
|
||||
## 7. NavSea 现场等价验收
|
||||
|
||||
RDC 在 Codex 完成后独立执行。
|
||||
|
||||
Android 设备:
|
||||
|
||||
`192.168.200.139:5555`
|
||||
|
||||
必须显式 `adb -s`。
|
||||
|
||||
最终至少执行:
|
||||
|
||||
1. Validation App STEP-101 T1~T4;
|
||||
2. crash buffer 检查;
|
||||
3. 20 次 reset/recreate;
|
||||
4. 安装 V19 进 NavSea 后做真实启动;
|
||||
5. 保留 NavSea 当前 `key={map-style-generation-...}` 正常 reset 触发条件;
|
||||
6. 保留/启用一次 RenderSegment diagnostics probe A/B;
|
||||
7. 连续至少 5 次冷启动,每次观察 >30 秒;
|
||||
8. 不允许出现:
|
||||
- `pthread_mutex_lock called on a destroyed mutex`
|
||||
- SIGABRT RenderThread
|
||||
- `MapRenderer::resetRenderer` teardown crash。
|
||||
|
||||
---
|
||||
|
||||
## 8. STEP-100 回归验收
|
||||
|
||||
修复 teardown 后必须确认 V18 的核心 locality 没被破坏。
|
||||
|
||||
至少复测 T4 R-C-R:
|
||||
|
||||
无关 R0:
|
||||
|
||||
```text
|
||||
buildDelta = 0
|
||||
invalidationDelta = 0
|
||||
reuseDelta > 0
|
||||
```
|
||||
|
||||
动态 R1 正常 build/invalidation。
|
||||
|
||||
禁止通过删除 mutex/readiness/revision 功能来修 crash。
|
||||
|
||||
---
|
||||
|
||||
## 9. Codex 执行边界
|
||||
|
||||
Codex负责:
|
||||
|
||||
- 只读检查真实 V18 代码;
|
||||
- 实现最小 Native 修复;
|
||||
- 编写/更新非 Jest C++ tests;
|
||||
- 更新 Android Validation STEP-101 场景;
|
||||
- 静态检查;
|
||||
- 生成报告。
|
||||
|
||||
Codex不负责:
|
||||
|
||||
- NavSea 修改;
|
||||
- V19 release;
|
||||
- tag;
|
||||
- publish;
|
||||
- 覆盖 V18;
|
||||
- Jest。
|
||||
|
||||
Mac Native 开发/编译原则保持;不要使用 Linux Native 环境。
|
||||
|
||||
---
|
||||
|
||||
## 10. 完成报告
|
||||
|
||||
生成:
|
||||
|
||||
`docs/报告/STEP-101_RenderOrchestrator销毁生命周期修复_Codex完成报告_v1.md`
|
||||
|
||||
Step 记录:
|
||||
|
||||
`docs/50_Step记录/STEP-101_RenderOrchestrator销毁生命周期修复_v1.md`
|
||||
|
||||
报告必须写:
|
||||
|
||||
- root cause;
|
||||
- start HEAD;
|
||||
- 修改文件;
|
||||
- destructor teardown 顺序;
|
||||
- observer detach 语义;
|
||||
- 为什么不依赖成员声明顺序;
|
||||
- tests added;
|
||||
- 实际运行 / NOT RUN;
|
||||
- STEP-100 locality 是否保持;
|
||||
- 风险;
|
||||
- 未发布 V19(Codex 阶段)。
|
||||
|
||||
Codex阶段不 push,由 RDC 验收后统一 commit/push。
|
||||
|
||||
---
|
||||
|
||||
## 11. V19 发布门槛
|
||||
|
||||
仅当:
|
||||
|
||||
- Native compile PASS;
|
||||
- focused C++ tests PASS;
|
||||
- Android Validation teardown loop PASS;
|
||||
- STEP-100 locality regression PASS;
|
||||
- NavSea V19 真实 5 次冷启动 >30s PASS;
|
||||
- crash buffer 无 destroyed mutex;
|
||||
|
||||
才允许发布:
|
||||
|
||||
- RN / Android:`13.4.1-particle.19`
|
||||
- iOS:`6.28.0-particle.19`
|
||||
- tag:`maplibre-particle/rn/13.4.1-particle.19`
|
||||
|
||||
V18 保持不可变,不覆盖、不删除。
|
||||
|
||||
---
|
||||
|
||||
## 12. 最终原则
|
||||
|
||||
正常:
|
||||
|
||||
```text
|
||||
MapView unmount
|
||||
Style generation replacement
|
||||
renderer.reset()
|
||||
Activity recreate
|
||||
```
|
||||
|
||||
都是合法生命周期。
|
||||
|
||||
Particle Native 必须做到:
|
||||
|
||||
> Renderer teardown 永远不能因为 observer late callback 访问已销毁 mutex/state 而杀掉宿主 App。
|
||||
510
docs/40_任务/STEP-101_RenderOrchestrator销毁生命周期修复_Codex任务_v2.md
Normal file
510
docs/40_任务/STEP-101_RenderOrchestrator销毁生命周期修复_Codex任务_v2.md
Normal file
@@ -0,0 +1,510 @@
|
||||
# STEP-101 RenderOrchestrator teardown 生命周期修复 — Codex 任务 v1
|
||||
|
||||
## 0. 任务目的
|
||||
|
||||
修复 Particle V18 Android 在正常 Renderer teardown / MapView reset 时发生的 Native SIGABRT。
|
||||
|
||||
现场已在 NavSea Android x86_64 设备稳定复现:
|
||||
|
||||
```text
|
||||
Fatal signal 6 (SIGABRT)
|
||||
thread: RenderThread 11
|
||||
|
||||
FORTIFY:
|
||||
pthread_mutex_lock called on a destroyed mutex
|
||||
|
||||
libmaplibre.so
|
||||
std::__ndk1::mutex::lock()
|
||||
...
|
||||
mbgl::android::MapRenderer::resetRenderer()
|
||||
```
|
||||
|
||||
V17 正常,V18 接入后稳定在启动约 9~11 秒触发。
|
||||
|
||||
本任务只修 Particle Native 生命周期;禁止在 NavSea 增加绕路、private wrapper、禁止阻止正常 MapView reset。
|
||||
|
||||
未经用户明确要求:不加入、不执行 Jest。
|
||||
|
||||
---
|
||||
|
||||
## 1. 冻结基线
|
||||
|
||||
工作树:
|
||||
|
||||
`/Users/tei/dev/MapLibreParticleLab-step101`
|
||||
|
||||
分支:
|
||||
|
||||
`step101-render-orchestrator-teardown`
|
||||
|
||||
起点必须是:
|
||||
|
||||
`origin/particle/main = d29e84c1a90daeea104b389d28b000c4f017d08d`
|
||||
|
||||
即正式 V18 Final HEAD。
|
||||
|
||||
V18 已发布,不得覆盖、重发或移动:
|
||||
|
||||
- `maplibre-particle/rn/13.4.1-particle.18`
|
||||
- Android `13.4.1-particle.18`
|
||||
- iOS `6.28.0-particle.18`
|
||||
|
||||
修复通过后由 RDC/ChatGPT 发布新不可变版本 V19。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已知根因证据
|
||||
|
||||
V18 STEP-100 新增:
|
||||
|
||||
```cpp
|
||||
RenderSegmentRevisionBook retainedSegmentRevisions;
|
||||
mutable std::mutex readinessDiagnosticsMutex;
|
||||
uint64_t readinessEventSequence;
|
||||
std::unordered_map<std::string, SourceReadinessEventState> sourceReadinessEvents;
|
||||
RenderMutationDiagnostics lastReadinessMutation;
|
||||
```
|
||||
|
||||
多个 RenderSource / Tile observer callback 会进入:
|
||||
|
||||
```cpp
|
||||
advanceRetainedSourceRevision(...)
|
||||
recordReadinessMutation(...)
|
||||
onTileChanged(...)
|
||||
onTileAction(...)
|
||||
buildReadinessDiagnostics(...)
|
||||
retainedSegmentSourceState(...)
|
||||
```
|
||||
|
||||
并 lock:
|
||||
|
||||
```cpp
|
||||
readinessDiagnosticsMutex
|
||||
```
|
||||
|
||||
V18 当前成员声明中:
|
||||
|
||||
```text
|
||||
renderSources
|
||||
renderLayers
|
||||
...
|
||||
retainedSegmentRevisions
|
||||
...
|
||||
readinessDiagnosticsMutex
|
||||
sourceReadinessEvents
|
||||
...
|
||||
threadPool
|
||||
```
|
||||
|
||||
C++ 成员按声明反序析构,因此 readiness state / mutex 会早于 renderSources 销毁。
|
||||
|
||||
而 RenderSource 在创建时:
|
||||
|
||||
```cpp
|
||||
renderSource->setObserver(this);
|
||||
```
|
||||
|
||||
observer 指向 RenderOrchestrator。
|
||||
|
||||
当前 `RenderOrchestrator::~RenderOrchestrator()` 只:
|
||||
|
||||
1. contextLost 时标记 layer;
|
||||
2. `threadPool.waitForEmpty()`;
|
||||
|
||||
没有在 readiness state 仍有效时显式 detach RenderSource observer / 清理 renderSources。
|
||||
|
||||
因此 V18 存在明确生命周期危险:
|
||||
|
||||
```text
|
||||
readinessDiagnosticsMutex destroyed
|
||||
↓
|
||||
renderSources still destroying/alive
|
||||
↓
|
||||
late tile/source callback
|
||||
↓
|
||||
RenderOrchestrator::onTile*
|
||||
↓
|
||||
lock destroyed mutex
|
||||
↓
|
||||
FORTIFY SIGABRT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 修复原则
|
||||
|
||||
不要只依赖调整成员声明顺序。
|
||||
|
||||
本任务应建立显式 teardown contract:
|
||||
|
||||
```text
|
||||
RenderOrchestrator destructor begins
|
||||
↓
|
||||
stop / drain deferred scheduler work
|
||||
↓
|
||||
detach observer from every RenderSource
|
||||
↓
|
||||
destroy/clear renderSources while all orchestrator state is still alive
|
||||
↓
|
||||
only then continue member teardown
|
||||
```
|
||||
|
||||
同时 `RenderSource::setObserver(nullptr)` 必须安全恢复到 NullObserver。
|
||||
|
||||
目标是即使未来成员声明顺序变化,Source callback 也不能在 owner teardown 后访问 RenderOrchestrator。
|
||||
|
||||
---
|
||||
|
||||
## 4. 必做实现
|
||||
|
||||
### 4.1 RenderSource nullptr observer 语义
|
||||
|
||||
当前:
|
||||
|
||||
```cpp
|
||||
void RenderSource::setObserver(RenderSourceObserver* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
```
|
||||
|
||||
改成与 Style Source / Layer 一致的安全语义:
|
||||
|
||||
```cpp
|
||||
observer = observer_ ? observer_ : &nullObserver;
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- constructor 仍默认 NullObserver;
|
||||
- `setObserver(nullptr)` 是合法 detach;
|
||||
- onTileChanged / onTileError / onTileAction 不需要加 null 分支;
|
||||
- 不吞掉正常有 observer 时的回调。
|
||||
|
||||
必须加非 Jest C++ 回归测试验证 nullptr detach 后 callback 不 crash、不调用旧 observer。
|
||||
|
||||
### 4.2 RenderOrchestrator 显式 teardown
|
||||
|
||||
在 `RenderOrchestrator::~RenderOrchestrator()` 中,在 readiness mutex/state 仍确定存活时:
|
||||
|
||||
1. 保留现有 contextLost layer handling;
|
||||
2. 等待已有 deferred work 完成;
|
||||
3. 对所有 `renderSources` 执行 observer detach;
|
||||
4. 显式 `renderSources.clear()`;
|
||||
5. 必要时对 glyph/image observer 也做已有 API 支持的 detach,但不要扩大范围;
|
||||
6. 不允许 teardown callback 再进入 RenderOrchestrator source callback。
|
||||
|
||||
顺序必须结合当前 TaggedScheduler / RenderSource / TilePyramid 的真实生命周期检查,而不是机械照抄上述编号。
|
||||
|
||||
如果存在“clear renderSources 本身可能产生新的 scheduler work”,需要设计第二次 drain 或更安全顺序,并在报告解释。
|
||||
|
||||
### 4.3 生命周期状态可选保护
|
||||
|
||||
如果仅 detach + explicit clear 仍无法证明并发安全,允许增加最小 teardown flag,例如 atomic bool,但只作为二次防线。
|
||||
|
||||
禁止用 flag 代替 observer detach。
|
||||
|
||||
禁止 catch FORTIFY;destroyed mutex abort 不是 C++ exception。
|
||||
|
||||
---
|
||||
|
||||
## 5. 不得修改
|
||||
|
||||
- STEP-100 Source→Segment locality 语义;
|
||||
- per-segment revision;
|
||||
- per-segment readiness;
|
||||
- mixed Build/Reuse/Fallback;
|
||||
- Fast Path gate;
|
||||
- singleContinuousSegment;
|
||||
- Source::isLoaded;
|
||||
- Style Z-order;
|
||||
- provider/network;
|
||||
- NavSea;
|
||||
- MapRenderer::resetRenderer 正常生命周期;
|
||||
- Android Activity 为避免 reset 而加 workaround。
|
||||
|
||||
---
|
||||
|
||||
## 6. 必做测试
|
||||
|
||||
### 6.1 Native 非 Jest
|
||||
|
||||
至少覆盖:
|
||||
|
||||
1. RenderSource 默认 NullObserver 可安全接 callback;
|
||||
2. setObserver(real) 正常转发;
|
||||
3. setObserver(nullptr) 后不再调用旧 observer;
|
||||
4. detach 后 onTileChanged / onTileError / onTileAction 安全;
|
||||
5. RenderOrchestrator teardown 有至少一个含 RenderSource 的场景;
|
||||
6. source callback 与 teardown 边界不访问已销毁 readiness state;
|
||||
7. STEP-100 locality 相关 focused tests 不回归。
|
||||
|
||||
如果现有测试设施不方便直接构造完整 RenderOrchestrator teardown,允许提取最小可测试 teardown helper,但禁止为了测试重构大范围生产结构。
|
||||
|
||||
### 6.2 Android Test App
|
||||
|
||||
在现有 ParticleCoreLayerValidationActivity / Validation App 增加专门 STEP-101 teardown 场景。
|
||||
|
||||
场景必须真实触发 Native Renderer teardown,而不是只 clear field。
|
||||
|
||||
至少提供:
|
||||
|
||||
```text
|
||||
T1 RESET_ONCE
|
||||
T2 RESET_LOOP_20
|
||||
T3 RESET_WITH_DYNAMIC_GEOJSON
|
||||
T4 RESET_WITH_DIAGNOSTICS
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- recreate/destroy MapView 或等价真实 renderer.reset;
|
||||
- 每轮等待足够让 source/tile work 进入正常运行;
|
||||
- T3 同时保持动态 GeoJSON/source mutation;
|
||||
- T4 在 reset 前调用一次 RendererRuntime diagnostics,模拟 NavSea probe 时序;
|
||||
- 20 次循环无 SIGABRT / crash / ANR;
|
||||
- reset 后新 renderer 能继续正常显示 / 获取 diagnostics。
|
||||
|
||||
不得通过延迟 reset、禁用 observer、关闭 GeoJSON 来逃避问题。
|
||||
|
||||
---
|
||||
|
||||
## 7. NavSea 现场等价验收
|
||||
|
||||
RDC 在 Codex 完成后独立执行。
|
||||
|
||||
Android 设备:
|
||||
|
||||
`192.168.200.139:5555`
|
||||
|
||||
必须显式 `adb -s`。
|
||||
|
||||
最终至少执行:
|
||||
|
||||
1. Validation App STEP-101 T1~T4;
|
||||
2. crash buffer 检查;
|
||||
3. 20 次 reset/recreate;
|
||||
4. 安装 V19 进 NavSea 后做真实启动;
|
||||
5. 保留 NavSea 当前 `key={map-style-generation-...}` 正常 reset 触发条件;
|
||||
6. 保留/启用一次 RenderSegment diagnostics probe A/B;
|
||||
7. 连续至少 5 次冷启动,每次观察 >30 秒;
|
||||
8. 不允许出现:
|
||||
- `pthread_mutex_lock called on a destroyed mutex`
|
||||
- SIGABRT RenderThread
|
||||
- `MapRenderer::resetRenderer` teardown crash。
|
||||
|
||||
---
|
||||
|
||||
## 8. STEP-100 回归验收
|
||||
|
||||
修复 teardown 后必须确认 V18 的核心 locality 没被破坏。
|
||||
|
||||
至少复测 T4 R-C-R:
|
||||
|
||||
无关 R0:
|
||||
|
||||
```text
|
||||
buildDelta = 0
|
||||
invalidationDelta = 0
|
||||
reuseDelta > 0
|
||||
```
|
||||
|
||||
动态 R1 正常 build/invalidation。
|
||||
|
||||
禁止通过删除 mutex/readiness/revision 功能来修 crash。
|
||||
|
||||
---
|
||||
|
||||
## 9. Codex 执行边界
|
||||
|
||||
Codex负责:
|
||||
|
||||
- 只读检查真实 V18 代码;
|
||||
- 实现最小 Native 修复;
|
||||
- 编写/更新非 Jest C++ tests;
|
||||
- 更新 Android Validation STEP-101 场景;
|
||||
- 静态检查;
|
||||
- 生成报告。
|
||||
|
||||
Codex不负责:
|
||||
|
||||
- NavSea 修改;
|
||||
- V19 release;
|
||||
- tag;
|
||||
- publish;
|
||||
- 覆盖 V18;
|
||||
- Jest。
|
||||
|
||||
Mac Native 开发/编译原则保持;不要使用 Linux Native 环境。
|
||||
|
||||
---
|
||||
|
||||
## 10. 完成报告
|
||||
|
||||
生成:
|
||||
|
||||
`docs/报告/STEP-101_RenderOrchestrator销毁生命周期修复_Codex完成报告_v1.md`
|
||||
|
||||
Step 记录:
|
||||
|
||||
`docs/50_Step记录/STEP-101_RenderOrchestrator销毁生命周期修复_v1.md`
|
||||
|
||||
报告必须写:
|
||||
|
||||
- root cause;
|
||||
- start HEAD;
|
||||
- 修改文件;
|
||||
- destructor teardown 顺序;
|
||||
- observer detach 语义;
|
||||
- 为什么不依赖成员声明顺序;
|
||||
- tests added;
|
||||
- 实际运行 / NOT RUN;
|
||||
- STEP-100 locality 是否保持;
|
||||
- 风险;
|
||||
- 未发布 V19(Codex 阶段)。
|
||||
|
||||
Codex阶段不 push,由 RDC 验收后统一 commit/push。
|
||||
|
||||
---
|
||||
|
||||
## 11. V19 发布门槛
|
||||
|
||||
仅当:
|
||||
|
||||
- Native compile PASS;
|
||||
- focused C++ tests PASS;
|
||||
- Android Validation teardown loop PASS;
|
||||
- STEP-100 locality regression PASS;
|
||||
- NavSea V19 真实 5 次冷启动 >30s PASS;
|
||||
- crash buffer 无 destroyed mutex;
|
||||
|
||||
才允许发布:
|
||||
|
||||
- RN / Android:`13.4.1-particle.19`
|
||||
- iOS:`6.28.0-particle.19`
|
||||
- tag:`maplibre-particle/rn/13.4.1-particle.19`
|
||||
|
||||
V18 保持不可变,不覆盖、不删除。
|
||||
|
||||
---
|
||||
|
||||
## 12. 最终原则
|
||||
|
||||
正常:
|
||||
|
||||
```text
|
||||
MapView unmount
|
||||
Style generation replacement
|
||||
renderer.reset()
|
||||
Activity recreate
|
||||
```
|
||||
|
||||
都是合法生命周期。
|
||||
|
||||
Particle Native 必须做到:
|
||||
|
||||
> Renderer teardown 永远不能因为 observer late callback 访问已销毁 mutex/state 而杀掉宿主 App。
|
||||
|
||||
---
|
||||
|
||||
# 13. Codex 6-Sol High 架构评审修订(v2,优先级高于前文冲突表述)
|
||||
|
||||
只读评审结论:`APPROVE_WITH_CHANGES`。
|
||||
|
||||
## 13.1 根因表述修正
|
||||
|
||||
当前已经**代码层证实**存在生命周期漏洞:`readinessDiagnosticsMutex` / readiness state 的析构顺序早于 `renderSources`,而 `RenderSource` observer 仍指向 `RenderOrchestrator`;source/tile teardown 可同步或延迟回调进入 `onTileAction/onTileChanged` 并访问 mutex。
|
||||
|
||||
该漏洞与现场 `pthread_mutex_lock called on a destroyed mutex` 高度吻合;在没有完整符号化 crash stack 精确到具体 callback 前,不把“唯一现场根因”写成数学意义上的唯一证明。
|
||||
|
||||
## 13.2 teardown 必须双 drain
|
||||
|
||||
最低安全顺序调整为:
|
||||
|
||||
```text
|
||||
contextLost layer handling
|
||||
↓
|
||||
第一次 threadPool.waitForEmpty()
|
||||
↓
|
||||
detach RenderSource observers
|
||||
↓
|
||||
detach GlyphManager / ImageManager observers
|
||||
↓
|
||||
renderSources.clear() // readiness mutex/state 此时仍存活
|
||||
↓
|
||||
第二次 threadPool.waitForEmpty()
|
||||
↓
|
||||
继续既有 backend/context render-job teardown
|
||||
↓
|
||||
成员析构
|
||||
```
|
||||
|
||||
原因:source/tile destruction 本身可能投递新的 tagged cleanup/deferred work,第一次 drain 不能覆盖 clear 过程中产生的新任务。
|
||||
|
||||
同时必须审计并在报告说明:`TaggedScheduler::waitForEmpty()` 不等于清空 `runOnRenderThread` 队列;后者依赖现有 backend/context render-job 生命周期。不得声称双 drain 自动证明所有 render-thread job 已清空。
|
||||
|
||||
## 13.3 Observer detach 范围
|
||||
|
||||
除了所有 `RenderSource`:
|
||||
|
||||
- `glyphManager->setObserver(nullptr)`;
|
||||
- `imageManager->setObserver(nullptr)`;
|
||||
|
||||
也应在 owner teardown 时显式 detach(前提是现有 API 的 nullptr 已安全回 NullObserver)。
|
||||
|
||||
`RenderSource::setObserver(nullptr)` 必须改为 NullObserver fallback。
|
||||
|
||||
不得直接给 `TilePyramid` / `Tile` observer 写 nullptr,除非其 API 本身有同等安全语义;本任务不扩展到这一步。
|
||||
|
||||
## 13.4 teardown flag
|
||||
|
||||
默认不增加 teardown atomic flag。
|
||||
|
||||
若实现审计发现真实并发 callback 不受 renderer thread / tagged scheduler 串行保证约束,必须先报告;atomic flag 只能二次防护,不能替代 observer detach、drain 和可等待取消。
|
||||
|
||||
## 13.5 Android Validation 证据升级
|
||||
|
||||
T1~T4 每一轮必须能证明发生了**真实 Native renderer reset**:
|
||||
|
||||
- 旧 MapView detach / SurfaceView detach;
|
||||
- `nativeReset()`;
|
||||
- `MapRenderer::resetRenderer()` 进入/完成;
|
||||
- 新 renderer style ready;
|
||||
- 新 renderer diagnostics 可用。
|
||||
|
||||
不能把 `setStyle()`、clear field、只读 diagnostics 当成 teardown 测试。
|
||||
|
||||
推荐按代次销毁并重建 MapView,或 Activity recreate;T2 至少 20 次已确认 reset。
|
||||
|
||||
T3:每轮 reset 前保持动态 GeoJSON/source mutation。
|
||||
|
||||
T4:每轮 reset 前调用一次 Native diagnostics,模拟 NavSea 8 秒 probe 的等价条件。
|
||||
|
||||
每轮应等待 source/tile 确实进入运行态,而不是只按固定 sleep 机械计数。
|
||||
|
||||
## 13.6 测试必须覆盖真实 source teardown
|
||||
|
||||
空 `RenderOrchestrator` 析构测试不够。
|
||||
|
||||
非 Jest C++ 测试至少需要一个含 RenderSource / tile callback 的 teardown 场景,使 source cancellation / callback 能在销毁边界发生,并验证旧 observer 不再收到回调。
|
||||
|
||||
## 13.7 正常 source erase / clearData 审计
|
||||
|
||||
必须只读检查 `clearData()` 和正常 source erase/replacement 路径,因为它们也会销毁 RenderSource。
|
||||
|
||||
本任务主要修 owner teardown;不得未经证明把 destructor 修复泛化为“所有 source replacement 异步问题均已解决”。若发现相同 observer 生命周期漏洞在正常 erase 路径存在,应做最小同源修复或明确 BLOCK,不得隐藏。
|
||||
|
||||
## 13.8 V19 候选验收顺序
|
||||
|
||||
V19 发布门槛修正为:
|
||||
|
||||
```text
|
||||
STEP-101 source code PASS
|
||||
→ 构建未公开的 V19 candidate artifacts
|
||||
→ Validation App 实机 PASS
|
||||
→ NavSea 使用 candidate 做 5 次冷启动/teardown 验收
|
||||
→ 公开发布不可变 V19
|
||||
→ public readback
|
||||
→ finalize/tag
|
||||
```
|
||||
|
||||
不得先公开 V19 再做 NavSea 验收。
|
||||
262
docs/40_任务/STEP-102_RenderSegment无Placement段局部复用_Codex任务_v1.md
Normal file
262
docs/40_任务/STEP-102_RenderSegment无Placement段局部复用_Codex任务_v1.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# STEP-102 RenderSegment 无 Placement 段局部复用 Codex 任务 v1
|
||||
|
||||
## 1. Step 编号和目的
|
||||
|
||||
STEP-102:修复 full CPU 多 Retained Segment 下 placement aggregate gate 的不必要扩散,使**结构上不具备 placement 能力**的 Retained Segment 能在其他 placement-bearing Segment fallback/live 时继续独立 composite/reuse。
|
||||
|
||||
本 Step 的设计依据:
|
||||
`docs/20_调查/RenderSegment多Retained段全局Placement门槛_粒子管理员审查说明_v3.md`。
|
||||
|
||||
## 2. 当前已冻结基线
|
||||
|
||||
- 仓库:`/Users/tei/dev/MapLibreParticleLab-step102`
|
||||
- branch:`step102-placement-free-retained-locality`
|
||||
- start HEAD:`6df21dac38f072c5ad35b8dfc7ec5217509602bc`
|
||||
- upstream base:MapLibre Native core 既有冻结基线,不升级
|
||||
- V19/V20 release worktree:冻结,只读,不修改
|
||||
- STEP-100 source-scoped locality:必须保持
|
||||
- STEP-101 teardown 修复:必须保持
|
||||
- Fast Path:本 Step 不修改
|
||||
- C-001:不升级
|
||||
|
||||
## 3. 本 Step 目标
|
||||
|
||||
必须实现:
|
||||
1. 增加结构性 placement-capable range 查询;
|
||||
2. full CPU 每个 Retained Segment 独立计算 placement gate;
|
||||
3. placement-free Retained 不再被其他 Segment 的 placementChanged/symbolFadeChange 纯 aggregate gate 拖入 fallback;
|
||||
4. placement-bearing Retained 继续使用现有保守 placement gate;
|
||||
5. 从 full CPU `globalLiveFallback` 移除纯 aggregate placement 条件;
|
||||
6. 保持真正全局 fail-closed 条件;
|
||||
7. diagnostics 增加结构 placement、per-segment gate、实际 composite/live 与全局 main-buffer execution 信息;
|
||||
8. RN diagnostics TS 类型做 additive 扩展;
|
||||
9. 增加对应 C++ 测试源码与 Android Validation 场景源码;
|
||||
10. 不改变 Style Z-order、mixed executor、C-001 和 RN method surface。
|
||||
|
||||
## 4. 非目标 / 禁止事项
|
||||
|
||||
禁止:
|
||||
- placement-bearing Segment 之间的局部碰撞缓存;
|
||||
- per-segment collision graph / symbol fade / placement fingerprint;
|
||||
- Fast Path 改造;
|
||||
- multi-continuous Fast Path;
|
||||
- 重写 `visitRenderSegmentExecution()`;
|
||||
- 修改 NavSea;
|
||||
- 新增 NavSea 私有 Native API;
|
||||
- 修改 C-001;
|
||||
- 修改 V19/V20 release worktree/tag;
|
||||
- 升级 MapLibre、NDK、Gradle、AGP、Java、Node 或其他工具链;
|
||||
- 为通过测试降低 fail-closed 门槛;
|
||||
- Android Gradle/build、APK/AAR build、ADB、设备操作;
|
||||
- Jest。用户未要求 Jest,本任务不得新增或执行 Jest。
|
||||
|
||||
## 5. 允许修改范围
|
||||
|
||||
生产代码优先限制在:
|
||||
- `src/mbgl/renderer/render_orchestrator.hpp`
|
||||
- `src/mbgl/renderer/render_orchestrator.cpp`
|
||||
- `src/mbgl/renderer/renderer_impl.cpp`
|
||||
- `include/mbgl/renderer/render_segment.hpp`
|
||||
- `src/mbgl/renderer/retained_underlay_runtime_state.hpp`
|
||||
- `src/mbgl/renderer/render_segment_json.hpp`
|
||||
- `packages/maplibre-particle-rn/src/types.ts`
|
||||
|
||||
测试/Validation 允许:
|
||||
- `test/renderer/retained_underlay_cache.test.cpp`
|
||||
- 与现有 Particle Validation 场景直接相关的最小 Android Test App 文件
|
||||
|
||||
文档允许:
|
||||
- 本任务书
|
||||
- `docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md`
|
||||
- `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md`
|
||||
- `粒子开发记录.md`
|
||||
- v3 审查说明只读,除非发现明确事实错误;若需改,停止并先报告
|
||||
|
||||
如果实现必须扩大生产代码范围,先停止并报告原因,不得自行扩张架构。
|
||||
|
||||
## 6. 禁止修改范围
|
||||
|
||||
- NavSea 仓库
|
||||
- `navsea-particle-integration` contract/RFC/ADR
|
||||
- Fast Path 逻辑、`tryRenderParticleFastFrame()`、`singleContinuousSegment()` 语义
|
||||
- `retainedRangeUsesPlacement()` 现有动态语义
|
||||
- mixed executor 算法
|
||||
- Source `isLoaded()` 定义
|
||||
- STEP-100 source revision/locality 语义
|
||||
- STEP-101 teardown 生命周期语义
|
||||
- renderer/backend 架构
|
||||
- release/version/tag/publish 坐标
|
||||
|
||||
## 7. 实施要求
|
||||
|
||||
### 7.1 结构性 placement-capable 查询
|
||||
|
||||
新增 full CPU retained 专用查询,必须基于 layer 结构,而不是当前帧 placementData。
|
||||
|
||||
最小保守语义:
|
||||
- range 中存在 `symbol` layer → placement-capable
|
||||
- 无 `symbol` layer → placement-free
|
||||
- custom/custom-drawable 继续由 unsupported gate 处理
|
||||
|
||||
不得用 `needsPlacement()==false` 证明 placement-free。
|
||||
|
||||
### 7.2 per-segment placement gate
|
||||
|
||||
每个 Retained Segment 至少形成两个明确事实:
|
||||
- structural placement capability
|
||||
- current full-CPU placement gate result
|
||||
|
||||
placement-free Segment 不受纯 global placement gate 阻塞。
|
||||
placement-bearing Segment 本 Step 继续沿用旧保守 gate,不承诺稳定后 reuse。
|
||||
|
||||
变量/字段命名不得把 `symbolFadeChange==0` 错称为严格 placement stable。
|
||||
|
||||
### 7.3 full CPU mixed execution
|
||||
|
||||
`segmentSupported` 改为使用对应 Segment placement gate。
|
||||
|
||||
`globalLiveFallback` 仅移除纯 aggregate placement 条件,其他真正 global 条件继续保留。
|
||||
|
||||
不得重写 `visitRenderSegmentExecution()`。
|
||||
|
||||
### 7.4 fallback reason
|
||||
|
||||
`static-placement` 必须按 Segment 自身 placement capability/gate 判定,不能从 aggregate reason 无差别传播。
|
||||
|
||||
### 7.5 diagnostics
|
||||
|
||||
每个 Segment 最少新增等价语义:
|
||||
- `placementCapable`
|
||||
- `placementGatePassed`
|
||||
- `actualExecution = composite | live`
|
||||
|
||||
全局最少新增等价语义:
|
||||
- `placementChanged`
|
||||
- `symbolFadeChange`
|
||||
- `placementTransitionActive`
|
||||
- `crossSourceCollisions`
|
||||
- `mainBufferExecutionMode = mixed | global-live`
|
||||
- `globalLiveFallbackReason`
|
||||
|
||||
`actualExecution` 必须反映本帧 main-buffer 最终实际执行,不能根据 cache finalDecision 推导。
|
||||
Diagnostics 查询必须无副作用、不得推进 revision。
|
||||
|
||||
### 7.6 RN 类型
|
||||
|
||||
只扩展现有 diagnostics 返回类型,不新增 method,不改变 `setRenderSegmentPlan()` 输入 contract。
|
||||
Android/iOS Shared Core JSON 语义保持一致。
|
||||
|
||||
## 8. 构建要求
|
||||
|
||||
Codex 本阶段**不得执行任何 Android 编译/Gradle/APK/AAR build**,也不得启动长时间 CMake/Ninja/Bazel 构建。
|
||||
|
||||
Codex 完成代码后只需提供精确验证命令,由后续 RDC/用户按规则执行。其中 Android 编译由用户手工执行。
|
||||
|
||||
Codex 可执行的机械静态检查仅限:
|
||||
- `git diff --check`
|
||||
- 只读 grep/rg/git diff/status
|
||||
- 不产生构建产物的格式/静态检查(若仓库已有且无需安装依赖)
|
||||
|
||||
不得安装或升级系统依赖来制造测试 PASS。
|
||||
|
||||
## 9. 测试要求
|
||||
|
||||
Codex 必须新增/补强测试源码,但本阶段不执行大型测试。
|
||||
|
||||
至少覆盖:
|
||||
1. placement-free R0 + placement-bearing R1:R0 可 composite,R1 live;
|
||||
2. 含 symbol 但当前 placementData 为空:仍判定 placementCapable=true;
|
||||
3. 两个 placement-free Retained:持续 reuse/composite;
|
||||
4. source-local fading/mutation 回归不误伤 R0;
|
||||
5. placement-bearing 在 transition disabled / `symbolFadeChange=1` 等状态仍不被本 Step 放宽;
|
||||
6. 真正 global gate 继续 global-live/fail-closed;
|
||||
7. topology 变化释放旧 resource;
|
||||
8. cache decision=reuse 但 global-live 时,diagnostics 的 actualExecution 必须为 live;
|
||||
9. diagnostics JSON/TS 字段语义一致且查询无副作用。
|
||||
|
||||
Android Validation 场景应能在后续手工构建后明确输出 STEP-102 验收所需字段,不依赖 NavSea。
|
||||
|
||||
## 10. 验收标准
|
||||
|
||||
代码审计门槛:
|
||||
- [ ] 新增结构性 placement-capable 查询
|
||||
- [ ] 未改变 `retainedRangeUsesPlacement()` 旧语义
|
||||
- [ ] full CPU per-segment placement gate 生效
|
||||
- [ ] placement-bearing 继续保守
|
||||
- [ ] `globalLiveFallback` 只移除纯 aggregate placement 条件
|
||||
- [ ] 真正 global gate 保留
|
||||
- [ ] mixed executor 未重写
|
||||
- [ ] Fast Path 无语义修改
|
||||
- [ ] per-segment fallback reason 正确
|
||||
- [ ] diagnostics 有 actualExecution 与 main-buffer mode/fallback reason
|
||||
- [ ] RN method surface 不变
|
||||
- [ ] C-001 不变
|
||||
- [ ] 测试源码覆盖设计矩阵
|
||||
- [ ] `git diff --check` PASS
|
||||
|
||||
运行态 PASS 不在 Codex 阶段宣称。Android 手工编译与真机验证未完成前,STEP-102 状态只能写“代码完成 / 等待验证”或同等非 PASS 状态。
|
||||
|
||||
## 11. Git 要求
|
||||
|
||||
- 工作分支:`step102-placement-free-retained-locality`
|
||||
- 禁止修改 particle/main 工作区
|
||||
- 禁止 `git add -A`、`git add .`、`git reset --hard`、`git clean`
|
||||
- 只 scoped staging 本任务文件
|
||||
- 不提交无关 dirty/untracked 文件
|
||||
- Codex 可在实现完成、静态检查通过后创建 scoped implementation commit,但**不得 merge 到 particle/main、不得 push release 分支/tag、不得发布制品**
|
||||
- 是否 push/merge 由后续独立验收决定
|
||||
|
||||
## 12. 必做输出
|
||||
|
||||
Codex 完成后必须交付:
|
||||
1. 生产代码修改;
|
||||
2. C++ 测试源码;
|
||||
3. Android Validation STEP-102 场景源码/日志字段;
|
||||
4. `docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md`;
|
||||
5. `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md`;
|
||||
6. 追加 `粒子开发记录.md`;
|
||||
7. 精确列出后续验证命令;
|
||||
8. 明确列出所有 NOT RUN / BLOCKED 项;
|
||||
9. Git diff/status/commit(若创建)事实。
|
||||
|
||||
## 13. 执行报告完整文件名
|
||||
|
||||
固定:
|
||||
`docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md`
|
||||
|
||||
同主题后续报告只递增 `_v2/_v3`,不得另造近义文件名。
|
||||
|
||||
## 14. 执行报告固定内容
|
||||
|
||||
至少包含:
|
||||
1. 执行结论:只能按实际写代码完成/等待验证、PARTIAL、BLOCKED 或 FAIL;未运行 Android 不得写运行态 PASS
|
||||
2. Git 基线:branch/start HEAD/end HEAD/status
|
||||
3. 实际修改文件
|
||||
4. 新增文件
|
||||
5. 实现内容逐条对照任务书
|
||||
6. 与 v3 设计差异
|
||||
7. Fast Path / mixed executor / C-001 未修改审计
|
||||
8. diagnostics 新字段与语义
|
||||
9. 测试源码覆盖矩阵
|
||||
10. 实际执行的静态检查
|
||||
11. 未执行的 build/test/Android/设备项目
|
||||
12. 用户手工 Android 构建命令
|
||||
13. 后续 RDC/真机验收命令与硬门槛
|
||||
14. 已知风险与未完成事项
|
||||
15. Git commit 信息(若有)
|
||||
|
||||
## 15. 阻塞与停止条件
|
||||
|
||||
遇到以下任一情况必须停止扩大修改并报告:
|
||||
- 结构性 placement capability 不能仅靠既有 layer type 安全判定,需要新增更大公共抽象;
|
||||
- 必须修改 Fast Path 才能完成本任务;
|
||||
- 必须重写 mixed executor;
|
||||
- 必须改变 collision/Placement 核心算法;
|
||||
- 必须修改 C-001 / RN method surface;
|
||||
- 必须修改 NavSea;
|
||||
- 必须扩大到 renderer/backend 架构重构;
|
||||
- 发现 global revision 仍有未预期的 placement 推进,需要新设计;
|
||||
- 需要升级工具链/依赖;
|
||||
- 需要删除或弱化既有测试/安全门槛。
|
||||
|
||||
若实现范围保持在 v3 冻结边界内,可直接完成代码并停在“等待手工构建/运行验证”。
|
||||
43
docs/40_任务/STEP-104_官方Native13.6.1升级阶段A_Codex任务_v1.md
Normal file
43
docs/40_任务/STEP-104_官方Native13.6.1升级阶段A_Codex任务_v1.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# STEP-104 官方 MapLibre Native Android 13.6.1 迁移:第一阶段 Codex 任务 v1
|
||||
|
||||
## 1. 基线与职责
|
||||
- 用户授权 **GPT-6.1 Sol / High** 实施官方跟进,使用 Mac 固定 GNU Screen 会话 `20825.7445.codex`,不要自行切换模型和推理档位。
|
||||
- 项目独立 worktree:`/Users/tei/dev/MapLibreParticleLab-upgrade-android-1361`,分支 `upgrade/android-native-13.6.1-20261009`。
|
||||
- 当前第一父基线:**官方 Android Native 13.6.1** peeled commit `c7506d6aff3800e946f89e1a51432fc22d1a6534`;原有自研稳定版本(.21)HEAD `630ec657687bad4200c059bbccbb950d9c6f7ce9`,审计与报告闭环 HEAD `b433775348373b10fba02dc0e1f728bacd72f9e7`。
|
||||
- Integrated repo Linux 远端 `main` 已同步至 `80667d6c343411d03a760425438e3d292f452118`;当前遵守 C-001/C-002、RFC-004、ADR-001,不得擅自改公开 API 或将 Android 新行为写进跨平台 contract。
|
||||
- 先读原工作树 `/Users/tei/dev/MapLibreParticleLab/AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/00_项目规范/`、`docs/00_项目总则/README.md` 与四份有效总则,再读现有审计报告 `/Users/tei/dev/MapLibreParticleLab-upstream-audit-20261009/docs/报告/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex完成报告_v1.md`、近期 STEP-100/101/102 记录以及本任务。
|
||||
- 另一个 Mac `particle/main` 工作树有用户未跟踪文件且落后远端,禁止修改;历史 release/STEP-103 工作树均不可改。
|
||||
|
||||
## 2. 本轮的工程目标和停点
|
||||
目标是形成一个**可测试的 Android Native 13.6.1 官方底座候选**,继续保留自研 Field/QBIN/Particle/WeatherColor/RenderSegment/Retained 功能,不重写、不扩大功能。当前不是新版发行。
|
||||
- A:在本分支以官方 13.6.1 为第一父,安全合入 `b433775348...` 自研历史的有效差异。优先使用 `git merge --no-commit --no-ff b433775348...`;解决全部 rename/content/modify-delete 冲突,不允许选择整文件 `ours/theirs` 丢失官方修复或自己的功能。核实 `git diff --check`、冲突标记和完整树,再创建明确 merge commit。可启用 rerere。
|
||||
- B:适配官方 `mbgl→mln` 命名空间、include、Layer/Source/Shader factory、`RenderLayer::update(PaintParameters)`、`RenderStaticData::backendSize` 移除、Renderer lifecycle、RenderSegment 和 GL 粒子后端。只修改当前升级必要的官方接入点,保留现有 fail-closed、source/placement/revision/fast-path gate、map Style 顺序、stencil/target 安全。
|
||||
- C:源码修改完成后,列出**精确可执行**的 Android Native C++/OpenGL 编译与定向测试命令,让 RDC 在 Mac 或 Linux 执行;Codex 自身不得进行耗时 build、link、codegen、打包或 Jest。可以执行 `git diff --check`、少量静态检查。
|
||||
- D:若完整迁移无法在本轮完成,优先形成单独的、可复现且可回退的 Git checkpoint、明确残留冲突/失败清单;未清除 Git 冲突不得提交伪造的成功 merge。发生公共 API/Contract 变化或 iOS 专属需求立即停下来报告,不自行扩大跨团队范围。
|
||||
|
||||
## 3. 必须保留的现有行为
|
||||
- C-002 QBIN V4 单帧 exact match、双帧合法插值、每 fieldKey 八帧和原子拒绝语义不变;不同 reference/dataset/profile 不混用;RN Host 负责加载、requestedForecastTime,Native submit 不调整时间。
|
||||
- WeatherColorLayer 与 RasterParticleLayer 独立;粒子 GPU ping-pong、trail 和 RenderSegment 局部缓存存在;不允许用 CPU 动画替代、不允许关闭关键保护逻辑使其编译通过。
|
||||
- Retained 保留 Z-order、opaque/translucent 绘制语义与 segment 索引;Source/layer/style/context/placement 变更失效安全、销毁不泄漏或使用陈旧 texture。
|
||||
- 官方新版 Feature State 接口不得被自研逻辑覆盖或静默禁用;只记录 Native 后续 RN 11.5 测试 Gate,不升级 RN 包本轮版本锁。
|
||||
|
||||
## 4. 范围
|
||||
- 允许:升级分支中的官方 Native Core/Shader/CMake、必要的 Android Native/JNI 接入、粒子模块源码、测试代码的机械迁移与必要接口适配,以及必要记录。
|
||||
- 禁止:修改 `particle/main`、`release/particle.21`、STEP-103 工作树、NavSea、Integration 合同、iOS 专属 Metal/Bridge 功能实现、官方仓库、Node/Gradle/NDK 工具链;禁止发布 AAR/npm、build APK、改 public API/ABI 语义。
|
||||
- 旧 .21 所有发布坐标保持冻结。iOS 旧实现应尽可能保留源码,但本轮只允许写 **NOT VERIFIED**,不允许声称 Metal/Swift/XCFramework PASS。
|
||||
|
||||
## 5. 记录和 Git:强制多次小提交
|
||||
- 在仓库**根目录的 `recoder_step.md`** 追加每项实质进展,简明中文且 append-only,记录日期、基线、当前变化、已完成、剩余问题、下一步、关联 commit。还需追加 `粒子开发记录.md`(合入后存在),同步更新 `docs/50_Step记录/STEP-104_官方Native13.6.1升级阶段A_v1.md`。
|
||||
- 本任务已有独立启动 checkpoint 提交。后续**至少尝试**按合并/结构迁移/接口修复/文档三个功能批次提交。每次提交限定本主题的文件并有清晰中英 commit message。不允许为了凑提交提交空文件或破坏历史;若阻塞,就如实说明只完成哪些。
|
||||
- **仅 push 本次升级分支**到 `origin/upgrade/android-native-13.6.1-20261009`;切勿 push `particle/main`、force push、合并回主线、push upstream。需等 RDC 独立编译验收后再由 RDC 最终执行 push;Codex 此轮只 commit,不负责最终远端验收。
|
||||
- 用户正式要求阶段记录必须叫 `recoder_step.md`,**不可擅自纠正拼写或用其它文件代替**。
|
||||
- 工作期间若发现现存不相关改动,不能纳入任何提交。
|
||||
|
||||
## 6. 完成报告与检查
|
||||
- 完成报告固定 `docs/报告/STEP-104_官方Native13.6.1升级阶段A_Codex完成报告_v1.md`,必须记录:实际模型与推理档位、原始 SHA 和候选 SHA、每个 commit 与变更范围、merge 冲突解决的准确状态、迁移清单、具体核心 API/行为检查、无 build 时 NOT RUN、给 RDC 的精确构建命令、剩余问题、Android/iOS/RN 明确边界、下一 Gate。
|
||||
- 命名绝对不能自称正式 SDK PASS;如只完成局部迁移标 PARTIAL / BLOCKED。Codex 结束前检查 `git status --short`、`git diff --check`、阶段日志存在,任务范围与 commit 对得上。
|
||||
- 对用户的最终下一停点是 Android 官方 13.6.1 候选的 Core/Android OpenGL 精确编译 Gate;RN 11.5/iOS/发布留后续。
|
||||
- 若需要新增跨平台语义/接口必须暂停并记录 Integration 协调所需证据,而不是自行做新合同。
|
||||
|
||||
## 7. 本阶段特殊实施规则
|
||||
按现有项目 `AGENTS.md`:**Codex 写代码,RDC 负责独立编译和验收**。仅在完成局部代码和提交后提供精确编译命令,等待 RDC 结果,如失败再进入下一轮修复。不要自行执行长时间构建。
|
||||
39
docs/40_任务/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex任务_v1.md
Normal file
39
docs/40_任务/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex任务_v1.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# UPSTREAM-001 MapLibre 官方升级兼容性架构审计(只读代码,2026-10-09)
|
||||
|
||||
## 授权与模式
|
||||
- 用户明确授权 Mac 使用 **GPT-6 Astra High** 做以未来跟随官方升级为目的的架构审计。
|
||||
- Codex 执行器须显式指定 `gpt-6-astra`、`model_reasoning_effort=high`,实际配置从 Codex JSONL 开始事件核实;如不一致,报告 BLOCKED,不能伪称。
|
||||
- 只读源代码。仅允许生成/修改本任务书和 `docs/报告/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex完成报告_v1.md`;禁止改 C++、RN、Java、ObjC、构建脚本和依赖。
|
||||
- 仓库为独立干净审计 worktree,基于正式远端 `origin/particle/main` 的 `.21`,不可操作其他已有脏工作树。无需构建 APK、AAR、Xcode,无需 Jest。不能伪造运行验收。
|
||||
- 不修改 Integration COORD/RFC/ADR/Contract;如建议跨平台契约变化仅列出待协调项。
|
||||
|
||||
## 权威输入
|
||||
- `/root/sourceserver/navsea-particle-integration` 为 Linux Integration;已由 RDC 同步到 `80667d6c343411d03a760425438e3d292f452118`。Mac 上可读取到的合同以已存在文件为准,不要猜测。
|
||||
- 阅读本仓库 `AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/10_架构/20_粒子系统总体架构设计_v1.md`、`docs/00_项目总则/粒子系统项目规则与设计决策_v1.md`、`docs/30_设计/STEP-094_通用RenderSegment模型与Style分类Diagnostics设计_v1.md` 和相关 STEP-098/099/100/101/102/103 实现记录。
|
||||
- 自定义现行发布:`630ec657687bad4200c059bbccbb950d9c6f7ce9` (`13.4.1-particle.21`)。
|
||||
- 初始 upstream Core:`18545ca10d296704b2cba675b182ff2c8da24588` (见 `PARTICLE_BASELINE.md`);验证实际 merge-base。
|
||||
- 官方 MapLibre Native Android `android-v13.6.1` peeled commit `c7506d6aff3800e946f89e1a51432fc22d1a6534`。
|
||||
- 官方 MapLibre Native iOS `ios-v6.31.0` peeled commit `01791ad02c1bfe3b22c42a97619b972aba962f82`。
|
||||
- 官方 MapLibre React Native `v11.5.0`;现有 Particle RN `11.3.6` peer/dev 锁及 Android AAR replacement、iOS SPM/Podspec 需独立审计。不能混淆 RN 11.5.0 与 Native 13.6.1。
|
||||
|
||||
## 必查问题
|
||||
1. 原始目标“官方可持续升级、自研粒子和 RenderSegment 可重复移植”离目前真实代码有多远?用逐文件证据分类:**纯新增扩展**、**不可避免的官方接入 hook**、**可外提的官方修改**、**深耦合必须重构**,另列构建/平台桥接。不要用“62 个修改文件 = 62 个冲突”。
|
||||
2. 在 `git diff` 与 `git merge-tree` dry-run 基础上,对 Android 13.6.1 和 iOS 6.31.0 分别量化冲突文件与交叉文件、可自动合并与疑似行为冲突。绝不可真实 merge/rebase 任何生产分支。优先核对 `renderer_impl.cpp`、`render_orchestrator.cpp`、`render_target.cpp`、`render_layer.hpp`、`render_source.cpp`、`paint_parameters.cpp`、RenderSegment/Retained cache、GPU backend、Style/Layer factory、JNI/Android/iOS 对接代码。
|
||||
3. 以源代码里的函数/类名证明现有 Particle Core/Field/WeatherColorLayer/GPU 模块是否独立;列出真正只需 hook 的文件和未来易碎调用。用修复方案区分 thin hook、抽象接口、适配器、source-to-segment dependency、offscreen target/placement 等,不得建议一刀切“重写”。
|
||||
4. RenderSegment 与 Particle Fast Path 的数据依赖、分层失效、Style 顺序、Opaque/Translucent、Placement、Context loss、资源所有权、Top/Bottom Retained、multi-segment 未来兼容约束。区分已实现功能和目前 fail-closed 限制。
|
||||
5. 核查 `packages/maplibre-particle-rn` 的 `package.json`、`app.plugin.js`、`MapLibreParticleRN.podspec`、Native API 等;给出 RN 11.5.0 受官方 Android 13.6.1/iOS 6.31.0 依赖推动的单 SDK 依赖收敛风险、代码适配点、功能验证清单。
|
||||
6. 准备升级顺序和可回滚 Gate:什么必须先重构、什么可以直接合并、哪些要不同平台分别验证,什么情况下必须停止并回 Integration 新 RFC/Contract。建议未来 upstream 版本跟踪工作流和“patch footprint budget”;明确对长期维护代价影响。
|
||||
7. 逐项目给出 P0/P1/P2 表,包含路径、当前耦合证据、方案、风险、工作量相对估计、验收标准、Android/iOS影响;结论为 GO / CONDITIONAL GO / BLOCKED,不得把未编译当 PASS。
|
||||
|
||||
## 调查方法与客观限制
|
||||
- 最少执行 `git merge-base`、`git diff --name-status`、`git merge-tree --write-tree --messages` 对两个官方 Native 目标作三方模拟;记录命令、exit code、冲突路径。merge-tree 会在 Git object db 创建对象但不改源码或分支,允许。
|
||||
- 深入看源码定义和调用,不只扫描关键词;尽量提供可读且可复核的 `path:line` 和 commit hash。
|
||||
- 官方 tag 比较若产生无共同祖先、shallow、无法下载等障碍,如实记录并提出可复现替代方案。
|
||||
- 不强行运行常规编译、Android 实机、iOS 设备或 Jest。
|
||||
- 对官方 RN 版本差异使用 release changelog、已有源码;未下载的 RN 文件不得假称已审查。
|
||||
- 审计报告必须中文,章节包含:结论摘要、核对的版本与 SHA、方法和数据可信度、两条 Native 升级线冲突统计与具体文件、Particle 耦合清单、RenderSegment 耦合清单、RN 11.5.0 适配风险、改造优先级矩阵、阶段性迁移与验收、阻塞和未知、实际模型和文件修改清单。
|
||||
|
||||
## 必做输出和 Git 收尾
|
||||
- 写入 `docs/报告/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex完成报告_v1.md`;如不存在 `docs/报告/` 则创建。
|
||||
- 工作树中仅允许审计任务 MD 和审计报告两份新增文档;完成 `git diff --check`、路径与报告完整性检查。
|
||||
- **不要自行 commit 或 push**;执行器将先独立核对报告,再将仅这两份文档以隔离分支提交、确认快进后 push 到 `origin/particle/main`,最终回填 Git 状态。若未收到执行器的最终 Git 回执,报告必须写 `Git 收尾待 RDC 验收`,不能自称已推送。
|
||||
@@ -0,0 +1,80 @@
|
||||
# STEP-092 Continuous Range 可退化分段 Retained Cache v1
|
||||
|
||||
## 状态
|
||||
|
||||
**进行中:Codex 实现完成,等待 RDC 独立编译与运行验证**
|
||||
|
||||
## 目标与基线
|
||||
|
||||
- 分支:`particle/main`
|
||||
- 起始 HEAD:`b29e564944197072a0effaec36ca95c48fe0649b`
|
||||
- 起始 `origin/particle/main`:`b29e564944197072a0effaec36ca95c48fe0649b`
|
||||
- Implementation commit:`a9eaec6b65cc26aa70e03002bdc1326c46cad245`(`feat: add continuous retained render ranges`),已 push 至 `origin/particle/main`。
|
||||
- Style Layer 顺序是唯一 Z-order;App 只提交现有 `startLayerId` / `endLayerId` 闭区间。
|
||||
- 保留未配置 explicit range 时的 `startsRetainedDynamicRange()` legacy underlay 行为。
|
||||
|
||||
## 实现结构
|
||||
|
||||
- `RetainedUnderlayRuntimeState` 是 map-scoped range config 所有者;使用 mutex 保护 ID/config/resolution,config revision 单调递增。
|
||||
- `RenderOrchestrator::createRenderTree()` 基于完整 `orderedLayers`(包含 hidden layer)把 ID 解析为 Style index;不存在、倒序或 Style 未 ready 均 fail closed,不保留旧 index。
|
||||
- 内部统一使用 `[continuousBegin, continuousEndExclusive)`:Bottom、Continuous、Top 均由 Style index 自然退化。
|
||||
- 现有 cache 泛化为带 `begin/endExclusive` 与 Bottom/Top role 的 retained range cache;两个 cache 对象不等于两个 GPU cache,texture/render target/compositor 只在对应 range 实际存在时 lazy 创建。
|
||||
- explicit valid 时完全忽略 legacy boundary;explicit invalid 时不用 legacy 猜测,走完整 Renderer。
|
||||
|
||||
## 四种结构
|
||||
|
||||
| Style 结构 | Render Range | Retained GPU cache |
|
||||
|---|---:|---:|
|
||||
| Bottom + Continuous + Top | 3 | 2 |
|
||||
| Bottom + Continuous | 2 | 1(Bottom) |
|
||||
| Continuous + Top | 2 | 1(Top) |
|
||||
| Continuous only | 1 | 0 |
|
||||
|
||||
`startLayerId == endLayerId` 是合法 single-layer Continuous。hidden endpoint 仍决定 topology;range 是否存在只看 Style index 区间,不看当前 drawable/group 是否为空。
|
||||
|
||||
## 绘制与 global index
|
||||
|
||||
- cache build 的 opaque 使用区间 reverse traversal,translucent 使用 forward traversal。
|
||||
- callback ordinal 来自完整 `layerGroupsByLayerIndex`,`parameters.currentLayer` 与 `depthRangeSize` 沿用全 Style 语义,不对子区间重新编号。
|
||||
- main 顺序固定为:Bottom composite(若有)→ Continuous opaque/translucent → Top composite(若有)。
|
||||
- Top 与 Bottom 均使用透明 RGBA offscreen、现有 direct sample compositor 和 premultiplied alpha blend;未新增 land-mask 或业务判断。
|
||||
|
||||
## Invalidation 与 fallback
|
||||
|
||||
- camera/viewport/pixel ratio/style/layer/source/tile/image/glyph/placement/context/debug/3D 等继续进入 STEP-089 的 content/topology/static revision 模型。
|
||||
- range config revision、continuous begin/end、Bottom/Top topology 纳入 revision;配置变化会释放实际存在 cache 并使 prepared tree/fast gate 失配。
|
||||
- endpoint 删除、missing、倒序与 Style 未 ready:diagnostics 给出原因,cache key 变空并释放资源,full renderer 安全 fallback;后续 Style 恢复会重新解析。
|
||||
- correctness-first:无法只归因 Bottom 或 Top 时,两侧实际存在 cache 可同时失效。
|
||||
|
||||
## Particle-only CPU Fast Path
|
||||
|
||||
- gate 只要求实际存在的 retained cache valid;Bottom/Top 不存在时为 vacuous success,不产生 cache-missing miss。
|
||||
- fast frame 仅遍历 Continuous 区间,仍使用全局 ordinal。
|
||||
- explicit Continuous 中只允许 Renderer 已知的 WeatherColor/RasterParticle dynamic candidate;出现未知 Layer 时 fail closed 到 full CPU frame,但 range cache/Z-order 仍保持。
|
||||
- Continuous-only 可进入 0-cache fast gate;是否最终命中仍需满足 Particle、revision、placement、scene 等既有条件。
|
||||
|
||||
## API 与 diagnostics
|
||||
|
||||
- C++/Android/iOS/RN 增加 `setContinuousLayerRange(..., startLayerId, endLayerId)`;空 ID 拒绝,相同 ID 接受。
|
||||
- 保留 `setRetainedUnderlayEnabled()` 与 `getRetainedUnderlayDiagnostics()`。
|
||||
- pull diagnostics 增加 configured/valid、IDs/index、Bottom/Top present/build/reuse/invalidation;保留 aggregate fallback 与 `lastReason`,无 per-frame Release 日志。
|
||||
|
||||
## Directed tests
|
||||
|
||||
已新增源码覆盖:single/multi layer、missing/reversed、hidden endpoint、reorder/delete、四种 topology、0/1/2 cache decision、无 cache 的 fast gate、config revision 与 explicit/legacy 排他。
|
||||
|
||||
## 待 RDC 执行
|
||||
|
||||
```bash
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner -j3
|
||||
build-step088-opengl/mbgl-test-runner \
|
||||
--gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'
|
||||
cmake --build build-ios --target ios-sdk-static -- -quiet
|
||||
git diff --check
|
||||
```
|
||||
|
||||
RDC 还需独立核验 OpenGL/Metal 透明 Top composite、0/1/2 texture/FBO 生命周期和 stable frame 复用。Android Gradle/APK/ADB/设备项未由 Codex 执行。
|
||||
|
||||
## 当前结论
|
||||
|
||||
源码与 directed test 已实现并完成 scoped implementation push;在 RDC 返回 OpenGL、Metal、Native test 实际结果前,本 Step 不判 PASS。
|
||||
@@ -0,0 +1,99 @@
|
||||
# STEP-092 Continuous Range 可退化分段 Retained Cache v2
|
||||
|
||||
## 状态
|
||||
|
||||
**CLOSED / PASS(Mac Native 验证闭环)**
|
||||
|
||||
本版在 v1 的 Codex 实现基础上补入 RDC 独立编译、测试、修复与双后端核验结果。Android Gradle/APK/ADB/实体机与 Metal GPU frame capture 未执行,不伪造为已验证。
|
||||
|
||||
## Git 基线
|
||||
|
||||
- 分支:`particle/main`
|
||||
- 起始 HEAD:`b29e564944197072a0effaec36ca95c48fe0649b`
|
||||
- Codex implementation:`a9eaec6b65cc26aa70e03002bdc1326c46cad245`
|
||||
- Codex 文档:`b89c8c8cb4d941abdcd704b278284e209ba7399b`
|
||||
- RDC 验证修复:`4908244d2`(`fix: close STEP-092 native validation issues`)
|
||||
- 最终文档收尾提交在本文件提交后回读,以最终交付结果为准。
|
||||
|
||||
## 已实现架构
|
||||
|
||||
- Style Layer 顺序是唯一 Z-order 事实来源。
|
||||
- App/RN 只提交现有 `startLayerId` / `endLayerId` 闭区间。
|
||||
- Native 基于完整 `orderedLayers` 解析 index;hidden endpoint 仍参与 topology。
|
||||
- `startLayerId == endLayerId` 为合法 single-layer Continuous。
|
||||
- 内部统一为 `[continuousBegin, continuousEndExclusive)`。
|
||||
- 四种结构自然退化:
|
||||
- Bottom + Continuous + Top → 3 Render Range / 2 retained caches
|
||||
- Bottom + Continuous → 2 Render Range / 1 Bottom cache
|
||||
- Continuous + Top → 2 Render Range / 1 Top cache
|
||||
- Continuous only → 1 Render Range / 0 retained cache
|
||||
- explicit valid 时不混用 legacy boundary;explicit invalid 时 fail closed,不复用 stale index/cache。
|
||||
- global layerIndex / ordinal / `currentLayer` / `depthRangeSize` 保持全 Style 语义。
|
||||
- Opaque reverse、Translucent forward 保持。
|
||||
- Particle-only Fast Path 只检查实际存在的 retained ranges。
|
||||
|
||||
## RDC 编译与测试结果
|
||||
|
||||
### OpenGL test-runner
|
||||
|
||||
第一次编译失败:
|
||||
- `renderer_impl.cpp:873-874`
|
||||
- 原因:循环变量被收窄为 `RenderItem&` 后访问不存在的 `index`。
|
||||
|
||||
第二次编译失败:
|
||||
- 改为 `LayerRenderItem&` 后,`hasRenderPass/render` 是 private override。
|
||||
|
||||
RDC 最终修复:
|
||||
- 用 `LayerRenderItem` 读取 `index`;
|
||||
- 通过 `RenderItem&` 调用公开虚接口。
|
||||
|
||||
第三轮:
|
||||
- `cmake --build build-step088-opengl --target mbgl-test-runner -j3`
|
||||
- 结果:PASS,exit code 0。
|
||||
### Native directed tests
|
||||
|
||||
命令:
|
||||
`build-step088-opengl/mbgl-test-runner --gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'`
|
||||
|
||||
第一轮:28/29 PASS。
|
||||
唯一失败:
|
||||
- `RetainedUnderlayCache.RuntimeControlDisablesAndReenablesMapScopedCache`
|
||||
- 原因:`setEnabled(false)` 已记录 aggregate invalidation,STEP-092 range cache 同步又调用 aggregate `invalidate()`,造成重复计数。
|
||||
|
||||
RDC 修复:
|
||||
- 保留 legacy aggregate invalidation 只记录一次;
|
||||
- 对实际 range cache 单独记录 Bottom/Top invalidation;
|
||||
- 不改变 runtime-disabled 语义。
|
||||
|
||||
第二轮:**29/29 PASS**。
|
||||
|
||||
覆盖 single/multi range、missing/reversed endpoint、hidden endpoint、reorder/delete、四种 topology、0/1/2 cache decision、explicit/legacy 排他、Fast Path、revision 与 runtime control。
|
||||
|
||||
## Metal / iOS
|
||||
|
||||
- `build-ios/CMakeCache.txt`:`MLN_WITH_METAL=ON`、`MLN_WITH_OPENGL=OFF`。
|
||||
- Xcode target 编译定义包含 `MLN_RENDER_BACKEND_METAL=1`。
|
||||
- `cmake --build build-ios --target ios-sdk-static -- -quiet`
|
||||
- 结果:PASS,exit code 0。
|
||||
- 警告仅包括既有 EAGL deprecated、bundle identifier 等,不构成 STEP-092 编译失败。
|
||||
## GPU resource / composite 核验
|
||||
|
||||
RDC 对实际源码路径独立核验:
|
||||
- Bottom/Top holder 可常驻,但 GPU texture/render target/compositor 只在 `prepareResources()` 被调用时 lazy 创建。
|
||||
- `prepareResources()` 只在对应 cache decision 为 Build/Reuse 时调用;不存在的 Range 为 Disabled,不调用资源准备。
|
||||
- 同 viewport 且已有 `offscreenTexture` 时不重建 texture;已有 `compositeLayerGroup` 时不重建 compositor。
|
||||
- retained target clear color 为透明 `(0,0,0,0)`。
|
||||
- composite 使用 `gfx::ColorMode::alphaBlended()`,其因子为 `One / OneMinusSrcAlpha`,对应 premultiplied-alpha。
|
||||
- OpenGL 与 Metal `RetainedUnderlayCompositeShader` 均直接采样 RGBA texture。
|
||||
- Final 顺序为 Bottom composite → Continuous → Top composite。
|
||||
- 29 项 directed tests 已验证 0/1/2 cache decision 与 stable reuse/invalidation 语义。
|
||||
|
||||
## 未执行项
|
||||
|
||||
- Android Gradle / AAR / APK / ADB / 安装 / 实体机视觉:未执行。
|
||||
- Metal GPU frame capture、iOS 实机 runtime resource counter:未执行;当前仓库无现成可直接运行的 STEP-092 Metal GPU runtime test target。
|
||||
- 未执行 Jest。
|
||||
|
||||
## 结论
|
||||
|
||||
STEP-092 的 Mac Native 实现、OpenGL 编译、Native directed tests、Metal-only iOS 编译、资源生命周期代码路径、透明 Top composite 与 Git 修复闭环均已通过。未执行的平台实体机/Frame Capture 项保留为后续产品级验证,不改变本 Step 的 Mac Native CLOSED / PASS 结论。
|
||||
238
docs/50_Step记录/STEP-093_ContinuousRange运行态综合验收_v1.md
Normal file
238
docs/50_Step记录/STEP-093_ContinuousRange运行态综合验收_v1.md
Normal file
@@ -0,0 +1,238 @@
|
||||
# STEP-093 Continuous Range 运行态综合验收 v1
|
||||
|
||||
## 1. 当前状态
|
||||
|
||||
**IMPLEMENTED / WAITING_RUNTIME_VALIDATION**
|
||||
|
||||
Codex 已完成 Android 运行态验收入口、跨平台 diagnostics 补强、Fast Path fail-closed 原因观测、定向 Native 测试源码和 RDC 操作手册。依照仓库职责分工与本轮用户指令,Codex 未执行 Android/iOS 长时间编译、安装、ADB、模拟器/真机操作或视觉验收。因此 Android 为 `WAITING_ANDROID_RUNTIME_VALIDATION`,iOS/Metal 为 `WAITING_IOS_RUNTIME_VALIDATION`;本版不能标记 `CLOSED / PASS`。
|
||||
|
||||
## 2. 起始 Git 基线
|
||||
|
||||
- Repository:`MapLibreParticleLab`
|
||||
- 机器:`Mac-mini-tei.lan`
|
||||
- 路径:`/Users/tei/dev/MapLibreParticleLab`
|
||||
- Branch:`particle/main`
|
||||
- Starting HEAD:`8a5d88008c142e2a80e0ff602d228e0e67de2d83`
|
||||
- Starting `origin/particle/main`:`8a5d88008c142e2a80e0ff602d228e0e67de2d83`
|
||||
- STEP-092 基线:`CLOSED / PASS(Mac Native 验证闭环)`
|
||||
- STEP-093 implementation commit:`b3ec8edc87ece404b5f7b3706f5acf2a70de6862`
|
||||
- 起始工作树差异:仅有本任务书 `docs/40_任务/STEP-093_ContinuousRange运行态综合验收_Codex任务_v1.md` 为 untracked;已保留并纳入本 Step 文档提交。
|
||||
|
||||
## 3. 实际调查到的测试入口
|
||||
|
||||
Android 已有入口为 `MapLibreAndroidTestApp` 的 `ParticleCoreLayerValidationActivity`。本 Step 复用该 Activity、既有 Host-submitted particle fixture、`weather-color` 和普通 Style layer,不建立新测试框架,也不引入特殊 layer type。
|
||||
|
||||
新增底部 `STEP 093` 菜单与常驻 diagnostics 区。入口支持:
|
||||
|
||||
- A:Bottom + Continuous + Top;
|
||||
- B:Bottom + Continuous;
|
||||
- C:Continuous + Top;
|
||||
- D:Continuous only;
|
||||
- E:Single-layer Continuous;
|
||||
- Continuous/Bottom/Top add 与 reorder;
|
||||
- 普通 layer 跨 Bottom/Continuous/Top 移动;
|
||||
- start/end endpoint visibility、删除与恢复;
|
||||
- missing start、missing end、reversed、style loading 期间配置、empty ID、恢复 valid;
|
||||
- Camera preset 循环覆盖 pan/zoom/rotate/pitch;
|
||||
- Continuous 内未知普通 layer 触发 Fast Path fail-closed;
|
||||
- 1 秒一次的屏幕 pull diagnostics;仅用户点 `READ DIAGNOSTICS` 或场景切换时写一条日志,不制造逐帧日志风暴。
|
||||
|
||||
Android Activity 声明增加 `orientation|keyboardHidden|screenSize` config changes,使 RDC 可在不重建 Map/Style 的前提下用旋转或尺寸变化观察 viewport invalidation。
|
||||
|
||||
iOS 当前只有正式 `MLNMapView` diagnostics API 与 RN bridge 字段补齐,没有新增专用 STEP-093 iOS validation 页面。因此 iOS runtime 必须后续由 RDC 准备实际入口并执行,不能由 Android 结果推导。
|
||||
|
||||
## 4. 本轮新增/修改内容
|
||||
|
||||
### 4.1 Renderer diagnostics
|
||||
|
||||
在既有 map-scoped diagnostics 上追加,而非另造一套状态源:
|
||||
|
||||
- Range:`continuousBegin`、`continuousEndExclusive`、`rangeFallback`;
|
||||
- Bottom/Top:`cacheState`、build/reuse/invalidation、last invalidation reason;
|
||||
- 资源生命周期:texture create、composite create、resource release;
|
||||
- Fast Path:eligible、active、fallback reason、hit、miss、full CPU frame;
|
||||
- 未知 Continuous layer 的明确原因:`unsupported-continuous-layer`。
|
||||
|
||||
这些 counter 是 Map 生命周期内累计事件数,不是 GPU memory byte 数。它们用于证明 stable frame 不重复创建资源及 invalidation 后能重建/reuse;不能替代 profiler 或 GPU capture。
|
||||
|
||||
### 4.2 跨端暴露
|
||||
|
||||
- Android JNI/Java:diagnostics 字符串数组由 20 项扩为 39 项,Java 构造索引与 Native 顺序逐项一致;
|
||||
- iOS ObjC++:`MLNRetainedUnderlayDiagnostics` 暴露同组字段;
|
||||
- RN Android/iOS/TypeScript/Test Host:透传并显示同组字段;
|
||||
- 原有 aggregate build/reuse/fallback/invalidation 字段保持,不删除兼容语义。
|
||||
|
||||
### 4.3 Android 可视场景
|
||||
|
||||
测试 Style 中仅使用普通 background/fill/line、已有 WeatherColor 与 RasterParticle:
|
||||
|
||||
- Bottom:深色 background + 青色 fill;
|
||||
- Continuous:WeatherColor + Particle;
|
||||
- Top:半透明黄色 fill、opaque 红色 fill、白色粗 line;
|
||||
- fail-closed:在 Continuous 内加入普通 fill;
|
||||
- cross-range:同一个普通 fill ID 分别位于 endpoint 前、endpoint 间、endpoint 后。
|
||||
|
||||
最终 Z-order 仍完全由 Style layer 数组顺序决定。App 只调用 `setContinuousLayerRange(startLayerId, endLayerId)`;没有 anchor/marker、业务 layer metadata 或 Renderer 业务 ID 硬编码。
|
||||
|
||||
### 4.4 定向测试源码
|
||||
|
||||
新增 `RetainedUnderlayCache.RuntimeValidationDiagnosticsExposeRangeResourcesAndFastPath`,覆盖 Continuous index、cache state、资源 counter、Fast Path counter;既有 Fast Path gate 测试增加 `UnsupportedContinuousLayer` 原因断言。
|
||||
|
||||
本轮未运行 test runner。STEP-092 既有 29/29 PASS 是历史基线,不能当作新增测试已通过;RDC 运行后预期相关 filter 共 30 项,但必须以实际 runner 输出为准。
|
||||
|
||||
## 5. 静态一致性审查
|
||||
|
||||
Codex 已完成:
|
||||
|
||||
- Native diagnostics 定义、runtime state、Android JNI/Java、iOS、RN 字段名与顺序逐项比对;
|
||||
- 四种 topology 与 single-layer 的 Style layer 顺序/endpoint 位置审查;
|
||||
- mutation、cross-range、endpoint、invalid、camera、fail-closed 菜单接线审查;
|
||||
- absent Bottom/Top 仍沿用 STEP-092 `Disabled` / lazy resource 路径,没有新增固定 GPU 分配;
|
||||
- Fast Path eligibility 与 decision counter 接入既有 gate,失败仍进入 full CPU frame;
|
||||
- `xmllint --noout`:Android Manifest 与 layout PASS;
|
||||
- `git diff --check`:PASS。
|
||||
|
||||
未执行:C++/Java/Kotlin/ObjC++/TypeScript 编译、Native tests、Gradle、APK、ADB、Android/iOS runtime。静态审查不等于运行态 PASS。
|
||||
|
||||
## 6. RDC Android 构建、安装与启动
|
||||
|
||||
在仓库根目录执行:
|
||||
|
||||
```bash
|
||||
./tools/particle_android_validation/build_validation_apk.sh
|
||||
adb devices
|
||||
adb -s <serial> install -r artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
|
||||
adb -s <serial> shell am start -n org.maplibre.android.testapp/.activity.particle.ParticleCoreLayerValidationActivity
|
||||
```
|
||||
|
||||
可选定向日志:
|
||||
|
||||
```bash
|
||||
adb -s <serial> logcat -c
|
||||
adb -s <serial> logcat -v threadtime ParticleValidation:I MapLibre:I '*:S'
|
||||
```
|
||||
|
||||
若使用非 x86_64 真机,当前 validation script 的固定 ABI 不适用;RDC 应按项目现行 Android 构建规则选择相符 ABI,并在证据中记录实际 APK、commit、ABI、设备与 renderer backend。
|
||||
|
||||
## 7. RDC Native 精确回归命令
|
||||
|
||||
如 RDC 使用 STEP-092 的现有 OpenGL build tree:
|
||||
|
||||
```bash
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner -j3
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'
|
||||
```
|
||||
|
||||
必须记录真实 test 数与结果;不能直接抄写“30/30”。
|
||||
|
||||
## 8. Android 逐项运行手册
|
||||
|
||||
### 8.1 通用观察方法
|
||||
|
||||
启动 Activity 后点 `STEP 093`。每次切场景等待 Style READY,再观察屏幕 diagnostics;需要固化证据时点 `READ DIAGNOSTICS` 并保存日志/截图。稳定性判断建议至少间隔 10–30 秒采两次快照:
|
||||
|
||||
- Particle 持续运动;
|
||||
- 对存在的 cache,build/texture/composite 不再增长,reuse 与 Fast hit 应增长;
|
||||
- 不存在的 range 显示 `present=false`、`state=disabled`,对应资源创建数不因稳定帧增长;
|
||||
- counter 为累计值,切场景时应比较增量,不要求绝对值归零。
|
||||
|
||||
### 8.2 Topology A–E
|
||||
|
||||
1. A:选 `A BOTTOM + CONTINUOUS + TOP`。预期 range valid、Bottom/Top present、cache count 2;opaque 红块完整盖住 Particle,黄色半透明区域正确混合,白线在最上层,无黑边/halo/错误变暗。
|
||||
2. B:选 `B BOTTOM + CONTINUOUS`。预期 Bottom present、Top absent、cache count 1;Top state disabled,Top 资源不增长,Fast Path 不因 Top absent 被阻断。
|
||||
3. C:选 `C CONTINUOUS + TOP`。预期 Bottom absent、Top present、cache count 1;Bottom state disabled;Top 仍正确覆盖 Particle。
|
||||
4. D:选 `D CONTINUOUS ONLY`。预期 valid、Bottom/Top 均 absent、cache count 0、不是 fallback;Particle 正常运行,Fast Path 可命中。
|
||||
5. E:选 `E SINGLE-LAYER CONTINUOUS`。预期 start ID 等于 end ID、startIndex 等于 endIndex、`continuousEndExclusive = startIndex + 1`,不 fallback。
|
||||
|
||||
### 8.3 Mutation 与跨边界
|
||||
|
||||
在 `MUTATION / FAST PATH` 子菜单依次执行:
|
||||
|
||||
- `CONTINUOUS ADD` → `CONTINUOUS REORDER` → `RESTORE DEFAULT`:恢复动作也等价验证非 endpoint layer 删除;
|
||||
- `BOTTOM ADD` → `BOTTOM REORDER` → restore;
|
||||
- `TOP ADD` → `TOP REORDER` → restore;
|
||||
- `CROSS → BOTTOM` → `CROSS → CONTINUOUS` → `CROSS → TOP`。
|
||||
|
||||
每次检查 endpoint ID 重新解析出的 index、present topology、invalidation/build/reuse 增量及最终画面顺序;不得出现旧 index、旧 cache 或自动按 layer 类型修正 range。
|
||||
|
||||
### 8.4 Endpoint 与 visibility
|
||||
|
||||
在 `ENDPOINT / VISIBILITY` 子菜单:
|
||||
|
||||
- start visible ↔ hidden、end visible ↔ hidden:index 与 topology 不变,hidden endpoint 仍是 endpoint;
|
||||
- `DELETE START`:range invalid、fallback、无 crash/stale cache;`RESTORE START` 后恢复 valid 并 rebuild/reuse;
|
||||
- 对 end 执行同样步骤。
|
||||
|
||||
### 8.5 Invalid explicit range
|
||||
|
||||
在 `INVALID RANGE` 子菜单依次执行 missing start、missing end、reversed、configure while style loading、empty ID、restore valid:
|
||||
|
||||
- missing/reversed/style-not-ready:不得猜测 endpoint,不复用 stale cache,diagnostics 给出原因;
|
||||
- empty ID:当前 API 应同步返回 `accepted=false`;
|
||||
- restore 后无需重建 Map instance,应重新 valid、build、reuse。
|
||||
|
||||
### 8.6 Camera/viewport
|
||||
|
||||
连续点四次 `CAMERA NEXT`,覆盖 target/zoom/bearing/pitch 组合。每次检查 invalidation → build → reuse,topology 不变,无错位、黑屏或 Particle/地图不同步。
|
||||
|
||||
旋转设备或改变模拟器窗口尺寸,确认同一 Activity/Map 上产生 viewport invalidation;如设备支持可改变 display scale/pixel ratio,并单独记录是否实际触发。
|
||||
|
||||
### 8.7 Fast Path fail-closed
|
||||
|
||||
先恢复 A,稳定后确认 eligible/active 与 hit 增长。再选 `FAST FAIL-CLOSED`:
|
||||
|
||||
- Continuous Range 仍 valid;
|
||||
- fallback reason 为 `unsupported-continuous-layer`;
|
||||
- Fast Path 不 active,full CPU frame 增长;
|
||||
- 普通未知 layer 不被跳过或移出 Continuous;
|
||||
- Bottom/Top 与最终 Z-order 仍正确。
|
||||
|
||||
### 8.8 长时间运行
|
||||
|
||||
建议 RDC 在可用设备上连续运行 15–30 分钟,循环 topology、camera、mutation、endpoint、visibility、invalid/restore、再次稳定:观察 texture/composite create 与 release 增量、系统内存/GPU 工具可获得的数据、黑屏/闪屏/stale cache/偶发层序/Particle 恢复。若没有可靠 GPU byte 数,明确记录限制,不伪造内存数字。
|
||||
|
||||
## 9. PASS / FAIL 判定
|
||||
|
||||
- `PASS`:必须有实际设备/模拟器操作、画面确认与 diagnostics/log 证据,并满足该行预期。
|
||||
- `FAIL`:实际结果违背预期;保留首个真实错误、场景、截图/日志和 commit。
|
||||
- `WAITING_*`:入口已准备但平台尚未执行。
|
||||
- 编译 PASS、静态检查 PASS、另一平台 PASS 均不能替代当前平台 runtime PASS。
|
||||
|
||||
## 10. 验收矩阵
|
||||
|
||||
| 类别 | 场景 | Android | iOS/Metal | 关键证据 | 结论 |
|
||||
|---|---|---|---|---|---|
|
||||
| Topology | Bottom+Continuous+Top | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | A 按钮、range/index、2 cache、画面截图待采集 | NOT RUN |
|
||||
| Topology | Bottom+Continuous | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | B 按钮、Top disabled/资源增量待采集 | NOT RUN |
|
||||
| Topology | Continuous+Top | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | C 按钮、Bottom disabled/资源增量待采集 | NOT RUN |
|
||||
| Topology | Continuous-only | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | D 按钮、valid + 0 cache + 非 fallback 待采集 | NOT RUN |
|
||||
| Range | Single-layer Continuous | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | E 按钮、start=end、endExclusive=start+1 待采集 | NOT RUN |
|
||||
| Z-order | Top covers Particle | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | opaque/semi-transparent/line 视觉截图待采集 | NOT RUN |
|
||||
| Cache | Stable reuse | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | 两次 counter 快照待采集 | NOT RUN |
|
||||
| Invalidation | Pan/Zoom/Rotate/Pitch | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | camera preset 前后 invalid/build/reuse 待采集 | NOT RUN |
|
||||
| Mutation | Continuous internal mutation | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | add/reorder/restore diagnostics 待采集 | NOT RUN |
|
||||
| Mutation | Cross-range move | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | cross layer 三位置的 index/Z-order 待采集 | NOT RUN |
|
||||
| Endpoint | start missing/recovery | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | invalid reason + restore valid 待采集 | NOT RUN |
|
||||
| Endpoint | end missing/recovery | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | invalid reason + restore valid 待采集 | NOT RUN |
|
||||
| Visibility | hidden endpoint topology | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | visible/hidden index 不变待采集 | NOT RUN |
|
||||
| Invalid | missing/reversed range | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | fallback/lastReason/no stale cache 待采集 | NOT RUN |
|
||||
| Fast Path | eligible | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | eligible/active/hit/full counter 待采集 | NOT RUN |
|
||||
| Fast Path | unknown layer fail-closed | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | unsupported reason/full CPU frame 待采集 | NOT RUN |
|
||||
| Alpha | Top premultiplied composite | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | transparent/opaque/semi/line 视觉证据待采集 | NOT RUN |
|
||||
| Stability | repeated operations / long run | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | 长时间 counter/内存/画面记录待采集 | NOT RUN |
|
||||
|
||||
## 11. 问题、限制与未执行项
|
||||
|
||||
- 未发现需要修改 STEP-092 数学定义、Style 顺序、0/1/2 cache 或 Fast Path 核心模型的架构阻塞。
|
||||
- diagnostics 是累计 counter,不是 per-scene reset;RDC 应使用前后增量。
|
||||
- 资源 release counter 表示 holder 释放事件,不是释放字节数。
|
||||
- Android 场景 Style reload 是可重复的测试手段;跨场景比较必须等待 READY。
|
||||
- 当前 iOS 没有专用 STEP-093 面板,只有 diagnostics API/bridge;这是明确待办,不虚报 iOS runtime 能力完成。
|
||||
- Android/iOS build、Native tests、APK、安装、ADB、真机/模拟器、视觉、长时间运行均 NOT RUN。
|
||||
|
||||
## 12. 下一步
|
||||
|
||||
1. RDC 对 implementation commit `b3ec8edc87ece404b5f7b3706f5acf2a70de6862` 执行 Native 精确回归与 Android build/runtime 矩阵。
|
||||
2. 若 Android 核心矩阵全部实际通过,可更新为 `ANDROID CLOSED / PASS + IOS WAITING_RUNTIME_VALIDATION`。
|
||||
3. 准备 iOS/Metal 对等 validation UI 或可重复操作入口,再独立执行 iOS 矩阵。
|
||||
4. 只有任务书 24 节全部完成、Git 与文档闭环后,才能更新为 `CLOSED / PASS`。
|
||||
66
docs/50_Step记录/STEP-094_通用RenderSegment分段渲染与Style分类诊断_v1.md
Normal file
66
docs/50_Step记录/STEP-094_通用RenderSegment分段渲染与Style分类诊断_v1.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# STEP-094 通用 RenderSegment 分段渲染与 Style 分类诊断 v1
|
||||
|
||||
## 状态
|
||||
|
||||
**PASS / CLOSED(RDC 代码与构建验收完成)**
|
||||
|
||||
Codex 完成实现后,RDC 已独立完成 OpenGL Native 编译与定向 tests、Metal-only iPhoneOS 编译、RN TypeScript/codegen、Android Validation APK 构建与产物自检。规定的代码/编译验收门槛全部通过;Android/iOS 实体机运行与视觉验证本 STEP 未执行,明确保留为 NOT RUN。
|
||||
|
||||
## 起始基线
|
||||
|
||||
- 机器:`Mac-mini-tei.lan`
|
||||
- 仓库:`/Users/tei/dev/MapLibreParticleLab`
|
||||
- 分支:`particle/main`
|
||||
- 起始 HEAD:`8fbb892a1236a55329ed9ef5a612640c9363d3f1`
|
||||
- 起始 `origin/particle/main`:同上
|
||||
- V12 tag:`maplibre-particle/rn/13.4.1-particle.12`(`7eaff6e12`)
|
||||
- 起始工作树:clean
|
||||
|
||||
## 实现结果
|
||||
|
||||
- 新增 typed Core `RenderSegmentPlan` / resolved plan / diagnostics model。
|
||||
- explicit plan、V12 Continuous Range 与 legacy boundary 统一进入一个 resolver。
|
||||
- Style boundary ID 在 RenderOrchestrator 按完整 orderedLayers 解析;hidden Layer 仍参与。
|
||||
- Renderer 改为 topology-sized cache vector;每个 Retained Segment 独立 lazy GPU cache,Continuous 无 retained resource。
|
||||
- Segment 按 Style 顺序执行,global layerIndex/original ordinal/currentLayer/depthRangeSize 保持。
|
||||
- Layer Impl fingerprint 支持明确 retained Segment 内的 layer-local invalidation;Source/Tile 等仍保守全 retained invalidation。
|
||||
- 单 Continuous 保留既有 Particle Fast Path;多 Continuous fail closed 到 full CPU frame。
|
||||
- pull diagnostics 返回完整 Style→Segment→Layer、config/topology revision、coverage 与每个 retained cache 统计。
|
||||
- Android/iOS/RN 沿既有 WeatherRuntimeBridge 增加 plan 与 diagnostics JSON ABI;RN public API 为 typed object/discriminated union。
|
||||
- RN Test Host 增加 `Apply C-R plan` 与 `Fetch Segment Diagnostics`,只在用户操作时拉取一次。
|
||||
|
||||
## 定向测试源码
|
||||
|
||||
在既有 `retained_underlay_cache.test.cpp` 增加 RenderSegmentPlan/Diagnostics tests,覆盖:全 Retained、全 Continuous、C-R-R、R-R-C、R-C-R-C-R、相邻 R 不合并、missing/duplicate/reversed、hidden boundary、插入 Layer membership、boundary 删除/恢复、compat R-C-R/Continuous-only、visibility 不推进 topology revision、Cache OFF diagnostics、完整 coverage/flatten、Continuous cache=null、严格 JSON strategy/schema。
|
||||
|
||||
RDC 已执行过滤集:8 个 suite、43/43 tests PASS;其中 RenderSegmentPlan 9、RenderSegmentDiagnostics 4,并同时覆盖 V12 Continuous/Retained/Fast Path 回归。
|
||||
|
||||
## RDC 验证结果
|
||||
|
||||
- OpenGL:`mbgl-test-runner` 编译 PASS(exit 0);定向过滤集 43/43 PASS。
|
||||
- Metal/iPhoneOS:确认 `MLN_WITH_METAL=ON`、`MLN_WITH_OPENGL=OFF`;`ios-sdk-static` 编译 PASS(exit 0)。
|
||||
- RN package TypeScript:PASS;RN Test Host 使用本工作树 package typecheck PASS。
|
||||
- RN codegen:顶层 `npx react-native codegen` 因工程未安装 `@react-native-community/cli` 无法作为入口;未修改依赖,改用当前已安装 RN 0.85 的 `@react-native/codegen` combine/generate-all 正式底层入口 PASS,并确认 Android Java/JNI、C++ JSI 与 iOS ObjC++ 生成物均含 `setRenderSegmentPlanJson` / `getRenderSegmentDiagnosticsJson`。
|
||||
- Android Validation APK:标准脚本 PASS;OpenglDebug / x86_64 / strip=true;APK 60,294,298 bytes;`libmaplibre.so` 39,421,736 bytes;SHA-256 `848c3196c64cee6dfb1e9627f4af32b6e235fdd82afd1cfb8474c7fc5d591c71`。
|
||||
- Android/iOS 实体机 runtime 与视觉:NOT RUN。
|
||||
- Jest:明确不加入、不执行。
|
||||
|
||||
## RDC 验证重点
|
||||
|
||||
1. Core 编译:重点检查 rapidjson header、RenderLayer Impl metadata、JNI String ABI 与 ObjC++ selector。
|
||||
2. Tests:验证 resolver/diagnostics 新 suites 及 V12 原有 Continuous/Retained/Fast Path suites。
|
||||
3. OpenGL/Metal:确认 N retained resource、相邻 retained 不合并、稳定帧不重复创建。
|
||||
4. RN codegen:确认新增两个 primitive JSON methods 在 Android/iOS generated Spec 与实现 selector 对齐。
|
||||
5. Runtime:拉取 snapshot,核对 `styleLayers` 与 flatten(segment.layers) 完全一致;Cache OFF 仍保留 topology。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 多 Continuous Fast Path 未优化,按任务边界明确 fail closed。
|
||||
- Source/Tile mutation 无安全通用 dependency graph,仍全 retained invalidation。
|
||||
- 旧 diagnostics 仅兼容摘要;新 API 才是多 Segment 权威事实。
|
||||
- 多 Continuous Fast Path 仍按设计 fail closed,不是本 STEP 缺陷。
|
||||
- Android/iOS 真机运行和视觉结果不在本次 PASS 证据内。
|
||||
|
||||
## 下一步
|
||||
|
||||
实现代码已以 `016fd1fff`(`feat: add generic render segment model`)提交并 push。完成报告与本 Step 记录作为独立文档收尾 commit 提交;后续如需产品级 runtime/视觉确认,应另做 Android/iOS 运行态验收,不反向改变本 STEP 的代码验收结论。
|
||||
50
docs/50_Step记录/STEP-095_V13独立严格代码与性能审查_v1.md
Normal file
50
docs/50_Step记录/STEP-095_V13独立严格代码与性能审查_v1.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# STEP-095 V13 独立严格代码与性能审查 v1
|
||||
|
||||
日期:2026-09-25(Asia/Tokyo)。任务:[STEP-095 任务书](../40_任务/STEP-095_V13独立严格代码与性能审查_Codex任务_v1.md)。调查:[独立源码与性能调查](../20_调查/STEP-095_V13独立严格代码与性能调查_v1.md)。报告:[Codex 完成报告](../报告/STEP-095_V13独立严格代码与性能审查_Codex完成报告_v1.md)。
|
||||
|
||||
## 1. 合同、环境与基线
|
||||
|
||||
只读独立审查 V13,先源码后旧报告。仅新增三份指定中文文档并追加开发记录;不修复源码,不执行构建、测试、codegen、打包、安装、设备或 profiler。按 AGENTS 已读当前基线、项目规范、有效总则及 STEP-088~094 相关任务/设计/记录/报告。
|
||||
|
||||
机器 `Mac-mini-tei.lan`,仓库 `/Users/tei/dev/MapLibreParticleLab`,分支 `particle/main`;起始工作树 clean,HEAD 和实际 origin 均 `05878d662308b9a92c20c433c3cd2943d74ae718`。冻结源码 `ee0b89e711bf01335b3aa71d36def785cd97fec3`,功能提交 `016fd1fff6a33cf795c10d4f5c5413d308383677`。RN/Android `13.4.1-particle.13`、iOS `6.28.0-particle.13`;manifest 源码准备提交 `ddf20dec9fe9cd05b77274827b6825829500dd5a` 至冻结点无生产源码变化。冻结点至起始 HEAD 仅有两份文档。
|
||||
|
||||
用户在本次同一会话恢复指令中明确指定 `gpt-6-astra high`,与任务要求一致。记录的是用户指定;没有独立的底层模型/effort 启动参数证明,不声称完成模型独立核验。原 285 行调查稿保留,仅校正模型记录、一个源码路径及补充精确桥接引用;不重写调查、不扩展搜索范围。
|
||||
|
||||
## 2. 本阶段交付
|
||||
|
||||
- 沿 Segment→Runtime→Renderer→GPU、Source→Field Runtime→RenderLayer→GPU 追踪,检查平台桥接、版本锁及 Integration 只读状态。
|
||||
- 新增 N01~N07:跨 target stencil、Metal depth/stencil 契约、失败 build 标成功、V4 PLAY 接线、JSON 严格性、数值入库语义、重复 attach listener。
|
||||
- C01~C07 区分源码成本与运行影响:完整快照、Metal wait、dirty 重分配、预算、线性扫描、全网格物化/UI、drawable 与场复制。
|
||||
- O01 给出旧 cache 计数污染新 topology 的具体链;E01/E02 区分 Host 错配与协调文档历史状态。
|
||||
- F01~F10 独立复核:6 项 CONFIRMED(F01/02/03/04/07/09)、4 项 QUALIFIED(F05/06/08/10)。不把设计限制、历史 TS 失败或计数错归扩大为新实测事故。
|
||||
- 给出 V12/V13 成本模型、缺失测试矩阵及后续修复批次;未创建修复任务,未修改 Integration。
|
||||
|
||||
## 3. 验证与未完成边界
|
||||
|
||||
本轮实际构建、测试、codegen、安装和设备验证全部 NOT RUN。STEP-094 构建/43 tests、旧报告 69 tests 与 TS 结果只列 HISTORY。源码查验不替代运行验证,缺陷触发的实际像素、故障注入、性能/峰值等保留 NEEDS_RUNTIME。
|
||||
|
||||
RDC 优先复核:同 source 同 tiles 的 R-R/R-C stencil;Metal attachment/load/clear;build 失败不得 reuse;只设一次时间后 PLAY 自动推进。其后验证完整 topology、invalid/recovery、30/60 FPS、峰值/长稳、销毁恢复。精确既有命令及证据要求见调查第 9 节;本轮未执行其中任何命令。
|
||||
|
||||
调查内容完成,产品运行态不判 PASS。外部模型参数、产物独立下载/重建、NavSea 实际接入、Vulkan、正式共享海陆 mask 均保留未核实范围,不作能力承诺。
|
||||
|
||||
## 4. Git 收尾
|
||||
|
||||
写稿时调查内容完成,Git 交付待提交/推送,整体暂记 PARTIAL;实际结果在本节追加,未完成 push 不预写 PASS。
|
||||
|
||||
仅四个允许路径:调查、本文、完成报告、根开发记录末尾追加。先验证引用/证据路径和 `git diff --check`,仅具体路径 staged,主提交 message 为 `docs: audit V13 source and performance for STEP-095`,push `origin particle/main`,不移动 tag、不 force push、不向 upstream push。
|
||||
|
||||
提交对象无法在自身正文中预先记录最终 SHA。采用主文档提交/推送后追加已知主提交证据,再提交收尾文档的方式;最后收尾提交 SHA、remote HEAD 和 clean status 在最终回复给出,可用 `git rev-parse HEAD` 与 `git ls-remote origin refs/heads/particle/main` 复核。
|
||||
|
||||
### 文档提交前检查
|
||||
|
||||
- 原调查仍为285行;新增Step/完成报告与开发记录追加齐备。9处相对文档链接、63处带行号源码引用的路径及行号范围检查通过;对校正引用回读源码,未执行产品测试。
|
||||
- 开发记录原内容逐字节保留,仅末尾追加;工作树只含四个允许路径,原暂存区为空。`git diff --check` exit 0;新增文档亦检查无行尾空白,staged后再执行cached检查。
|
||||
|
||||
### 实际主提交与远端回读(收尾事实)
|
||||
|
||||
- 主提交:`ad5f92c48ea353c18548c79d223e9a06888330d3`,message:`docs: audit V13 source and performance for STEP-095`;仅四个允许文档,417行增加,无源码变化。
|
||||
- 提交前 `git diff --cached --check` exit 0;主提交后 `git diff --check` exit 0。一次提交遇到瞬时index.lock,回读时锁已自行消失,重试成功;没有删锁或执行破坏性Git操作。
|
||||
- `git push origin particle/main` exit 0,远端从 `05878d662` 前进至 `ad5f92c48`;随后 `git ls-remote origin refs/heads/particle/main` exit 0,返回完整主提交SHA,与本地HEAD及origin tracking一致。
|
||||
- 主提交推送核对后的 `git status --porcelain=v1` 为空:工作树clean。冻结V13至主提交只含本轮四文档和既有审查/任务两文档,无生产源码、shader、API、依赖、build、manifest或产物变化。
|
||||
- 调查内容及主交付:**PASS**;V13产品运行态仍 **NOT RUN / 未验收**。无构建、测试、安装或设备操作。
|
||||
- 本条和完成报告的结果追加由后续scoped收尾提交保存,message:`docs: record STEP-095 delivery verification`。其自身最终SHA不能预写进自身内容;最终回复记录该收尾提交、再次push/remote核对和clean status。此说明不将尚未发生的第二次push冒充已完成。
|
||||
56
docs/50_Step记录/STEP-096_V13隔离盲审_v1.md
Normal file
56
docs/50_Step记录/STEP-096_V13隔离盲审_v1.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# STEP-096 V13 隔离盲审 v1
|
||||
|
||||
## 状态与范围
|
||||
|
||||
状态:**完成(仅隔离盲审文档交付)**。日期:2026-09-25。
|
||||
|
||||
本阶段按[当前任务书](../40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md)独立读取隔离快照源码和当前规范,形成调查、Step 与完成报告。完成不表示 V13 构建、测试、GPU 画面或性能通过。未做代码修复,后续验证全部 NOT RUN。
|
||||
|
||||
## 输入与可核实环境
|
||||
|
||||
| 项目 | 事实及限制 |
|
||||
|---|---|
|
||||
| 唯一工作目录 | `/Users/tei/dev/MapLibreParticleV13Blind096` |
|
||||
| 机器观察值 | `Mac-mini-tei.lan` |
|
||||
| 目标导出 SHA | `ee0b89e711bf01335b3aa71d36def785cd97fec3`,来自任务书;未用 Git 对象独立核验 |
|
||||
| 版本声明 | [manifest](../../release/maplibre-particle/release-manifest.json#L4):revision 13,RN/Android `13.4.1-particle.13`,iOS `6.28.0-particle.13` |
|
||||
| 产物 sourceCommit 声明 | `ddf20dec9fe9cd05b77274827b6825829500dd5a`,不作为本快照 HEAD |
|
||||
| 当前 branch / Git HEAD / clean / remote | NOT AVAILABLE;本轮未运行 Git |
|
||||
| 实际 TUI、screen、模型和 effort 启动记录 | NOT AVAILABLE;未访问目录外配置、会话日志或终端回放补证 |
|
||||
|
||||
已读取 AGENTS.md、PARTICLE_BASELINE.md、`docs/00_项目规范/`、总则 README 及所列当前有效总则,包括当前基线与开发路线 v2,以及本任务。当前总则中的旧发布坐标与快照 `.13` 声明分开记录,不重写总则或历史。未打开外部路径、历史调查/Step/完成报告、既有审查材料或开发日志;本轮输出目录只用于写入和检查本轮三份新稿。
|
||||
|
||||
## 只读过程
|
||||
|
||||
1. 从公开 API 和目录建立 Style/分段、Renderer/gfx、场 ingress/runtime、平台 bridge 与 GPU 数据路径地图。
|
||||
2. 追踪正常、拒绝、fallback、失效和销毁路径,区分 owner、共享不可变快照与 GPU 资源;对候选寻找反例,不按问题数量补齐。
|
||||
3. 阅读 C++、GLSL、Metal、Android、iOS、RN、测试源码和配置;核对公开 PLAY 调用方、纹理更新条件、attachment 状态、CRC/容量、线程派发与同步点。
|
||||
4. 排除颜色投影仅看第一分量、强引用环、关闭缓存同步遗漏、纯重排遗漏等未成立候选;保留粒子独立前置更新门槛的完整证据。
|
||||
5. 写入三份中文报告;对本轮新稿进行文件存在、相对链接、引用行号和行尾空格的轻量静态检查。未启动构建、测试 runner、设备或 profiler。
|
||||
|
||||
## 结果
|
||||
|
||||
调查形成 **13 条独立 finding**:P1 四条(B01、B02、B06、B13),P2 九条;无 P0。类型为确定缺陷七条、源码确定成本四条、设计限制两条。这里的“确定”限定源码控制流/数值语义,不代表已发生用户事故;全部运行效果 NEEDS_RUNTIME。
|
||||
|
||||
主要正确性证据为跨渲染目标 stencil 记录、Metal depth/stencil clear 请求传递、encoded 播放推进、粒子完整内容身份、8-bit 零值和 Mercator 度量、retained 失败提交。成本和设计限制涉及 Metal 同步等待、资源重复分配、重复物化、UI 同步处理、共享地理 mask 与 store 总预算。每条的条件、精确路径/行号、反例、影响边界、安全修复与验证方案见调查报告。
|
||||
|
||||
## 三份交付文件
|
||||
|
||||
| 文件 | 内容 |
|
||||
|---|---|
|
||||
| [调查报告](../20_调查/STEP-096_V13隔离盲审调查_v1.md) | 架构地图、B01—B13 证据、反例、性能模型、覆盖缺口、验证矩阵、分批建议 |
|
||||
| [本 Step 记录](STEP-096_V13隔离盲审_v1.md) | 范围、输入、只读过程、结果、未运行验证、后续责任 |
|
||||
| [Codex 完成报告](../报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md) | 交付状态、发现索引、证据质量、边界与移交方案 |
|
||||
|
||||
## 未运行验证与阻塞
|
||||
|
||||
- CMake/Ninja/Xcode/Gradle、编译、链接、codegen、打包:**NOT RUN**。
|
||||
- C++/GL/Metal/Jest 测试、设备安装/启动、GPU capture、性能与内存测量:**NOT RUN**。
|
||||
- Git 状态、commit、push、远端核对和产物公网回读:**NOT RUN**。
|
||||
- 外部仓库、上游差异、真实安装环境、历史日志、启动配置:**NOT AVAILABLE**。
|
||||
|
||||
这些是任务约束和证据边界,不阻塞文档交付;它们阻止把本报告升级为运行态或发布验收。未确认 Vulkan 全链、全部图层组合及竞态行为,详见调查覆盖缺口。源码未写入;没有 Git diff 或导出对象逐文件比对证据,不声称已核验工作树 clean。
|
||||
|
||||
## 下一步与停止
|
||||
|
||||
Codex 在三份报告自检后停止,不继续修复、追加开发日志或解盲比较。RDC 随后冻结三份原稿的 SHA-256 与时间,独立移交正式仓库同路径、追加 `粒子开发记录.md`,执行四文件 scoped commit/push 和远端核查;这些动作本轮均未执行。新代码任务优先处理 B01/B02/B06/B13,并补 B12 失败恢复;其余数值/域语义和性能/容量工作按调查报告分批推进。验证场景和已有 runner 的定向执行命令已写入调查报告,交由后续 RDC 阶段执行。
|
||||
81
docs/50_Step记录/STEP-097_V13三轮审查问题合并修复_v1.md
Normal file
81
docs/50_Step记录/STEP-097_V13三轮审查问题合并修复_v1.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# STEP-097 V13 三轮审查问题合并修复 v1
|
||||
|
||||
状态:进行中。目标:按阶段修复三轮审查的当前源码问题,保护 C-001 与既有公开协议。基线:Mac-mini-tei.lan,`/Users/tei/dev/MapLibreParticleLab`,`particle/main`,起始 `720d309364628f85049cf9969d71c71e8dfacce9`,起始工作树 clean,子模块无偏离。当前 `.13` 发布 tag 指向 `ee0b89e71`;不修改发布坐标。
|
||||
|
||||
| 检查点 | 状态 | 实际事实、阻塞和下一步 |
|
||||
| --- | --- | --- |
|
||||
| 阶段 0 基线与反证 | 完成(静态) | 读取三轮审查、STEP-094~096 交付及 C-001/RFC-001 本地副本。当前 HEAD 比任务书基线只新增任务文档;远端 particle/main 经 `git ls-remote` 核对一致。建立 24 项矩阵。Integration 远端同步状态待 RDC 复核。 |
|
||||
| A1 Renderer 正确性 | Android/Core 检查点完成,iOS runtime 用户豁免 | `e67e4961b` 记录 01/02/03/19 的部分代码;19 有 GTest。01/02/03 缺少任务要求的专用可执行像素/附件/故障注入测试入口;且未进行 GL/Metal 编译。故 A1 不判完成,严格停止于此,不进入 A2。 |
|
||||
| A2 Field/粒子正确性 | Android/Core 验证完成;iOS runtime 用户豁免 | 04–07 在当前 GPT-6 Luna High 可见会话实现,RDC 独立验证完成;详见本记录末尾补记及 `docs/报告/STEP-097_A2_阶段验证记录_v3.md`。A2 达到 Android/Core 阶段门槛,不能据此关闭整个 STEP-097。 |
|
||||
| B 输入/生命周期 | 计划 | 尚未开始。 |
|
||||
| C 安全性能 | 计划 | 尚未开始;必须先完成 A1 正确性。 |
|
||||
| D 交付 | 部分完成 | 已写 24 项矩阵、集中验证清单、Step、本轮完成报告和开发记录。所有构建、测试、运行、发布均 NOT RUN;后续 RDC 独立审查。 |
|
||||
|
||||
允许范围与禁止范围按任务书。未完成项目不勾选。RDC 后续执行构建及运行;本轮不运行构建或 Jest。
|
||||
|
||||
## 2026-09-25 RDC/FZG1 A1 APK 实际验证补记
|
||||
|
||||
- 用户授权在 FZG1 而非 Win11 虚拟机测试。Mac RDC 以 HEAD `91c2491b0` 的 clean 基线执行标准 OpenGL x86_64 Validation APK 脚本:Gradle `BUILD SUCCESSFUL in 15m 59s`,APK 60,295,184 bytes,SHA-256 `8677197c5f83a22747cb51f0c261edffc5db4678fc25b3f366474f6ecb94dc99`。
|
||||
- 经 `adb -s 192.168.200.139:5555` 在 Panasonic FZG1-2 覆盖安装 `Success`;设备内安装 APK SHA-256 与产物一致。保存原包备份、20 张截图/UI XML、ADB 操作日志与实时 Logcat;设备实际验证见 `docs/报告/STEP-097_A1_FZG1测试APK与实机验证报告_v1.md`。
|
||||
- R-C-R、R-C、C-R、C-only、single continuous、缓存 OFF/ON、Camera、缺失 START/END 后恢复、TOP_REORDER、跨连续区与 fail-closed 均已做**既有场景冒烟**,未发现本次测试窗口内 FATAL/SIGSEGV/SIGABRT。
|
||||
- B/D 场景 top 不可见而诊断仍 topPresent=true 的现象已记录为待复核,不凭此断言确定像素错误;01 同 tile fixture、02 Metal、03 render exception 注入、19 GTest 仍未完成。因此 **A1 保持阻塞/PARTIAL,A2/B/C 未开始**。此补记更新了之前 Codex 报告中“全部测试 NOT RUN”的后续事实,不追溯修改旧报告。
|
||||
|
||||
## 2026-09-26 RDC 第 19 项 GTest 实跑补记
|
||||
|
||||
- Mac 同一 `particle/main` HEAD `0d13552bed84f427dd43cae9856391bd26622179` 将 `build-step088-opengl/mbgl-test-runner` 增量编译/链接完成:95/95 steps,exit 0,261.74 秒;构建警告记录于原始日志,不影响测试退出状态。
|
||||
- 定向 `RenderSegmentDiagnostics.OldCacheReleaseCannotChargeReplacementAtSameIndex`:**1/1 PASS、exit 0**;相关 `RenderSegmentDiagnostics.*`:**5/5 PASS、exit 0**。测试证明旧 revision 释放不污染新 topology 相同 index 的当前段计数。详细报告:`docs/报告/STEP-097_A1_第19项GTest运行验证报告_v1.md`。
|
||||
- 19 的**已存在 GTest 实测门槛通过**,但不等于 GPU 内存无泄漏或整项资源实机验收;01/02/03 专用测试入口仍缺,A1 依然 PARTIAL,不进入 A2/B/C。本补记覆盖此前 Codex 与 FZG1 报告中的历史 `GTest NOT RUN` 记录,不改写旧报告。
|
||||
|
||||
## 2026-09-26 FZG1 第 19 项设备辅助验收
|
||||
|
||||
- Mac RDC 确认 APK 源码 `91c2491b0` 到当前 `237a3e660` 只改变文档,复用原 OpenGL x86_64 APK;在 FZG1-2(ADB `192.168.200.139:5555`)执行 `install -r` 得 `Success`,设备内 APK SHA-256 `8677197c5f83a22747cb51f0c261edffc5db4678fc25b3f366474f6ecb94dc99` 与源文件相同。
|
||||
- 两轮 A/B/C/D/E/A 拓扑循环及 TOP_REORDER、CROSS_CONTINUOUS、CACHE OFF/ON、缺失 START 后恢复完成:20 张 1920×1200 截图与 20 份 UI XML;18 个有效检查点 `valid=true/fallback=false`、预期无效检查点 fail-closed。B/T `textureCreate-resourceRelease` 在现有诊断的 19 个场景均为 0 或 1;实时日志无 FATAL/SIGSEGV/SIGABRT。
|
||||
- 设备辅助冒烟 **PASS**,前述 19 GTest **1/1 PASS**;没有 on-device GTest、逐 revision GPU 内部观测或显存泄漏证明。B/D `topPresent=true` 与视觉不一致的既有疑点仍待单独核查;01/02/03 专项测试未闭合,A1 整体继续 PARTIAL。报告:`docs/报告/STEP-097_A1_第19项FZG1运行验证报告_v1.md`。
|
||||
|
||||
## 2026-09-26 Codex 继续 A1 测试入口
|
||||
|
||||
- 新增 Android 同源同 tile 的 R-R/R-C-R/C-R-R 本地 fixture 与诊断菜单;新增 Metal 附件/clear GTest 源码;新增 LayerGroup 正反范围异常、observer 与 cache 失败后重试 GTest 源码。生产 Metal clear 逻辑抽成仅内部调用的辅助函数,使测试检查同一路径,不调整公开协议。
|
||||
- 本轮只做静态检查;构建、GTest、Jest、设备像素、Metal validation 均 **NOT RUN**。01/02/03 仍需 RDC 编译与设备验证;A1 保持 PARTIAL,A2/B/C 未启动。第 19 项原有 RDC 1/1 PASS 不受影响。
|
||||
|
||||
## 2026-09-26 A1 收口,允许进入 A2
|
||||
|
||||
- A1 新 Android APK 源码 `8c006ac83`,构建/安装/设备内 SHA-256 复核成功;FZG1 18 个同源同 tile RR/RCR/CRR 检查点、中心/区域外像素采样均一致,脚本 exit 0,实时日志无崩溃。03 原生异常恢复 GTest 2/2 PASS;19 已有 GTest 1/1 和诊断组 5/5 PASS。
|
||||
- Metal host 可编译,但无 Metal device,两项测试均 SKIP;用户明确不做 iOS runtime,本轮验收按用户决定接受,不能记为 iOS 实测 PASS。B/D 的 topPresent 历史疑点保留;详见 `docs/报告/STEP-097_A1_Android专项验收报告_v1.md`。
|
||||
- A1 Android/Core 阶段完成;下一步严格 A2→B→C,每阶段保留独立 RDC 构建及验证。STEP-098 未启动、未提交;`.13` 发布冻结不动。
|
||||
|
||||
## 2026-09-26 A2 RDC 中途验证,尚未进入 B
|
||||
|
||||
- Codex GPT-6-Sol medium 在 A2 四项范围内写入生产/测试源码但触及当期使用额度,未完成最终审查/提交。RDC OpenGL 原生编译 exit 0、16/16 定向 GTest PASS;Shader generator 双次 exit 0/幂等;Metal host 源码编译 exit 0、同样 16/16 Core GTest PASS,**没有 iOS runtime**。
|
||||
- A2 仍 PARTIAL;完整差异和构建/测试日志位于 `artifacts/maplibre-particle/step097-a2-rdc/`,中文事实报告:`docs/报告/STEP-097_A2_阶段验证记录_v1.md`。B/C 均未启动;用户未跟踪 STEP-098 与已发布 `.13` 未动。已安排 Codex 额度恢复后严格串行继续。
|
||||
|
||||
## 2026-09-26 A2 Core/Android 最终验证收口(B/C 未启动)
|
||||
|
||||
- Codex 配置:GPT-6 Luna High,可见会话。仓库 `/Users/tei/dev/MapLibreParticleLab`,`particle/main`,验证基线 HEAD `5bb1a0e6353c5dfe8db8a61bbeba9cef447280ef`;A2 源码保持 dirty、未提交。Integration `main` 已有报告基线 `318f8ccf911ac3136c3086a1d14e61f83e2d4bce`,C-001 未改。
|
||||
- 04–07 完成:唯一 Core forecast clock 加 synchronous notification reentry guard;严格 GPU endpoint identity 与 mix-only immutable snapshot reuse;内部 RGBA8 signed zero/byte 解码;Mercator U/V 同纬度度量。旧 `sameFieldGpuContent` 的语义未改变,修正了与其 version-agnostic payload 等价定义相冲突的旧测试断言。新增 source 回归覆盖 50 次 mix ticks 不重物化、endpoint/revision 改变触发 materialize、clear fail-closed 与重入单 tick。
|
||||
- RDC 独立结果:原 58/58 完整回归 PASS;当前 broad filter OpenGL 121/121 与 Metal host 121/121 PASS;三项 A2 定向测试两平台各 3/3 PASS;shader generator 连跑两次幂等。Metal host 仅 Mac Core runner,不是 iOS 设备验证。
|
||||
- 标准 Android OpenGL Debug x86_64 APK `61,753,803` bytes,SHA-256 `27bf4a6cc191bd86c4d1c10398478d81c2999edd61fe7242e40e5188516b0ca5`;已安装到 FZG1-2(`192.168.200.139:5555`),设备 APK hash 相同。V4 Golden Wind test-only fixture 覆盖 load、seek 25/75、speed 2x/1x、PLAY 30 秒、responsive UI、PAUSE、stable pause、replay、clear、reload、再次 PLAY/PAUSE;runner exit 0、17 PNG、24 steps、ANR=0。15 秒截图可见粒子。
|
||||
- Mix-only 计数按两个稳定资源 epoch 记录:clear/reload 前 upload/reset=`6/2` 稳定;clear/reload 后合法增至 `10/4`,reload 后 playback 稳定。不能说跨 clear/reload 零上传或零 reset。APK source diff SHA-256 与 `mix-reuse-build-source.diff` 一致:`18927a5f30a88f5c1c3a00e0017473dc33b04151c227e4baf52250dc4ad2e6a2`。
|
||||
- 历史异常保留:12:43 首次 FZG1 ANR 根因为 source notification 同步重入 forecast tick,当前 `forecastTickInProgress` 与 `RasterArrayV4ClockSourceNotificationReentryDoesNotAdvanceTwice` 覆盖此项;后续有过无 ANR 但主线程高负载、PLAY/TIME 无响应的失败试跑,栈指向 forecast tick 内重复投影物化。最终 mix reuse APK 通过本次闭环。历史 debuggerd、失败试跑和最终日志均保留在 `artifacts/maplibre-particle/step097-a2-final-validation/`。
|
||||
- A1 与 A2 的 Android/Core 阶段检查完成;iOS runtime 明确按用户决定记 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`,不写成 iOS PASS。STEP-097 整体仍 PARTIAL:B/C 未开始,Jest 未运行,STEP-098 未运行,`.13` 未发布/覆盖。Git commit/push 留给 RDC 独立 QA 后执行。
|
||||
|
||||
### 2026-09-26 A2 源码独立 scoped commit 核验
|
||||
|
||||
- A2 的 26 个生产源码、shader、TestApp-only V4 Golden fixture 和定向测试文件已固定为 `f49ffa68a17e0a505199bdbeccf07f8543f3a05f` 并推送,`origin/particle/main` 回读一致;没有 stage 用户未跟踪 STEP-098。完整代码/设备证据仍见 `docs/报告/STEP-097_A2_阶段验证记录_v3.md`,不因 Git 提交改变原 APK 的 `git_dirty=true` 来源事实。STEP-097 整体 PARTIAL,B/C 待用户指令。
|
||||
|
||||
## 2026-09-26 B 阶段源码、Core 复核与 Native 版本阻塞(未收口)
|
||||
|
||||
- Codex 两次自动任务(Android 第 10 项销毁监听、旧数值夹具纠正)均使用 `codex exec --json` + GPT-6 Luna High,均有 `turn.completed` 和 exit 0,JSONL/status.json 已持久化于 `artifacts/maplibre-particle/step097-b10-codex/` 与 `step097-b-fixture-codex/`。
|
||||
- 08 N05:长度感知 JSON/NUL/重复键/非法配置清除与恢复测试入口已实施;09 N06:提交前有限数值验证和旧有效修订保护已实施;10 N07:View owner、世代隔离与新 Map 销毁 observer 测试源码已实施;20 E01:Host package/lock 均指向正式 .13,正式 tarball SHA-256 与 SRI 已核对。
|
||||
- RDC Mac Core 构建 PASS,四项 B 定向 GTest 4/4 PASS;broad 初次 132/134,真实原因是旧四单元 16-bit 测试借用了 4-byte UInt8 storage;仅修为合法 8-byte little-endian fixture 后复编与扩大回归 **134/134 PASS**,未放宽生产校验。
|
||||
- 硬阻塞:B10 新 `MapLibreMap.addOnDestroyListener()` 不存在于已发布 .13 source commit `ddf20dec9`,现有 RN Gradle 默认正式 .13 AAR 无法提供该符号;本地新源码 Android 测试不能替代正式 RN consumer 精确配对构建。禁止借此修改 .13 发行产物。
|
||||
- Linux Android 采用远端 `b1239ac3b` 新独立 worktree,并从 Mac 传入 B scoped patch/测试,原 Linux dirty 工作区未动。首次 Gradle 仅因工作树缺少 ANDROID_HOME 失败,按既有 SDK 路径重试;结果见 B 专项报告的后续记录。
|
||||
- 当前 B = PARTIAL / BLOCKED_NATIVE_AAR_COMPATIBILITY,尚未 scoped commit/push;C 与 STEP-098 均不启动,iOS runtime 保持用户豁免。详见 `docs/报告/STEP-097_B_独立验收与版本阻塞报告_v1.md`。
|
||||
|
||||
### 2026-09-26 B 阶段 Mac RDC 最新核验(仍阻塞)
|
||||
- B10 `codex exec --json` 终态 `turn.completed`、exit 0,完整 JSONL/status.json 持久化;旧 16-bit fixture 纠正任务亦同。RDC 复编后 B 定向 6/6、扩展 139/139 PASS。
|
||||
- Android `MapLibreMapDestroyListenerTest` 2/2 PASS,Native Java 编译 exit 0;隔离 Kotlin owner 4/4 PASS,均非默认 RN consumer 集成验收。日志和 XML 见 `artifacts/maplibre-particle/step097-b-rdc/`。
|
||||
- .13 release source 无新 `MapLibreMap.addOnDestroyListener()`,新 RN Kotlin 源码默认依赖 .13 AAR;B 保持 `PARTIAL / BLOCKED_NATIVE_AAR_COMPATIBILITY`。Linux 隔离 Gradle 仍待最终状态;未启动 C、STEP-098,也未修改 .13 发布资产。
|
||||
|
||||
### 2026-09-26 B scoped Git 阻塞检查点
|
||||
- Mac RDC 在独立 worktree 对 21 个 B 文件逐项 SHA-256 一致检查后,提交并推送 `step097-b-blocked-20260926`:`e463ba04ce956a54eed02b77f981eeeedd9a5534`,远端回读一致;`particle/main` 仍为 `b1239ac3b`,原 dirty/untracked(含 STEP-098)未动。
|
||||
- 该提交只冻结 PARTIAL/BLOCKED 的源码及证据,不是 B PASS;C 与 STEP-098 仍禁止启动,.13 发布资产不变。
|
||||
137
docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md
Normal file
137
docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# STEP-098 QBIN V4 单帧与八帧滚动缓存
|
||||
|
||||
状态:**进行中(Codex 源码交付;等待 RDC 独立构建/定向测试及平台验收)**
|
||||
日期:2026-09-26(JST)
|
||||
|
||||
## 目标与基线
|
||||
|
||||
- 目标:单帧真实时刻首显、合法同批双帧插值、每 `fieldKey` 最多八帧有序滚动,保留现有 RN API 两步调用。
|
||||
- 仓库:Mac `/Users/tei/dev/MapLibreParticleLab`;branch `particle/main`;开工 HEAD `b1239ac3b1554943200e6fbf14321459ccc86527`,结束时 HEAD 未变。
|
||||
- Integration:`main` / `origin/main`=`1dd576d3304e267e53ed64d31f9711d2350ce10a`;RFC-004、ADR-001、C-002、COORD-005 均已读。旧 RFC-003 阻塞由本轮明确的新接受契约解除;旧阻塞报告保留不改。
|
||||
- 当前 Android Native/RN 坐标仍为 `13.4.1-particle.13`;本次未改版本或发布资产。iOS 基础版本 `6.28.0`。
|
||||
- 工作树开工已有 STEP-097 B 修改/未跟踪文件、STEP-098 原任务与旧阻塞报告;保留原样。`git submodule status` 全部与记录 SHA 一致。
|
||||
|
||||
## 本轮完成
|
||||
|
||||
- `FieldSeries` 在 exact validTime 返回真实单帧窗口;非精确时间只解析本地相邻 pair。
|
||||
- 按 key 区分共存 schema 与插值批次身份。新批次可进入滚动序列并按精确时间单帧显示;插值要求 fieldID、reference time、resolved profile ID/version 与 grid/plane schema 全部相同。Ingress 保存已验证 profile 身份。
|
||||
- 满额候选集合先按新帧时间选择远端点,等距删除原最早端;通过 schema 邻接校验后原子 swap。拒绝帧不先淘汰。八帧以上正常插入使用既有成功结果。
|
||||
- 新增 decoded raw-plane + validity 字节计数;单帧 T0/T1 共享一份 materialized Snapshot,WeatherColor/Particle 首次 GPU 安装共享相同 endpoint 资源。
|
||||
- 扩展 Runtime、Binding、Ingress、RasterArraySource 定向测试代码,覆盖单帧/双帧/滚动/跨批次/原子拒绝/内存计数/重复清理场景;详见设计和完成报告矩阵。
|
||||
- RN TypeScript、Android Kotlin/JNI、iOS bridge 静态核对:旧 API 名称、参数、返回类型和两步顺序不变;未修改 bridge。
|
||||
- 新增中文设计文档与本报告;开发记录仅追加本轮事实。
|
||||
|
||||
## 修改范围
|
||||
|
||||
STEP-098 本轮源代码与测试:
|
||||
|
||||
- `include/mbgl/particle/field/field_runtime.hpp`
|
||||
- `src/mbgl/particle/field/field_runtime.cpp`
|
||||
- `src/mbgl/particle/field/field_projection_materialization.cpp`
|
||||
- `src/mbgl/particle/ingress/qbin_v2_decoder.cpp`
|
||||
- `src/mbgl/renderer/layers/render_particle_validation_layer.cpp`
|
||||
- `src/mbgl/renderer/layers/render_weather_color_layer.cpp`
|
||||
- `test/particle/field_binding.test.cpp`
|
||||
- `test/particle/field_runtime.test.cpp`
|
||||
- `test/particle/qbin_v2_decoder.test.cpp`
|
||||
- `test/source/raster_array_v4_host_api.test.cpp`
|
||||
|
||||
文档/记录:
|
||||
|
||||
- `docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.md`
|
||||
- `docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md`
|
||||
- `docs/报告/STEP-098_QBIN_V4单帧与八帧滚动缓存_Codex完成报告_v1.md`
|
||||
- 根目录 `粒子开发记录.md`(追加)
|
||||
|
||||
未修改用户原任务书、STEP-097 的矩阵/记录/清单/桥接文件、NavSea/Server、QBIN 格式、版本锁、tag、manifest、制品。`test/particle/field_runtime.test.cpp` 与 `test/source/raster_array_v4_host_api.test.cpp` 开工前已有 B 阶段 dirty 内容;原 B 的 fixture 修正保留,本轮只叠加 STEP-098 测试,并为 Source 测试 QBIN helper 增加 forecast reference 参数。
|
||||
|
||||
## API / ABI 与限制
|
||||
|
||||
- RN 和平台 bridge 公开方法签名/枚举名称:未变。
|
||||
- `DecodedFieldFrame` 增加了解析 profile 身份字段,C++ 结构二进制布局变化;Native/RN 配套版本必须同源码重编。没有用 `.13` 旧 AAR 验证该结构。
|
||||
- `decodedByteSize()` 只计原始 plane storage 与 validity bitset,不含 profile 元数据、CPU 物化数组、图像、GPU texture、粒子/trail。没有执行 CPU/GPU 峰值或长时间泄漏测量。
|
||||
- 单帧 Particle 的实际 GPU 运动、GL/Metal texture 复用、context loss 和设备视觉尚待平台实测。
|
||||
|
||||
## RDC 分阶段执行命令(本轮未运行)
|
||||
|
||||
### B:Shared Core Store / Ingress / Binding
|
||||
|
||||
```bash
|
||||
ninja -C build-step088-opengl mbgl-test-runner
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='ParticleFieldRuntime.*:ParticleFieldBinding.*:ParticleEncodedFieldIngress.*'
|
||||
```
|
||||
|
||||
### C:Projection / Source / Renderer 与 OpenGL、Metal host 回归
|
||||
|
||||
```bash
|
||||
ninja -C build-step088-opengl mbgl-test-runner
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*'
|
||||
ninja -C build-step097-metal-host mbgl-test-runner
|
||||
build-step097-metal-host/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*'
|
||||
```
|
||||
|
||||
先完成 B 并检查结果,再执行 C;Metal host GTest 不等于 iOS 设备 Metal 通过。未通过/退出未知时停在原阶段。Codex 本轮只运行 `git diff --check`,未运行上述命令、Android Gradle、iOS/Xcode、Jest、设备或发布。
|
||||
|
||||
### D:RN / 平台验证前置条件
|
||||
|
||||
RN 端确认现有顺序为成功 await `submitEncodedField(...)` 后才 await `setEncodedForecastTime(...)`;失败提交不得调用 setTime。T17 使用 V15 同源码 Native/RN 配套构建和 Host 手工验证,不能用现有 `.13` AAR 替代。
|
||||
|
||||
Windows 11 用户手工验收(待相同 V15 Test Host APK、RN 包与 Native AAR 可用后):
|
||||
|
||||
```powershell
|
||||
cd D:\React\MapLibreParticleRNTestHost-V4
|
||||
npm install <RDC提供的同版本V15 RN package tgz路径>
|
||||
npx expo prebuild --platform android
|
||||
cd android
|
||||
$env:ANDROID_HOME='C:\Users\taibe\AppData\Local\Android\Sdk'
|
||||
$env:ANDROID_SDK_ROOT=$env:ANDROID_HOME
|
||||
.\gradlew.bat :app:assembleDebug
|
||||
adb -s 192.168.200.139 install -r <同源码V15 Test Host APK路径>
|
||||
adb -s 192.168.200.139 shell am force-stop org.maplibre.particle.rntesthost
|
||||
adb -s 192.168.200.139 shell am start -n org.maplibre.particle.rntesthost/.MainActivity
|
||||
```
|
||||
|
||||
在 Host 可复用的本地 QBIN 场景中一次完成:首帧单帧显示/粒子持续运动、标量无粒子、第二帧中点 mix、乱序 8 帧、未来/过去/内部插入与淘汰、跨 reference/profile 日切首帧及回退、duplicate/revision/stale/损坏帧、wind/wave key 隔离、当前 endpoint 淘汰清场、100+ 次滚动及 clear。逐项记录真实请求时间与实际显示 validTime、T0/T1/mix、提交结果、异常日志、进程内存趋势。ADB 全部显式指定 `192.168.200.139`;不得将 Test Host 冒充 NavSea 验收。
|
||||
|
||||
iOS 由 Mac 用户使用同一冻结源码和配套产物手工构建;在 Metal 设备验证单帧首显、单帧向量运动、双帧 mix、跨批次 unavailable、双向淘汰、key 隔离、坏帧不覆盖好投影、clear/context 恢复及长时间内存趋势。Metal host runner 结果不能替代该设备证据。
|
||||
|
||||
## T01–T17 状态
|
||||
|
||||
测试覆盖映射见设计文档 §6。以下“代码覆盖”仅说明测试源码中存在场景;**实际运行均为 NOT RUN**。
|
||||
|
||||
| 项 | 代码覆盖状态 | 实际运行 |
|
||||
| --- | --- | --- |
|
||||
| T01 | 已覆盖 | NOT RUN |
|
||||
| T02 | 已覆盖 | NOT RUN |
|
||||
| T03 | 已覆盖 | NOT RUN |
|
||||
| T04 | 已覆盖 | NOT RUN |
|
||||
| T05 | 已覆盖 | NOT RUN |
|
||||
| T06 | 已覆盖 | NOT RUN |
|
||||
| T07 | 已覆盖 | NOT RUN |
|
||||
| T08 | 部分覆盖;现有 revision/stale 入口 + 满额分支,尚无单一 T08 全覆盖测试 | NOT RUN |
|
||||
| T09 | 部分覆盖;profile/decode/numeric/grid 拒绝及原子性,错误向量仍由既有 binding 测试覆盖 | NOT RUN |
|
||||
| T10 | 部分覆盖;pair mix 0.25/0.5/0.99 已覆盖,精确 T1 以单帧表示 | NOT RUN |
|
||||
| T11 | 已覆盖 | NOT RUN |
|
||||
| T12 | 已覆盖 | NOT RUN |
|
||||
| T13 | 已覆盖 | NOT RUN |
|
||||
| T14 | 已覆盖 | NOT RUN |
|
||||
| T15 | 部分覆盖;materialization/renderer 源码有覆盖,GPU/context loss 未运行 | NOT RUN |
|
||||
| T16 | 部分覆盖;120 次 Core Store 双向滚动/clear 及 byte count 已覆盖,Runtime 切换/GPU 泄漏未运行 | NOT RUN |
|
||||
| T17 | 部分覆盖;bridge 静态检查,自动化成功/失败序列与配套消费构建未运行 | NOT RUN |
|
||||
|
||||
## 当前结果与下一步
|
||||
|
||||
- 当前结果:**源码已实施,等待 RDC 阶段 B 独立构建和测试;没有 PASS 结论。**
|
||||
- `git diff --check`:通过(只代表空白/patch 格式检查)。
|
||||
- 未完成:所有新增 C++ 测试执行、OpenGL/Metal host 构建、Android/RN 同版本配套构建、iOS/Metal 设备验证、窗口拖动/跨天/内存实测、V15 pipeline、commit/push。
|
||||
- 剩余阻塞:当前仅为 RDC 尚未运行本轮实现;`.13` 不能与新增 C++ Frame layout 配对,需后续同源码新版本构建。
|
||||
- 下一责任:RDC 按 B→C 顺序执行并反馈真实日志;Android、iOS 设备与 Test Host 验收在后续配套阶段完成。当前停止于 Codex 源码交付,不进入 V15 pipeline。
|
||||
|
||||
|
||||
## 2026-09-27 RDC 独立构建与定向测试补充(覆盖“本轮 NOT RUN”的后续事实)
|
||||
|
||||
- Codex `turn.completed` / exit 0 后,RDC 先执行 B;初次 runner 无 ninja PATH、Source 测试访问 private store、两处 fixture Grid 不合法,均已按首个真实错误做定向修复,记录见 `docs/报告/STEP-098_RDC定向验收报告_v1.md`。
|
||||
- B OpenGL Core/Binding/Ingress 编译 PASS,19/19 GTest PASS。
|
||||
- C1 OpenGL Host 扩展 `Particle*.*:Source.RasterArray*` 119/119 PASS。
|
||||
- C2 Metal Host 编译 PASS,同 filter 119/119 PASS。
|
||||
- 源级测试不等于 Android RN consumer/iOS 真机 GPU、内存/交互通过;V15 Pipeline 此时尚未启动。下一关必须为同源码发布构建和分端实测。
|
||||
175
docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md
Normal file
175
docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# STEP-099 RenderSource 就绪与 RenderSegment 失效诊断
|
||||
|
||||
状态:**CLOSED / PASS**
|
||||
日期:2026-10-06(JST)
|
||||
|
||||
## 基线
|
||||
|
||||
- 仓库:`/Users/tei/dev/MapLibreParticleLab-step099`
|
||||
- 分支:`step099-render-source-diagnostics`
|
||||
- frozen release:`maplibre-particle/rn/13.4.1-particle.17`
|
||||
- frozen release commit:`e8b451fe70054107773e82484c80e90df3889147`
|
||||
- implementation commit:`8a5214d92dd2f8899db76d2194da42999fa0c87d`
|
||||
- Integration/NavSea:未修改。
|
||||
|
||||
## 本 Step 完成内容
|
||||
|
||||
- Renderer readiness snapshot additive 暴露 style/image manager/render orchestrator/sprite readiness、fading、global content revision、per-source 状态和最近 mutation。
|
||||
- per-source diagnostics 暴露 sourceId/type/enabled/isLoaded;tile-backed source 提供 tileCount/incomplete/loaded/fading。
|
||||
- RenderSegment diagnostics 只读推导 `dependentSourceIds` / `unknownDependencies`;source-less layer 不制造 source dependency,共享 source 可出现在多个 segment。
|
||||
- mutation sequence/source/tile action/reason 只消费既有 renderer 事件;正式 revision 增长逻辑不变。
|
||||
- 正式 loaded 判定保持:
|
||||
`renderTreeParameters->loaded = updateParameters->styleLoaded && isLoaded();`
|
||||
- diagnostics snapshot 不进入正式 loaded/cache/fast path/segment execution。
|
||||
- RN 仅增加 diagnostics 类型字段;没有 NavSea 私有 API,没有改变业务 API。
|
||||
- Android Test App 提供 T1 STATIC、T2 GEOJSON_1HZ、T3 PERMANENT_UNREADY、T4 R-C-R。
|
||||
|
||||
## Native 验证
|
||||
|
||||
Metal host `RenderSegmentDiagnostics.*`:
|
||||
|
||||
- 6/6 PASS;
|
||||
- 新增 `ReadinessSnapshotMapsSourcesToSegmentsWithoutSideEffects` PASS;
|
||||
- 覆盖 source readiness、tile stats、source→segment、shared source、source-less 与重复 query 无副作用。
|
||||
|
||||
最终源码再次尝试 Metal configure 时当前 Mac 缺 `libuv` pkg-config,因此第二次 host rerun 未进入 build;不虚报 PASS。最终代码已经被 Android 全量 native build 成功编译并由 T1~T4 运行覆盖。
|
||||
|
||||
Vulkan:因当前 Mac 缺 `libuv`,NOT RUN tests。
|
||||
|
||||
Jest:NOT RUN,用户未要求。
|
||||
|
||||
## Android 构建
|
||||
|
||||
首轮 Android NDK 暴露:
|
||||
|
||||
```text
|
||||
error: missing field 'tileCount' initializer
|
||||
[-Werror,-Wmissing-designated-field-initializers]
|
||||
```
|
||||
|
||||
只补全 `RenderSourceReadinessStats` 默认空字段显式初始化。
|
||||
|
||||
随后 native build 通过,但 strip 阶段因 Mac 磁盘仅剩约 2 GiB:
|
||||
|
||||
```text
|
||||
No space left on device
|
||||
```
|
||||
|
||||
仅清理可再生 Gradle 9.5.1 cache / 失败中间产物后恢复约 12 GiB,再次增量构建:
|
||||
|
||||
- `BUILD SUCCESSFUL in 4m 54s`
|
||||
- 86 actionable tasks:7 executed / 79 up-to-date
|
||||
- OpenGL Debug / x86_64
|
||||
- APK:61,923,024 bytes
|
||||
- libmaplibre.so:39,602,856 bytes
|
||||
- SHA-256:
|
||||
`5de73f0358b835a78d3ae7e2ac22f4efdb2a66775b8c63654a8bb7313957d90a`
|
||||
|
||||
设备:
|
||||
|
||||
- `192.168.200.139:5555`
|
||||
- FZG1-2
|
||||
- Android 13 / API 33 / x86_64
|
||||
|
||||
## T1~T4 结果
|
||||
|
||||
### T1 STATIC
|
||||
|
||||
- 1 个启动 false window;
|
||||
- avg/max = 204 ms;
|
||||
- 随后 global loaded 稳定为 true;
|
||||
- retained cache 可持续 reuse;
|
||||
- fast path 可进入 active。
|
||||
|
||||
### T2 GEOJSON_1HZ
|
||||
|
||||
- 两个 GeoJSON source 交错更新,总 update 122 次,约 61 次/源;
|
||||
- 10 个 loaded=false window;
|
||||
- avg 203 ms;
|
||||
- max 205 ms;
|
||||
- open 0;
|
||||
- 约 60 s 中 false 总时长约 2.03 s,约 3.4%。
|
||||
|
||||
结论:存在 readiness thrash,但不是“几乎永远 false”。
|
||||
|
||||
### T3 PERMANENT_UNREADY
|
||||
|
||||
`step099-unready-raster-array`:
|
||||
|
||||
- 无 layer;
|
||||
- enabled=false;
|
||||
- isLoaded=false;
|
||||
- 其他主要 source loaded。
|
||||
|
||||
结果:
|
||||
|
||||
- global renderOrchestratorLoaded=false 持续;
|
||||
- 观察结束 open false window = 21,459 ms;
|
||||
- retained cache 持续 style-not-loaded fallback。
|
||||
|
||||
结论:单个与 segment 无关的 permanently unready source 足以拉低 V17 全局 loaded。
|
||||
|
||||
### T4 R-C-R
|
||||
|
||||
- R0 deps=[step099-static]
|
||||
- C deps=[particle-fixture]
|
||||
- R1 deps=[org.maplibre.annotations, step099-dynamic, step099-static]
|
||||
- dynamic update:61 次
|
||||
|
||||
结果:
|
||||
|
||||
- loaded false windows:4
|
||||
- avg 203 ms
|
||||
- max 207 ms
|
||||
- contentRevision:1760 → 2540
|
||||
- diagnostics 对 dynamic source 正确给出 affected=[2]
|
||||
- R0 不依赖 dynamic source,但:
|
||||
- build 1 → 121
|
||||
- invalidation 20 → 200
|
||||
|
||||
结论:dependency diagnostics 已能表达 source-local 影响,但 V17 正式 content revision/cache invalidation 仍为 global。
|
||||
|
||||
## Q1~Q7
|
||||
|
||||
1. Q1:**YES**。permanently unloaded source 会造成全局 style-not-loaded。
|
||||
2. Q2:**YES**。1 Hz GeoJSON 会产生约 200 ms readiness false window;T2 avg 203 / max 205 ms。
|
||||
3. Q3:**NO(本次观测)**。双 1 Hz source 并未让 global loaded 几乎始终 false。
|
||||
4. Q4:**YES**。GeoJSON tile mutation 推进 global content revision,并使 retained cache 重建/失效。
|
||||
5. Q5:**YES**。不引用动态 GeoJSON 的 R0 仍受 global revision 影响;源码还确认 `retainedRangeIsStable` 全局检查所有 source fading。
|
||||
6. Q6:fast path 仍有 global update signature(sources/layers/images 等)、global content revision、global fade、pendingChanges、placement/light/non-particle transition/repaint、annotation mutation、retained revision/cache/topology/boundary,以及 singleContinuous gate。
|
||||
7. Q7 blocker:
|
||||
- runtime confirmed:`PERMANENT_SOURCE_UNLOADED`、`DYNAMIC_SOURCE_READINESS_THRASH`、`GLOBAL_CONTENT_REVISION`
|
||||
- source confirmed:`GLOBAL_FADE`、`GLOBAL_UPDATE_SIGNATURE`
|
||||
- OTHER:pending/placement/light/repaint/annotation/topology/boundary/singleContinuous。
|
||||
|
||||
## 证据
|
||||
|
||||
忽略目录:
|
||||
|
||||
`artifacts/maplibre-particle/android-validation/`
|
||||
|
||||
- `build-info.txt`
|
||||
- `build.log`
|
||||
- `MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk`
|
||||
- `step099-logcat.txt`
|
||||
- `step099-device-info.txt`
|
||||
- `step099-metal-gtest.log`
|
||||
|
||||
STEP-099 log SHA-256:
|
||||
|
||||
`0f15d75dde77e7dd2f4d98c46a4c1501a628205e8aae62130b0cb96db6b8482f`
|
||||
|
||||
## 边界结论
|
||||
|
||||
本 Step 未修改:
|
||||
|
||||
- retained cache 算法;
|
||||
- fast path gate;
|
||||
- singleContinuous / multi-continuous;
|
||||
- segment-local invalidation 正式语义;
|
||||
- RenderSegment execution;
|
||||
- NavSea;
|
||||
- Source isLoaded;
|
||||
- RN 业务 API。
|
||||
|
||||
下一阶段应拆分处理 global source readiness、source/segment-local content revision/invalidation,再独立处理 fast-path global gates。
|
||||
132
docs/50_Step记录/STEP-100_SourceScoped_RenderSegment局部失效_v1.md
Normal file
132
docs/50_Step记录/STEP-100_SourceScoped_RenderSegment局部失效_v1.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# STEP-100 SourceScoped RenderSegment 局部失效记录 v1
|
||||
|
||||
状态:**CLOSED / PASS(Android runtime)**
|
||||
日期:2026-10-06
|
||||
|
||||
## 基线
|
||||
|
||||
- worktree:`/Users/tei/dev/MapLibreParticleLab-step100`
|
||||
- branch:`step100-segment-local-source-invalidation`
|
||||
- start HEAD:`c4b481fd2c5b5da20d31f6ae54011f0552d7dbd0`
|
||||
- V17 tag:`maplibre-particle/rn/13.4.1-particle.17`
|
||||
- V17 frozen commit:`e8b451fe70054107773e82484c80e90df3889147`
|
||||
|
||||
## 实现
|
||||
|
||||
- Source/Tile mutation 增加 source-scoped revision;
|
||||
- global retained content revision 继续保留;
|
||||
- production renderer 与 diagnostics 共用 source→segment dependency;
|
||||
- RETAINED Segment 独立 readiness / stability / Build / Reuse / Fallback;
|
||||
- unrelated source unloaded/fading 不再拖垮该 Segment;
|
||||
- full CPU mixed execution 支持 R0 Reuse + C Live + R1 Fallback;
|
||||
- Fast Path gate、singleContinuous、多 Continuous语义未改;
|
||||
- Source::isLoaded 与 global renderTree loaded 语义未改。
|
||||
|
||||
## Android Build
|
||||
|
||||
标准 validation pipeline 最终:
|
||||
|
||||
```text
|
||||
RC=0
|
||||
BUILD SUCCESS
|
||||
variant=OpenglDebug
|
||||
abi=x86_64
|
||||
apk_bytes=61956640
|
||||
libmaplibre_bytes=39636472
|
||||
sha256=86e22bf081bf7d3196f0bf0e7c56af51bde01e9f0b01e0bab238cb794273315a
|
||||
```
|
||||
|
||||
RDC 另修复 validation script 的 pipefail/SIGPIPE 141:
|
||||
`awk ... {print $1; exit}` → 完整消费管道。
|
||||
|
||||
## FZG1-2
|
||||
|
||||
- Android 13
|
||||
- API 33
|
||||
- x86_64
|
||||
- ADB:`192.168.200.139:5555`
|
||||
|
||||
### T1 STATIC
|
||||
|
||||
- false window:1
|
||||
- avg/max:203 ms
|
||||
- R0/R1 build=1 后持续 reuse
|
||||
|
||||
### T4 R-C-R 主验收
|
||||
|
||||
窗口:
|
||||
- baseline:tick 8
|
||||
- final:tick 130
|
||||
- 约 61.6 s
|
||||
|
||||
global revision:
|
||||
`128 → 973`
|
||||
|
||||
R0:
|
||||
```text
|
||||
build 1 → 1
|
||||
invalidation 20 → 20
|
||||
reuse 132 → 4042
|
||||
sourceRevision unchanged
|
||||
```
|
||||
|
||||
R1:
|
||||
```text
|
||||
build 5 → 135
|
||||
invalidation 26 → 211
|
||||
```
|
||||
|
||||
结论:
|
||||
- R0 buildDelta=0
|
||||
- R0 invalidationDelta=0
|
||||
- R0 reuseDelta=+3910
|
||||
- global revision 仍增长
|
||||
- dynamic source affected=[2]
|
||||
|
||||
**主硬门槛 PASS。**
|
||||
|
||||
### T2 GEOJSON 1HZ
|
||||
|
||||
- 约 35 s
|
||||
- falseWindowCount=6
|
||||
- avg=203 ms
|
||||
- max=205 ms
|
||||
- R0 build=1 / invalidation=18 保持稳定,reuse 增长
|
||||
|
||||
### T3 PERMANENT UNREADY
|
||||
|
||||
global loaded=false 持续约 21.468 s。
|
||||
|
||||
unready source:
|
||||
- no layer
|
||||
- enabled=false
|
||||
- isLoaded=false
|
||||
|
||||
R0/R1:
|
||||
- build=1 不变
|
||||
- invalidation=19 不变
|
||||
- reuse:11 → 1200
|
||||
- decision=reuse
|
||||
|
||||
说明 global loaded 兼容事实仍为 false,但无关 retained cache 继续安全复用。
|
||||
|
||||
## Native Host Test
|
||||
|
||||
Codex 已新增 `RenderSegmentLocality.*` 测试源码。
|
||||
|
||||
当前 Intel Mac 缺 `libuv`,Metal host configure 被环境阻塞。RDC 曾尝试 Homebrew 安装,但发现会连带升级 CMake/OpenSSL/Python 且 Intel 无 bottle 支持,已主动停止。
|
||||
|
||||
因此:
|
||||
- Native host GTest:ENV BLOCKED / NOT RUN
|
||||
- Android full native build:PASS
|
||||
- Android runtime:PASS
|
||||
|
||||
Jest:NOT RUN。
|
||||
|
||||
## 结论
|
||||
|
||||
STEP-100 功能目标成立:
|
||||
|
||||
> GeoJSON Source 更新只刷新依赖它的 retained segment;无关 retained segment 不再一起刷新。
|
||||
|
||||
允许进入 V18 unified release。
|
||||
54
docs/50_Step记录/STEP-101_RenderOrchestrator销毁生命周期修复_v1.md
Normal file
54
docs/50_Step记录/STEP-101_RenderOrchestrator销毁生命周期修复_v1.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# STEP-101 RenderOrchestrator 销毁生命周期修复记录 v1
|
||||
|
||||
状态:**CLOSED / PASS(Native + Android runtime)**
|
||||
日期:2026-10-07
|
||||
|
||||
## 目标与基线
|
||||
|
||||
- 工作区:`/Users/tei/dev/MapLibreParticleLab-step101`
|
||||
- 分支:`step101-render-orchestrator-teardown`
|
||||
- start HEAD:`d29e84c1a90daeea104b389d28b000c4f017d08d`
|
||||
- implementation commit:`64cf8f44350eb8ec4b45360db4d3f9505ac4ac0b`(`fix: make render orchestrator teardown safe`),已 push 到 `origin/particle/main` 并回读一致。
|
||||
- 工作合同:`docs/40_任务/STEP-101_RenderOrchestrator销毁生命周期修复_Codex任务_v2.md`,第 13 节优先于前文冲突项。
|
||||
- V18 为不可变已发布版本;本阶段未创建、发布或标记 V19。
|
||||
- 目标:修复 RenderSource/Tile 销毁时 observer 可能回调已析构的 RenderOrchestrator readiness mutex/state 的生命周期漏洞。
|
||||
|
||||
V18 成员声明使 readiness mutex/state 早于 `renderSources` 自动析构。Tile 销毁时同步发出 `Cancelled` 回调的路径可达,且与现场 Android destroyed mutex SIGABRT 高度吻合;没有完整符号化栈与修复后等价实机结果,暂不把它写成唯一确认的现场根因。
|
||||
|
||||
## 必做项进度
|
||||
|
||||
- [x] `RenderSource::setObserver(nullptr)` 恢复 NullObserver,保留正常 observer 转发。
|
||||
- [x] Orchestrator 析构:保留 contextLost layer handling;第一次 tagged drain;detach RenderSource、GlyphManager、ImageManager observer;在 readiness state 存活时清理 sources;第二次 tagged drain。
|
||||
- [x] 静态审计独立 render-job 队列:`waitForEmpty()` 不排空该队列;OpenGL context 析构的 `runRenderJobs(true)` 属于后续 backend 清理,测试中也单独调用 `runRenderJobs()`。不能以双 drain 代替 render-job 验收。
|
||||
- [x] 新增非 Jest C++ 测试源码:默认/真实/detach observer、三种 tile callback、Cancelled、source 清理后第二次 drain、render-job 单独处理和重复 teardown。helper 像生产代码一样注册 Orchestrator observer,并断言 source 销毁前旧 observer 已被替换。
|
||||
- [x] Android Validation 增加 T1 RESET_ONCE、T2 RESET_LOOP_20、T3 RESET_WITH_DYNAMIC_GEOJSON、T4 RESET_WITH_DIAGNOSTICS;通过 Activity recreate 触发 MapView 销毁/新建,并输出 SurfaceView detach、nativeReset、resetRenderer、style ready 与 diagnostics 日志供逐次配对。
|
||||
- [x] 只读审计正常 `renderSources.erase()` / `clearData()`:两者在 Orchestrator 存活期间执行;TileCache 析构等待其延迟释放任务结束。本阶段没有扩大其行为修改,运行态异步边界仍待 RDC 验证。
|
||||
- [x] 静态核对 STEP-100 locality、Fast Path、`singleContinuousSegment`、`Source::isLoaded()` 等代码未被本次 diff 修改。
|
||||
- [x] Native:Android full native build PASS;focused Android C++ TestRunner 6/6 PASS。Mac host 因 libuv 环境阻塞,未虚报。
|
||||
- [x] Android Validation APK build PASS;T1~T4 实机 PASS;T2 完整 20 次真实 reset/recreate,crash buffer 为空。
|
||||
- [x] STEP-100 T4 R-C-R locality 回归 PASS:R0 buildDelta=0、invalidationDelta=0、reuseDelta=+3878。
|
||||
- [ ] V19 candidate、NavSea 五次冷启动与正式 V19 发布:属于后续发行 Gate,尚未执行。
|
||||
|
||||
## 允许与禁止范围
|
||||
|
||||
实际变更限于 Orchestrator/RenderSource 生命周期、对应 C++ 测试、Android Validation 场景及 Java/JNI reset 观测日志。未修改 NavSea、provider/network、STEP-100 locality 实现、发布坐标或 V18 产物。未运行 Jest。
|
||||
|
||||
## 检查与当前结果
|
||||
|
||||
本次验证仅包含源码 diff 静态审计与 `git diff --check`。构建、链接、GTest、Gradle/APK、ADB、设备、NavSea、发布均 **NOT RUN**;源码交付不能记为运行态 PASS。完成报告:`docs/报告/STEP-101_RenderOrchestrator销毁生命周期修复_Codex完成报告_v1.md`。
|
||||
|
||||
## 阻塞与下一步
|
||||
|
||||
当前没有已观测编译失败;实际编译与场景行为仍未知。由 RDC 按完成报告的命令独立编译、运行 Native 测试、Android T1~T4、STEP-100 locality,并核对每次 `RESET_REQUEST` 对应 SurfaceView detach、`nativeReset`、`resetRenderer` 和新 renderer ready。随后才进入 V19 candidate 与 NavSea 等价验收;全部门槛满足后才可考虑正式发布。
|
||||
|
||||
|
||||
## RDC 最终证据
|
||||
|
||||
- Android Validation APK:61,957,678 bytes;`libmaplibre.so` 39,637,512 bytes;SHA-256 `14cbd35ed0bc1366389ddea69925901013e3b209ed3575462421a7920c73c721`。
|
||||
- T1~T4 teardown:全部 PASS;T2 20 次 reset;动态 GeoJSON / diagnostics 条件均无 crash。
|
||||
- STEP-100 locality:global revision 62→894;R0 build 1→1、invalidation 19→19、reuse 12→3890;PASS。
|
||||
- Android C++ focused TestRunner:4 个 `RenderSegmentLocality` + 2 个 `RenderOrchestratorTeardown` 全部 PASS;status=0。
|
||||
- Mac host GTest:ENV BLOCKED(本机缺可用 libuv pkg-config),不影响 Android full native/device 闭环结论。
|
||||
- Jest:NOT RUN。
|
||||
|
||||
**STEP-101 CLOSED / PASS。** 下一阶段进入 V19 candidate → NavSea 等价冷启动 Gate → 不可变公开发行。
|
||||
60
docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md
Normal file
60
docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# STEP-102 RenderSegment 无 Placement 段局部复用记录 v1
|
||||
|
||||
状态:**进行中(代码完成,等待独立构建与运行验证)**
|
||||
日期:2026-10-08
|
||||
|
||||
## 目标与基线
|
||||
|
||||
- 工作区:`/Users/tei/dev/MapLibreParticleLab-step102`
|
||||
- 分支:`step102-placement-free-retained-locality`
|
||||
- 起点 HEAD:`6df21dac38f072c5ad35b8dfc7ec5217509602bc`
|
||||
- 工作合同:`docs/40_任务/STEP-102_RenderSegment无Placement段局部复用_Codex任务_v1.md`
|
||||
- 设计依据:`docs/20_调查/RenderSegment多Retained段全局Placement门槛_粒子管理员审查说明_v3.md`
|
||||
- 发布坐标:V19/V20 工作区与发行内容冻结;本 Step 不创建版本。
|
||||
|
||||
目标是让结构上没有 symbol layer 的 Retained Segment 在其他段 placement 活跃时继续独立缓存并经 main-buffer composite。
|
||||
|
||||
## 必做项
|
||||
|
||||
- [x] 基于 style layer type 查询结构性 placement capability;不使用当前帧 `needsPlacement()` 证明 placement-free。
|
||||
- [x] full CPU 每段计算 placement gate;含 symbol 的段仍受 changed、fade 与 transition 保守门槛约束。
|
||||
- [x] `segmentSupported` 和 fallback reason 按段生成;full CPU global-live 只移除纯 aggregate placement 条件。
|
||||
- [x] 保留 3D、debug、MapMode、sprite/image、light 等真实全局门槛和既有 revision/key 失效。
|
||||
- [x] diagnostics 增加结构、逐段 gate、实际 main-buffer 执行及全局 placement/execution 字段;RN TS 只增加诊断字段。
|
||||
- [x] 新增 C++ 源码测试与 Android STEP-102 Validation fixture/日志场景。
|
||||
- [x] 静态核对 Fast Path、mixed executor、C-001、RN method surface 未修改。
|
||||
- [ ] C++ 编译与定向测试、Android 用户手工构建、设备场景、iOS/Metal 验证:尚未执行。
|
||||
|
||||
## 允许与禁止范围
|
||||
|
||||
代码修改仅在任务书允许的 renderer、RN diagnostics 类型、`retained_underlay_cache.test.cpp` 和 Android Particle Validation 文件。未修改 `visitRenderSegmentExecution()`、`tryRenderParticleFastFrame()`、`retainedRangeUsesPlacement()`、Placement 算法、NavSea、C-001、发布文件或总则。既有未跟踪 v2/v3 审查说明及任务书保持原样。
|
||||
|
||||
## 构建、测试与当前结果
|
||||
|
||||
只读源码/diff 审计及 `git diff --check` 已执行,后者通过;新增未跟踪文件另用 `git diff --no-index --check` 检查,无空白错误(差异本身使退出码为 1)。CMake/Ninja/Bazel、GTest、Android Gradle、APK/AAR、ADB、设备、Jest、NavSea、发布全部 **NOT RUN**。静态检查不构成运行态 PASS。
|
||||
|
||||
## 必做输出
|
||||
|
||||
- STEP-102 生产代码、C++ 测试源码、Android Validation 场景源码。
|
||||
- `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md`。
|
||||
- 本记录与 `粒子开发记录.md` 追加。
|
||||
- 报告中列出精确后续验证命令、硬门槛、NOT RUN 与剩余风险。
|
||||
|
||||
## 阻塞与下一步
|
||||
|
||||
目前没有已观察到的编译或运行失败;真正结果仍未知。由 RDC/用户按报告完成 Native focused tests、用户手工 Android APK 构建和 T1/T2 设备场景,核对 R0/R1 的 `placementCapable`、`placementGatePassed`、`actualExecution` 与 build/reuse/invalidation。构建或设备失败时保留首个真实错误与日志,再按任务边界修复;本 Step 未进入后续发行阶段。
|
||||
|
||||
## RDC 独立验证补记(2026-10-08)
|
||||
|
||||
- 从现有工作树、任务书、v3 审查依据和项目总则恢复审查;原 Codex 阶段的 NOT RUN 记录保留,以下为新增 RDC 事实。
|
||||
- `git diff --check`:退出码 0,PASS;无关的 `platform/windows/vendor/vcpkg` 子模块状态变化不纳入本任务。
|
||||
- 以 AppleClang 对 `test/renderer/retained_underlay_cache.test.cpp` 执行 `-std=c++20 -fsyntax-only`:退出码 0,语法检查 PASS;不是 GTest 运行结果。
|
||||
- 本地临时独立 C++ helper smoke 测试:结构性 symbol 判定、placement gate、全局 live reason 共 10 个断言,10/10 PASS;测试文件位于 `/tmp/step102-placement-smoke.cpp`,不是正式 GTest。
|
||||
- Mac CMake `cmake --preset macos-metal`:配置退出码 1,阻塞于缺少 `libuv`;未进入 GTest 编译或运行,未安装/升级依赖。日志 `/tmp/step102-cmake-config.log`。
|
||||
- 额外审查并修复 Android STEP-102 Validation 切换入口:进入该场景时停止 STEP-093 诊断轮询、清除 STEP-093/097 标志,避免旧场景轮询污染 STEP-102 证据。
|
||||
- Metal Bazel Core 构建 `bazel build -c opt --//:renderer=metal //:mbgl-core` 已完成:退出码 0,642/642 actions,耗时 875.118s,产物 `bazel-bin/libmbgl-core.a`,构建 PASS;日志 `/tmp/step102-bazel-core.log`。该 PASS 仅表示 Native Core 编译,不代表 GTest/Android/运行态 PASS。
|
||||
- Android Gradle/APK/ADB 与设备验证依任务规则均未执行;STEP-102 继续保持“进行中 / 待 Android 实际验收”,不得标记 CLOSED / PASS。
|
||||
|
||||
## V21 发布决策(2026-10-08)
|
||||
|
||||
用户明确接受未执行正式 GTest、Android T1/T2、iOS/Metal 运行态验证的风险,要求 STEP-102 经源码审查即纳入 V21 发行。代码审查未发现明确阻断项;先前 Metal Core 642/642 编译通过。本步骤依然不属于运行态验收 PASS。发布须完整执行 `prepare → build → publish → finalize`;发布记录应明确验收豁免。
|
||||
28
docs/50_Step记录/STEP-104_官方Native13.6.1升级阶段A_v1.md
Normal file
28
docs/50_Step记录/STEP-104_官方Native13.6.1升级阶段A_v1.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# STEP-104 官方 Native 13.6.1 升级阶段 A
|
||||
|
||||
- 状态:进行中。
|
||||
- 当前基线:官方 Android Native `c7506d6aff3800e946f89e1a51432fc22d1a6534`;自研旧版本 .21 `630ec657687bad4200c059bbccbb950d9c6f7ce9`。
|
||||
- 目标:把现有 Particle、WeatherColor、RasterArray、RenderSegment/Retained 与 Android Native 接口移植到官方 13.6.1,保持原语义;形成能进行精确编译验证的候选代码。
|
||||
- 必做:合并/冲突、代码边界适配、append-only `recoder_step.md`、多提交、完成报告、RDC 静态及精确编译。
|
||||
- 允许:本分支 Core/Android Native/构建配置/必要测试/记录。
|
||||
- 禁止:NavSea、其他 worktree、主线和正式发行、未经协调的公共合同变化。
|
||||
- 构建与测试:暂未运行;由 RDC 独立执行,不因任务书生成而记 PASS。
|
||||
- 本轮输出:`docs/40_任务/STEP-104_官方Native13.6.1升级阶段A_Codex任务_v1.md`、`docs/报告/STEP-104_官方Native13.6.1升级阶段A_Codex完成报告_v1.md`、`recoder_step.md`、阶段代码 Git checkpoints。
|
||||
- 当前结果:Gate 0 官方第一父基线检出;自研合并未开始。
|
||||
- 阻塞:尚无;旧/新版差异已在 UPSTREAM-001 审计,需逐项移植。
|
||||
- 下一步:Codex 迁移,RDC 独立编译,失败反馈给 Codex;未获得真实编译/设备结果不得宣称发布成功。
|
||||
|
||||
## Gate 1 实际进展(2026-10-09)
|
||||
|
||||
- 官方为第一父的 Git merge commit:`f8378fd7113c4d230500f0b82902d2356907f4a9`。
|
||||
- 76 个冲突路径已处理、没有未合并 index 条目;RDC 已检查 Git history 和 Native 代码空白格式。
|
||||
- 与旧发布的 Particle/QBIN/RenderSegment 功能是否能够完整编译、正确渲染仍未验证。本任务目标保持进行中;下一 Gate 为 Android Native 精确编译。
|
||||
- 本检查点只能称为 `SOURCE_MERGED / BUILD_NOT_RUN`,不是 Android/iOS SDK PASS。
|
||||
|
||||
## Gate 2 / 2026-10-09 / RDC Native 编译实际结果
|
||||
|
||||
- 结果:Android x86_64 OpenGL Native **PASS**(Gradle `BUILD SUCCESSFUL in 22m 24s`;进程退出码 0),编译提交 `a4b5f4eaa0eccb734e00d67adb5e750bba320404`。
|
||||
- 产物:`MapLibreAndroid/build/intermediates/cmake/openglDebug/obj/x86_64/libmaplibre.so`,`377246848` bytes,SHA-256 `ff5a5eb45f84ff633a87fe385fb04ee39ba63ed3bc486003408e02cea78c8907`。
|
||||
- 已排除的构建阻塞:新 worktree 的 cheap-ruler-cpp、tile-spec/earcut、supercluster LICENSE 依赖检出缺失;按 Git 固定提交恢复,无需修改产品源码。
|
||||
- 未完成项:其余 ABI、Android 安装/真机 GPU、Vulkan、RN 11.5.0、iOS Metal、发布均 NOT RUN;STEP-104 为 **PARTIAL**(阶段 A Native 编译 Gate 通过,产品发行 Gate 未开始)。
|
||||
- 下一步:Android 多 ABI + 真实 GPU/Style/RenderSegment 功能验收,再进入 RN 11.5.0 公共桥接联调。
|
||||
11
docs/50_Step记录/STEP-105_FZG1-2_MapLibre13.6.1打包安装记录_v1.md
Normal file
11
docs/50_Step记录/STEP-105_FZG1-2_MapLibre13.6.1打包安装记录_v1.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# STEP-105 FZG1-2 MapLibre Native 13.6.1 Validation APK 安装记录
|
||||
|
||||
- 日期:2026-10-09(JST)
|
||||
- 代码来源:官方 Native Android 13.6.1 + Particle .21 迁移候选,分支 `upgrade/android-native-13.6.1-20261009`,构建源提交 `30d0e6665e`。
|
||||
- 构建与目标:Mac,`MapLibreAndroidTestApp`、OpenGL Debug、Native x86_64,Gradle 6m48s 初次完成;因 Sentry 辅助库多 ABI 被旧检查规则拒绝;修订验证规则后增量 Gradle 10s,ZIP/ABI/体积检查 PASS。
|
||||
- 脚本修改:`tools/particle_android_validation/build_validation_apk.sh` 仅允许非目标 ABI 中已确认的 Sentry 库;`libmaplibre.so` 与 Custom Layer 必须仍为 x86_64;独立提交 `73db0356ac5860366f314ddba23b716220e7c16a`。
|
||||
- APK:`artifacts/maplibre-particle/step105-native1361-fzg/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk`,66,505,502 字节,SHA-256 `77bc0b238fb476494410a603443030b104d78f97a737307be52460bf5a68f5aa`。
|
||||
- 设备:FZG1-2 / Android 13 / ADB `192.168.200.139:5555`。覆盖安装 `adb install -r` **Success**;设备实际版本 `13.6.1`,签名一致、首次安装日期不变,设备文件 SHA 与 Mac 完全一致。
|
||||
- NavSea 仍为前台 App,未主动启动测试 App;运行、GPU 绘制、RenderSegment 等仍 **NOT RUN**,不可写成已通过。
|
||||
- 回退:旧版 13.4.1-particle.21 APK 已独立保存于忽略目录 `artifacts/.../rollback/`,未纳入 Git。
|
||||
- Gate:本阶段 **APK_BUILD_AND_INSTALL_PASS**;下一阶段是 FZG 可视运行及完整功能回归。
|
||||
13
docs/50_Step记录/STEP-105_FZG1-2_MapLibre13.6.1运行验收记录_v1.md
Normal file
13
docs/50_Step记录/STEP-105_FZG1-2_MapLibre13.6.1运行验收记录_v1.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# STEP-105 / FZG1-2 MapLibre Native 13.6.1 实机运行记录 v1
|
||||
|
||||
- 日期:2026-10-09 JST。
|
||||
- 设备:FZG1-2 Android 13 x86_64,ADB 192.168.200.139:5555。源码:upgrade/android-native-13.6.1-20261009 / c30add4d335c5c02aadac5756c1606b5bc497269。
|
||||
- PASS:粒子页面启动和用户观察、Cache 开关、Pan/双击 Zoom 后存活与缓存边界失效、STEP-101 单次重建、STEP-101 流式 Logcat 20 次 Native reset 完整配对、STEP-099 R-C-R 底层复用、QBIN V4 Golden 时间控制六项、STEP-102 T1 Symbol 安全回退、默认界面恢复。
|
||||
- STEP-101 T2 证据:20 请求、20 Native reset enter/complete、40 Renderer reset enter/complete、21 ready、crash buffer 0;最初的环形缓冲被覆盖测试不计正式 PASS。
|
||||
- STEP-099 T4:动态 GeoJSON 71 次更新,R0 buildDelta=0、reuseDelta=3677、invalidationDelta=0。
|
||||
- STEP-102 T1:R0 buildDelta=0、reuseDelta=3683、invalidationDelta=0;R1 包含 Symbol,gate=false、Live/Fallback,符合预期。
|
||||
- FAIL:STEP-102 T2_TWO_FREE 的 R1 持续 placementCapable=true、gate=false、Live/Fallback,reuse=0、invalidation 增加 3682;按 fixture R1 为 Fill,理应支持 retained;R0 reuseDelta=3682、buildDelta=0、invalidationDelta=0。无 crash,不证明错绘或确定回归起点。
|
||||
- 疑点:运行时注入的 Annotation Symbol、真实 Style Layer Index 或 Segment 范围;应先提取完整诊断和旧 .21 对照,保留 fail-closed,不直接改 Core 公共语义。
|
||||
- 证据目录(不提交 Git):artifacts/maplibre-particle/step105-fzg-runtime-20261009/。截图、UI XML、Logcat、crash buffer 齐备。
|
||||
- 恢复:ADB 冷启动默认粒子页 GLOBAL/ACTIVE/EAST/MIX0%/256,当前 FZG 前台 Test App 13.6.1,Crash Buffer 0。
|
||||
- 状态:PARTIAL / T2 EXPECTATION FAIL。未编译、未执行 Jest、未更改源码或 NavSea,下一 Gate 是 T2 定向调查修正后回归。
|
||||
48
docs/50_Step记录/STEP-106_STEP102_T2_Placement边界修正_v1.md
Normal file
48
docs/50_Step记录/STEP-106_STEP102_T2_Placement边界修正_v1.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# STEP-106 STEP-102 T2 自动 Annotation 层边界修正记录 v1
|
||||
|
||||
日期:2026-10-09(JST)
|
||||
|
||||
**状态:SOURCE_FIXED / STATIC_PASS / ANDROID_BUILD_NOT_RUN / DEVICE_RETEST_NOT_RUN**
|
||||
|
||||
## 事实
|
||||
|
||||
- 旧版 13.4.1-particle.21 在 FZG 同样复现 T2 R1 placementCapable=true/gate=false/live/static-placement/reuse0,已保存同场景旧版日志。新版 13.6.1 在比较结束后成功恢复,设备 APK SHA 正确。
|
||||
- 两版 AnnotationManager 会自动在 Style 末尾插入 Symbol Layer org.maplibre.annotations.points。T2 测试 Fixture 的上层自身为 Fill,但原 R-C-R Plan 的 R1 从 step102-upper 延续至最后一层,把该内部 Symbol 也算进去。
|
||||
- 不允许修改或跳过 Shared Core/Renderer Placement 安全 Gate。此次只改两个 Android Test App Kotlin 文件;新增 C2 live 尾部区段,单独承载 MapLibre Annotation Symbol,从而使 T2 的 R1 仅含 Fill;T1 R1 仍含自身 Symbol。
|
||||
- 为 tick8 新增 STEP102_STYLE_LAYER_LAYOUT 日志,供下次实际 APK 验证真实 Style Layer 顺序、分段边界。
|
||||
- 代码 Git 提交:86906c8a6af474a8d064c6f6d7d431e2a7e3efe6;静态检查 PASS,没有执行 Gradle、ADB 修正版验证、Jest。
|
||||
|
||||
## 需用户手工编译
|
||||
|
||||
在 Mac 终端:
|
||||
|
||||
```bash
|
||||
cd /Users/tei/dev/MapLibreParticleLab-upgrade-android-1361
|
||||
export JAVA_HOME=/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
||||
export ANDROID_HOME=/Users/tei/Library/Android/sdk
|
||||
export ANDROID_SDK_ROOT="$ANDROID_HOME"
|
||||
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$PATH"
|
||||
export MAPLIBRE_VALIDATION_OUT_DIR="$PWD/artifacts/maplibre-particle/step106-t2-fix"
|
||||
./tools/particle_android_validation/build_validation_apk.sh
|
||||
```
|
||||
|
||||
脚本内部使用 Gradle `--console=plain`。请保留 BUILD SUCCESS 和 build-info.txt,APK 生成后再由 RDC 安装到 FZG。不得把目前设备上的 13.6.1 旧 APK 当成包含本修复的版本。
|
||||
|
||||
## 复测门槛
|
||||
|
||||
- APK 完整性、包名、版本、Native x86_64、哈希校验;签名不符禁止卸载重装。
|
||||
- 新版 STEP102_STYLE_LAYER_LAYOUT 必须显示自动 Annotation Symbol 在最后的独立 Continuous C2;Plan valid、segments=4。
|
||||
- T1_FREE_SYMBOL:R0 continued Composite/Reuse、R1 placementCapable=true 且需要时 Live、C2 包含 Annotation;不崩溃。
|
||||
- T2_TWO_FREE:R0 和 R1 均 placementCapable=false、gate=true、actualExecution=composite;tick8→130 的 buildDelta=0、invalidationDelta=0、reuseDelta>0;C2 Live;不崩溃。
|
||||
- 复测 STEP-099 T4 R-C-R R0 locality,STEP-101 单次/20次 Native Reset(日志须持续采集),V4 Golden 最小烟测。保留失败路径及原始日志。
|
||||
- 修正作用域限定 Test App 分段验证,不等同生产快帧性能达标。若仍 fallback,应保留 Placement fail-closed,重新诊断而非强制 PASS。
|
||||
|
||||
## 2026-10-09 手工边界获用户明确授权后的 RDC 编译与 FZG 闭环
|
||||
|
||||
- 本轮用户明确要求“你编译和验证吧”。在 Mac 执行 Android Test App Gradle,源码 HEAD 23f7b8a4d7、干净;Gradle/Validation PASS。新版 APK SHA256=0ef3b033cd33139db07258745e9cd9d023170ce69767e3f8a5159821776ec9ef,66,505,495 字节,x86_64 MapLibre Native。
|
||||
- FZG1-2 签名检查一致,adb install -r Success;设备 base.apk SHA 与 Mac 相同、versionName=13.6.1。
|
||||
- T1_FREE_SYMBOL(两窗口):Style 实际 5 层/4 段;R0 reuseΔ+3682、buildΔ0、invalidΔ0;R1 Symbol 继续保守 live/static-placement,PASS。
|
||||
- T2_TWO_FREE(两窗口):R0、R1 均 placementCapable=false/gate=true/composite;两段各 reuseΔ+3683、buildΔ0、invalidΔ0;尾部 Annotation Symbol C2 live,PASS,原 T2 阻塞正式解除。
|
||||
- STEP099 T4:R0 reuseΔ+3675、build/invalidΔ0,PASS。STEP101 T1:1 个 nativeReset 完成,PASS;T2:20 Native reset 完整配对、21 ready、40 Render reset enter/complete,PASS。
|
||||
- QBIN V4 Golden t0/t1 插入、Runtime V4 READY 最小烟测 PASS。Crash Buffer 均无故障记录。FZG 已恢复默认 GLOBAL/ACTIVE/EAST/MIX0%/256,修正版 APK 哈希再次核对一致。
|
||||
- 状态更新:**STEP-106 CLOSED/PASS(FZG Android x86_64/OpenGL 定向问题及回归)**。不代表 ARM64、RN、iOS、Vulkan、全链发行通过。原始日志保存在 Git 忽略的 artifacts/maplibre-particle/step106-t2-fix/。
|
||||
73
docs/50_Step记录/V15_iOS_WeatherColor纹理生命周期修复_v1.md
Normal file
73
docs/50_Step记录/V15_iOS_WeatherColor纹理生命周期修复_v1.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# V15 iOS WeatherColor 纹理生命周期修复
|
||||
|
||||
状态:**进行中(RDC Mac 定向验证 PASS;等待 iPad 人工验收)**
|
||||
日期:2026-09-27(JST)
|
||||
|
||||
## 目标与基线
|
||||
|
||||
- 仅修复 V15 WeatherColor 的 Metal 纹理绑定生命周期,不涉及 V12/V13、JavaScript、NavSea API、Android 行为或发行版本/tag。
|
||||
- 仓库:`/Users/tei/dev/MapLibreParticleLab`;机器:Mac mini、Darwin 24.6.0、x86_64;分支:`particle/main`。
|
||||
- 开工 HEAD:`cd71640a84901212ce4681e296f027befdff4ee0`;`maplibre-particle/rn/13.4.1-particle.15` peeled commit 与 HEAD 相同;`origin/particle/main` 同步于 HEAD。
|
||||
- manifest 的 V15 `sourceCommit` 为 `1fdc5df625d405233703136eb2dc12032d932da2`;后续 finalize release 生成的 V15 tag 指向 HEAD `cd71640a84901212ce4681e296f027befdff4ee0`。这两个坐标分别表示 manifest 源码提交与后续 tag HEAD,不构成冲突;本任务相关已跟踪源码在两提交间相同,tag 与发行内容未改。
|
||||
- 开工时仅有用户提供的 V15 任务书为未跟踪文件;始终保留。现有 submodule 均已初始化,本轮未修改。
|
||||
- 执行模型/推理档位:GPT-6 Luna High。
|
||||
|
||||
## 根因与修改
|
||||
|
||||
Metal LayerGroup 在 drawable 的 `upload()` 后才执行 Tweaker。旧实现于 Tweaker 的 `execute()` 才向既有 drawable 调用 `setTexture()`;当 endpoint 纹理已在 WeatherColor `update()` 中更换、wrap 范围不变时,drawable 的上传阶段仍持有旧纹理,随后 draw 才首次绑定新纹理,可能触发 `assert(!textureDirty)`。
|
||||
|
||||
本轮修改:
|
||||
|
||||
- 在 `update()` 进入资源更新时保存 drawable 原有 T0/T1 实际纹理指针;资源 endpoint 安装完成后比较新旧指针。
|
||||
- 把 wrap 区间变化或任一纹理 endpoint 指针变化统一作为重建条件;重建在 WeatherColor update 阶段执行,builder 在 drawable 上传前安装正确纹理。
|
||||
- 移除 WeatherColor Tweaker 的三处 `setTexture()`;Tweaker 只写 UBO 中的 mix、opacity、color stops、scale/bounds 等参数。
|
||||
- 新增 `WeatherColorTextureLifecycle` 定向测试,覆盖无变化、单端/双端替换、T0/T1 交叉复用、T0=T1 合并/保持、wrap 改变、隐藏期间 endpoint 替换后恢复、空资源首次创建与释放。
|
||||
|
||||
动态 mix/opacity/stops 不参与 endpoint 比较,因此这些值单独变化不会触发 drawable 重建或纹理上传。Resources 清空后下次更新会重新创建纹理和 drawables;隐藏期间不更新时,恢复后的 endpoint 比较仍在下一次 update、drawable upload 之前发生。
|
||||
|
||||
## 修改文件
|
||||
|
||||
- `include/mbgl/renderer/layers/weather_color_texture_lifecycle.hpp`(新增)
|
||||
- `src/mbgl/renderer/layers/render_weather_color_layer.cpp`
|
||||
- `test/renderer/weather_color_texture_lifecycle.test.cpp`(新增)
|
||||
- `test/CMakeLists.txt`
|
||||
- `docs/50_Step记录/V15_iOS_WeatherColor纹理生命周期修复_v1.md`(新增)
|
||||
- `docs/报告/V15_iOS_WeatherColor纹理生命周期修复_Codex完成报告_v1.md`(新增)
|
||||
- `粒子开发记录.md`(追加)
|
||||
|
||||
未修改任务书、用户其他文件、公共 API/ABI、Style Z-order、shader slot、版本锁、release tag、ZIP/manifest、Android、RN/JS、NavSea、V12/V13 或粒子 advection/State/Trail/Retained 代码。
|
||||
|
||||
## 本阶段检查与状态
|
||||
|
||||
- 已完成只读源码调用链复核和 diff 静态核对准备。
|
||||
- `git diff --check`:由 Codex 执行,结果记录于完成报告。
|
||||
- RDC 首次 OpenGL runner build:**FAIL**,`weather_color_texture_lifecycle.test.cpp:60:17` 因 `nullptr` 参数无法推导模板类型;RDC 反馈 production renderer object 已编译。Codex 仅为该断言显式指定 `<int>`。RDC 随后 OpenGL build retry exit 0、定向 GTest 6/6 PASS;Metal host build exit 0、定向 GTest 6/6 PASS。原始日志位于 `/tmp/navsea_v15_weathercolor_validation/`(`opengl_build.log`、`opengl_build_retry.log`、`opengl_test.log`、`metal_host_build.log`、`metal_host_test.log`)。Codex 未运行构建或测试。
|
||||
- iOS App/Xcode 编译、签名、安装、Metal 真机渲染和 iPad 事故场景:**等待用户手工验收**。
|
||||
- 现有仓库内未找到 `STEP_RECORD.md`;按根 `AGENTS.md` 追加 `粒子开发记录.md`,没有新建或猜造该文件。
|
||||
- RDC host 验证已完成,用户授权的 scoped commit/push 已完成;当前只等待用户手工 iPad 验收。
|
||||
|
||||
## RDC Mac 定向验证命令
|
||||
|
||||
先按 OpenGL,再按 Metal host 顺序执行:
|
||||
|
||||
```bash
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner --parallel 3
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='WeatherColorTextureLifecycle.*'
|
||||
cmake --build build-step097-metal-host --target mbgl-test-runner --parallel 3
|
||||
build-step097-metal-host/mbgl-test-runner --gtest_filter='WeatherColorTextureLifecycle.*'
|
||||
```
|
||||
|
||||
RDC 已按顺序完成 OpenGL 与 Metal host 验证,结果均 PASS(各 6/6)。Metal host 测试仅验证 host 可执行代码,不等于 iOS 设备 Metal PASS。当前等待用户手工 iPad 验收;本阶段不再构建。
|
||||
|
||||
## Git 收尾
|
||||
|
||||
- scoped 实现提交:`5af91fe7a105f0ac047e18db1dc063c9ffd69d44`(`fix: 修复 V15 WeatherColor Metal 纹理生命周期`),仅纳入本任务 7 个文件。
|
||||
- 已推送 `origin/particle/main`;`git ls-remote` 回读的远端 HEAD 为 `5af91fe7a105f0ac047e18db1dc063c9ffd69d44`。
|
||||
- 验证结果补录提交:`4712e1752af2a8238def5839c8754270de4195c9`(`docs: 记录 V15 WeatherColor RDC 验证与推送`),包含 Step、完成报告、开发记录;推送后远端 HEAD 已回读为该提交。
|
||||
- 未跟踪 V15 任务书未提交;V15 release tag 和发行内容未改。当前仍 **WAITING FOR MANUAL IPAD VALIDATION**。
|
||||
|
||||
## 2026-09-27 v16 发行构建兼容补充
|
||||
|
||||
- 统一发行 v16 的 Android 四 ABI 与 Maven Local 构建通过;首次 iOS Bazel 编译在 render_weather_color_layer.cpp 报找不到新增的 weather_color_texture_lifecycle.hpp。
|
||||
- 根因:bazel/core.bzl 的 MLN_CORE_HEADERS 为显式清单,新增头文件未列入;仅追加该头文件路径,不改 WeatherColor 算法或公开 API。
|
||||
- iOS Bazel 构建需由 RDC 在同一 v16 独立 worktree 重新验证;未通过前不得宣称 v16 发布或 iPad 修复通过。
|
||||
130
docs/60_测试/STEP-097_V13修复后集中验证清单_v1.md
Normal file
130
docs/60_测试/STEP-097_V13修复后集中验证清单_v1.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# STEP-097 V13 修复后集中验证清单 v1
|
||||
|
||||
状态:**STEP-097 整体 PARTIAL;A1 与 A2 的 Android/Core 检查已完成,B/C 未开始。** 下方较早段落按当时事实保留;后续 RDC 结果以本文末尾带日期的更新为准。Metal host Core 测试不等于 iOS runtime,iOS runtime 按用户豁免记 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`。
|
||||
|
||||
## 通用 Core 与现有测试入口(RDC)
|
||||
|
||||
在本仓 Mac 当前 checkout,使用已配置的现有 build 目录;若目录不存在,先按当前构建规范配置。此处不自动运行:
|
||||
|
||||
```sh
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner -j3
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='RenderSegmentPlan.*:RenderSegmentDiagnostics.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'
|
||||
```
|
||||
|
||||
新入口 `RenderSegmentDiagnostics.OldCacheReleaseCannotChargeReplacementAtSameIndex` 预期同 index 的旧 revision release 不计入新 topology,当前 revision release 计 1。`RetainedUnderlayCache.UnsupportedAndResourceFailureFallBackSafely` 为旧入口,用于资源失败后的基础状态;尚不能替代真实 layer render 异常注入。失败保留完整日志,回传首个错误和日志路径。
|
||||
|
||||
## Android OpenGL(Particle-Android / RDC,NOT RUN)
|
||||
|
||||
```sh
|
||||
./tools/particle_android_validation/build_validation_apk.sh
|
||||
```
|
||||
|
||||
RDC 应使用同一 commit 生成 APK,再由后续授权的 Win11/模拟器操作按标准流水线安装。现有 Test Host 仅有 C-R 控制,尚缺同一 vector source/same tiles 的 R-R、R-C-R、C-R-R fixture,故该 APK 即使构建成功也不能关闭 01/03。需比较 cache ON/OFF 的首帧、重建、reuse、主目标与离屏目标像素;失败后 diagnostics 不得 Ready,下帧可恢复。记录 Renderer、ABI、SHA-256、截图与日志。不得引用 STEP-094 历史 43/43 作为本轮结果。
|
||||
|
||||
## iOS Metal(Particle-iOS / RDC,NOT RUN)
|
||||
|
||||
```sh
|
||||
cmake --build build-ios --target ios-sdk-static -- -quiet
|
||||
```
|
||||
|
||||
同 commit 的 iOS simulator 与真机需开启 Metal API Validation,捕获 retained R-R/R-C-R 的 color/depth/stencil texture、load/clear/store,特别确认 simulator 的 Depth32Float_Stencil8 同时绑定 depth 和 stencil。故障注入覆盖附件创建失败、encoder 创建失败及 layer render 异常;预期不发布 Ready cache、后续能 fallback/retry。专用自动测试入口尚缺,不能因静态修改或 `ios-sdk-static` 成功就宣称 Metal runtime PASS。
|
||||
|
||||
## 后续 GPU 性能(粒子负责人协调,NOT RUN)
|
||||
|
||||
完成 A1/A2/B/C 代码与平台测试入口后,以相同设备、commit、Style、视口和场数据采样 cache ON/OFF、R×viewport×fieldKey 阶梯,记录 30/60 FPS、p50/p95/p99、GPU/CPU frame time、纹理创建/释放、峰值/长稳内存、方向/缩放/状态恢复。Metal capture 记录 `waitUntilCompleted` 的实际同步点及资源依赖。未经运行不填写数字;F06 multi-C 与 F08 精细失效另行设计。
|
||||
|
||||
## Test Host 依赖(B 阶段后,NOT RUN)
|
||||
|
||||
目前默认 RN `.10` 与 Native `.13` 错配,阶段 B 未开始,不得运行安装并声称配对成功。B 修正 package/lock/SPM 后,RDC 再在 Test Host 目录执行:
|
||||
|
||||
```sh
|
||||
npm ci
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
必须同时检查实际已安装 RN tgz、Android Gradle substitution、iOS SPM exactVersion 与 lockfile;不得以 node_modules 临时软链代替默认安装结果。本清单不含 Jest 命令。
|
||||
|
||||
## 2026-09-25 FZG1 A1 部分执行结果(覆盖上方 Codex 交付时的 NOT RUN 状态)
|
||||
|
||||
- 标准构建脚本已由 Mac RDC 实际执行;HEAD `91c2491b0`,x86_64 OpenGL Debug APK `BUILD SUCCESSFUL`,SHA-256 `8677197c5f83a22747cb51f0c261edffc5db4678fc25b3f366474f6ecb94dc99`。冻结于 `artifacts/maplibre-particle/step097-fzg1/`。
|
||||
- ADB `192.168.200.139:5555` 对 FZG1-2 实际执行覆盖安装、20 组截图/UI XML、既有 STEP-093 topology、CACHE OFF/ON、相机、非法范围恢复与 mutation/fail-closed,日志见 `docs/报告/STEP-097_A1_FZG1测试APK与实机验证报告_v1.md`。
|
||||
- 此处只是设备冒烟;A1 的同 tile stencil fixture、Metal 附件验证、真正 LayerGroup exception 注入与 `OldCacheReleaseCannotChargeReplacementAtSameIndex` GTest **仍 NOT RUN/缺专用入口**;A2/B/C 和软件发布亦未执行。
|
||||
|
||||
## 2026-09-26 第 19 项原生 GTest 已执行
|
||||
|
||||
- RDC 使用当前源码 HEAD `0d13552bed84f427dd43cae9856391bd26622179` 增量重编译 `mbgl-test-runner`:95/95 steps,exit 0;第 19 项 `OldCacheReleaseCannotChargeReplacementAtSameIndex` **1/1 PASS**;`RenderSegmentDiagnostics.*` **5/5 PASS**,两次退出码均为 0。原始日志和分析见 `docs/报告/STEP-097_A1_第19项GTest运行验证报告_v1.md`。
|
||||
- 上方第 19 项“NOT RUN”是 2026-09-25 FZG1 冒烟时点的历史事实,现已由本条更新。01 同 tile、02 Metal、03 render exception 测试仍未闭合;A1 不得整体标 PASS。
|
||||
|
||||
## 2026-09-26 第 19 项 FZG1 设备辅助测试结果
|
||||
|
||||
- 经 RDC 在 FZG1-2 重新覆盖安装与 hash 复核,执行两轮 topology 轮换和资源诊断场景,20 个截图检查点;18 个有效配置均 valid=true/fallback=false,缺失 START fail-closed 后恢复。B/T 的粗粒度 create-release 差额 0/1,实时日志中无应用崩溃记录。详见 `docs/报告/STEP-097_A1_第19项FZG1运行验证报告_v1.md` 与 Mac 忽略目录 `artifacts/maplibre-particle/step097-fzg1-gtest19-device/`。
|
||||
- 这次是 Android Runtime 冒烟,前述第 19 项精确计数归属 GTest 由 Mac 原生测试覆盖;01 同 source/tile stencil、02 Metal、03 绘制异常注入仍缺,A1 整体 PARTIAL,A2/B/C 未实施。
|
||||
|
||||
## 2026-09-26 A1 新入口执行清单(RDC,NOT RUN)
|
||||
|
||||
通用 Core(当前 OpenGL 构建目录):
|
||||
|
||||
```sh
|
||||
cmake --build build-step088-opengl --target mbgl-test-runner -j3
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='RenderOrchestratorError.*:RenderSegmentDiagnostics.OldCacheReleaseCannotChargeReplacementAtSameIndex'
|
||||
```
|
||||
|
||||
预期异常 observer/failed 与 cache 不复用、重试后 Reuse;第 19 项保持 1/1 PASS。Metal GTest `MetalRetainedAttachments.*` 需由 RDC 使用可在 Mac 主机执行且配置 `MLN_WITH_METAL=ON` 的 `mbgl-test-runner` 构建目录执行;先检查所用目录的 CMakeCache、目标和 Metal device,再编译、执行并记录命令与日志。不能用 iOS 静态库构建替代主机 GTest。真机/simulator 的创建失败、encoder 失败与 API Validation 仍单独执行。
|
||||
|
||||
Android 同源 stencil:以本提交标准脚本构建 Validation APK,打开 Particle Core Layer Validation → STEP-093 → STEP-097 SAME SOURCE STENCIL;依次选择 RR、RCR、CRR。每种拓扑在 CACHE ON 首帧、稳定 reuse、REBUILD CURRENT 后,再切 CACHE OFF 与 ON;保存每个检查点截图、`STEP097_STENCIL_PLAN/READY/DIAGNOSTICS` 日志及 `READ SNAPSHOT`。预期 `accepted=true`、`valid=true`、`fallback=false`,多个 retained 段分别 build/reuse,四层同一 source 的轮廓与填充在缓存切换后无残影/漏裁剪。再以相机移动强制重建;记录主目标与离屏结果。此清单是待执行判据,不能据此宣称像素 PASS。真正 GPU 绘制异常及下一帧 full fallback/recovery 需 RDC 专项注入;GTest 状态机不能代替它。
|
||||
|
||||
## 2026-09-26 A1 实测结果(覆盖上方待运行记录)
|
||||
|
||||
- Android/FZG1:新 APK 源码 `8c006ac83`,SHA-256 `48df19cf5a4c4250934efa2596423d3ad9571fe49a65b9b704a81cdb41f58671`;同 source/tile RR/RCR/CRR、重建、缓存 OFF/ON 18/18 状态与像素采样检查通过,无本次捕获的 FATAL。
|
||||
- Core:03 `RenderOrchestratorError.*` 2/2 PASS;19 `OldCacheReleaseCannotChargeReplacementAtSameIndex` 1/1 PASS,诊断组 5/5 PASS。
|
||||
- Metal:编译通过,2/2 SKIP(无 Metal device);用户豁免 iOS runtime,标 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`,不是 iOS 运行测试 PASS。详见 `docs/报告/STEP-097_A1_Android专项验收报告_v1.md`。后续 A2/B/C 未执行。
|
||||
|
||||
## 2026-09-26 A2 中途静态/Core 结果(不是 A2 关闭)
|
||||
|
||||
- OpenGL `mbgl-test-runner` 编译 exit 0;定向 16/16 PASS;两次 Shader generator 均 exit 0 且输出一致。Metal host 可编译并执行同一跨 Core GTest 16/16 PASS,未运行 iOS 设备。
|
||||
- 上述结果仅覆盖现有原生测试入口。Codex A2 代码尚未审查/提交,Android 设备/APK 仍 NOT RUN,不能推进 B/C。证据与完整边界见 `docs/报告/STEP-097_A2_阶段验证记录_v1.md`。
|
||||
|
||||
## 2026-09-26 A2 最终验证结果(RDC 独立执行)
|
||||
|
||||
### Core / Shader
|
||||
|
||||
- 原先因旧测试断言与既有语义不一致而失败的 58 项完整集合,在修复断言后 **58/58 PASS**。`sameFieldGpuContent()` 仍表达忽略 producer generation/dataVersion 的解码 payload 等价;`sameFieldGpuEndpoint()` 单独负责严格 GPU endpoint identity。
|
||||
- 当前 broad filter 在 OpenGL 与 Metal host `mbgl-test-runner` 各 **121/121 PASS**。命令:
|
||||
|
||||
```sh
|
||||
build-step088-opengl/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*:Source.HostField*:Source.ParticleField*:Source.CanonicalField*'
|
||||
build-step097-metal-host/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*:Source.HostField*:Source.ParticleField*:Source.CanonicalField*'
|
||||
```
|
||||
|
||||
- 三项 A2 Source 定向回归在 OpenGL 与 Metal host 各 **3/3 PASS**:mix-only 50 ticks 不重物化、真 endpoint 与 revision 变化触发物化、同步通知重入不双推进、clear fail-closed。
|
||||
- `node shaders/generate_shader_code.mjs` 两次执行成功且输出幂等。Metal host 是 Mac 上 Core 测试,不是 iOS device runtime。
|
||||
|
||||
### Android / FZG1-2
|
||||
|
||||
- RDC 使用 `./tools/particle_android_validation/build_validation_apk.sh` 构建标准 OpenGL Debug x86_64 APK;61,753,803 bytes,SHA-256 `27bf4a6cc191bd86c4d1c10398478d81c2999edd61fe7242e40e5188516b0ca5`。FZG1-2 `192.168.200.139:5555` 安装成功,设备 APK SHA-256 相同。
|
||||
- Test-App-only V4 Golden Wind T0/T1:load、seek 25/75、speed 2x/1x、PLAY 30 秒、PLAY 时 UI/TIME 可响应、PAUSE/stable pause、replay、CLEAR、reload、再次 PLAY/PAUSE;脚本 exit 0、17 PNG、24 steps、ANR=0。`05_play_15s.png` 可见粒子。30 秒场景闭环不是长期稳定性或性能测试。
|
||||
- stable mix-only epoch 中 renderer 日志的 `fieldUploadCount=6/resetCount=2` 保持不变;explicit CLEAR/reload 后 upload 合法增至 10,reset 增至 4;reload 后 playback 稳定在该新计数。不能宣称跨 CLEAR/reload 零上传/零 reset。
|
||||
- APK 工作树源 diff 与 `mix-reuse-build-source.diff` SHA-256 均为 `18927a5f30a88f5c1c3a00e0017473dc33b04151c227e4baf52250dc4ad2e6a2`,源码快照一致。原始 build/device/test 日志、steps 与截图位于 `artifacts/maplibre-particle/step097-a2-final-validation/`。
|
||||
|
||||
### 历史失败与范围
|
||||
|
||||
- 12:43 首次 ANR 为 synchronous Source notification 重入 forecast tick;`forecastTickInProgress` guard 与重入 GTest 已修复并覆盖。
|
||||
- 后续无 ANR 但主线程仍高负载、PLAY/TIME 无响应的试跑由 debuggerd 定位到每 tick 重物化大场和深比较;mix-only immutable endpoint reuse 后通过本次 FZG1 闭环。旧失败日志和 debuggerd 保留,不从报告中删除。
|
||||
- 本次不测 iOS runtime;标 `USER_ACCEPTED_WITHOUT_IOS_RUNTIME_TEST`。没有完成 GPU 性能基准、FPS/pXX 或长期运行测试。STEP-097 整体仍 PARTIAL,B/C 未开始;不包含 Jest、STEP-098、发布 `.13`。
|
||||
|
||||
### 2026-09-26 A2 源码独立 scoped commit 核验
|
||||
|
||||
- A2 的 26 个生产源码、shader、TestApp-only V4 Golden fixture 和定向测试文件已固定为 `f49ffa68a17e0a505199bdbeccf07f8543f3a05f` 并推送,`origin/particle/main` 回读一致;没有 stage 用户未跟踪 STEP-098。完整代码/设备证据仍见 `docs/报告/STEP-097_A2_阶段验证记录_v3.md`,不因 Git 提交改变原 APK 的 `git_dirty=true` 来源事实。STEP-097 整体 PARTIAL,B/C 待用户指令。
|
||||
|
||||
## 2026-09-26 B 阶段 RDC 实测与待闭合
|
||||
|
||||
- Mac Core 增量构建 PASS;B 的 JSON 严格校验、非法配置清除与恢复、数值溢出拒绝和合法 validity=0 四项 GTest:**4/4 PASS**。
|
||||
- 扩大回归初次 132/134,旧 16-bit fixture 误用 4-byte UInt8 storage;修正为合法四样本 8-byte 小端之后重新编译,broad **134/134 PASS**,没有放宽生产校验。
|
||||
- Test Host package.json/package-lock.json 的 RN tarball 均为正式 `13.4.1-particle.13`,实包 SHA-256/SRI 一致。
|
||||
- Android 要分别验证本仓新源码的 MapLibreMap destroy listener JUnit 与 RN module 对正式 `.13` AAR 的 compile;前者不能替代后者。正式 .13 source commit 无 `addOnDestroyListener`,因此当前 bridge 存在 ABI 阻塞,不能标 Android consumer PASS。
|
||||
- C、STEP-098、Jest 与正式发布不执行;完整证据见 `docs/报告/STEP-097_B_独立验收与版本阻塞报告_v1.md`。
|
||||
|
||||
## 2026-09-26 B 阶段 RDC 验证更新
|
||||
- Mac 最新 GTest runner:定向 6/6、扩展 139/139 PASS,旧 broad 2 项失败经纠正测试 fixture 后消除;完整日志 `artifacts/maplibre-particle/step097-b-rdc/validation-*.log`。
|
||||
- Android Native OpenGL Debug:`MapLibreMapDestroyListenerTest` 2/2 PASS;`compileOpenglDebugJavaWithJavac` exit 0;owner Kotlin 独立 JVM JUnit 4/4 PASS(源码 SHA 与当前 B10 一致)。隔离单测不能替代 React Native 模块与发布 AAR 精确配对编译。
|
||||
- B10 当前默认 RN Gradle 对已发布 .13 Native AAR 依赖新缺失符号 `addOnDestroyListener`;RN consumer 校验标 `BLOCKED_NATIVE_AAR_COMPATIBILITY`,禁止记录 PASS 或覆盖 .13。Linux 独立 Gradle 状态另记,C 与 STEP-098 均不得越过此门槛。
|
||||
@@ -4,12 +4,15 @@ The rendering backend is selected at build time through Gradle product flavors.
|
||||
|
||||
## Available backends
|
||||
|
||||
| Flavor | Backend | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| `opengl` | OpenGL ES | Stable | Default, widest device compatibility |
|
||||
| `vulkan` | Vulkan | Stable | Better performance on modern devices |
|
||||
| `webgpuDawn` | WebGPU (Dawn) | Experimental | Uses Vulkan internally, see [WebGPU](./android-webgpu.md) |
|
||||
| `webgpuWgpu` | WebGPU (wgpu-native) | Experimental | Uses Vulkan internally, arm64-v8a only, see [WebGPU](./android-webgpu.md) |
|
||||
| Flavor | Backend | Status | Maven Central artifact | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `opengl` | OpenGL ES | Stable | `org.maplibre.gl:android-sdk-opengl` | Default, widest device compatibility |
|
||||
| `vulkan` | Vulkan | Stable | `org.maplibre.gl:android-sdk-vulkan` | Better performance on modern devices |
|
||||
| `webgpuDawn` | WebGPU (Dawn) | Experimental | not published | Uses Vulkan internally, see [WebGPU](./android-webgpu.md) |
|
||||
| `webgpuWgpu` | WebGPU (wgpu-native) | Experimental | not published | Uses Vulkan internally, arm64-v8a only, see [WebGPU](./android-webgpu.md) |
|
||||
| `multiBackend` | OpenGL ES + Vulkan | Experimental | `org.maplibre.gl:android-sdk-vulkan-opengl` | Both backends in one AAR, chosen at runtime |
|
||||
|
||||
`org.maplibre.gl:android-sdk` is also published and currently maps to the `vulkan` flavor's release build. `-debug` suffixed artifact (e.g. `android-sdk-vulkan-debug`) is published for each flavor as well.
|
||||
|
||||
## Building with a specific backend
|
||||
|
||||
@@ -29,6 +32,9 @@ cd platform/android
|
||||
|
||||
# WebGPU (wgpu-native)
|
||||
./gradlew :MapLibreAndroidTestApp:installWebgpuWgpuDebug
|
||||
|
||||
# Both OpenGL ES and Vulkan, backend chosen at runtime
|
||||
./gradlew :MapLibreAndroidTestApp:installMultiBackendDebug
|
||||
```
|
||||
|
||||
The same pattern applies to the library module (`MapLibreAndroid`):
|
||||
@@ -49,5 +55,8 @@ Each flavor sets different CMake arguments:
|
||||
- `vulkan`: `-DMLN_WITH_VULKAN=ON`
|
||||
- `webgpuDawn`: `-DMLN_WITH_WEBGPU=ON`, `-DMLN_WEBGPU_IMPL_DAWN=ON`
|
||||
- `webgpuWgpu`: `-DMLN_WITH_WEBGPU=ON`, `-DMLN_WEBGPU_IMPL_WGPU=ON`
|
||||
- `multiBackend`: `-DMLN_ANDROID_MULTI_BACKEND=ON`
|
||||
|
||||
Only one backend is active per build. Renderer-specific Java code lives in `src/opengl/`, `src/vulkan/`, or `src/webgpu/` source sets.
|
||||
For `opengl`, `vulkan`, and the WebGPU flavors, only one backend is compiled in and it's fixed for the lifetime of the app. `multiBackend` is the exception - it ships both the OpenGL ES and Vulkan native libraries and picks one at runtime.
|
||||
|
||||
Renderer-specific Java code is split between flavor-specific source sets (`src/opengl/`, `src/vulkan/`, `src/multiBackend/`) and shared per-backend code in `src/sharedRenderer/opengl/` and `src/sharedRenderer/vulkan/`.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user