Attach captured canvas payloads to document snapshots

This commit is contained in:
2026-06-05 18:03:33 +02:00
parent d0412e3bf9
commit f4f6eb903e
10 changed files with 298 additions and 23 deletions

View File

@@ -415,6 +415,7 @@ struct PlanCanvasDocumentSnapshotArgs {
float opacity = 0.75F;
int blend_mode = 4;
std::uint32_t pending_face_payloads_per_layer = pp::document::cube_face_count;
std::uint32_t captured_face_payloads_per_layer = 0;
};
struct PlanImageImportArgs {
@@ -2407,7 +2408,7 @@ void print_help()
<< " plan-tools-panel --panel presets|color|color-advanced|layers|brush|grids|animation [--already-visible]\n"
<< " plan-about-menu --command help|about|news|crash|performance [--version-major N] [--version-minor N] [--version-fix N] [--no-diagnostics] [--no-canvas]\n"
<< " plan-canvas-clear [--no-canvas] [--r N] [--g N] [--b N] [--a N]\n"
<< " plan-canvas-document-snapshot [--no-canvas] [--width N] [--height N] [--layers N] [--frames N] [--frame-duration-ms N] [--current-layer N] [--current-frame N] [--hidden-layer N] [--alpha-locked-layer N] [--opacity N] [--blend-mode N] [--pending-face-payloads-per-layer N]\n"
<< " plan-canvas-document-snapshot [--no-canvas] [--width N] [--height N] [--layers N] [--frames N] [--frame-duration-ms N] [--current-layer N] [--current-frame N] [--hidden-layer N] [--alpha-locked-layer N] [--opacity N] [--blend-mode N] [--pending-face-payloads-per-layer N] [--captured-face-payloads-per-layer N]\n"
<< " plan-image-import --width N --height N\n"
<< " plan-document-resize [--current-resolution N] [--selected-resolution-index N]\n"
<< " plan-layer-rename --old-name NAME --new-name NAME\n"
@@ -5867,7 +5868,7 @@ pp::foundation::Status parse_plan_canvas_document_snapshot_args(
} else if (key == "--width" || key == "--height" || key == "--layers" || key == "--frames"
|| key == "--frame-duration-ms" || key == "--current-layer" || key == "--current-frame"
|| key == "--hidden-layer" || key == "--alpha-locked-layer"
|| key == "--pending-face-payloads-per-layer") {
|| key == "--pending-face-payloads-per-layer" || key == "--captured-face-payloads-per-layer") {
if (i + 1 >= argc) {
return pp::foundation::Status::invalid_argument("missing value for option");
}
@@ -5893,8 +5894,10 @@ pp::foundation::Status parse_plan_canvas_document_snapshot_args(
args.hidden_layer = value.value();
} else if (key == "--alpha-locked-layer") {
args.alpha_locked_layer = value.value();
} else {
} else if (key == "--pending-face-payloads-per-layer") {
args.pending_face_payloads_per_layer = value.value();
} else {
args.captured_face_payloads_per_layer = value.value();
}
} else if (key == "--opacity") {
if (i + 1 >= argc) {
@@ -5933,11 +5936,36 @@ int plan_canvas_document_snapshot(int argc, char** argv)
std::vector<std::uint32_t> frame_durations(args.frames, args.frame_duration_ms);
std::vector<std::string> layer_names;
std::vector<std::vector<std::uint8_t>> payload_bytes;
std::vector<std::vector<pp::app::DocumentCanvasFacePayloadInput>> captured_payloads;
std::vector<pp::app::DocumentCanvasLayerSnapshotInput> layers;
layer_names.reserve(args.layers);
payload_bytes.reserve(static_cast<std::size_t>(args.layers) * args.captured_face_payloads_per_layer);
captured_payloads.reserve(args.layers);
layers.reserve(args.layers);
for (std::uint32_t layer_index = 0; layer_index < args.layers; ++layer_index) {
layer_names.push_back("Layer " + std::to_string(layer_index + 1U));
captured_payloads.push_back({});
auto& layer_payloads = captured_payloads.back();
layer_payloads.reserve(args.captured_face_payloads_per_layer);
for (std::uint32_t payload_index = 0; payload_index < args.captured_face_payloads_per_layer; ++payload_index) {
const auto face_index = payload_index % pp::document::cube_face_count;
payload_bytes.push_back(std::vector<std::uint8_t> {
static_cast<std::uint8_t>((layer_index + 1U) & 0xFFU),
static_cast<std::uint8_t>(face_index & 0xFFU),
static_cast<std::uint8_t>((payload_index + 1U) & 0xFFU),
255U,
});
layer_payloads.push_back(pp::app::DocumentCanvasFacePayloadInput {
.frame_index = args.frames == 0U ? 0U : args.current_frame % args.frames,
.face_index = face_index,
.x = args.width == 0U ? 0U : payload_index % args.width,
.y = args.height == 0U ? 0U : payload_index % args.height,
.width = 1U,
.height = 1U,
.rgba8 = std::span<const std::uint8_t>(payload_bytes.back().data(), payload_bytes.back().size()),
});
}
layers.push_back(pp::app::DocumentCanvasLayerSnapshotInput {
.name = layer_names.back(),
.visible = layer_index != args.hidden_layer,
@@ -5946,6 +5974,7 @@ int plan_canvas_document_snapshot(int argc, char** argv)
.blend_mode = layer_index == args.current_layer ? args.blend_mode : 0,
.frame_durations_ms = std::span<const std::uint32_t>(frame_durations),
.pending_face_payloads = args.pending_face_payloads_per_layer,
.captured_face_payloads = std::span<const pp::app::DocumentCanvasFacePayloadInput>(layer_payloads),
});
}
@@ -5984,6 +6013,7 @@ int plan_canvas_document_snapshot(int argc, char** argv)
<< ",\"activeLayerBlend\":\"" << pp::paint::blend_mode_name(active_layer.blend_mode)
<< "\",\"activeLayerAlphaLocked\":" << json_bool(active_layer.alpha_locked)
<< ",\"pendingFacePayloads\":" << value.pending_face_payloads
<< ",\"capturedFacePayloads\":" << value.captured_face_payloads
<< ",\"metadataOnly\":" << json_bool(value.metadata_only)
<< ",\"requiresRendererPayloadReadback\":"
<< json_bool(value.requires_renderer_payload_readback)