From 0489c4229eb2f0654be66e733149dc566cf9f695 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 4 Jun 2026 19:20:06 +0200 Subject: [PATCH] Route default canvas resolution through platform services --- docs/modernization/build-inventory.md | 5 ++++- docs/modernization/debt.md | 1 + docs/modernization/roadmap.md | 5 +++++ src/app.h | 1 + src/app_commands.cpp | 3 ++- src/app_events.cpp | 5 +++++ src/canvas.h | 6 ------ src/node_canvas.cpp | 6 ++++-- src/platform_api/platform_services.h | 1 + .../legacy_platform_services.cpp | 9 +++++++++ .../windows_platform_services.cpp | 5 +++++ .../platform_api/platform_services_tests.cpp | 20 +++++++++++++++++++ 12 files changed, 57 insertions(+), 10 deletions(-) diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index b536ffa..616a884 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -776,7 +776,10 @@ Known warnings after the current CMake app build: - `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 - `pp_document` directly. + `pp_document` directly. Shared `canvas.h` no longer owns the platform + `CANVAS_RES` macro; default canvas allocation now asks `PlatformServices`, + preserving the WebGL 512 default in the legacy fallback while DEBT-0057 + tracks moving that policy into an injected Web platform service. - `pp_legacy_engine` intentionally contains retained legacy runtime shell sources for now, so it concentrates existing legacy tablet, video, HMD, log, and low-level utility warnings until those paths move to cleaner component diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 2478466..460a772 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -74,6 +74,7 @@ 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`, but that helper still encodes the retained compile-time platform policy: Windows/macOS use `stat` mtime reload checks, while other platforms treat already-loaded layouts as successful no-op loads | 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` now forward-declares Android asset-manager types and uses `Asset::set_android_asset_manager` instead of public mutable manager state, but retained `Asset` still stores Android asset handles 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` | Reduce legacy asset I/O header coupling without rewriting Android asset loading before the asset manager/storage boundary exists | Windows app build; `cmake --build --preset android-arm64 --target pp_assets`; Android package smoke once package builds consume shared targets | 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-0057 | Open | Modernization | Default canvas allocation size now dispatches through `PlatformServices::default_canvas_resolution`, removing the `CANVAS_RES` platform macro from `src/canvas.h`, but WebGL's retained 512 default still lives in `src/platform_legacy/legacy_platform_services.cpp` until the Web shell owns injected services | 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 | ## Closed Debt diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 02e9699..1622ad9 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -667,6 +667,11 @@ hides the Android asset handles behind `Asset::set_android_asset_manager`, and keeps concrete Android asset-manager headers in `asset.cpp`/the Android entrypoint. This reduces legacy asset I/O header coupling while the actual Android asset-reader implementation remains inside `pp_legacy_assets_io`. +Default canvas allocation size now dispatches through `PlatformServices`, so +`NodeCanvas` and command-line conversion creation paths preserve the desktop +1536 and WebGL 512 defaults without carrying the old `CANVAS_RES` platform +macro in `canvas.h`; DEBT-0057 tracks moving the retained WebGL policy branch +out of the legacy fallback when the Web shell owns injected services. Prepared-file save/download handoff is now also part of the service contract, so iOS/Web export completion routes through `PlatformServices` after the app writes the temporary/exported payload. diff --git a/src/app.h b/src/app.h index 3a45deb..467fcc6 100644 --- a/src/app.h +++ b/src/app.h @@ -192,6 +192,7 @@ public: [[nodiscard]] bool uses_ppbr_export_data_directory_override() const; [[nodiscard]] bool platform_supports_sonarpen() const; void start_platform_sonarpen(); + [[nodiscard]] int default_canvas_resolution() const; [[nodiscard]] bool draws_canvas_tip_for_input(kEventSource source, kEventType type) const; [[nodiscard]] float adjust_canvas_input_pressure(float pressure) const; void pick_dir(std::function callback); diff --git a/src/app_commands.cpp b/src/app_commands.cpp index 70188b2..c89afbf 100644 --- a/src/app_commands.cpp +++ b/src/app_commands.cpp @@ -40,7 +40,8 @@ void App::cmd_convert(std::string pano_path, std::string out_path) glBlendEquation(add_blend_equation()); Canvas* command_canvas = new Canvas; - command_canvas->create(CANVAS_RES, CANVAS_RES); + const int canvas_resolution = default_canvas_resolution(); + command_canvas->create(canvas_resolution, canvas_resolution); command_canvas->project_open_thread(pano_path); command_canvas->export_equirectangular_thread(out_path); } diff --git a/src/app_events.cpp b/src/app_events.cpp index 2875ba4..88fc49c 100644 --- a/src/app_events.cpp +++ b/src/app_events.cpp @@ -211,6 +211,11 @@ void App::start_platform_sonarpen() active_platform_services().start_sonarpen(); } +int App::default_canvas_resolution() const +{ + return active_platform_services().default_canvas_resolution(); +} + bool App::draws_canvas_tip_for_input(kEventSource source, kEventType type) const { return active_platform_services().draws_canvas_tip_for_pointer( diff --git a/src/canvas.h b/src/canvas.h index 652acbb..f6f683c 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -10,12 +10,6 @@ #include #include "mp4enc.h" -#if __WEB__ -#define CANVAS_RES 512 -#else -#define CANVAS_RES 1536 -#endif - struct PPIThumb { int width = 128; diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 53e2e51..fabc23b 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -153,7 +153,8 @@ void NodeCanvas::init() m_mouse_ignore = false; m_canvas = std::make_unique(); - m_canvas->create(CANVAS_RES, CANVAS_RES); + const int canvas_resolution = App::I->default_canvas_resolution(); + m_canvas->create(canvas_resolution, canvas_resolution); m_canvas->m_unsaved = false; m_canvas->m_node = this; @@ -179,7 +180,8 @@ void NodeCanvas::init() void NodeCanvas::restore_context() { Node::restore_context(); - m_canvas->create(CANVAS_RES, CANVAS_RES); + const int canvas_resolution = App::I->default_canvas_resolution(); + m_canvas->create(canvas_resolution, canvas_resolution); m_sampler.create(); diff --git a/src/platform_api/platform_services.h b/src/platform_api/platform_services.h index 8c6f24c..4bf4e63 100644 --- a/src/platform_api/platform_services.h +++ b/src/platform_api/platform_services.h @@ -73,6 +73,7 @@ public: [[nodiscard]] virtual bool uses_ppbr_export_data_directory_override() = 0; [[nodiscard]] virtual bool supports_sonarpen() = 0; virtual void start_sonarpen() = 0; + [[nodiscard]] virtual int default_canvas_resolution() = 0; [[nodiscard]] virtual bool draws_canvas_tip_for_pointer( bool is_mouse, bool is_stylus, diff --git a/src/platform_legacy/legacy_platform_services.cpp b/src/platform_legacy/legacy_platform_services.cpp index 3798359..8e3d7d1 100644 --- a/src/platform_legacy/legacy_platform_services.cpp +++ b/src/platform_legacy/legacy_platform_services.cpp @@ -510,6 +510,15 @@ public: #endif } + [[nodiscard]] int default_canvas_resolution() override + { +#if __WEB__ + return 512; +#else + return 1536; +#endif + } + [[nodiscard]] bool draws_canvas_tip_for_pointer( bool is_mouse, bool is_stylus, diff --git a/src/platform_windows/windows_platform_services.cpp b/src/platform_windows/windows_platform_services.cpp index 423a279..bb372a2 100644 --- a/src/platform_windows/windows_platform_services.cpp +++ b/src/platform_windows/windows_platform_services.cpp @@ -508,6 +508,11 @@ public: { } + [[nodiscard]] int default_canvas_resolution() override + { + return 1536; + } + [[nodiscard]] bool draws_canvas_tip_for_pointer( bool is_mouse, bool is_stylus, diff --git a/tests/platform_api/platform_services_tests.cpp b/tests/platform_api/platform_services_tests.cpp index dea43e6..b112fa1 100644 --- a/tests/platform_api/platform_services_tests.cpp +++ b/tests/platform_api/platform_services_tests.cpp @@ -274,6 +274,12 @@ public: ++sonarpen_starts; } + [[nodiscard]] int default_canvas_resolution() override + { + ++default_canvas_resolution_requests; + return canvas_resolution; + } + [[nodiscard]] bool draws_canvas_tip_for_pointer( bool is_mouse, bool is_stylus, @@ -362,6 +368,7 @@ public: int ppbr_export_data_directory_override_checks = 0; int sonarpen_support_checks = 0; int sonarpen_starts = 0; + int default_canvas_resolution_requests = 0; int canvas_tip_policy_checks = 0; int canvas_pressure_adjustments = 0; int prepare_writable_file_requests = 0; @@ -376,6 +383,7 @@ public: bool network_tls_verification_disabled = false; bool ppbr_export_data_directory_override = false; bool sonarpen_supported = false; + int canvas_resolution = 1536; bool canvas_tip_visible = false; bool last_canvas_tip_mouse = false; bool last_canvas_tip_stylus = false; @@ -815,6 +823,17 @@ void platform_services_dispatch_sonarpen_policy_and_start(pp::tests::Harness& ha PP_EXPECT(harness, fake.sonarpen_starts == 1); } +void platform_services_dispatch_default_canvas_resolution(pp::tests::Harness& harness) +{ + FakePlatformServices fake("unused"); + pp::platform::PlatformServices& services = fake; + + PP_EXPECT(harness, services.default_canvas_resolution() == 1536); + fake.canvas_resolution = 512; + PP_EXPECT(harness, services.default_canvas_resolution() == 512); + PP_EXPECT(harness, fake.default_canvas_resolution_requests == 2); +} + void platform_services_dispatch_canvas_input_policy(pp::tests::Harness& harness) { FakePlatformServices fake("unused"); @@ -873,6 +892,7 @@ int main() "platform services dispatch ppbr export directory policy", platform_services_dispatch_ppbr_export_directory_policy); harness.run("platform services dispatch sonarpen policy and start", platform_services_dispatch_sonarpen_policy_and_start); + harness.run("platform services dispatch default canvas resolution", platform_services_dispatch_default_canvas_resolution); harness.run("platform services dispatch canvas input policy", platform_services_dispatch_canvas_input_policy); return harness.finish(); }