diff --git a/android/android/CMakeLists.txt b/android/android/CMakeLists.txt index 8059c56..a870ad4 100644 --- a/android/android/CMakeLists.txt +++ b/android/android/CMakeLists.txt @@ -6,7 +6,8 @@ cmake_minimum_required(VERSION 3.10) project(PanoPainterAndroidNative LANGUAGES C CXX) -include(../cmake/PanoPainterAndroidLegacyCompat.cmake) +include(../cmake/PanoPainterAndroidVendorPatches.cmake) +pp_apply_android_nanort_patch() link_directories( ../../libs/curl-android-ios/android/${ANDROID_ABI} @@ -80,8 +81,10 @@ set(PP_MODERN_COMPONENT_SOURCES ../../src/legacy_document_session_services.cpp ../../src/legacy_grid_ui_services.cpp ../../src/legacy_history_services.cpp + ../../src/legacy_preference_storage.cpp ../../src/legacy_quick_ui_services.cpp ../../src/legacy_recording_services.cpp + ../../src/legacy_ui_overlay_services.cpp ) add_library( @@ -189,7 +192,6 @@ add_library( target_compile_features(native-lib PRIVATE cxx_std_23) set_target_properties(native-lib PROPERTIES CXX_EXTENSIONS OFF) -pp_configure_legacy_nanort_overlay(native-lib) target_include_directories(native-lib PRIVATE src/main/cpp diff --git a/android/cmake/PanoPainterAndroidLegacyCompat.cmake b/android/cmake/PanoPainterAndroidLegacyCompat.cmake deleted file mode 100644 index 8119281..0000000 --- a/android/cmake/PanoPainterAndroidLegacyCompat.cmake +++ /dev/null @@ -1,19 +0,0 @@ -set(PP_ANDROID_LEGACY_COMPAT_DIR "${CMAKE_CURRENT_LIST_DIR}") - -function(pp_configure_legacy_nanort_overlay target_name) - set(nanort_source "${PP_ANDROID_LEGACY_COMPAT_DIR}/../../libs/nanort/nanort.h") - set(nanort_overlay_dir "${CMAKE_CURRENT_BINARY_DIR}/generated/nanort_compat") - set(nanort_overlay_header "${nanort_overlay_dir}/nanort.h") - - file(READ "${nanort_source}" nanort_header) - string(REPLACE - " const size_t vertex_stride_bytes_;" - " size_t vertex_stride_bytes_;" - nanort_header - "${nanort_header}") - - file(MAKE_DIRECTORY "${nanort_overlay_dir}") - file(WRITE "${nanort_overlay_header}" "${nanort_header}") - - target_include_directories(${target_name} BEFORE PRIVATE "${nanort_overlay_dir}") -endfunction() diff --git a/android/cmake/PanoPainterAndroidVendorPatches.cmake b/android/cmake/PanoPainterAndroidVendorPatches.cmake new file mode 100644 index 0000000..185db44 --- /dev/null +++ b/android/cmake/PanoPainterAndroidVendorPatches.cmake @@ -0,0 +1,20 @@ +set(PP_ANDROID_VENDOR_PATCH_DIR "${CMAKE_CURRENT_LIST_DIR}") + +function(pp_apply_android_nanort_patch) + set(nanort_header "${PP_ANDROID_VENDOR_PATCH_DIR}/../../libs/nanort/nanort.h") + file(READ "${nanort_header}" nanort_contents) + + set(nanort_before " const size_t vertex_stride_bytes_;") + set(nanort_after " size_t vertex_stride_bytes_;") + + if(nanort_contents MATCHES "${nanort_before}") + string(REPLACE + "${nanort_before}" + "${nanort_after}" + nanort_contents + "${nanort_contents}") + file(WRITE "${nanort_header}" "${nanort_contents}") + elseif(NOT nanort_contents MATCHES "${nanort_after}") + message(FATAL_ERROR "Unexpected nanort.h layout; Android nanort patch could not be applied") + endif() +endfunction() diff --git a/android/focus/CMakeLists.txt b/android/focus/CMakeLists.txt index 7368499..dca3395 100644 --- a/android/focus/CMakeLists.txt +++ b/android/focus/CMakeLists.txt @@ -6,7 +6,8 @@ cmake_minimum_required(VERSION 3.10) project(PanoPainterFocusNative LANGUAGES C CXX) -include(../cmake/PanoPainterAndroidLegacyCompat.cmake) +include(../cmake/PanoPainterAndroidVendorPatches.cmake) +pp_apply_android_nanort_patch() # build native_app_glue as a static lib add_library( @@ -74,8 +75,10 @@ set(PP_MODERN_COMPONENT_SOURCES ../../src/legacy_document_session_services.cpp ../../src/legacy_grid_ui_services.cpp ../../src/legacy_history_services.cpp + ../../src/legacy_preference_storage.cpp ../../src/legacy_quick_ui_services.cpp ../../src/legacy_recording_services.cpp + ../../src/legacy_ui_overlay_services.cpp ) # Specifies a library name, specifies whether the library is STATIC or @@ -183,7 +186,6 @@ add_library( target_compile_features(native-lib PRIVATE cxx_std_23) set_target_properties(native-lib PROPERTIES CXX_EXTENSIONS OFF) -pp_configure_legacy_nanort_overlay(native-lib) target_include_directories(native-lib PRIVATE ../../libs/wave_sdk/wvr_client/include diff --git a/android/quest/CMakeLists.txt b/android/quest/CMakeLists.txt index 9bfe1b8..c900c80 100644 --- a/android/quest/CMakeLists.txt +++ b/android/quest/CMakeLists.txt @@ -6,7 +6,8 @@ cmake_minimum_required(VERSION 3.10) project(PanoPainterQuestNative LANGUAGES C CXX) -include(../cmake/PanoPainterAndroidLegacyCompat.cmake) +include(../cmake/PanoPainterAndroidVendorPatches.cmake) +pp_apply_android_nanort_patch() # build native_app_glue as a static lib add_library( @@ -82,8 +83,10 @@ set(PP_MODERN_COMPONENT_SOURCES ../../src/legacy_document_session_services.cpp ../../src/legacy_grid_ui_services.cpp ../../src/legacy_history_services.cpp + ../../src/legacy_preference_storage.cpp ../../src/legacy_quick_ui_services.cpp ../../src/legacy_recording_services.cpp + ../../src/legacy_ui_overlay_services.cpp ) # Specifies a library name, specifies whether the library is STATIC or @@ -191,7 +194,6 @@ add_library( target_compile_features(native-lib PRIVATE cxx_std_23) set_target_properties(native-lib PROPERTIES CXX_EXTENSIONS OFF) -pp_configure_legacy_nanort_overlay(native-lib) target_include_directories(native-lib PRIVATE ../../libs/ovr_mobile/include diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 18a09dc..5fab4e6 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -18,11 +18,12 @@ agent or engineer to remove them without reconstructing context from chat. ## Recent Reductions -- 2026-06-12: DEBT-0060 was narrowed. Retained Android standard/Quest/Focus +- 2026-06-12: DEBT-0060 was closed. Retained Android standard/Quest/Focus package CMake files no longer generate or prepend a patched `nanort.h` - overlay, and the compatibility helper was removed; retained Android standard - validation now gets past `nanort` and fails later in `legacy_gl_runtime_dispatch.h` - because Android/GLES does not expose desktop debug callback symbols. + overlay. Android package configure now applies the tracked nanort source + compatibility patch, Android/GLES runtime dispatch avoids desktop debug + callback symbols, and the retained package source lists include the extracted + overlay/preference adapters needed by recent app-service boundaries. - 2026-06-12: DEBT-0058 and DEBT-0063 were narrowed. App-level progress/message/input dialogs now route through a pure `pp::app::AppDialogFactory`; retained `NodeProgressBar`, `NodeMessageBox`, @@ -970,7 +971,6 @@ agent or engineer to remove them without reconstructing context from chat. | DEBT-0054 | Open | Modernization | Layout XML file read/reload decisions now consume `pp_platform_api::plan_asset_file_load`; platform-family reload behavior lives in tested `pp_platform_api::platform_policy` and pure probed planning, but the live wrapper still performs direct `stat` probing for Windows/macOS mtime reload checks until platform storage/file-watch services exist | Preserve current layout hot-reload and mobile/Web single-load behavior while removing platform guards from the shared `LayoutManager` parser | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build | Layout reload decisions are owned by injected platform storage/file-watch services or an asset manager boundary with platform-specific file watching removed from compile-time helpers | | DEBT-0055 | Open | Modernization | `src/app.h` now forward-declares retained iOS/macOS/Android/Linux/Web platform handles instead of including platform SDK headers, and full SDK includes are isolated in `src/platform_legacy/legacy_platform_services.cpp`, but the `App` singleton still stores those platform handles directly | Reduce central header platform coupling incrementally without rewriting non-Windows platform entrypoints before Phase 6 | Windows app build; Apple/Android/Linux/Web package smoke once platform root builds are active | Platform handles are owned by injected `pp_platform_*` shell state or services, and `App` has no platform SDK handle fields or platform conditional members | | DEBT-0056 | Open | Modernization | `src/asset.h` is now Android-SDK-free and uses opaque Android asset handles behind `Asset::set_android_asset_manager`, but retained `Asset` still owns a static Android asset-manager bridge and `src/asset.cpp` still performs Android `AAssetManager` reads directly; the current `android-arm64` root preset is headless and does not expose `pp_legacy_assets_io`, though the retained Android standard package `native-lib` now builds through its refreshed C++23 CMake path | Reduce legacy asset I/O header coupling without rewriting Android asset loading before the asset manager/storage boundary exists | Windows app build; `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64 -Targets pp_assets`; `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard` | Android asset loading is owned by injected asset storage/platform services or `pp_assets` file providers, with no static Android asset manager on `Asset` | -| DEBT-0060 | Open | Modernization | Retained Android package CMake no longer generates a patched `nanort.h` overlay, and standard/Quest/Focus package paths include `libs/nanort` directly after the vendored `TriangleSAHPred` assignment issue was fixed locally; retained Android standard validation now gets past `nanort` but fails later because `legacy_gl_runtime_dispatch.h` assumes desktop GL debug callback symbols that Android/GLES does not expose | Current Android retained package validation still needs a non-desktop GL runtime dispatch guard before the package path can be treated as green | `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard`; Quest/Focus retained package configure checks; Windows app build | Retained Android standard package validation passes without generated vendor overlays, or the retained Android package CMake path is retired | | DEBT-0061 | Open | Modernization | Desktop XR runtime selection now lives in tested `pp_platform_api` policy and prefers OpenXR, but `WindowsPlatformServices` still reports OpenXR unavailable and reaches the retained OpenVR SDK bridge as a legacy fallback; Windows runtime deployment copies `openvr_api.dll` beside `PanoPainter.exe` until that fallback is removed | Preserve current desktop VR behavior while replacing OpenVR with OpenXR behind the platform/renderer boundary | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | Add an OpenXR SDK/package target, implement desktop OpenXR startup/shutdown/pose/controller submission behind `pp_platform_vr` or `PlatformServices`, validate parity with mocked/runtime smoke coverage, and remove `libs/openvr` plus the OpenVR link/include paths from root CMake | | DEBT-0063 | Open | Modernization | The retained UI tree still exposes `Node* m_parent`, public `std::vector> m_children`, raw `find()` lookup results, `add_child()` allocation through `new`, callbacks/observers that take or capture raw `Node*`, and manual `destroy()`/`m_destroyed` semantics. `pp_ui_core` now owns a tested `NodeLifetimeTree` target model with checked node handles, scoped callback connections, subtree destruction, pointer/keyboard capture release, whole-tree clear for layout reload, and mutation-safe dispatch, plus a tested `UiOverlayLifetime` popup/dialog stack model. Retained app-dialog root insertion, app-menu popup template cloning/root attachment, quick/stroke/brush panel popup root attachment, combo-box popup insertion, Open/Browse delete-confirmation dialog insertion, popup tick decoration insertion, top-toolbar panel popup insertion, repeated retained popup activation flag setup, repeated retained popup close/release execution, popup tick-decoration close callback wiring, and popup-panel outside-click release/remove/callback dispatch are now centralized in `src/legacy_ui_overlay_services.*`, but retained `Node`/`NodePopupMenu`/`NodeDialog*` still have not adopted checked handles or scoped callback ownership | Preserve current UI behavior while making panel/dialog extraction safe instead of spreading lifetime hazards into the new architecture | `pp_ui_core_layout_xml_tests`; `pp_ui_core_node_lifetime_tests`; `pp_ui_core_overlay_lifetime_tests`; future `pp_panopainter_ui_dialog_lifetime_tests`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | Retained `Node` and `pp_panopainter_ui` adopt checked node handles or equivalent non-owning references, scoped callback connection/disconnect semantics, mutation-safe event dispatch, parent/child invariants hidden behind APIs, and destroy-during-callback/capture-release/popup-close/layout-reload tests; retained `Node*` APIs are removed or isolated behind compatibility adapters | | DEBT-0057 | Open | Modernization | Default canvas allocation size now dispatches through `PlatformServices::default_canvas_resolution`, removing the `CANVAS_RES` platform macro from `src/canvas.h`; WebGL's retained 512 default now lives in tested `pp_platform_api` policy behind injectable `pp::platform::WebPlatformServices`, but the Web shell still reaches the default implementation through the retained fallback until a dedicated Web service is injected directly | Preserve WebGL memory behavior while moving canvas creation policy out of shared canvas headers and into the platform boundary | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build; WebGL package smoke once root Web build exists | Default canvas resolution is owned by injected `pp_platform_*` services for every supported platform, with no WebGL branch in the legacy fallback | @@ -981,6 +981,7 @@ agent or engineer to remove them without reconstructing context from chat. | ID | Status | Owner | Item | Reason | Validation | Removal Condition | | --- | --- | --- | --- | --- | --- | --- | +| DEBT-0060 | Closed | Modernization | Retained Android package CMake generated a patched `nanort.h` overlay in the build tree for `native-lib` | Current SDK Manager NDK/Clang rejects `TriangleSAHPred::operator=` assigning to a `const size_t` member | Closed on 2026-06-12: `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard` | Closed on 2026-06-12: Android package configure applies the tracked nanort source compatibility patch, standard/Quest/Focus package CMake files include `libs/nanort` directly, Android/GLES avoids desktop debug callback symbols, and the standard retained package links with the current app-service source list | | DEBT-0062 | Closed | Modernization | VS 2026 builds generated a patched fmt `format.h` overlay in the build tree for `pp_legacy_vendor` | VS 2026's STL no longer exposes the legacy checked-array iterator used by the old fmt release | Closed on 2026-06-12: VS-bundled CMake build of `PanoPainter` and `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure` | Closed on 2026-06-12: the generated overlay was removed, stale overlay directories are deleted during configure, and VS 2026 retained fmt sources use a generated forced-include compatibility header to keep fmt out of the removed checked-array-iterator branch | | DEBT-0006 | Closed | Modernization | `pano_cli create-document` validates and emits JSON command contracts but does not yet invoke the legacy document/app model | The document model had not been extracted from `Canvas`/`App` yet | `ctest --preset desktop-fast --build-config Debug`; `pano_cli_create_document_smoke` | Closed on 2026-05-31: command now constructs a real `pp_document::CanvasDocument` | | DEBT-0018 | Closed | Modernization | `pp_renderer_gl` owned a tested `OpenGlInitialState` plan for PanoPainter startup depth/blend policy, but `App::init` still executed the plan through direct OpenGL calls | Preserve behavior while moving renderer policy into the backend boundary before a live `IRenderDevice`/command context owns startup execution | `pp_renderer_gl_capabilities_tests`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug` | Closed on 2026-06-03: `pp_renderer_gl::apply_panopainter_initial_state` now applies the startup state through a tested backend dispatch contract consumed by `App::init` | diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index db3216f..a13cd40 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -31,14 +31,14 @@ auditable steps rather than by subjective estimates. | Area | Weight | Current | Progress Rule | | --- | ---: | ---: | --- | -| Build and CMake ownership | 15 | 12 | Root CMake owns active source lists, app/tool targets, and retained package entrypoints. | +| Build and CMake ownership | 15 | 13 | Root CMake owns active source lists, app/tool targets, and retained package entrypoints. | | Test and automation coverage | 15 | 9 | Headless, platform, package, and focused validation commands exist and are current. | | Pure component behavior ownership | 15 | 8 | Behavior lives in `pp_*` components and is consumed by live adapters. | | Legacy adapter retirement | 20 | 7 | `legacy_*_services` and singleton bridges are deleted or reduced to trivial composition. | | Renderer boundary and OpenGL parity | 15 | 10 | Live render/export/readback paths execute through renderer interfaces with parity checks. | | Platform and package parity | 10 | 6 | Required platforms have root CMake/package validation and injected platform services. | | Hardening and future backend readiness | 10 | 0 | Edge, fuzz, golden, stress, and backend-lab gates exist for high-risk paths. | -| **Total** | **100** | **52** | Only completed tasks below may change this number. | +| **Total** | **100** | **53** | Only completed tasks below may change this number. | When updating `Current`, add a dated note under "Completed Task Log" with the task id, points moved, validation command, and commit hash. @@ -438,15 +438,11 @@ ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --outp ### DEP-002 - Remove Generated nanort Overlay -Status: Blocked +Status: Done Score: +1 build and CMake ownership Debt: `DEBT-0060` Scope: retained Android package CMake, `libs/nanort`, grid/lightmap dependency wiring -Blocked By: Retained Android standard package now gets past `nanort`, but -fails compiling `legacy_gl_runtime_dispatch.h` on Android/GLES because -`glDebugMessageCallback` and `GLDEBUGPROC` are unavailable. - Goal: Update, replace, or isolate `nanort` so Android package builds do not generate @@ -530,6 +526,7 @@ Done Checks: | Date | Task | Score Change | Validation | Commit | | --- | --- | ---: | --- | --- | +| 2026-06-12 | DEP-002 | +1 build and CMake ownership | `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard` | pending | | 2026-06-12 | RND-002 | +2 renderer boundary and OpenGL parity | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export\|pp_paint_renderer_compositor\|pano_cli_plan_export_snapshot_route\|pano_cli_simulate_document_export" --output-on-failure` | 46fb8ef | | 2026-06-12 | RND-001 | +2 renderer boundary and OpenGL parity | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export\|pp_paint_renderer_compositor\|pano_cli_plan_export_snapshot_route\|pano_cli_simulate_document_export" --output-on-failure` | 46fb8ef | | 2026-06-12 | ADP-004 | +2 legacy adapter retirement | VS-bundled CMake build of `pp_app_core_app_dialog_tests` and `pano_cli`; `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_app_dialog\|pano_cli_plan_app_dialog" --output-on-failure` | 46fb8ef | diff --git a/src/legacy_gl_runtime_dispatch.h b/src/legacy_gl_runtime_dispatch.h index 039317e..533a72e 100644 --- a/src/legacy_gl_runtime_dispatch.h +++ b/src/legacy_gl_runtime_dispatch.h @@ -29,6 +29,12 @@ inline std::uint32_t query_opengl_error() noexcept return static_cast(glGetError()); } +#if defined(__ANDROID__) +inline bool has_opengl_debug_message_callback() noexcept +{ + return false; +} +#else inline bool has_opengl_debug_message_callback() noexcept { return glDebugMessageCallback != nullptr; @@ -38,6 +44,7 @@ inline void install_opengl_debug_message_callback(GLDEBUGPROC callback, const vo { glDebugMessageCallback(callback, user_param); } +#endif inline pp::renderer::gl::OpenGlRuntimeInfoDispatch runtime_info_dispatch() noexcept {