Render captured canvas snapshots through renderer boundary
This commit is contained in:
@@ -268,7 +268,11 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
|
||||
plus the save-readiness report now consumed before retained live saves. For
|
||||
payload-complete or metadata-only snapshots, the same app-core boundary now
|
||||
exports through the pure `pp_document` PPI writer and reports generated byte
|
||||
counts plus decoded dirty-face counts in `ppiExport` JSON. It is covered by
|
||||
counts plus decoded dirty-face counts in `ppiExport` JSON. Payload-complete
|
||||
snapshots also feed the active frame through the `pp_paint_renderer`
|
||||
document-frame compositor and renderer-neutral recording upload path,
|
||||
reporting texture, transition, command, byte, and active-frame payload counts
|
||||
in `rendererUpload` JSON. It is covered by
|
||||
`pano_cli_plan_canvas_document_snapshot_smoke` plus the payload-bearing
|
||||
snapshot smoke.
|
||||
- `pano_cli save-document-project` writes that pure document export to a PPI
|
||||
|
||||
@@ -11,7 +11,7 @@ and validation command.
|
||||
|
||||
| Capability | Current Area | Target Owner | Required Tests |
|
||||
| --- | --- | --- | --- |
|
||||
| PPI open/save | `Canvas`, serializer, dialogs | `pp_document`, `pp_assets`, `pano_cli` | Round-trip tiny project, old-version fixture, corrupt/truncated fixture, live-canvas-to-`pp_document` snapshot projection with captured RGBA8 payloads, pending renderer-readback counts, save-readiness reporting before retained live saves, and pure PPI export from payload-complete snapshots |
|
||||
| PPI open/save | `Canvas`, serializer, dialogs | `pp_document`, `pp_assets`, `pano_cli` | Round-trip tiny project, old-version fixture, corrupt/truncated fixture, live-canvas-to-`pp_document` snapshot projection with captured RGBA8 payloads, pending renderer-readback counts, save-readiness reporting before retained live saves, pure PPI export from payload-complete snapshots, and renderer-neutral active-frame upload from the same snapshot |
|
||||
| Open-document routing | `App::open_document` | `pp_app_core`, `pano_cli`, `pp_panopainter_ui`, `pp_document`, `pp_assets` | Project/ABR/PPBR route tests, malformed path tests, open-action plan tests, CLI route/action smoke, app open smoke |
|
||||
| Document session decisions | `App::open_document`, `App::request_close`, save hotkeys, file menu, dialogs | `pp_app_core`, `pano_cli`, `pp_panopainter_ui` | Clean/dirty/prompt-open/save/save-as/save-version/save-before-workflow/name/new-document resolution/overwrite/version-target decision tests, CLI session, new-document, document-file, and document-version smoke, app close/open/save/new/browse smoke |
|
||||
| Version metadata | `scripts/pre-build.py`, `version.*` | build system, `pp_foundation` | Generated header smoke test, missing-tag behavior |
|
||||
@@ -26,7 +26,7 @@ and validation command.
|
||||
| PNG/JPEG import | `Image`, `Canvas` import paths | `pp_assets`, `pp_document` | Fixture import, malformed file |
|
||||
| PNG/JPEG export | `Canvas`, `Image`, export dialogs | `pp_assets`, `pp_paint_renderer`, `pp_app_core` | Golden output tolerance, export start/target planning tests |
|
||||
| Equirectangular import/export | `Canvas`, shaders, RTT, export dialogs | `pp_paint_renderer`, `pp_app_core` | Tiny cube/equirect golden, app-core file target tests |
|
||||
| Cube face export | `Canvas` | `pp_paint_renderer` | Pure six-face document frame composite, renderer texture-upload bridge, OpenGL command-plan coverage, six-face golden set |
|
||||
| Cube face export | `Canvas` | `pp_paint_renderer` | Pure six-face document frame composite, renderer texture-upload bridge, payload-complete canvas-snapshot renderer-upload automation, OpenGL command-plan coverage, six-face golden set |
|
||||
| Depth export | `Canvas`, grid tools | `pp_paint_renderer` | Float/readback validation |
|
||||
|
||||
## Brush And Painting
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -674,7 +674,10 @@ prepare and log a payload-completeness report from that snapshot before
|
||||
delegating to retained `Canvas::project_save`; the app-core snapshot boundary
|
||||
also has a tested pure PPI export helper, and
|
||||
`pano_cli plan-canvas-document-snapshot` runs that helper for payload-complete
|
||||
snapshots and reports generated byte/dirty-face summaries. Live save writer
|
||||
snapshots and reports generated byte/dirty-face summaries. The same automation
|
||||
now feeds payload-complete snapshots through the `pp_paint_renderer`
|
||||
document-frame compositor and renderer-neutral recording upload path, reporting
|
||||
texture, transition, byte, payload, and command counts. Live save writer
|
||||
replacement, export adoption, and renderer-owned readback remain under
|
||||
`DEBT-0010`/`DEBT-0013`/`DEBT-0036`.
|
||||
`pano_cli plan-image-import` exposes app-core planning for File > Import image
|
||||
@@ -2219,6 +2222,10 @@ Results:
|
||||
report (`payloadComplete` and `canExportPpi`) used by the live save bridge,
|
||||
and payload-complete snapshots now run the pure `pp_document` PPI exporter
|
||||
and decoded-project summary before emitting `ppiExport` JSON.
|
||||
- The same payload-complete snapshot automation now uploads the active document
|
||||
frame through `pp_paint_renderer::upload_document_frame_faces` and the
|
||||
`RecordingRenderDevice`, emitting `rendererUpload` JSON with texture,
|
||||
transition, command, byte, and active-frame payload counts.
|
||||
- `pp_app_core_document_import_tests` passed, covering wide equirectangular,
|
||||
legacy vertical cube strip, regular transform-placement, and invalid-dimension
|
||||
import route decisions, equirectangular service dispatch, transform import
|
||||
@@ -2497,6 +2504,11 @@ Results:
|
||||
document-canvas tests decode the generated bytes, and
|
||||
`pano_cli plan-canvas-document-snapshot` reports `ppiExport` readiness,
|
||||
byte count, and dirty-face count for agent automation.
|
||||
- Payload-complete canvas snapshot automation also crosses the renderer
|
||||
boundary now: `pano_cli plan-canvas-document-snapshot` records the same
|
||||
snapshot through the pure document-frame compositor and renderer-neutral
|
||||
texture upload stream, so agents can validate document/canvas payloads moving
|
||||
into renderer commands before live canvas export/save writer replacement.
|
||||
- Snapshot creation now rejects invalid embedded RGBA8 face payloads before
|
||||
document export or history can persist malformed state.
|
||||
- Package-smoke wrappers validate the Windows CMake app executable/runtime
|
||||
|
||||
@@ -1474,13 +1474,13 @@ if(TARGET pano_cli)
|
||||
COMMAND pano_cli plan-canvas-document-snapshot --width 128 --height 64 --layers 3 --frames 2 --current-layer 2 --current-frame 1 --hidden-layer 0 --alpha-locked-layer 2 --opacity 0.5 --blend-mode 4 --pending-face-payloads-per-layer 6)
|
||||
set_tests_properties(pano_cli_plan_canvas_document_snapshot_smoke PROPERTIES
|
||||
LABELS "app;document;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"width\":128.*\"height\":64.*\"layers\":3.*\"frames\":2.*\"activeLayer\":2.*\"activeFrame\":1.*\"activeLayerName\":\"Layer 3\".*\"activeLayerOpacity\":0.5.*\"activeLayerBlend\":\"overlay\".*\"activeLayerAlphaLocked\":true.*\"pendingFacePayloads\":18.*\"metadataOnly\":true.*\"requiresRendererPayloadReadback\":true.*\"documentFacePayloads\":0.*\"saveReport\":\\{\"payloadComplete\":false,\"canExportPpi\":false\\}.*\"ppiExport\":\\{\"ready\":false,\"bytes\":0,\"dirtyFaces\":0\\}")
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"width\":128.*\"height\":64.*\"layers\":3.*\"frames\":2.*\"activeLayer\":2.*\"activeFrame\":1.*\"activeLayerName\":\"Layer 3\".*\"activeLayerOpacity\":0.5.*\"activeLayerBlend\":\"overlay\".*\"activeLayerAlphaLocked\":true.*\"pendingFacePayloads\":18.*\"metadataOnly\":true.*\"requiresRendererPayloadReadback\":true.*\"documentFacePayloads\":0.*\"saveReport\":\\{\"payloadComplete\":false,\"canExportPpi\":false\\}.*\"ppiExport\":\\{\"ready\":false,\"bytes\":0,\"dirtyFaces\":0\\}.*\"rendererUpload\":\\{\"ready\":false,\"textures\":0,\"bytes\":0,\"transitions\":0,\"facePayloads\":0,\"compositedLayerFaces\":0,\"commands\":0,\"uploadCommands\":0,\"transitionCommands\":0\\}")
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_document_snapshot_payload_smoke
|
||||
COMMAND pano_cli plan-canvas-document-snapshot --width 128 --height 64 --layers 2 --frames 2 --current-layer 1 --current-frame 1 --pending-face-payloads-per-layer 2 --captured-face-payloads-per-layer 2)
|
||||
set_tests_properties(pano_cli_plan_canvas_document_snapshot_payload_smoke PROPERTIES
|
||||
LABELS "app;document;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"layers\":2.*\"frames\":2.*\"activeLayer\":1.*\"activeFrame\":1.*\"pendingFacePayloads\":4.*\"capturedFacePayloads\":4.*\"metadataOnly\":false.*\"requiresRendererPayloadReadback\":false.*\"documentFacePayloads\":4.*\"saveReport\":\\{\"payloadComplete\":true,\"canExportPpi\":true\\}.*\"ppiExport\":\\{\"ready\":true,\"bytes\":[1-9][0-9]*,\"dirtyFaces\":4\\}")
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-canvas-document-snapshot\".*\"layers\":2.*\"frames\":2.*\"activeLayer\":1.*\"activeFrame\":1.*\"pendingFacePayloads\":4.*\"capturedFacePayloads\":4.*\"metadataOnly\":false.*\"requiresRendererPayloadReadback\":false.*\"documentFacePayloads\":4.*\"saveReport\":\\{\"payloadComplete\":true,\"canExportPpi\":true\\}.*\"ppiExport\":\\{\"ready\":true,\"bytes\":[1-9][0-9]*,\"dirtyFaces\":4\\}.*\"rendererUpload\":\\{\"ready\":true,\"textures\":6,\"bytes\":[1-9][0-9]*,\"transitions\":6,\"facePayloads\":2,\"compositedLayerFaces\":2,\"commands\":12,\"uploadCommands\":6,\"transitionCommands\":6\\}")
|
||||
|
||||
add_test(NAME pano_cli_plan_canvas_document_snapshot_no_canvas
|
||||
COMMAND pano_cli plan-canvas-document-snapshot --no-canvas)
|
||||
|
||||
@@ -5998,6 +5998,15 @@ int plan_canvas_document_snapshot(int argc, char** argv)
|
||||
bool ppi_export_ready = false;
|
||||
std::size_t ppi_export_bytes = 0;
|
||||
std::uint32_t ppi_export_dirty_faces = 0;
|
||||
bool renderer_upload_ready = false;
|
||||
std::size_t renderer_texture_count = 0;
|
||||
std::size_t renderer_transition_count = 0;
|
||||
std::uint64_t renderer_uploaded_bytes = 0;
|
||||
std::size_t renderer_face_payloads = 0;
|
||||
std::size_t renderer_composited_layer_faces = 0;
|
||||
std::size_t renderer_command_count = 0;
|
||||
std::size_t renderer_upload_command_count = 0;
|
||||
std::size_t renderer_transition_command_count = 0;
|
||||
if (save_report.can_export_ppi) {
|
||||
const auto exported = pp::app::export_document_canvas_save_snapshot_to_ppi(value);
|
||||
if (!exported) {
|
||||
@@ -6014,6 +6023,37 @@ int plan_canvas_document_snapshot(int argc, char** argv)
|
||||
ppi_export_ready = true;
|
||||
ppi_export_bytes = exported.value().bytes.size();
|
||||
ppi_export_dirty_faces = decoded.value().project.body.summary.dirty_face_count;
|
||||
|
||||
constexpr pp::paint::Rgba clear_color {};
|
||||
pp::renderer::RecordingRenderDevice render_device;
|
||||
const auto uploaded = pp::paint_renderer::upload_document_frame_faces(
|
||||
render_device,
|
||||
pp::paint_renderer::DocumentFrameUploadRequest {
|
||||
.document = &document,
|
||||
.frame_index = document.active_frame_index(),
|
||||
.clear_color = clear_color,
|
||||
});
|
||||
if (!uploaded) {
|
||||
print_error("plan-canvas-document-snapshot", uploaded.status().message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
renderer_upload_ready = true;
|
||||
renderer_texture_count = uploaded.value().texture_count;
|
||||
renderer_transition_count = uploaded.value().transition_count;
|
||||
renderer_uploaded_bytes = uploaded.value().uploaded_bytes;
|
||||
renderer_face_payloads = uploaded.value().composite.face_payload_count;
|
||||
renderer_composited_layer_faces = uploaded.value().composite.composited_layer_face_count;
|
||||
const auto commands = render_device.commands();
|
||||
renderer_command_count = commands.size();
|
||||
for (const auto& command : commands) {
|
||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::upload_texture) {
|
||||
++renderer_upload_command_count;
|
||||
}
|
||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::transition_texture) {
|
||||
++renderer_transition_command_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "{\"ok\":true,\"command\":\"plan-canvas-document-snapshot\""
|
||||
@@ -6045,6 +6085,15 @@ int plan_canvas_document_snapshot(int argc, char** argv)
|
||||
<< "},\"ppiExport\":{\"ready\":" << json_bool(ppi_export_ready)
|
||||
<< ",\"bytes\":" << ppi_export_bytes
|
||||
<< ",\"dirtyFaces\":" << ppi_export_dirty_faces
|
||||
<< "},\"rendererUpload\":{\"ready\":" << json_bool(renderer_upload_ready)
|
||||
<< ",\"textures\":" << renderer_texture_count
|
||||
<< ",\"bytes\":" << renderer_uploaded_bytes
|
||||
<< ",\"transitions\":" << renderer_transition_count
|
||||
<< ",\"facePayloads\":" << renderer_face_payloads
|
||||
<< ",\"compositedLayerFaces\":" << renderer_composited_layer_faces
|
||||
<< ",\"commands\":" << renderer_command_count
|
||||
<< ",\"uploadCommands\":" << renderer_upload_command_count
|
||||
<< ",\"transitionCommands\":" << renderer_transition_command_count
|
||||
<< "}"
|
||||
<< "}}\n";
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user