diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index e7e2b045..5bb1d322 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -166,6 +166,8 @@ set(PP_PANOPAINTER_APP_SOURCES src/legacy_document_session_services.h src/platform_legacy/legacy_platform_services.cpp src/platform_legacy/legacy_platform_services.h + src/platform_legacy/legacy_platform_state.cpp + src/platform_legacy/legacy_platform_state.h src/version.cpp ) diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 0eac82eb..43326112 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1,7 +1,7 @@ # PanoPainter Modernization Roadmap Status: live -Last updated: 2026-06-16 +Last updated: 2026-06-17 This roadmap is now architecture-first. The active execution queue lives in `docs/modernization/tasks.md`. @@ -80,18 +80,34 @@ What is still carrying too much live ownership: Current hotspot files: - `src/canvas.cpp`: 17 lines -- `src/app_layout.cpp`: 125 lines +- `src/app_layout.cpp`: 109 lines - `src/canvas_modes.cpp`: 1 line - `src/node.cpp`: 12 lines -- `src/main.cpp`: 87 lines +- `src/main.cpp`: 10 lines - `src/node_panel_brush.cpp`: 2 lines -- `src/node_stroke_preview.cpp`: 160 lines -- `src/node_canvas.cpp`: 85 lines +- `src/node_stroke_preview.cpp`: 76 lines +- `src/node_canvas.cpp`: 69 lines - `src/app.cpp`: 94 lines - `src/app_dialogs.cpp`: 95 lines Latest slice: +- The live Windows entry shell now routes through + `run_main_application(...)` in + `src/platform_windows/windows_runtime_shell.*`, leaving `src/main.cpp` as a + minimal entry wrapper around `main(...)` and `WinMain(...)`. +- Retained legacy storage-path state now lives in + `src/platform_legacy/legacy_platform_state.*` instead of staying inline in + `src/platform_legacy/legacy_platform_services.cpp`, which trims another + process-global platform-state pocket out of the legacy platform shell. +- The remaining `NodeStrokePreview` clone-init, stroke-frame planning, + mix-pass adapter wiring, sample-pass adapter wiring, and immediate-draw + request construction now route through + `src/legacy_node_stroke_preview_runtime_services.*`, + `src/legacy_node_stroke_preview_draw_services.*`, and + `src/legacy_node_stroke_preview_sample_services.*`, leaving + `src/node_stroke_preview.cpp` as a thinner live adapter. + - `NodeCanvas::handle_event()` now routes through `handle_legacy_node_canvas_event(...)` in `src/legacy_canvas_tool_services.*`, leaving `src/node_canvas.cpp` as a much diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index e31208ca..edae76a2 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -1,7 +1,7 @@ # Modernization Task Tracker Status: live -Last updated: 2026-06-16 +Last updated: 2026-06-17 This file now tracks only active architecture work. Completed, blocked, and superseded task history moved to @@ -36,10 +36,10 @@ Completed, blocked, and superseded task history moved to - `pp_legacy_paint_document`: 7 files, about 5709 lines - `pp_legacy_app`: 20 files, about 4368 lines - `pp_legacy_ui_core`: 20 files, about 3770 lines -- The biggest single-file choke points are still `src/canvas_modes.cpp`, - `src/node.cpp`, - `src/main.cpp`, `src/node_panel_brush.cpp`, `src/node_stroke_preview.cpp`, - `src/node_canvas.cpp`, `src/app.cpp`, and `src/app_dialogs.cpp`. +- The biggest remaining single-file pressure is no longer the old entrypoint + shell files; it now sits mostly in retained legacy service layers behind + `src/node_stroke_preview.cpp`, `src/app.cpp`, `src/app_dialogs.cpp`, and the + extracted canvas/platform containment files. - The platform boundary is not finished: - `pp_platform_api` still compiles Apple implementation files - `platform_apple` no longer reaches `App::I` directly, and Linux FPS title @@ -391,6 +391,13 @@ Current slice: render-target validation, viewport/clear-color save-restore, and immediate runtime request assembly out of the live node file and leaves `src/node_stroke_preview.cpp` at 160 lines. +- `NodeStrokePreview` clone-finalize setup, stroke-frame planning, mix-pass + adapter wiring, sample-pass adapter wiring, and the remaining + immediate-draw request construction now also route through + `src/legacy_node_stroke_preview_runtime_services.*`, + `src/legacy_node_stroke_preview_draw_services.*`, and + `src/legacy_node_stroke_preview_sample_services.*`, which leaves + `src/node_stroke_preview.cpp` at 76 lines. - `CanvasModeGrid` plus `ActionModeGrid` undo/redo now also live in `src/legacy_canvas_mode_helpers.cpp` instead of staying inline in `src/canvas_modes.cpp`, which leaves the live canvas-modes file as a @@ -759,6 +766,9 @@ Current slice: loop, and shutdown cleanup now also lives in `src/platform_windows/windows_runtime_shell.*` instead of `src/main.cpp`, which reduces the entry TU to a much smaller composition root +- the remaining Windows app shell in `main(...)` now also routes through + `run_main_application(...)` in `src/platform_windows/windows_runtime_shell.*`, + which reduces `src/main.cpp` to a minimal `main`/`WinMain` wrapper - prepared-file background work now runs through an `AppRuntime`-owned worker queue instead of a retained static worker in `src/app_events.cpp` - canvas async import/export/save/open background work now also runs through an @@ -1115,6 +1125,9 @@ Current slice: - retained GLFW window hooks and the non-Linux fallback storage-path return now also route through retained local state helpers instead of reading `App::I` directly in those method bodies +- retained storage-path state now also lives in + `src/platform_legacy/legacy_platform_state.*` instead of staying inline in + `src/platform_legacy/legacy_platform_services.cpp` - retained Apple callback injection and broader `platform_legacy` singleton reach are still open - The remaining Win32 shell wrappers for close, async lock/swap, diff --git a/src/legacy_node_stroke_preview_draw_services.cpp b/src/legacy_node_stroke_preview_draw_services.cpp index 98fd9cc3..26d0ec8e 100644 --- a/src/legacy_node_stroke_preview_draw_services.cpp +++ b/src/legacy_node_stroke_preview_draw_services.cpp @@ -187,6 +187,33 @@ bool execute_legacy_node_stroke_preview_mix_pass( return mix_result.ok; } +bool execute_legacy_node_stroke_preview_mix_pass( + const Brush& brush, + glm::vec2 preview_size, + RTT& mixer_rtt, + glm::vec2 bb_min, + glm::vec2 bb_sz, + Sampler& linear_sampler, + Texture2D& background_texture, + Texture2D& stroke_texture, + Texture2D& dual_texture, + std::function draw_mix) +{ + return execute_legacy_node_stroke_preview_mix_pass( + LegacyNodeStrokePreviewMixPassExecutionRequest { + .brush = brush, + .preview_size = preview_size, + .mixer_rtt = mixer_rtt, + .bb_min = bb_min, + .bb_sz = bb_sz, + .linear_sampler = linear_sampler, + .background_texture = background_texture, + .stroke_texture = stroke_texture, + .dual_texture = dual_texture, + .draw_mix = std::move(draw_mix), + }); +} + bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request) { return request.bind_dual_pass_textures && diff --git a/src/legacy_node_stroke_preview_draw_services.h b/src/legacy_node_stroke_preview_draw_services.h index 3e1dabc5..f6ea7e06 100644 --- a/src/legacy_node_stroke_preview_draw_services.h +++ b/src/legacy_node_stroke_preview_draw_services.h @@ -61,6 +61,18 @@ struct LegacyNodeStrokePreviewMixPassExecutionRequest { [[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass( const LegacyNodeStrokePreviewMixPassExecutionRequest& request); +[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass( + const Brush& brush, + glm::vec2 preview_size, + RTT& mixer_rtt, + glm::vec2 bb_min, + glm::vec2 bb_sz, + Sampler& linear_sampler, + Texture2D& background_texture, + Texture2D& stroke_texture, + Texture2D& dual_texture, + std::function draw_mix); + [[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes( const LegacyNodeStrokePreviewLiveRenderRequest& request); diff --git a/src/legacy_node_stroke_preview_runtime_services.cpp b/src/legacy_node_stroke_preview_runtime_services.cpp index f5262bfb..44fb93ca 100644 --- a/src/legacy_node_stroke_preview_runtime_services.cpp +++ b/src/legacy_node_stroke_preview_runtime_services.cpp @@ -14,6 +14,7 @@ #include "legacy_canvas_stroke_shader_services.h" #include "legacy_canvas_stroke_services.h" #include "legacy_node_stroke_preview_execution_services.h" +#include "legacy_node_stroke_preview_sample_services.h" #include "legacy_ui_gl_dispatch.h" #include "paint_renderer/compositor.h" #include "renderer_gl/opengl_capabilities.h" @@ -299,6 +300,19 @@ std::vector plan_legacy_node_stroke_preview_stroke }); } +std::vector plan_legacy_node_stroke_preview_stroke_frames( + const Stroke& stroke, + float zoom, + glm::vec2 mixer_size) +{ + return plan_legacy_node_stroke_preview_stroke_frames( + LegacyNodeStrokePreviewStrokeComputeRequest { + .stroke = stroke, + .zoom = zoom, + .mixer_size = mixer_size, + }); +} + bool execute_legacy_node_stroke_preview_immediate_runtime( const LegacyNodeStrokePreviewImmediateRuntimeRequest& request) { @@ -375,6 +389,92 @@ bool execute_legacy_node_stroke_preview_immediate_runtime( return sequence_ok; } +void initialize_legacy_node_stroke_preview_clone(Node* dest) +{ + static_cast(dest)->init_controls(); +} + +bool execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview) +{ + if (preview.m_size.x == 0 || preview.m_size.y == 0) { + return false; + } + + const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw( + pp::panopainter::LegacyNodeStrokePreviewImmediateDrawRequest { + .brush = preview.m_brush, + .preview_size = preview.m_size, + .zoom = preview.root()->m_zoom, + .min_flow = preview.m_min_flow, + .stroke_max_size_override = preview.m_max_size, + .pad_override = preview.m_pad_override, + .camera_fov = Canvas::I->m_cam_fov, + .camera_rot = Canvas::I->m_cam_rot, + .render_device_features = pp::panopainter::stroke_preview_render_device_features(), + .preview_rtt = preview.m_rtt, + .preview_rtt_mixer = preview.m_rtt_mixer, + .preview_stroke_texture = preview.m_tex, + .preview_dual_texture = preview.m_tex_dual, + .preview_background_texture = preview.m_tex_background, + .preview_image_texture = preview.m_tex_preview, + .linear_sampler = preview.m_sampler_linear, + .repeat_sampler = preview.m_sampler_linear_repeat, + .prepare_render_target = [&] { + pp::panopainter::apply_legacy_node_stroke_preview_viewport( + 0, + 0, + preview.m_rtt.getWidth(), + preview.m_rtt.getHeight()); + preview.m_rtt.bindFramebuffer(); + preview.m_rtt.clear(); + pp::panopainter::bind_legacy_node_stroke_preview_live_samplers( + preview.m_sampler_mipmap, + preview.m_sampler_linear, + preview.m_sampler_linear_repeat); + }, + .finish_render_target = [&] { + preview.m_rtt.unbindFramebuffer(); + }, + .compute_frames = [&](const Stroke& stroke, float frame_zoom) { + return plan_legacy_node_stroke_preview_stroke_frames( + stroke, + frame_zoom, + glm::vec2(preview.m_rtt.getWidth(), preview.m_rtt.getHeight())); + }, + .draw_samples = [&](std::array& shapes, Texture2D& texture, bool copy_stroke_destination) { + return pp::panopainter::execute_legacy_node_stroke_preview_sample_pass( + preview.m_rtt, + shapes, + preview.m_brush_shape, + texture, + copy_stroke_destination); + }, + .draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) { + pp::panopainter::execute_legacy_node_stroke_preview_mix_pass( + *preview.m_brush, + preview.m_size, + preview.m_rtt_mixer, + bb_min, + bb_sz, + preview.m_sampler_linear, + preview.m_tex_background, + preview.m_tex, + preview.m_tex_dual, + [&] { + preview.m_plane.draw_fill(); + }); + }, + .draw_checkerboard = [&] { + preview.m_plane.draw_fill(); + }, + .draw_composite = [&] { + preview.m_plane.draw_fill(); + }, + }); + assert(sequence_ok); + return sequence_ok; +} + } // namespace pp::panopainter std::atomic_int NodeStrokePreview::s_instances{ 0 }; diff --git a/src/legacy_node_stroke_preview_runtime_services.h b/src/legacy_node_stroke_preview_runtime_services.h index 974ed005..c7304590 100644 --- a/src/legacy_node_stroke_preview_runtime_services.h +++ b/src/legacy_node_stroke_preview_runtime_services.h @@ -16,6 +16,9 @@ #include #include +class Node; +class NodeStrokePreview; + namespace pp::panopainter { [[nodiscard]] pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept; @@ -63,6 +66,11 @@ struct LegacyNodeStrokePreviewStrokeComputeRequest { [[nodiscard]] std::vector plan_legacy_node_stroke_preview_stroke_frames( const LegacyNodeStrokePreviewStrokeComputeRequest& request); +[[nodiscard]] std::vector plan_legacy_node_stroke_preview_stroke_frames( + const Stroke& stroke, + float zoom, + glm::vec2 mixer_size); + struct LegacyNodeStrokePreviewImmediateRuntimeRequest { const std::shared_ptr& brush; glm::vec2 preview_size {}; @@ -128,4 +136,7 @@ struct LegacyNodeStrokePreviewImmediateDrawRequest { [[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_runtime( const LegacyNodeStrokePreviewImmediateRuntimeRequest& request); +void initialize_legacy_node_stroke_preview_clone(Node* dest); +[[nodiscard]] bool execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview); + } // namespace pp::panopainter diff --git a/src/legacy_node_stroke_preview_sample_services.cpp b/src/legacy_node_stroke_preview_sample_services.cpp index b767ab79..1ae755d1 100644 --- a/src/legacy_node_stroke_preview_sample_services.cpp +++ b/src/legacy_node_stroke_preview_sample_services.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "legacy_node_stroke_preview_sample_services.h" +#include "legacy_node_stroke_preview_runtime_services.h" namespace pp::panopainter { @@ -57,4 +58,41 @@ glm::vec4 execute_legacy_node_stroke_preview_sample_pass( return result.dirty_bounds; } +glm::vec4 execute_legacy_node_stroke_preview_sample_pass( + RTT& preview_rtt, + std::array& vertices, + DynamicShape& brush_shape, + Texture2D& blend_tex, + bool copy_stroke_destination) +{ + return execute_legacy_node_stroke_preview_sample_pass( + LegacyNodeStrokePreviewSamplePassRequest { + .target_size = { static_cast(preview_rtt.getWidth()), static_cast(preview_rtt.getHeight()) }, + .vertices = vertices, + .brush_shape = brush_shape, + .copy_stroke_destination = copy_stroke_destination, + .bind_destination_texture = [&] { + bind_legacy_node_stroke_preview_destination_texture(blend_tex); + }, + .copy_framebuffer_to_destination_texture = []( + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) { + copy_legacy_node_stroke_preview_destination_texture_region( + src_x, + src_y, + dst_x, + dst_y, + width, + height); + }, + .unbind_destination_texture = [&] { + unbind_legacy_node_stroke_preview_destination_texture(blend_tex); + }, + }); +} + } // namespace pp::panopainter diff --git a/src/legacy_node_stroke_preview_sample_services.h b/src/legacy_node_stroke_preview_sample_services.h index d55c117b..df8ebaf1 100644 --- a/src/legacy_node_stroke_preview_sample_services.h +++ b/src/legacy_node_stroke_preview_sample_services.h @@ -25,4 +25,11 @@ struct LegacyNodeStrokePreviewSamplePassRequest { [[nodiscard]] glm::vec4 execute_legacy_node_stroke_preview_sample_pass( const LegacyNodeStrokePreviewSamplePassRequest& request); +[[nodiscard]] glm::vec4 execute_legacy_node_stroke_preview_sample_pass( + RTT& preview_rtt, + std::array& vertices, + DynamicShape& brush_shape, + Texture2D& blend_tex, + bool copy_stroke_destination); + } // namespace pp::panopainter diff --git a/src/main.cpp b/src/main.cpp index 95180537..400d8ce5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,84 +1,10 @@ #include "pch.h" -#include "log.h" -#include "shader.h" -#include "shape.h" -#include "texture.h" -#include "image.h" -#include "app.h" -#include "canvas.h" -#include "platform_windows/windows_bootstrap_helpers.h" -#include "platform_windows/windows_platform_services.h" -#include "platform_windows/windows_lifecycle_shell.h" + #include "platform_windows/windows_runtime_shell.h" -#include "platform_windows/windows_splash.h" -#include "platform_windows/windows_stylus_input.h" -#include "platform_windows/windows_window_shell.h" -#include "platform_windows/windows_vr_shell.h" -#include "../resource.h" -#include "wacom.h" -#include "abr.h" - -using pp::platform::windows::retained_state; int main(int argc, char** argv) { - auto& state = retained_state(); - state.hInst = GetModuleHandle(NULL); - - App::I = new App(); - App::I->set_platform_services(&pp::platform::windows::platform_services()); - App::I->initLog(); - - pp::platform::windows::init_shcore_API(); - pp::platform::windows::initialize_stylus_input(); - - if (pp::platform::windows::SetProcessDpiAwareness_fn) - pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE); - - pp::platform::windows::ensure_runtime_data_directory(); - - pp::platform::windows::SplashScreen splash(GetModuleHandle(NULL)); - - pp::platform::windows::initialize_retained_input_state(); - - pp::platform::windows::setup_exception_handler(); - - pp::platform::windows::read_WMI_info(); - - App::I->create(); - - auto startup = pp::platform::windows::initialize_main_window_startup_state(); - auto context = pp::platform::windows::OpenGlWindowContext {}; - switch (pp::platform::windows::initialize_main_window_and_gl(startup, state.hWnd, state.hInst, state.window_title, context)) - { - case pp::platform::windows::MainStartupResult::Ok: - break; - case pp::platform::windows::MainStartupResult::GladLoadFailure: - return 0; - case pp::platform::windows::MainStartupResult::MissingCoreContextSupport: - return -1; - } - - //wglSwapIntervalEXT(1); - - bool start_in_vr = false; - if (argc > 1) - { - switch (const_hash(argv[1])) - { - case const_hash("convert"): - App::I->initShaders(); - App::I->cmd_convert(argv[2], argv[3]); - return 0; - case const_hash("-vrmode"): - start_in_vr = true; - break; - default: - break; - } - } - - pp::platform::windows::run_main_window_runtime(startup, start_in_vr, splash); + return pp::platform::windows::run_main_application(argc, argv); } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 5d76cd8e..28efe723 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -28,8 +28,7 @@ void NodeStrokePreview::clone_children(Node* dest) const void NodeStrokePreview::clone_finalize(Node* dest) const { - NodeStrokePreview* n = (NodeStrokePreview*)dest; - n->init_controls(); + pp::panopainter::initialize_legacy_node_stroke_preview_clone(dest); } void NodeStrokePreview::init_controls() @@ -40,21 +39,18 @@ void NodeStrokePreview::init_controls() void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) { - const auto& b = m_brush; const bool mix_ok = pp::panopainter::execute_legacy_node_stroke_preview_mix_pass( - pp::panopainter::LegacyNodeStrokePreviewMixPassExecutionRequest { - .brush = *b, - .preview_size = m_size, - .mixer_rtt = m_rtt_mixer, - .bb_min = bb_min, - .bb_sz = bb_sz, - .linear_sampler = m_sampler_linear, - .background_texture = m_tex_background, - .stroke_texture = m_tex, - .dual_texture = m_tex_dual, - .draw_mix = [this] { - m_plane.draw_fill(); - }, + *m_brush, + m_size, + m_rtt_mixer, + bb_min, + bb_sz, + m_sampler_linear, + m_tex_background, + m_tex, + m_tex_dual, + [this] { + m_plane.draw_fill(); }); assert(mix_ok); } @@ -64,97 +60,26 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples( Texture2D& blend_tex, bool copy_stroke_destination) { - const glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() }; return pp::panopainter::execute_legacy_node_stroke_preview_sample_pass( - pp::panopainter::LegacyNodeStrokePreviewSamplePassRequest { - .target_size = size, - .vertices = P, - .brush_shape = m_brush_shape, - .copy_stroke_destination = copy_stroke_destination, - .bind_destination_texture = [&] { - pp::panopainter::bind_legacy_node_stroke_preview_destination_texture(blend_tex); - }, - .copy_framebuffer_to_destination_texture = []( - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) { - pp::panopainter::copy_legacy_node_stroke_preview_destination_texture_region( - src_x, - src_y, - dst_x, - dst_y, - width, - height); - }, - .unbind_destination_texture = [&] { - pp::panopainter::unbind_legacy_node_stroke_preview_destination_texture(blend_tex); - }, - }); + m_rtt, + P, + m_brush_shape, + blend_tex, + copy_stroke_destination); } std::vector NodeStrokePreview::stroke_draw_compute(const Stroke& stroke, float zoom) const { return pp::panopainter::plan_legacy_node_stroke_preview_stroke_frames( - pp::panopainter::LegacyNodeStrokePreviewStrokeComputeRequest { - .stroke = stroke, - .zoom = zoom, - .mixer_size = glm::vec2(m_rtt.getWidth(), m_rtt.getHeight()), - }); + stroke, + zoom, + glm::vec2(m_rtt.getWidth(), m_rtt.getHeight())); } void NodeStrokePreview::draw_stroke_immediate() { if (m_size.x == 0 || m_size.y == 0) return; - const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw( - pp::panopainter::LegacyNodeStrokePreviewImmediateDrawRequest { - .brush = m_brush, - .preview_size = m_size, - .zoom = root()->m_zoom, - .min_flow = m_min_flow, - .stroke_max_size_override = m_max_size, - .pad_override = m_pad_override, - .camera_fov = Canvas::I->m_cam_fov, - .camera_rot = Canvas::I->m_cam_rot, - .render_device_features = pp::panopainter::stroke_preview_render_device_features(), - .preview_rtt = m_rtt, - .preview_rtt_mixer = m_rtt_mixer, - .preview_stroke_texture = m_tex, - .preview_dual_texture = m_tex_dual, - .preview_background_texture = m_tex_background, - .preview_image_texture = m_tex_preview, - .linear_sampler = m_sampler_linear, - .repeat_sampler = m_sampler_linear_repeat, - .prepare_render_target = [&] { - pp::panopainter::apply_legacy_node_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); - m_rtt.bindFramebuffer(); - m_rtt.clear(); - pp::panopainter::bind_legacy_node_stroke_preview_live_samplers( - m_sampler_mipmap, - m_sampler_linear, - m_sampler_linear_repeat); - }, - .finish_render_target = [&] { - m_rtt.unbindFramebuffer(); - }, - .compute_frames = [&](const Stroke& stroke, float frame_zoom) { - return stroke_draw_compute(stroke, frame_zoom); - }, - .draw_samples = [&](std::array& shapes, Texture2D& texture, bool copy_stroke_destination) { - return stroke_draw_samples(shapes, texture, copy_stroke_destination); - }, - .draw_mix = [&](const glm::vec2& bb_min, const glm::vec2& bb_sz) { - stroke_draw_mix(bb_min, bb_sz); - }, - .draw_checkerboard = [&] { - m_plane.draw_fill(); - }, - .draw_composite = [&] { - m_plane.draw_fill(); - }, - }); + const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(*this); assert(sequence_ok); } diff --git a/src/node_stroke_preview.h b/src/node_stroke_preview.h index ba90f429..1977693f 100644 --- a/src/node_stroke_preview.h +++ b/src/node_stroke_preview.h @@ -7,11 +7,14 @@ #include "texture.h" #include "legacy_node_stroke_preview_draw_services.h" #include "legacy_node_stroke_preview_execution_services.h" +#include "legacy_node_stroke_preview_runtime_services.h" class NodeStrokePreview : public NodeBorder { using StrokeFrame = pp::panopainter::LegacyNodeStrokePreviewFrame; + friend bool pp::panopainter::execute_legacy_node_stroke_preview_immediate_draw(NodeStrokePreview& preview); + static RTT m_rtt; static RTT m_rtt_mixer; static Texture2D m_tex; // blending tmp texture diff --git a/src/platform_legacy/legacy_platform_services.cpp b/src/platform_legacy/legacy_platform_services.cpp index 2ab700f4..559caf04 100644 --- a/src/platform_legacy/legacy_platform_services.cpp +++ b/src/platform_legacy/legacy_platform_services.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "platform_legacy/legacy_platform_services.h" +#include "platform_legacy/legacy_platform_state.h" #include "app.h" #include "legacy_ui_gl_dispatch.h" @@ -131,25 +132,6 @@ struct RetainedLegacyGlfwWindowState final { } #endif -struct RetainedLegacyStoragePaths final { - pp::platform::PlatformStoragePaths storage_paths; -}; - -[[nodiscard]] RetainedLegacyStoragePaths& active_legacy_storage_paths() -{ - static RetainedLegacyStoragePaths state = [] { - RetainedLegacyStoragePaths retained; - retained.storage_paths = { - App::I->data_path, - App::I->work_path, - App::I->rec_path, - App::I->tmp_path, - }; - return retained; - }(); - return state; -} - #if defined(__IOS__) || defined(__OSX__) [[nodiscard]] NSMutableArray* apple_file_types_array(const std::vector& file_types) { @@ -169,7 +151,6 @@ struct RetainedLegacyAppleState final { decltype(App::I->osx_view) osx_view = nullptr; decltype(App::I->osx_app) osx_app = nullptr; #endif - pp::platform::PlatformStoragePaths storage_paths; }; [[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state() @@ -179,21 +160,9 @@ struct RetainedLegacyAppleState final { #ifdef __IOS__ retained.ios_view = App::I->ios_view; retained.ios_app = App::I->ios_app; - retained.storage_paths = { - App::I->data_path, - App::I->work_path, - App::I->rec_path, - App::I->tmp_path, - }; #elif defined(__OSX__) retained.osx_view = App::I->osx_view; retained.osx_app = App::I->osx_app; - retained.storage_paths = { - App::I->data_path, - App::I->work_path, - App::I->rec_path, - App::I->tmp_path, - }; #endif return retained; }(); @@ -208,7 +177,7 @@ struct RetainedLegacyAppleState final { #elif defined(__OSX__) [apple_state.osx_app init_dirs]; #endif - return apple_state.storage_paths; + return active_legacy_storage_paths(); } [[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& active_apple_document_platform_services() @@ -406,7 +375,7 @@ public: {}, }; #else - return active_legacy_storage_paths().storage_paths; + return pp::platform::legacy::active_legacy_storage_paths(); #endif } diff --git a/src/platform_legacy/legacy_platform_state.cpp b/src/platform_legacy/legacy_platform_state.cpp new file mode 100644 index 00000000..6a62d66b --- /dev/null +++ b/src/platform_legacy/legacy_platform_state.cpp @@ -0,0 +1,30 @@ +#include "pch.h" +#include "platform_legacy/legacy_platform_state.h" + +#include "app.h" + +namespace pp::platform::legacy { +namespace { + +struct RetainedLegacyStoragePaths final { + pp::platform::PlatformStoragePaths storage_paths; +}; + +} + +[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths() +{ + static RetainedLegacyStoragePaths state = [] { + RetainedLegacyStoragePaths retained; + retained.storage_paths = { + App::I->data_path, + App::I->work_path, + App::I->rec_path, + App::I->tmp_path, + }; + return retained; + }(); + return state.storage_paths; +} + +} diff --git a/src/platform_legacy/legacy_platform_state.h b/src/platform_legacy/legacy_platform_state.h new file mode 100644 index 00000000..5cc7fa6a --- /dev/null +++ b/src/platform_legacy/legacy_platform_state.h @@ -0,0 +1,9 @@ +#pragma once + +#include "platform_api/platform_services.h" + +namespace pp::platform::legacy { + +[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths(); + +} diff --git a/src/platform_windows/windows_runtime_shell.cpp b/src/platform_windows/windows_runtime_shell.cpp index a7330ba5..fae8e0e3 100644 --- a/src/platform_windows/windows_runtime_shell.cpp +++ b/src/platform_windows/windows_runtime_shell.cpp @@ -7,6 +7,7 @@ #include "platform_windows/windows_bootstrap_helpers.h" #include "platform_windows/windows_lifecycle_shell.h" #include "platform_windows/windows_platform_services.h" +#include "platform_windows/windows_stylus_input.h" #include "platform_windows/windows_window_shell.h" #include "wacom.h" #include "../resource.h" @@ -101,6 +102,68 @@ void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTAN } +int run_main_application(int argc, char** argv) +{ + auto& state = retained_state(); + state.hInst = GetModuleHandle(NULL); + + App::I = new App(); + App::I->set_platform_services(&pp::platform::windows::platform_services()); + App::I->initLog(); + + pp::platform::windows::init_shcore_API(); + pp::platform::windows::initialize_stylus_input(); + + if (pp::platform::windows::SetProcessDpiAwareness_fn) + pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE); + + pp::platform::windows::ensure_runtime_data_directory(); + + pp::platform::windows::SplashScreen splash(state.hInst); + + pp::platform::windows::initialize_retained_input_state(); + + pp::platform::windows::setup_exception_handler(); + + pp::platform::windows::read_WMI_info(); + + App::I->create(); + + auto startup = pp::platform::windows::initialize_main_window_startup_state(); + auto context = pp::platform::windows::OpenGlWindowContext {}; + switch (pp::platform::windows::initialize_main_window_and_gl(startup, state.hWnd, state.hInst, state.window_title, context)) + { + case pp::platform::windows::MainStartupResult::Ok: + break; + case pp::platform::windows::MainStartupResult::GladLoadFailure: + return 0; + case pp::platform::windows::MainStartupResult::MissingCoreContextSupport: + return -1; + } + + //wglSwapIntervalEXT(1); + + bool start_in_vr = false; + if (argc > 1) + { + switch (const_hash(argv[1])) + { + case const_hash("convert"): + App::I->initShaders(); + App::I->cmd_convert(argv[2], argv[3]); + return 0; + case const_hash("-vrmode"): + start_in_vr = true; + break; + default: + break; + } + } + + pp::platform::windows::run_main_window_runtime(startup, start_in_vr, splash); + return 0; +} + void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash) { auto& state = retained_state(); diff --git a/src/platform_windows/windows_runtime_shell.h b/src/platform_windows/windows_runtime_shell.h index f3e1d2ce..e2dbf5f8 100644 --- a/src/platform_windows/windows_runtime_shell.h +++ b/src/platform_windows/windows_runtime_shell.h @@ -5,6 +5,7 @@ namespace pp::platform::windows { +int run_main_application(int argc, char** argv); void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash); }