Export document frame faces as PNGs
This commit is contained in:
@@ -67,6 +67,25 @@ pp::foundation::Status prepare_legacy_document_export_snapshot(App& app, const c
|
||||
recorded_upload.value().command_count,
|
||||
recorded_upload.value().upload_command_count,
|
||||
recorded_upload.value().transition_command_count);
|
||||
|
||||
const auto face_pngs = pp::paint_renderer::export_document_frame_face_pngs(
|
||||
pp::paint_renderer::DocumentFrameCompositeRequest {
|
||||
.document = &snapshot.value().document,
|
||||
.frame_index = snapshot.value().document.active_frame_index(),
|
||||
.clear_color = {},
|
||||
});
|
||||
if (!face_pngs) {
|
||||
LOG("%s document export face PNG export failed: %s", context, face_pngs.status().message);
|
||||
return face_pngs.status();
|
||||
}
|
||||
|
||||
LOG(
|
||||
"%s document export face PNG export: faces=%zu bytes=%llu facePayloads=%zu compositedLayerFaces=%zu",
|
||||
context,
|
||||
face_pngs.value().face_count,
|
||||
static_cast<unsigned long long>(face_pngs.value().encoded_bytes),
|
||||
face_pngs.value().composite.face_payload_count,
|
||||
face_pngs.value().composite.composited_layer_face_count);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "paint_renderer/compositor.h"
|
||||
|
||||
#include "assets/image_pixels.h"
|
||||
#include "renderer_api/recording_renderer.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -211,6 +212,18 @@ void mark_shader_blend_fallback(
|
||||
}
|
||||
}
|
||||
|
||||
void append_rgba8_bytes(std::vector<std::uint8_t>& bytes, std::span<const pp::paint::Rgba> pixels)
|
||||
{
|
||||
bytes.clear();
|
||||
bytes.reserve(pixels.size() * pp::document::rgba8_components);
|
||||
for (const auto& pixel : pixels) {
|
||||
bytes.push_back(static_cast<std::uint8_t>(rgba8_channel(pixel.r)));
|
||||
bytes.push_back(static_cast<std::uint8_t>(rgba8_channel(pixel.g)));
|
||||
bytes.push_back(static_cast<std::uint8_t>(rgba8_channel(pixel.b)));
|
||||
bytes.push_back(static_cast<std::uint8_t>(rgba8_channel(pixel.a)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pp::foundation::Status composite_layer(
|
||||
@@ -439,6 +452,35 @@ pp::foundation::Result<RecordedDocumentFrameUploadResult> record_document_frame_
|
||||
return pp::foundation::Result<RecordedDocumentFrameUploadResult>::success(std::move(result));
|
||||
}
|
||||
|
||||
pp::foundation::Result<DocumentFrameFacePngExportResult> export_document_frame_face_pngs(
|
||||
DocumentFrameCompositeRequest request)
|
||||
{
|
||||
auto composite = composite_document_frame(request);
|
||||
if (!composite) {
|
||||
return pp::foundation::Result<DocumentFrameFacePngExportResult>::failure(composite.status());
|
||||
}
|
||||
|
||||
DocumentFrameFacePngExportResult result;
|
||||
result.composite = std::move(composite.value());
|
||||
std::vector<std::uint8_t> rgba8;
|
||||
for (std::size_t face_index = 0; face_index < result.composite.faces.size(); ++face_index) {
|
||||
append_rgba8_bytes(rgba8, result.composite.faces[face_index].pixels);
|
||||
auto encoded = pp::assets::encode_png_rgba8(
|
||||
result.composite.extent.width,
|
||||
result.composite.extent.height,
|
||||
rgba8);
|
||||
if (!encoded) {
|
||||
return pp::foundation::Result<DocumentFrameFacePngExportResult>::failure(encoded.status());
|
||||
}
|
||||
|
||||
result.encoded_bytes += static_cast<std::uint64_t>(encoded.value().size());
|
||||
result.face_pngs[face_index] = std::move(encoded.value());
|
||||
++result.face_count;
|
||||
}
|
||||
|
||||
return pp::foundation::Result<DocumentFrameFacePngExportResult>::success(std::move(result));
|
||||
}
|
||||
|
||||
bool stroke_composite_requires_feedback(
|
||||
pp::paint::BlendMode layer_blend_mode,
|
||||
pp::paint::StrokeBlendMode stroke_blend_mode,
|
||||
|
||||
@@ -139,6 +139,13 @@ struct RecordedDocumentFrameUploadResult {
|
||||
std::size_t transition_command_count = 0;
|
||||
};
|
||||
|
||||
struct DocumentFrameFacePngExportResult {
|
||||
DocumentFrameCompositeResult composite {};
|
||||
std::array<std::vector<std::byte>, pp::document::cube_face_count> face_pngs {};
|
||||
std::size_t face_count = 0;
|
||||
std::uint64_t encoded_bytes = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] pp::foundation::Status composite_layer(
|
||||
std::span<pp::paint::Rgba> destination,
|
||||
pp::renderer::Extent2D extent,
|
||||
@@ -157,6 +164,9 @@ struct RecordedDocumentFrameUploadResult {
|
||||
[[nodiscard]] pp::foundation::Result<RecordedDocumentFrameUploadResult> record_document_frame_upload(
|
||||
DocumentFrameUploadRequest request);
|
||||
|
||||
[[nodiscard]] pp::foundation::Result<DocumentFrameFacePngExportResult> export_document_frame_face_pngs(
|
||||
DocumentFrameCompositeRequest request);
|
||||
|
||||
[[nodiscard]] bool stroke_composite_requires_feedback(
|
||||
pp::paint::BlendMode layer_blend_mode,
|
||||
pp::paint::StrokeBlendMode stroke_blend_mode,
|
||||
|
||||
Reference in New Issue
Block a user