Thin Windows entry, preview shell, and platform legacy state
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<void()> 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 &&
|
||||
|
||||
@@ -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<void()> draw_mix);
|
||||
|
||||
[[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes(
|
||||
const LegacyNodeStrokePreviewLiveRenderRequest& request);
|
||||
|
||||
|
||||
@@ -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<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<LegacyNodeStrokePreviewFrame> 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<NodeStrokePreview*>(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<vertex_t, 4>& 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 };
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
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<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
|
||||
const LegacyNodeStrokePreviewStrokeComputeRequest& request);
|
||||
|
||||
[[nodiscard]] std::vector<LegacyNodeStrokePreviewFrame> plan_legacy_node_stroke_preview_stroke_frames(
|
||||
const Stroke& stroke,
|
||||
float zoom,
|
||||
glm::vec2 mixer_size);
|
||||
|
||||
struct LegacyNodeStrokePreviewImmediateRuntimeRequest {
|
||||
const std::shared_ptr<Brush>& 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
|
||||
|
||||
@@ -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<vertex_t, 4>& vertices,
|
||||
DynamicShape& brush_shape,
|
||||
Texture2D& blend_tex,
|
||||
bool copy_stroke_destination)
|
||||
{
|
||||
return execute_legacy_node_stroke_preview_sample_pass(
|
||||
LegacyNodeStrokePreviewSamplePassRequest {
|
||||
.target_size = { static_cast<float>(preview_rtt.getWidth()), static_cast<float>(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
|
||||
|
||||
@@ -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<vertex_t, 4>& vertices,
|
||||
DynamicShape& brush_shape,
|
||||
Texture2D& blend_tex,
|
||||
bool copy_stroke_destination);
|
||||
|
||||
} // namespace pp::panopainter
|
||||
|
||||
78
src/main.cpp
78
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)
|
||||
|
||||
@@ -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::StrokeFrame> 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<vertex_t, 4>& 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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<NSString*>* apple_file_types_array(const std::vector<std::string>& 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
|
||||
}
|
||||
|
||||
|
||||
30
src/platform_legacy/legacy_platform_state.cpp
Normal file
30
src/platform_legacy/legacy_platform_state.cpp
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
9
src/platform_legacy/legacy_platform_state.h
Normal file
9
src/platform_legacy/legacy_platform_state.h
Normal file
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user