From 61f86f5aaeaccf5778814787dfa9889aa1eef1b2 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 2 Jun 2026 09:37:57 +0200 Subject: [PATCH] Add renderer boundary automation guard --- docs/modernization/build-inventory.md | 10 ++- docs/modernization/roadmap.md | 10 +-- scripts/automation/analyze.ps1 | 13 ++++ scripts/automation/analyze.sh | 11 +++- .../automation/check-renderer-boundary.ps1 | 62 +++++++++++++++++++ scripts/automation/check-renderer-boundary.sh | 34 ++++++++++ 6 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 scripts/automation/check-renderer-boundary.ps1 create mode 100644 scripts/automation/check-renderer-boundary.sh diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index b80be28..e71cca0 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -196,9 +196,9 @@ Known local toolchain state: longer expose raw OpenGL enum defaults; default texture formats, sampler filters/wraps, and render-target formats resolve through backend-owned overloads. - The Windows entrypoint also consumes backend-owned generic OpenGL error-code - and info-string tokens; WGL context/pixel-format constants remain in the - platform shell for a later platform-boundary slice. + The Windows entrypoint also consumes backend-owned generic OpenGL + error-code/info-string tokens and WGL core-context/pixel-format attribute + catalogs. Desktop VR drawing also consumes backend-owned scissor/depth/blend state, depth clear masks, active texture units, and fallback 2D texture unbind targets while retaining the existing VR SDK/platform bridge shape. @@ -237,6 +237,10 @@ Known local toolchain state: - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test for the current headless component matrix; see DEBT-0007 for remaining app and platform triplet migration. +- `scripts/automation/analyze.*` runs shader validation plus a + renderer-boundary guard that reports JSON and fails if active non-backend + source code reintroduces raw `GL_*`/`WGL_*` constants outside the allowed + legacy OpenGL implementation files. - `pp_ui_core` consumes vcpkg tinyxml2 only when `PP_USE_VCPKG_TINYXML2=ON` through the vcpkg preset; default and Android validation still use the retained vendored fallback tracked by DEBT-0012. diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index decb66a..6c79a71 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -463,9 +463,8 @@ Legacy `Texture2D`, `TextureManager`, `Sampler`, and `RTT` public headers no longer expose raw OpenGL enum defaults; default texture formats, sampler filters/wraps, and render-target formats are resolved through backend-owned overloads. -The Windows entrypoint now delegates generic OpenGL error-code and info-string -tokens to `pp_renderer_gl`; WGL context/pixel-format constants remain in the -platform shell for a later platform-boundary slice. +The Windows entrypoint now delegates generic OpenGL error-code/info-string +tokens and WGL core-context/pixel-format attribute catalogs to `pp_renderer_gl`. The existing renderer classes are not yet fully behind the renderer interfaces. @@ -723,7 +722,7 @@ Results: names used by `Shader`, preserves the legacy hash ids, and rejects empty, unnamed, null-name, mismatched-hash, and duplicate-name catalogs. - PowerShell analyze automation returns JSON summaries and includes the shader - validation target. + validation target and renderer-boundary guard. - `windows-msvc-vcpkg-headless` configured through the Visual Studio bundled vcpkg root, installed the manifest dependencies, built the headless component matrix, and passed `desktop-fast-vcpkg`. @@ -738,6 +737,9 @@ Results: `out/build/windows-msvc-default/Debug/PanoPainter.exe`. - PowerShell build/test automation wrappers return JSON summaries and passed local smoke checks. +- Renderer-boundary automation fails if active non-backend source code + reintroduces raw `GL_*`/`WGL_*` constants outside the allowed legacy OpenGL + implementation files. - PowerShell package-smoke wrapper validates the Windows CMake app executable and runtime `data/` copy. - Android arm64 configured with NDK 29.0.14206865 through the platform-build diff --git a/scripts/automation/analyze.ps1 b/scripts/automation/analyze.ps1 index 01551fb..e0e6242 100644 --- a/scripts/automation/analyze.ps1 +++ b/scripts/automation/analyze.ps1 @@ -19,16 +19,25 @@ if ($NoApp) { & cmake @argsList $configureExitCode = $LASTEXITCODE $shaderExitCode = 0 +$rendererBoundaryExitCode = 0 if ($configureExitCode -eq 0) { & cmake --build --preset $Preset --target panopainter_validate_shaders $shaderExitCode = $LASTEXITCODE } +if ($configureExitCode -eq 0) { + & powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "check-renderer-boundary.ps1") + $rendererBoundaryExitCode = $LASTEXITCODE +} + $exitCode = $configureExitCode if ($exitCode -eq 0 -and $shaderExitCode -ne 0) { $exitCode = $shaderExitCode } +if ($exitCode -eq 0 -and $rendererBoundaryExitCode -ne 0) { + $exitCode = $rendererBoundaryExitCode +} $elapsed = [int]((Get-Date) - $started).TotalMilliseconds @@ -44,6 +53,10 @@ $elapsed = [int]((Get-Date) - $started).TotalMilliseconds [ordered]@{ name = "shader-validation" exitCode = $shaderExitCode + }, + [ordered]@{ + name = "renderer-boundary" + exitCode = $rendererBoundaryExitCode } ) elapsedMs = $elapsed diff --git a/scripts/automation/analyze.sh b/scripts/automation/analyze.sh index d81b811..ab7f58b 100644 --- a/scripts/automation/analyze.sh +++ b/scripts/automation/analyze.sh @@ -1,20 +1,29 @@ #!/usr/bin/env sh set -u +script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" preset="${1:-linux-clang}" start="$(date +%s)" cmake --preset "$preset" -DPP_ENABLE_CLANG_TIDY=ON -DPP_ENABLE_CPPCHECK=ON configure_exit_code="$?" shader_exit_code="0" +renderer_boundary_exit_code="0" if [ "$configure_exit_code" -eq 0 ]; then cmake --build --preset "$preset" --target panopainter_validate_shaders shader_exit_code="$?" fi +if [ "$configure_exit_code" -eq 0 ]; then + "$script_dir/check-renderer-boundary.sh" + renderer_boundary_exit_code="$?" +fi exit_code="$configure_exit_code" if [ "$exit_code" -eq 0 ] && [ "$shader_exit_code" -ne 0 ]; then exit_code="$shader_exit_code" fi +if [ "$exit_code" -eq 0 ] && [ "$renderer_boundary_exit_code" -ne 0 ]; then + exit_code="$renderer_boundary_exit_code" +fi end="$(date +%s)" elapsed_ms="$(( (end - start) * 1000 ))" -printf '{"command":"analyze","preset":"%s","exitCode":%s,"checks":[{"name":"configure","exitCode":%s},{"name":"shader-validation","exitCode":%s}],"elapsedMs":%s}\n' "$preset" "$exit_code" "$configure_exit_code" "$shader_exit_code" "$elapsed_ms" +printf '{"command":"analyze","preset":"%s","exitCode":%s,"checks":[{"name":"configure","exitCode":%s},{"name":"shader-validation","exitCode":%s},{"name":"renderer-boundary","exitCode":%s}],"elapsedMs":%s}\n' "$preset" "$exit_code" "$configure_exit_code" "$shader_exit_code" "$renderer_boundary_exit_code" "$elapsed_ms" exit "$exit_code" diff --git a/scripts/automation/check-renderer-boundary.ps1 b/scripts/automation/check-renderer-boundary.ps1 new file mode 100644 index 0000000..b0ff110 --- /dev/null +++ b/scripts/automation/check-renderer-boundary.ps1 @@ -0,0 +1,62 @@ +[CmdletBinding()] +param( + [string]$Root = "" +) + +$ErrorActionPreference = "Stop" +if ([string]::IsNullOrWhiteSpace($Root)) { + $Root = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path +} +$started = Get-Date +$pattern = '\b(?:GL|WGL)_[A-Z0-9_]+\b' +$allowed = @( + "src/renderer_gl/", + "src/rtt.cpp", + "src/texture.cpp" +) +$violations = @() +$files = Get-ChildItem -Path (Join-Path $Root "src") -Recurse -File -Include *.c,*.cc,*.cpp,*.h,*.hpp + +foreach ($file in $files) { + $relative = $file.FullName.Substring($Root.Length).TrimStart('\', '/').Replace('\', '/') + $isAllowed = $false + foreach ($prefix in $allowed) { + if ($relative.StartsWith($prefix)) { + $isAllowed = $true + break + } + } + if ($isAllowed) { + continue + } + + $lineNumber = 0 + foreach ($line in Get-Content -LiteralPath $file.FullName) { + $lineNumber += 1 + $trimmed = $line.TrimStart() + if ($trimmed.StartsWith("//")) { + continue + } + $matches = [regex]::Matches($line, $pattern) + foreach ($match in $matches) { + $violations += [ordered]@{ + file = $relative + line = $lineNumber + token = $match.Value + } + } + } +} + +$exitCode = if ($violations.Count -eq 0) { 0 } else { 1 } +$elapsed = [int]((Get-Date) - $started).TotalMilliseconds + +[ordered]@{ + command = "check-renderer-boundary" + exitCode = $exitCode + violationCount = $violations.Count + violations = @($violations | Select-Object -First 50) + elapsedMs = $elapsed +} | ConvertTo-Json -Compress -Depth 4 + +exit $exitCode diff --git a/scripts/automation/check-renderer-boundary.sh b/scripts/automation/check-renderer-boundary.sh new file mode 100644 index 0000000..7767a14 --- /dev/null +++ b/scripts/automation/check-renderer-boundary.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env sh +set -u + +script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" +root="${1:-$(CDPATH= cd -- "$script_dir/../.." && pwd)}" +start="$(date +%s)" +tmp="${TMPDIR:-/tmp}/panopainter-renderer-boundary-$$.txt" + +find "$root/src" -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | while IFS= read -r file; do + rel="${file#"$root"/}" + case "$rel" in + src/renderer_gl/*|src/rtt.cpp|src/texture.cpp) + continue + ;; + esac + awk -v rel="$rel" ' + /^[[:space:]]*\/\// { next } + match($0, /\<(GL|WGL)_[A-Z0-9_]+\>/) { + print rel ":" FNR ":" substr($0, RSTART, RLENGTH) + } + ' "$file" +done > "$tmp" + +count="$(wc -l < "$tmp" | tr -d '[:space:]')" +end="$(date +%s)" +elapsed_ms="$(( (end - start) * 1000 ))" +exit_code="0" +if [ "$count" -ne 0 ]; then + exit_code="1" +fi + +printf '{"command":"check-renderer-boundary","exitCode":%s,"violationCount":%s,"elapsedMs":%s}\n' "$exit_code" "$count" "$elapsed_ms" +rm -f "$tmp" +exit "$exit_code"