Share recorded document upload reporting
This commit is contained in:
@@ -252,7 +252,8 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
|
|||||||
rectangles into full renderer-sized RGBA buffers with layer visibility,
|
rectangles into full renderer-sized RGBA buffers with layer visibility,
|
||||||
opacity, and blend mode applied in document order, then uploading those six
|
opacity, and blend mode applied in document order, then uploading those six
|
||||||
faces through the renderer-neutral `IRenderDevice` texture API using the
|
faces through the renderer-neutral `IRenderDevice` texture API using the
|
||||||
recording backend.
|
recording backend. It also covers the shared recorded-upload report helper
|
||||||
|
consumed by CLI and live export-readiness bridges.
|
||||||
- `pano_cli simulate-document-export` exposes the same pure document-to-PPI
|
- `pano_cli simulate-document-export` exposes the same pure document-to-PPI
|
||||||
export, asset-level decode, and document reimport path through JSON
|
export, asset-level decode, and document reimport path through JSON
|
||||||
automation and is covered by `pano_cli_simulate_document_export_smoke`.
|
automation and is covered by `pano_cli_simulate_document_export_smoke`.
|
||||||
@@ -270,16 +271,16 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
|
|||||||
exports through the pure `pp_document` PPI writer and reports generated byte
|
exports through the pure `pp_document` PPI writer and reports generated byte
|
||||||
counts plus decoded dirty-face counts in `ppiExport` JSON. Payload-complete
|
counts plus decoded dirty-face counts in `ppiExport` JSON. Payload-complete
|
||||||
snapshots also feed the active frame through the `pp_paint_renderer`
|
snapshots also feed the active frame through the `pp_paint_renderer`
|
||||||
document-frame compositor and renderer-neutral recording upload path,
|
document-frame compositor and renderer-neutral recorded-upload report helper,
|
||||||
reporting texture, transition, command, byte, and active-frame payload counts
|
reporting texture, transition, command, byte, and active-frame payload counts
|
||||||
in `rendererUpload` JSON. It is covered by
|
in `rendererUpload` JSON. It is covered by
|
||||||
`pano_cli_plan_canvas_document_snapshot_smoke` plus the payload-bearing
|
`pano_cli_plan_canvas_document_snapshot_smoke` plus the payload-bearing
|
||||||
snapshot smoke.
|
snapshot smoke.
|
||||||
- Live equirectangular, layer, animation-frame, and cube-face export adapters
|
- Live equirectangular, layer, animation-frame, and cube-face export adapters
|
||||||
now prepare and log the same payload-bearing canvas document snapshot plus
|
now prepare and log the same payload-bearing canvas document snapshot plus
|
||||||
renderer-neutral active-frame upload report before delegating to retained
|
shared renderer-neutral active-frame upload report before delegating to
|
||||||
`Canvas` export execution. Depth and video export remain on the older retained
|
retained `Canvas` export execution. Depth and video export remain on the older
|
||||||
path.
|
retained path.
|
||||||
- `pano_cli save-document-project` writes that pure document export to a PPI
|
- `pano_cli save-document-project` writes that pure document export to a PPI
|
||||||
file and is covered by `pano_cli_save_document_project_roundtrip_smoke`,
|
file and is covered by `pano_cli_save_document_project_roundtrip_smoke`,
|
||||||
which inspects and loads the generated file.
|
which inspects and loads the generated file.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -677,13 +677,14 @@ also has a tested pure PPI export helper, and
|
|||||||
snapshots and reports generated byte/dirty-face summaries. The same automation
|
snapshots and reports generated byte/dirty-face summaries. The same automation
|
||||||
now feeds payload-complete snapshots through the `pp_paint_renderer`
|
now feeds payload-complete snapshots through the `pp_paint_renderer`
|
||||||
document-frame compositor and renderer-neutral recording upload path, reporting
|
document-frame compositor and renderer-neutral recording upload path, reporting
|
||||||
texture, transition, byte, payload, and command counts. Live save writer
|
texture, transition, byte, payload, and command counts through the shared
|
||||||
replacement, export adoption, and renderer-owned readback remain under
|
`record_document_frame_upload` report helper. Live save writer replacement,
|
||||||
|
export adoption, and renderer-owned readback remain under
|
||||||
`DEBT-0010`/`DEBT-0013`/`DEBT-0036`.
|
`DEBT-0010`/`DEBT-0013`/`DEBT-0036`.
|
||||||
Live equirectangular, layer, animation-frame, and cube-face export adapters now
|
Live equirectangular, layer, animation-frame, and cube-face export adapters now
|
||||||
prepare the same payload-bearing document snapshot and renderer-neutral upload
|
prepare the same payload-bearing document snapshot and renderer-neutral upload
|
||||||
report before delegating to retained `Canvas` export execution, so export
|
report helper before delegating to retained `Canvas` export execution, so export
|
||||||
workflows consume the boundary without changing file output yet.
|
workflows consume the shared renderer boundary without changing file output yet.
|
||||||
`pano_cli plan-image-import` exposes app-core planning for File > Import image
|
`pano_cli plan-image-import` exposes app-core planning for File > Import image
|
||||||
route decisions, including wide equirectangular images, legacy vertical cube
|
route decisions, including wide equirectangular images, legacy vertical cube
|
||||||
strips, regular transform-placement images, and invalid image dimensions; live
|
strips, regular transform-placement images, and invalid image dimensions; live
|
||||||
@@ -2515,12 +2516,13 @@ Results:
|
|||||||
- Payload-complete canvas snapshot automation also crosses the renderer
|
- Payload-complete canvas snapshot automation also crosses the renderer
|
||||||
boundary now: `pano_cli plan-canvas-document-snapshot` records the same
|
boundary now: `pano_cli plan-canvas-document-snapshot` records the same
|
||||||
snapshot through the pure document-frame compositor and renderer-neutral
|
snapshot through the pure document-frame compositor and renderer-neutral
|
||||||
texture upload stream, so agents can validate document/canvas payloads moving
|
texture upload stream through `pp_paint_renderer::record_document_frame_upload`,
|
||||||
into renderer commands before live canvas export/save writer replacement.
|
so agents can validate document/canvas payloads moving into renderer commands
|
||||||
|
before live canvas export/save writer replacement.
|
||||||
- Live image/collection/cube export adapters now prepare and log the same
|
- Live image/collection/cube export adapters now prepare and log the same
|
||||||
document/canvas plus renderer-upload readiness before retained `Canvas`
|
document/canvas plus shared renderer-upload readiness report before retained
|
||||||
export calls. Depth and video export remain on their prior retained paths;
|
`Canvas` export calls. Depth and video export remain on their prior retained
|
||||||
actual image/cube writer replacement remains tracked under export debt.
|
paths; actual image/cube writer replacement remains tracked under export debt.
|
||||||
- Snapshot creation now rejects invalid embedded RGBA8 face payloads before
|
- Snapshot creation now rejects invalid embedded RGBA8 face payloads before
|
||||||
document export or history can persist malformed state.
|
document export or history can persist malformed state.
|
||||||
- Package-smoke wrappers validate the Windows CMake app executable/runtime
|
- Package-smoke wrappers validate the Windows CMake app executable/runtime
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "legacy_document_canvas_services.h"
|
#include "legacy_document_canvas_services.h"
|
||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
#include "renderer_api/recording_renderer.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -46,41 +45,28 @@ pp::foundation::Status prepare_legacy_document_export_snapshot(App& app, const c
|
|||||||
return pp::foundation::Status::success();
|
return pp::foundation::Status::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
pp::renderer::RecordingRenderDevice render_device;
|
const auto recorded_upload = pp::paint_renderer::record_document_frame_upload(
|
||||||
const auto uploaded = pp::paint_renderer::upload_document_frame_faces(
|
|
||||||
render_device,
|
|
||||||
pp::paint_renderer::DocumentFrameUploadRequest {
|
pp::paint_renderer::DocumentFrameUploadRequest {
|
||||||
.document = &snapshot.value().document,
|
.document = &snapshot.value().document,
|
||||||
.frame_index = snapshot.value().document.active_frame_index(),
|
.frame_index = snapshot.value().document.active_frame_index(),
|
||||||
.clear_color = {},
|
.clear_color = {},
|
||||||
});
|
});
|
||||||
if (!uploaded) {
|
if (!recorded_upload) {
|
||||||
LOG("%s document export renderer upload failed: %s", context, uploaded.status().message);
|
LOG("%s document export renderer upload failed: %s", context, recorded_upload.status().message);
|
||||||
return uploaded.status();
|
return recorded_upload.status();
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t upload_commands = 0;
|
|
||||||
std::size_t transition_commands = 0;
|
|
||||||
const auto commands = render_device.commands();
|
|
||||||
for (const auto& command : commands) {
|
|
||||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::upload_texture) {
|
|
||||||
++upload_commands;
|
|
||||||
}
|
|
||||||
if (command.kind == pp::renderer::RecordedRenderCommandKind::transition_texture) {
|
|
||||||
++transition_commands;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& uploaded = recorded_upload.value().upload;
|
||||||
LOG(
|
LOG(
|
||||||
"%s document export renderer upload: textures=%zu bytes=%llu transitions=%zu facePayloads=%zu commands=%zu uploadCommands=%zu transitionCommands=%zu",
|
"%s document export renderer upload: textures=%zu bytes=%llu transitions=%zu facePayloads=%zu commands=%zu uploadCommands=%zu transitionCommands=%zu",
|
||||||
context,
|
context,
|
||||||
uploaded.value().texture_count,
|
uploaded.texture_count,
|
||||||
static_cast<unsigned long long>(uploaded.value().uploaded_bytes),
|
static_cast<unsigned long long>(uploaded.uploaded_bytes),
|
||||||
uploaded.value().transition_count,
|
uploaded.transition_count,
|
||||||
uploaded.value().composite.face_payload_count,
|
uploaded.composite.face_payload_count,
|
||||||
commands.size(),
|
recorded_upload.value().command_count,
|
||||||
upload_commands,
|
recorded_upload.value().upload_command_count,
|
||||||
transition_commands);
|
recorded_upload.value().transition_command_count);
|
||||||
return pp::foundation::Status::success();
|
return pp::foundation::Status::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
|
|
||||||
|
#include "renderer_api/recording_renderer.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -412,6 +414,31 @@ pp::foundation::Result<DocumentFrameUploadResult> upload_document_frame_faces(
|
|||||||
return pp::foundation::Result<DocumentFrameUploadResult>::success(std::move(result));
|
return pp::foundation::Result<DocumentFrameUploadResult>::success(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pp::foundation::Result<RecordedDocumentFrameUploadResult> record_document_frame_upload(
|
||||||
|
DocumentFrameUploadRequest request)
|
||||||
|
{
|
||||||
|
pp::renderer::RecordingRenderDevice render_device;
|
||||||
|
auto uploaded = upload_document_frame_faces(render_device, request);
|
||||||
|
if (!uploaded) {
|
||||||
|
return pp::foundation::Result<RecordedDocumentFrameUploadResult>::failure(uploaded.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordedDocumentFrameUploadResult result;
|
||||||
|
result.upload = std::move(uploaded.value());
|
||||||
|
const auto commands = render_device.commands();
|
||||||
|
result.command_count = commands.size();
|
||||||
|
for (const auto& command : commands) {
|
||||||
|
if (command.kind == pp::renderer::RecordedRenderCommandKind::upload_texture) {
|
||||||
|
++result.upload_command_count;
|
||||||
|
}
|
||||||
|
if (command.kind == pp::renderer::RecordedRenderCommandKind::transition_texture) {
|
||||||
|
++result.transition_command_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp::foundation::Result<RecordedDocumentFrameUploadResult>::success(std::move(result));
|
||||||
|
}
|
||||||
|
|
||||||
bool stroke_composite_requires_feedback(
|
bool stroke_composite_requires_feedback(
|
||||||
pp::paint::BlendMode layer_blend_mode,
|
pp::paint::BlendMode layer_blend_mode,
|
||||||
pp::paint::StrokeBlendMode stroke_blend_mode,
|
pp::paint::StrokeBlendMode stroke_blend_mode,
|
||||||
|
|||||||
@@ -132,6 +132,13 @@ struct DocumentFrameUploadResult {
|
|||||||
std::uint64_t uploaded_bytes = 0;
|
std::uint64_t uploaded_bytes = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RecordedDocumentFrameUploadResult {
|
||||||
|
DocumentFrameUploadResult upload {};
|
||||||
|
std::size_t command_count = 0;
|
||||||
|
std::size_t upload_command_count = 0;
|
||||||
|
std::size_t transition_command_count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] pp::foundation::Status composite_layer(
|
[[nodiscard]] pp::foundation::Status composite_layer(
|
||||||
std::span<pp::paint::Rgba> destination,
|
std::span<pp::paint::Rgba> destination,
|
||||||
pp::renderer::Extent2D extent,
|
pp::renderer::Extent2D extent,
|
||||||
@@ -147,6 +154,9 @@ struct DocumentFrameUploadResult {
|
|||||||
pp::renderer::IRenderDevice& device,
|
pp::renderer::IRenderDevice& device,
|
||||||
DocumentFrameUploadRequest request);
|
DocumentFrameUploadRequest request);
|
||||||
|
|
||||||
|
[[nodiscard]] pp::foundation::Result<RecordedDocumentFrameUploadResult> record_document_frame_upload(
|
||||||
|
DocumentFrameUploadRequest request);
|
||||||
|
|
||||||
[[nodiscard]] bool stroke_composite_requires_feedback(
|
[[nodiscard]] bool stroke_composite_requires_feedback(
|
||||||
pp::paint::BlendMode layer_blend_mode,
|
pp::paint::BlendMode layer_blend_mode,
|
||||||
pp::paint::StrokeBlendMode stroke_blend_mode,
|
pp::paint::StrokeBlendMode stroke_blend_mode,
|
||||||
|
|||||||
@@ -541,6 +541,62 @@ void uploads_document_frame_faces_to_renderer_api(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, transition_count == pp::document::cube_face_count);
|
PP_EXPECT(h, transition_count == pp::document::cube_face_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void records_document_frame_upload_report(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const AnimationFrame root_frames[] {
|
||||||
|
{ .duration_ms = 100, .face_pixels = {} },
|
||||||
|
};
|
||||||
|
const AnimationFrame layer_frames[] {
|
||||||
|
{
|
||||||
|
.duration_ms = 100,
|
||||||
|
.face_pixels = {
|
||||||
|
LayerFacePixels {
|
||||||
|
.face_index = 1,
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1,
|
||||||
|
.rgba8 = { 0, 0, 255, 255 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const DocumentLayerConfig layers[] {
|
||||||
|
{
|
||||||
|
.name = "Paint",
|
||||||
|
.frames = std::span<const AnimationFrame>(layer_frames, 1),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const auto document = CanvasDocument::create_from_snapshot(DocumentSnapshotConfig {
|
||||||
|
.width = 1,
|
||||||
|
.height = 1,
|
||||||
|
.layers = std::span<const DocumentLayerConfig>(layers, 1),
|
||||||
|
.frames = std::span<const AnimationFrame>(root_frames, 1),
|
||||||
|
.selection_masks = {},
|
||||||
|
});
|
||||||
|
PP_EXPECT(h, document);
|
||||||
|
if (!document) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto report = pp::paint_renderer::record_document_frame_upload(
|
||||||
|
pp::paint_renderer::DocumentFrameUploadRequest {
|
||||||
|
.document = &document.value(),
|
||||||
|
.frame_index = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, report);
|
||||||
|
if (report) {
|
||||||
|
PP_EXPECT(h, report.value().upload.texture_count == pp::document::cube_face_count);
|
||||||
|
PP_EXPECT(h, report.value().upload.transition_count == pp::document::cube_face_count);
|
||||||
|
PP_EXPECT(h, report.value().upload.uploaded_bytes == 24U);
|
||||||
|
PP_EXPECT(h, report.value().upload.composite.face_payload_count == 1U);
|
||||||
|
PP_EXPECT(h, report.value().command_count == 12U);
|
||||||
|
PP_EXPECT(h, report.value().upload_command_count == pp::document::cube_face_count);
|
||||||
|
PP_EXPECT(h, report.value().transition_command_count == pp::document::cube_face_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void document_frame_upload_rejects_invalid_requests(pp::tests::Harness& h)
|
void document_frame_upload_rejects_invalid_requests(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
RecordingRenderDevice device;
|
RecordingRenderDevice device;
|
||||||
@@ -922,6 +978,7 @@ int main()
|
|||||||
harness.run("composites_document_frame_cube_faces", composites_document_frame_cube_faces);
|
harness.run("composites_document_frame_cube_faces", composites_document_frame_cube_faces);
|
||||||
harness.run("document_frame_composite_rejects_invalid_requests", document_frame_composite_rejects_invalid_requests);
|
harness.run("document_frame_composite_rejects_invalid_requests", document_frame_composite_rejects_invalid_requests);
|
||||||
harness.run("uploads_document_frame_faces_to_renderer_api", uploads_document_frame_faces_to_renderer_api);
|
harness.run("uploads_document_frame_faces_to_renderer_api", uploads_document_frame_faces_to_renderer_api);
|
||||||
|
harness.run("records_document_frame_upload_report", records_document_frame_upload_report);
|
||||||
harness.run("document_frame_upload_rejects_invalid_requests", document_frame_upload_rejects_invalid_requests);
|
harness.run("document_frame_upload_rejects_invalid_requests", document_frame_upload_rejects_invalid_requests);
|
||||||
harness.run("detects_feedback_requirements", detects_feedback_requirements);
|
harness.run("detects_feedback_requirements", detects_feedback_requirements);
|
||||||
harness.run("plans_stroke_composite_paths", plans_stroke_composite_paths);
|
harness.run("plans_stroke_composite_paths", plans_stroke_composite_paths);
|
||||||
|
|||||||
@@ -6024,36 +6024,26 @@ int plan_canvas_document_snapshot(int argc, char** argv)
|
|||||||
ppi_export_bytes = exported.value().bytes.size();
|
ppi_export_bytes = exported.value().bytes.size();
|
||||||
ppi_export_dirty_faces = decoded.value().project.body.summary.dirty_face_count;
|
ppi_export_dirty_faces = decoded.value().project.body.summary.dirty_face_count;
|
||||||
|
|
||||||
constexpr pp::paint::Rgba clear_color {};
|
const auto recorded_upload = pp::paint_renderer::record_document_frame_upload(
|
||||||
pp::renderer::RecordingRenderDevice render_device;
|
|
||||||
const auto uploaded = pp::paint_renderer::upload_document_frame_faces(
|
|
||||||
render_device,
|
|
||||||
pp::paint_renderer::DocumentFrameUploadRequest {
|
pp::paint_renderer::DocumentFrameUploadRequest {
|
||||||
.document = &document,
|
.document = &document,
|
||||||
.frame_index = document.active_frame_index(),
|
.frame_index = document.active_frame_index(),
|
||||||
.clear_color = clear_color,
|
.clear_color = {},
|
||||||
});
|
});
|
||||||
if (!uploaded) {
|
if (!recorded_upload) {
|
||||||
print_error("plan-canvas-document-snapshot", uploaded.status().message);
|
print_error("plan-canvas-document-snapshot", recorded_upload.status().message);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_upload_ready = true;
|
renderer_upload_ready = true;
|
||||||
renderer_texture_count = uploaded.value().texture_count;
|
renderer_texture_count = recorded_upload.value().upload.texture_count;
|
||||||
renderer_transition_count = uploaded.value().transition_count;
|
renderer_transition_count = recorded_upload.value().upload.transition_count;
|
||||||
renderer_uploaded_bytes = uploaded.value().uploaded_bytes;
|
renderer_uploaded_bytes = recorded_upload.value().upload.uploaded_bytes;
|
||||||
renderer_face_payloads = uploaded.value().composite.face_payload_count;
|
renderer_face_payloads = recorded_upload.value().upload.composite.face_payload_count;
|
||||||
renderer_composited_layer_faces = uploaded.value().composite.composited_layer_face_count;
|
renderer_composited_layer_faces = recorded_upload.value().upload.composite.composited_layer_face_count;
|
||||||
const auto commands = render_device.commands();
|
renderer_command_count = recorded_upload.value().command_count;
|
||||||
renderer_command_count = commands.size();
|
renderer_upload_command_count = recorded_upload.value().upload_command_count;
|
||||||
for (const auto& command : commands) {
|
renderer_transition_command_count = recorded_upload.value().transition_command_count;
|
||||||
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\""
|
std::cout << "{\"ok\":true,\"command\":\"plan-canvas-document-snapshot\""
|
||||||
|
|||||||
Reference in New Issue
Block a user