From ac4fef8346e0144a36533e2e31a8bcfb0b436621 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Fri, 5 Jun 2026 12:17:04 +0200 Subject: [PATCH] Refresh retained Android package CMake --- android/android/CMakeLists.txt | 67 ++++++++++++++++- .../PanoPainterAndroidLegacyCompat.cmake | 19 +++++ android/focus/CMakeLists.txt | 72 +++++++++++++++++-- android/quest/CMakeLists.txt | 72 +++++++++++++++++-- android/src/cpp/main.cpp | 2 + docs/modernization/build-inventory.md | 18 +++-- docs/modernization/debt.md | 16 +++-- docs/modernization/roadmap.md | 13 +++- src/app.h | 3 +- src/app_layout.cpp | 1 + src/app_vr.cpp | 1 + src/node_canvas.cpp | 1 + src/pch.cpp | 11 ++- 13 files changed, 264 insertions(+), 32 deletions(-) create mode 100644 android/cmake/PanoPainterAndroidLegacyCompat.cmake diff --git a/android/android/CMakeLists.txt b/android/android/CMakeLists.txt index c8a0d24..33e60e4 100644 --- a/android/android/CMakeLists.txt +++ b/android/android/CMakeLists.txt @@ -2,7 +2,9 @@ # This ensures that a certain set of CMake features is available to # your build. -cmake_minimum_required(VERSION 3.4.1) +cmake_minimum_required(VERSION 3.10) + +include(../cmake/PanoPainterAndroidLegacyCompat.cmake) link_directories( ../../libs/curl-android-ios/android/${ANDROID_ABI} @@ -23,11 +25,66 @@ add_library(yuv SHARED IMPORTED) set_target_properties(yuv PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../../libs/libyuv/lib/android/${ANDROID_ABI}/libyuv.so) -# now build app's shared lib -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +set(PP_MODERN_COMPONENT_SOURCES + ../../src/app_core/document_export.cpp + ../../src/app_core/document_route.cpp + ../../src/app_core/document_session.cpp + ../../src/assets/brush_package.cpp + ../../src/assets/image_format.cpp + ../../src/assets/image_metadata.cpp + ../../src/assets/image_pixels.cpp + ../../src/assets/ppi_header.cpp + ../../src/assets/settings_document.cpp + ../../src/document/document.cpp + ../../src/document/ppi_export.cpp + ../../src/document/ppi_import.cpp + ../../src/foundation/binary_stream.cpp + ../../src/foundation/event.cpp + ../../src/foundation/log.cpp + ../../src/foundation/parse.cpp + ../../src/foundation/task_queue.cpp + ../../src/foundation/trace.cpp + ../../src/paint/blend.cpp + ../../src/paint/brush.cpp + ../../src/paint/stroke.cpp + ../../src/paint/stroke_script.cpp + ../../src/paint_renderer/compositor.cpp + ../../src/platform_api/asset_file_load_policy.cpp + ../../src/platform_api/network_tls_policy.cpp + ../../src/platform_api/platform_policy.cpp + ../../src/platform_api/platform_services.cpp + ../../src/platform_legacy/legacy_platform_services.cpp + ../../src/renderer_api/recording_renderer.cpp + ../../src/renderer_api/renderer_api.cpp + ../../src/renderer_api/shader_catalog.cpp + ../../src/renderer_gl/command_plan.cpp + ../../src/renderer_gl/opengl_capabilities.cpp + ../../src/renderer_gl/shader_bindings.cpp + ../../src/legacy_app_dialog_services.cpp + ../../src/legacy_app_preference_services.cpp + ../../src/legacy_app_shell_services.cpp + ../../src/legacy_app_startup_services.cpp + ../../src/legacy_brush_package_export_services.cpp + ../../src/legacy_brush_package_import_services.cpp + ../../src/legacy_brush_ui_services.cpp + ../../src/legacy_canvas_tool_services.cpp + ../../src/legacy_canvas_view_services.cpp + ../../src/legacy_cloud_services.cpp + ../../src/legacy_document_animation_services.cpp + ../../src/legacy_document_canvas_services.cpp + ../../src/legacy_document_export_services.cpp + ../../src/legacy_document_layer_services.cpp + ../../src/legacy_document_open_services.cpp + ../../src/legacy_document_session_services.cpp + ../../src/legacy_grid_ui_services.cpp + ../../src/legacy_history_services.cpp + ../../src/legacy_quick_ui_services.cpp + ../../src/legacy_recording_services.cpp +) add_library( native-lib SHARED + ${PP_MODERN_COMPONENT_SOURCES} ../../libs/yoga/yoga/event/event.cpp ../../libs/yoga/yoga/internal/experiments.cpp ../../libs/yoga/yoga/log.cpp @@ -128,6 +185,10 @@ add_library( ../../src/node_metadata.cpp ) +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 ../src/cpp diff --git a/android/cmake/PanoPainterAndroidLegacyCompat.cmake b/android/cmake/PanoPainterAndroidLegacyCompat.cmake new file mode 100644 index 0000000..8119281 --- /dev/null +++ b/android/cmake/PanoPainterAndroidLegacyCompat.cmake @@ -0,0 +1,19 @@ +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/focus/CMakeLists.txt b/android/focus/CMakeLists.txt index 9bbebf3..c178c09 100644 --- a/android/focus/CMakeLists.txt +++ b/android/focus/CMakeLists.txt @@ -2,7 +2,9 @@ # This ensures that a certain set of CMake features is available to # your build. -cmake_minimum_required(VERSION 3.4.1) +cmake_minimum_required(VERSION 3.10) + +include(../cmake/PanoPainterAndroidLegacyCompat.cmake) # build native_app_glue as a static lib add_library( @@ -17,23 +19,79 @@ set_target_properties( ${CMAKE_SOURCE_DIR}/../../libs/wave_sdk/wvr_client/lib/${ANDROID_ABI}/libwvr_api.so ) +set(PP_MODERN_COMPONENT_SOURCES + ../../src/app_core/document_export.cpp + ../../src/app_core/document_route.cpp + ../../src/app_core/document_session.cpp + ../../src/assets/brush_package.cpp + ../../src/assets/image_format.cpp + ../../src/assets/image_metadata.cpp + ../../src/assets/image_pixels.cpp + ../../src/assets/ppi_header.cpp + ../../src/assets/settings_document.cpp + ../../src/document/document.cpp + ../../src/document/ppi_export.cpp + ../../src/document/ppi_import.cpp + ../../src/foundation/binary_stream.cpp + ../../src/foundation/event.cpp + ../../src/foundation/log.cpp + ../../src/foundation/parse.cpp + ../../src/foundation/task_queue.cpp + ../../src/foundation/trace.cpp + ../../src/paint/blend.cpp + ../../src/paint/brush.cpp + ../../src/paint/stroke.cpp + ../../src/paint/stroke_script.cpp + ../../src/paint_renderer/compositor.cpp + ../../src/platform_api/asset_file_load_policy.cpp + ../../src/platform_api/network_tls_policy.cpp + ../../src/platform_api/platform_policy.cpp + ../../src/platform_api/platform_services.cpp + ../../src/platform_legacy/legacy_platform_services.cpp + ../../src/renderer_api/recording_renderer.cpp + ../../src/renderer_api/renderer_api.cpp + ../../src/renderer_api/shader_catalog.cpp + ../../src/renderer_gl/command_plan.cpp + ../../src/renderer_gl/opengl_capabilities.cpp + ../../src/renderer_gl/shader_bindings.cpp + ../../src/legacy_app_dialog_services.cpp + ../../src/legacy_app_preference_services.cpp + ../../src/legacy_app_shell_services.cpp + ../../src/legacy_app_startup_services.cpp + ../../src/legacy_brush_package_export_services.cpp + ../../src/legacy_brush_package_import_services.cpp + ../../src/legacy_brush_ui_services.cpp + ../../src/legacy_canvas_tool_services.cpp + ../../src/legacy_canvas_view_services.cpp + ../../src/legacy_cloud_services.cpp + ../../src/legacy_document_animation_services.cpp + ../../src/legacy_document_canvas_services.cpp + ../../src/legacy_document_export_services.cpp + ../../src/legacy_document_layer_services.cpp + ../../src/legacy_document_open_services.cpp + ../../src/legacy_document_session_services.cpp + ../../src/legacy_grid_ui_services.cpp + ../../src/legacy_history_services.cpp + ../../src/legacy_quick_ui_services.cpp + ../../src/legacy_recording_services.cpp +) + # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add.library() commands, # and CMake builds them for you. When you build your app, Gradle # automatically packages shared libraries with your APK. -# now build app's shared lib -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - add_library( native-lib SHARED + ${PP_MODERN_COMPONENT_SOURCES} + ../../libs/yoga/yoga/event/event.cpp + ../../libs/yoga/yoga/internal/experiments.cpp ../../libs/yoga/yoga/log.cpp ../../libs/yoga/yoga/Utils.cpp ../../libs/yoga/yoga/YGConfig.cpp ../../libs/yoga/yoga/YGEnums.cpp ../../libs/yoga/yoga/YGLayout.cpp - ../../libs/yoga/yoga/YGMarker.cpp ../../libs/yoga/yoga/YGNode.cpp ../../libs/yoga/yoga/YGNodePrint.cpp ../../libs/yoga/yoga/YGStyle.cpp @@ -121,6 +179,10 @@ add_library( ../../src/settings.cpp ) +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 src/main/cpp diff --git a/android/quest/CMakeLists.txt b/android/quest/CMakeLists.txt index c31ad1c..f1aad51 100644 --- a/android/quest/CMakeLists.txt +++ b/android/quest/CMakeLists.txt @@ -2,7 +2,9 @@ # This ensures that a certain set of CMake features is available to # your build. -cmake_minimum_required(VERSION 3.4.1) +cmake_minimum_required(VERSION 3.10) + +include(../cmake/PanoPainterAndroidLegacyCompat.cmake) # build native_app_glue as a static lib add_library( @@ -25,23 +27,79 @@ set_target_properties( ) +set(PP_MODERN_COMPONENT_SOURCES + ../../src/app_core/document_export.cpp + ../../src/app_core/document_route.cpp + ../../src/app_core/document_session.cpp + ../../src/assets/brush_package.cpp + ../../src/assets/image_format.cpp + ../../src/assets/image_metadata.cpp + ../../src/assets/image_pixels.cpp + ../../src/assets/ppi_header.cpp + ../../src/assets/settings_document.cpp + ../../src/document/document.cpp + ../../src/document/ppi_export.cpp + ../../src/document/ppi_import.cpp + ../../src/foundation/binary_stream.cpp + ../../src/foundation/event.cpp + ../../src/foundation/log.cpp + ../../src/foundation/parse.cpp + ../../src/foundation/task_queue.cpp + ../../src/foundation/trace.cpp + ../../src/paint/blend.cpp + ../../src/paint/brush.cpp + ../../src/paint/stroke.cpp + ../../src/paint/stroke_script.cpp + ../../src/paint_renderer/compositor.cpp + ../../src/platform_api/asset_file_load_policy.cpp + ../../src/platform_api/network_tls_policy.cpp + ../../src/platform_api/platform_policy.cpp + ../../src/platform_api/platform_services.cpp + ../../src/platform_legacy/legacy_platform_services.cpp + ../../src/renderer_api/recording_renderer.cpp + ../../src/renderer_api/renderer_api.cpp + ../../src/renderer_api/shader_catalog.cpp + ../../src/renderer_gl/command_plan.cpp + ../../src/renderer_gl/opengl_capabilities.cpp + ../../src/renderer_gl/shader_bindings.cpp + ../../src/legacy_app_dialog_services.cpp + ../../src/legacy_app_preference_services.cpp + ../../src/legacy_app_shell_services.cpp + ../../src/legacy_app_startup_services.cpp + ../../src/legacy_brush_package_export_services.cpp + ../../src/legacy_brush_package_import_services.cpp + ../../src/legacy_brush_ui_services.cpp + ../../src/legacy_canvas_tool_services.cpp + ../../src/legacy_canvas_view_services.cpp + ../../src/legacy_cloud_services.cpp + ../../src/legacy_document_animation_services.cpp + ../../src/legacy_document_canvas_services.cpp + ../../src/legacy_document_export_services.cpp + ../../src/legacy_document_layer_services.cpp + ../../src/legacy_document_open_services.cpp + ../../src/legacy_document_session_services.cpp + ../../src/legacy_grid_ui_services.cpp + ../../src/legacy_history_services.cpp + ../../src/legacy_quick_ui_services.cpp + ../../src/legacy_recording_services.cpp +) + # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add.library() commands, # and CMake builds them for you. When you build your app, Gradle # automatically packages shared libraries with your APK. -# now build app's shared lib -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - add_library( native-lib SHARED + ${PP_MODERN_COMPONENT_SOURCES} + ../../libs/yoga/yoga/event/event.cpp + ../../libs/yoga/yoga/internal/experiments.cpp ../../libs/yoga/yoga/log.cpp ../../libs/yoga/yoga/Utils.cpp ../../libs/yoga/yoga/YGConfig.cpp ../../libs/yoga/yoga/YGEnums.cpp ../../libs/yoga/yoga/YGLayout.cpp - ../../libs/yoga/yoga/YGMarker.cpp ../../libs/yoga/yoga/YGNode.cpp ../../libs/yoga/yoga/YGNodePrint.cpp ../../libs/yoga/yoga/YGStyle.cpp @@ -129,6 +187,10 @@ add_library( ../../src/settings.cpp ) +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 ../../libs/ovr_platform/Include diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index ec29989..de6c35f 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -35,7 +35,9 @@ #include "keymap.h" #include "main.h" #include "settings.h" +#if __has_include("com_omixlab_panopainter_MainActivity.h") #include "com_omixlab_panopainter_MainActivity.h" +#endif #ifdef __QUEST__ #include "oculus_vr.h" diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index fb6e5bc..19845e4 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -14,9 +14,9 @@ Keep it updated as platform paths move to shared CMake targets. | Windows AppX | `PanoPainterPackage/Package.appxmanifest`, `.wapproj` referenced by solution | Distribution packaging | | macOS | `PanoPainter-OSX/` project files and `Info.plist` | Uses `NSOpenGLView` today | | iOS | `PanoPainter/Info.plist`, related Apple sources | Uses OpenGL ES today | -| Android standard | `android/android/build.gradle`, `android/android/CMakeLists.txt` | Native library target `native-lib` | -| Android Quest | `android/quest/build.gradle`, `android/quest/CMakeLists.txt` | OVR SDK imported libraries | -| Android Focus/Wave | `android/focus/build.gradle`, `android/focus/CMakeLists.txt` | Wave SDK imported libraries | +| Android standard | `android/android/build.gradle`, `android/android/CMakeLists.txt` | Retained native library target `native-lib`; CMake 3.10/C++23 baseline now links the standard arm64 package path with modern component/service sources and the generated `nanort` overlay helper | +| Android Quest | `android/quest/build.gradle`, `android/quest/CMakeLists.txt` | OVR SDK imported libraries; CMake 3.10/C++23 baseline and current Yoga source list configure with the shared Android package compatibility helper | +| Android Focus/Wave | `android/focus/build.gradle`, `android/focus/CMakeLists.txt` | Wave SDK imported libraries; CMake 3.10/C++23 baseline and current Yoga source list configure with the shared Android package compatibility helper | | Linux | `linux/CMakeLists.txt` | Old CMake 3.4, C++14 flag | | WebGL/Emscripten | `webgl/CMakeLists.txt` | Old CMake 3.4, WebGL2 flags | @@ -73,6 +73,10 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 - ctest --preset desktop-fast-vcpkg --build-config Debug cmake --preset android-arm64 powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64 +cmake -S android/android -B out/build/android-legacy-standard-arm64 -G Ninja -DCMAKE_TOOLCHAIN_FILE="$env:ANDROID_NDK_HOME\build\cmake\android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23 +cmake --build out/build/android-legacy-standard-arm64 --target native-lib +cmake -S android/quest -B out/build/android-legacy-quest-arm64 -G Ninja -DCMAKE_TOOLCHAIN_FILE="$env:ANDROID_NDK_HOME\build\cmake\android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23 +cmake -S android/focus -B out/build/android-legacy-focus-arm64 -G Ninja -DCMAKE_TOOLCHAIN_FILE="$env:ANDROID_NDK_HOME\build\cmake\android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23 powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly cmake --fresh --preset windows-clangcl-asan @@ -1032,10 +1036,10 @@ Known warnings after the current CMake app build: handles instead of public mutable Android asset-manager state or SDK forward declarations; concrete Android asset-manager headers remain in `asset.cpp` and the retained Android entrypoint while DEBT-0056 tracks replacing the - static Android asset bridge with injected asset storage. A focused legacy - Android object build validates `src/asset.cpp`; the full old Android - `native-lib` target still fails later on unrelated C++ standard/header - modernization issues. + static Android asset bridge with injected asset storage. The retained Android + standard package now links `native-lib` for arm64 through the refreshed C++23 + package CMake path; DEBT-0060 tracks the generated `nanort` overlay that keeps + that package gate clean without modifying the vendor submodule. - `pp_legacy_paint_document` is an object-library containment boundary for retained action, bezier, brush, canvas, canvas-layer, and event code. It should shrink as app painting and document behavior consume `pp_paint` and diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 04b02a0..6cd452e 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -249,6 +249,13 @@ agent or engineer to remove them without reconstructing context from chat. legacy Android `asset.cpp` object compiled under the old Android CMake path; the full legacy `native-lib` target still fails later on unrelated pre-modernization C++ standard/header issues. +- 2026-06-05: DEBT-0009/0011 were narrowed for retained Android packages. + Standard/Quest/Focus package CMake files now use CMake 3.10, target C++23, + share the current modern component/service source set, and route `nanort` + through a generated compatibility overlay without dirtying the submodule. + The standard arm64 `native-lib` package target builds and links directly; + Quest and Focus package CMake paths configure with the current Yoga source + list. APK/package migration into root CMake remains open. - 2026-06-04: DEBT-0036 was narrowed again. Canvas stroke commit, thumbnail, and object-draw history paths now query saved blend state through tested `pp_renderer_gl` capability-state dispatch; CanvasLayer equirect @@ -266,15 +273,15 @@ agent or engineer to remove them without reconstructing context from chat. | ID | Status | Owner | Item | Reason | Validation | Removal Condition | | --- | --- | --- | --- | --- | --- | --- | | DEBT-0001 | Open | Modernization | Existing platform build files remain alongside new CMake | Required for incremental migration without losing platform coverage | Existing platform builds plus new CMake configure | Remove after all platform builds consume shared CMake targets | -| DEBT-0002 | Open | Modernization | Vendored SDK and patched libraries retained initially | Some dependencies are SDK-only, patched, or have platform-specific binaries | Dependency inventory and platform build smoke tests | Replace with vcpkg packages or document permanent vendored status after triplet evaluation | +| DEBT-0002 | Open | Modernization | Vendored SDK and patched libraries retained initially, including the generated Android package `nanort` compatibility overlay tracked by DEBT-0060 | Some dependencies are SDK-only, patched, or have platform-specific binaries | Dependency inventory and platform build smoke tests | Replace with vcpkg packages or document permanent vendored status after triplet evaluation | | DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, `App::rec_loop`, `App::update_ui_observer`, `App::render_task*`, `App::ui_task*`, `App::render_thread_*`, `App::ui_thread_*`, file-menu save actions, `NodeCanvas` canvas hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path/message/report decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress/worker decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display and renderer diagnostic decisions, app dialog metadata decisions, app frame/UI-observer decisions, app thread/task orchestration decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-export-message`, `pano_cli plan-export-report`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-app-dialog`, `pano_cli plan-app-thread`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-canvas-hotkey`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/dialog/thread/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar/canvas-command contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, app dialog node creation, status/display UI rendering, renderer diagnostic capability adaptation, app task/thread execution, UI observer parent walking/callback execution, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4/PBO execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_frame_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_app_dialog_tests`; `pp_app_core_app_thread_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pp_app_core_canvas_hotkey_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-export-message --kind timelapse --destination success`; `pano_cli plan-export-report --kind license-disabled`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-recording-session --running --no-encoder`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12 --framebuffer-fetch --float32 --float32-linear --float16`; `pano_cli plan-app-dialog --kind message --cancel`; `pano_cli plan-app-frame`; `pano_cli plan-app-thread --kind ui-loop --live-reload`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-canvas-hotkey --event key-up --key z --ctrl --undo-count 2`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | | DEBT-0004 | Open | Modernization | Android, Linux, WebGL, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them | Prevent platform regressions during incremental migration; raw Windows `.sln/.vcxproj` files were removed on 2026-05-31 by user decision | `cmake --preset windows-msvc-default`; platform-specific configure/build smoke checks as each platform is migrated | Root CMake owns every platform source list and package path | | DEBT-0005 | Open | Modernization | Temporary local CTest harness is used before Catch2 is wired through vcpkg | `vcpkg` is not currently on PATH, but headless tests need to run now | `ctest --preset desktop-fast --build-config Debug` | Replace `tests/test_harness.h` tests with Catch2 tests once vcpkg toolchain/presets are validated | | DEBT-0007 | Open | Modernization | `vcpkg.json` and `windows-msvc-vcpkg-headless` are validated for the headless Windows component matrix, but app targets still use vendored libraries and Android/Apple triplets are not proven | Dependency migration must stay incremental while SDK/patched/vendor dependencies remain in use | `$env:VCPKG_ROOT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg"; cmake --preset windows-msvc-vcpkg-headless`; `ctest --preset desktop-fast-vcpkg --build-config Debug` | Component targets consume vcpkg packages where reliable and desktop app, Android, and Apple triplets are validated or explicitly documented as permanent vendor exceptions | | DEBT-0008 | Open | Modernization | `windows-msvc-default` preset is used for local validation because the VS 2026 generator is not installed here | The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 | `cmake --preset windows-msvc-default`; `ctest --preset desktop-fast --build-config Debug` | Validate `windows-vs2026-x64` on a machine with Visual Studio 2026 installed and make it the default Windows validation preset | -| DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, not APK/package variants; standard arm64/x64, Quest arm64, and Focus/Wave arm64 have named root build presets and share the refreshed `platform-build` component matrix | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64`; `cmake --build --preset android-x64`; `cmake --build --preset android-quest-arm64`; `cmake --build --preset android-focus-arm64` | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands | +| DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, while retained standard/Quest/Focus package CMake paths now have a refreshed CMake 3.10/C++23 baseline outside root CMake; standard arm64 `native-lib` builds directly and Quest/Focus package paths configure | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64`; `cmake --build --preset android-x64`; `cmake --build --preset android-quest-arm64`; `cmake --build --preset android-focus-arm64`; `cmake --build out/build/android-legacy-standard-arm64 --target native-lib`; Quest/Focus retained package configure checks | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands | | DEBT-0010 | Open | Modernization | `pp_document` is a pure layer/frame/document/undo-history model with alpha-lock metadata, snapshot construction, per-layer frame metadata, renderer-free RGBA8 face payload storage, snapshot-embedded face-payload validation, renderer-free alpha8 selection-mask storage, PPI import/export helpers, and stroke-script-to-face-payload CLI automation, but it is not yet wired to legacy `Canvas`, legacy save, or legacy action commands | Keep extraction incremental while preserving app behavior | `ctest --preset desktop-fast --build-config Debug`; `pano_cli create-document --width 64 --height 32 --layers 2`; `pano_cli load-project --path tests\data\projects\minimal-project.ppi`; `pp_document_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_simulate_document_edits_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Legacy document behavior is represented by `pp_document` tests and the app consumes it through a boundary/facade | -| DEBT-0011 | Open | Modernization | `package-smoke` validates the Windows CMake app artifact and now reports a structured package readiness matrix for Windows AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, but those package outputs are still `blocked` because root CMake package targets do not exist yet | Platform package targets are not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug`; `bash -n scripts/automation/package-smoke.sh` | Package-smoke builds and validates Windows AppX, Android APK variants, Apple bundles, and WebGL output where local toolchains are present | +| DEBT-0011 | Open | Modernization | `package-smoke` validates the Windows CMake app artifact and reports a structured package readiness matrix for Windows AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output; retained Android package native CMake paths are refreshed but APK outputs are still `blocked` because root CMake package targets do not exist yet | Platform package targets are not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug`; `bash -n scripts/automation/package-smoke.sh`; retained Android standard `native-lib` build and Quest/Focus configure checks | Package-smoke builds and validates Windows AppX, Android APK variants, Apple bundles, and WebGL output where local toolchains are present | | DEBT-0012 | Open | Modernization | `pp_ui_core` uses vcpkg tinyxml2 on `windows-msvc-vcpkg-headless`, but retains `pp_vendor_tinyxml2` for default and unproven platform presets | Mobile/AppX/Apple triplets and app packaging still need validation before removing the vendored fallback | `ctest --preset desktop-fast-vcpkg --build-config Debug`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64` | All supported presets consume vcpkg tinyxml2 or document a permanent vendored exception | | DEBT-0013 | Open | Modernization | `pp_assets`, `pp_document`, `pano_cli inspect-project`, `pano_cli load-project`, and `pano_cli save-project` validate the fixed PPI header, thumbnail/body byte layout, generated multi-layer/multi-frame PPI writing with explicit layer opacity/blend/alpha-lock/visibility metadata, per-layer frame durations, metadata-only and targeted dirty-face-payload save/load round-trips, layer/frame index, dirty-face descriptors, dirty-face PNG payload metadata, asset-level RGBA PNG payload decoding, pure document-to-PPI export, CLI document export automation, file-writing document export automation, stroke-script-generated document payload export, and decoded pixel attachment to `pp_document`, but full legacy PPI round-trip parity is not yet extracted | Full PPI save parity requires staged extraction of legacy `Canvas` serialization and image/layer payload handling | `ctest --preset desktop-fast --build-config Debug`; `pp_assets_image_pixels_tests`; `pp_assets_ppi_header_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_inspect_project_layout_smoke`; `pano_cli_load_project_metadata_smoke`; `pano_cli_save_project_roundtrip_smoke`; `pano_cli_save_project_payload_roundtrip_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Full PPI load/save fixtures cover thumbnails, decoded layer face payloads attached to documents, frames, corrupt payloads, dirty-face payload saving, arbitrary legacy canvas payload/layout combinations, and legacy app round-trip compatibility | | DEBT-0014 | Open | Modernization | `windows-clangcl-asan` now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer | Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible | `cmake --fresh --preset windows-clangcl-asan`; `cmake --build --preset windows-clangcl-asan --target pp_foundation` | Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make `platform-build.ps1 -Presets windows-clangcl-asan` pass for the headless matrix | @@ -318,7 +325,8 @@ agent or engineer to remove them without reconstructing context from chat. | DEBT-0053 | Open | Modernization | Prepared-file writable target selection and prepared-file export-dialog policy now dispatch through `PlatformServices`; iOS temporary-file and WebGL data-path target planning live in tested `pp_platform_api::platform_policy`, but retained iOS/Web save/download handoff execution still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve mobile/Web export handoff behavior while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple/Web package smoke once root package builds exist | Prepared-file target selection, export-dialog policy, and save/download handoff are owned by injected platform services with no legacy adapter branch | | 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`, and the old Android `native-lib` target still has unrelated C++ standard/header modernization failures | 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`; legacy Android `CMakeFiles/native-lib.dir/.../src/asset.cpp.o` object compile | 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-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`; `cmake --build out/build/android-legacy-standard-arm64 --target native-lib` | 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 generates a patched `nanort.h` overlay in the build tree for `native-lib` instead of modifying the `libs/nanort` submodule | Current NDK/Clang rejects `TriangleSAHPred::operator=` assigning to a `const size_t` member, but the retained grid/lightmap path still includes `nanort` before that dependency is replaced or updated | `cmake --build out/build/android-legacy-standard-arm64 --target native-lib`; Quest/Focus retained package configure checks; Windows app build | Update/replace `nanort`, move grid/lightmap baking behind a component that owns its dependency, or retire the retained Android package CMake path so no generated vendor overlay is required | | 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::platform_policy`, but the Web shell still reaches it through the legacy platform fallback until injected Web services own the policy | 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 | | DEBT-0058 | Open | Modernization | App-level progress/message/input dialog metadata, including message-dialog OK/cancel captions, now consumes pure `pp_app_core` through `App::show_progress`, `App::message_box`, `App::input_box`, `pano_cli plan-app-dialog`, and `pp_app_core_app_dialog_tests`; live execution is centralized in `src/legacy_app_dialog_services.*`, but the bridge still creates retained `NodeProgressBar`, `NodeMessageBox`, and `NodeInputBox` instances and inserts them into the legacy layout tree | Preserve current app-shell dialog behavior while moving shared dialog policy toward UI/app services | `pp_app_core_app_dialog_tests`; `pano_cli plan-app-dialog --kind progress --total -4`; `pano_cli plan-app-dialog --kind message --cancel`; `pano_cli plan-app-dialog --kind input --ok-caption Save`; `ctest --preset desktop-fast --build-config Debug`; Windows app build | Progress/message/input dialog creation, callback wiring, layout insertion, lifetime ownership, and headless automation are owned by injected app/UI services with `App` methods acting only as adapters | | DEBT-0059 | Open | Modernization | iOS root CMake headless builds assign generated bundle identifiers and disable code signing for executable test/tool targets | The current Apple gate is compile validation for shared component targets; signed iOS app/package validation is not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.ps1 -Presets macos,ios-simulator,ios-device`; `sh scripts/automation/platform-build.sh "ios-device"` on `panopainter-mac` | Root CMake owns the signed Apple app/package targets, package-smoke validates Apple bundles where signing material is available, and headless iOS test/tool targets are either excluded from signed package builds or use explicit test-runner signing policy | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index fa886d5..6d31a4d 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1410,6 +1410,14 @@ layout XML file mtime reload policy, recording cleanup policy, default canvas resolution, and canvas tip visibility. Platform SDK calls and filesystem probes remain in the platform shells or thin runtime wrappers while those decisions are headless-testable. +The retained Android standard/Quest/Focus package CMake files now use CMake +3.10, request C++23 through target compile features, include the extracted +modern component/service source set that the legacy package still links +monolithically, and share a generated `nanort` compatibility overlay from +`android/cmake/PanoPainterAndroidLegacyCompat.cmake` instead of dirtying the +vendor submodule. The standard package `native-lib` arm64 target now compiles +and links with the current NDK; Quest and Focus configure with the aligned Yoga +source list and their SDK imported-library paths. Implementation tasks: @@ -2359,7 +2367,10 @@ Results: through the platform-build wrapper by default. Focused validation compiled representative headless component/tool targets across all four presets, and the full refreshed component/test matrix remains the default gate for local - platform sweeps. + platform sweeps. The retained Android standard package CMake path also now + configures/builds `native-lib` directly for arm64 using C++23 and the shared + modern component source set, while Quest and Focus package CMake paths + configure with the same compatibility helper and current Yoga source list. - Desktop VR drawing now routes generic OpenGL scissor/depth/blend state, blend/depth state snapshots and restores, depth clears, active texture units, and fallback 2D texture unbinds through tested renderer GL backend dispatch; diff --git a/src/app.h b/src/app.h index 1c8d1db..f078ddb 100644 --- a/src/app.h +++ b/src/app.h @@ -19,7 +19,6 @@ #include "node_canvas.h" #include "node_dialog_layer_rename.h" #include "node_progress_bar.h" -#include "node_panel_grid.h" #include "node_panel_quick.h" #include "node_input_box.h" #include "node_panel_animation.h" @@ -32,6 +31,8 @@ class PlatformServices; struct PlatformStoragePaths; } +class NodePanelGrid; + #if defined(__OBJC__) && defined(__IOS__) @class GameViewController; @class AppDelegate; diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 25e06ad..b78d6e9 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "app.h" +#include "node_panel_grid.h" #include "node_icon.h" #include "node_dialog_open.h" #include "node_text.h" diff --git a/src/app_vr.cpp b/src/app_vr.cpp index d526a66..4dd6b18 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -3,6 +3,7 @@ #include #include "app.h" +#include "node_panel_grid.h" #include "util.h" #include "shape.h" #include "renderer_gl/opengl_capabilities.h" diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index ef87f64..99d2b94 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -11,6 +11,7 @@ #include "app_core/canvas_view.h" #include "app_core/document_animation.h" #include "app.h" +#include "node_panel_grid.h" #include "legacy_canvas_tool_services.h" #include "legacy_history_services.h" #include "log.h" diff --git a/src/pch.cpp b/src/pch.cpp index e3fe1a5..a9462f0 100644 --- a/src/pch.cpp +++ b/src/pch.cpp @@ -7,13 +7,12 @@ #include #include -#ifdef _DEBUG - #pragma comment (lib, "libcurl_debug.lib") -#else - #pragma comment (lib, "libcurl.lib") -#endif // DEBUG - #ifdef _WIN32 + #ifdef _DEBUG + #pragma comment (lib, "libcurl_debug.lib") + #else + #pragma comment (lib, "libcurl.lib") + #endif // DEBUG #pragma comment(lib, "BugTrapU-x64.lib") #pragma comment(lib, "shell32.lib") #pragma comment(lib, "opengl32.lib")