292 lines
10 KiB
C++
292 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "document/document.h"
|
|
#include "foundation/result.h"
|
|
#include "paint/blend.h"
|
|
#include "renderer_api/renderer_api.h"
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <span>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace pp::paint_renderer {
|
|
|
|
enum class StrokeCompositePath : std::uint8_t {
|
|
fixed_function_blend,
|
|
framebuffer_fetch,
|
|
ping_pong_textures,
|
|
};
|
|
|
|
struct LayerCompositeView {
|
|
std::span<const pp::paint::Rgba> pixels;
|
|
float opacity = 1.0F;
|
|
bool visible = true;
|
|
pp::paint::BlendMode blend_mode = pp::paint::BlendMode::normal;
|
|
};
|
|
|
|
struct StrokeCompositeRequest {
|
|
pp::renderer::Extent2D extent {};
|
|
pp::renderer::TextureFormat target_format = pp::renderer::TextureFormat::rgba8;
|
|
pp::renderer::TextureUsage target_usage = pp::renderer::TextureUsage::render_target
|
|
| pp::renderer::TextureUsage::sampled
|
|
| pp::renderer::TextureUsage::copy_source
|
|
| pp::renderer::TextureUsage::copy_destination;
|
|
pp::paint::BlendMode layer_blend_mode = pp::paint::BlendMode::normal;
|
|
pp::paint::StrokeBlendMode stroke_blend_mode = pp::paint::StrokeBlendMode::normal;
|
|
bool dual_brush_blend = false;
|
|
bool pattern_blend = false;
|
|
};
|
|
|
|
struct StrokeCompositePlan {
|
|
StrokeCompositePath path = StrokeCompositePath::fixed_function_blend;
|
|
pp::renderer::PaintFeedbackPlan feedback {};
|
|
pp::renderer::TextureDesc target_desc {};
|
|
std::uint64_t target_bytes = 0;
|
|
std::uint64_t auxiliary_bytes = 0;
|
|
std::uint64_t estimated_working_bytes = 0;
|
|
bool complex_blend = false;
|
|
bool reads_destination_color = false;
|
|
bool requires_auxiliary_texture = false;
|
|
bool requires_texture_copy = false;
|
|
bool requires_render_target_blit = false;
|
|
bool requires_explicit_transition = false;
|
|
};
|
|
|
|
struct CanvasBlendGateRequest {
|
|
pp::renderer::Extent2D extent {};
|
|
std::span<const int> layer_blend_modes;
|
|
bool has_stroke_blend_mode = false;
|
|
int stroke_blend_mode = 0;
|
|
bool dual_brush_blend = false;
|
|
bool pattern_blend = false;
|
|
};
|
|
|
|
struct CanvasBlendGatePlan {
|
|
bool shader_blend = false;
|
|
bool complex_blend = false;
|
|
bool compatibility_fallback = false;
|
|
bool stroke_complex = false;
|
|
bool dual_brush_complex = false;
|
|
bool pattern_complex = false;
|
|
int first_complex_layer_index = -1;
|
|
StrokeCompositePath path = StrokeCompositePath::fixed_function_blend;
|
|
bool reads_destination_color = false;
|
|
bool requires_auxiliary_texture = false;
|
|
bool requires_texture_copy = false;
|
|
bool requires_render_target_blit = false;
|
|
};
|
|
|
|
struct CanvasStrokeFeedbackPlan {
|
|
StrokeCompositePath path = StrokeCompositePath::fixed_function_blend;
|
|
bool reads_destination_color = false;
|
|
bool requires_auxiliary_texture = false;
|
|
bool requires_texture_copy = false;
|
|
bool requires_render_target_blit = false;
|
|
bool compatibility_fallback = false;
|
|
};
|
|
|
|
struct DocumentFaceCompositeRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
std::size_t frame_index = 0;
|
|
std::uint32_t face_index = 0;
|
|
pp::paint::Rgba clear_color {};
|
|
};
|
|
|
|
struct DocumentFaceCompositeResult {
|
|
pp::renderer::Extent2D extent {};
|
|
std::vector<pp::paint::Rgba> pixels;
|
|
std::size_t visited_layer_count = 0;
|
|
std::size_t composited_layer_count = 0;
|
|
std::size_t face_payload_count = 0;
|
|
};
|
|
|
|
struct DocumentFrameCompositeRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
std::size_t frame_index = 0;
|
|
pp::paint::Rgba clear_color {};
|
|
};
|
|
|
|
struct DocumentFrameCompositeResult {
|
|
pp::renderer::Extent2D extent {};
|
|
std::array<DocumentFaceCompositeResult, pp::document::cube_face_count> faces {};
|
|
std::size_t visited_layer_count = 0;
|
|
std::size_t composited_layer_face_count = 0;
|
|
std::size_t face_payload_count = 0;
|
|
};
|
|
|
|
struct DocumentFrameUploadRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
std::size_t frame_index = 0;
|
|
pp::paint::Rgba clear_color {};
|
|
bool transition_to_shader_read = true;
|
|
};
|
|
|
|
struct DocumentFrameUploadResult {
|
|
DocumentFrameCompositeResult composite {};
|
|
std::array<std::unique_ptr<pp::renderer::ITexture2D>, pp::document::cube_face_count> face_textures {};
|
|
std::size_t texture_count = 0;
|
|
std::size_t transition_count = 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;
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
struct DocumentFrameEquirectangularPngExportResult {
|
|
pp::renderer::Extent2D face_extent {};
|
|
pp::renderer::Extent2D equirectangular_extent {};
|
|
std::vector<std::byte> png;
|
|
std::uint64_t encoded_bytes = 0;
|
|
std::size_t face_payload_count = 0;
|
|
std::size_t composited_layer_face_count = 0;
|
|
};
|
|
|
|
struct DocumentDepthExportRenderPlanRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
std::size_t frame_index = 0;
|
|
pp::renderer::Extent2D output_extent {
|
|
.width = 1024,
|
|
.height = 1024,
|
|
};
|
|
};
|
|
|
|
struct DocumentDepthExportRenderPlan {
|
|
pp::renderer::Extent2D output_extent {
|
|
.width = 1024,
|
|
.height = 1024,
|
|
};
|
|
std::size_t merged_face_draw_count = 0;
|
|
std::size_t layer_depth_draw_count = 0;
|
|
std::size_t visited_layer_count = 0;
|
|
std::size_t visible_layer_count = 0;
|
|
std::size_t face_payload_count = 0;
|
|
bool uses_perspective_camera = true;
|
|
bool requires_renderer_readback = true;
|
|
};
|
|
|
|
struct DocumentLayerEquirectangularPngExportRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
std::size_t frame_index = 0;
|
|
pp::paint::Rgba clear_color {};
|
|
};
|
|
|
|
struct DocumentLayerEquirectangularPng {
|
|
std::size_t layer_index = 0;
|
|
std::string layer_name;
|
|
pp::renderer::Extent2D face_extent {};
|
|
pp::renderer::Extent2D equirectangular_extent {};
|
|
std::vector<std::byte> png;
|
|
std::uint64_t encoded_bytes = 0;
|
|
std::size_t face_payload_count = 0;
|
|
std::size_t composited_layer_face_count = 0;
|
|
};
|
|
|
|
struct DocumentLayerEquirectangularPngExportResult {
|
|
std::vector<DocumentLayerEquirectangularPng> layers;
|
|
std::uint64_t encoded_bytes = 0;
|
|
std::size_t layer_count = 0;
|
|
};
|
|
|
|
struct DocumentAnimationFrameEquirectangularPngExportRequest {
|
|
const pp::document::CanvasDocument* document = nullptr;
|
|
pp::paint::Rgba clear_color {};
|
|
};
|
|
|
|
struct DocumentAnimationFrameEquirectangularPng {
|
|
std::size_t frame_index = 0;
|
|
pp::renderer::Extent2D face_extent {};
|
|
pp::renderer::Extent2D equirectangular_extent {};
|
|
std::vector<std::byte> png;
|
|
std::uint64_t encoded_bytes = 0;
|
|
std::size_t face_payload_count = 0;
|
|
std::size_t composited_layer_face_count = 0;
|
|
};
|
|
|
|
struct DocumentAnimationFrameEquirectangularPngExportResult {
|
|
std::vector<DocumentAnimationFrameEquirectangularPng> frames;
|
|
std::uint64_t encoded_bytes = 0;
|
|
std::size_t frame_count = 0;
|
|
};
|
|
|
|
struct DocumentFrameExportReadinessResult {
|
|
RecordedDocumentFrameUploadResult recorded_upload {};
|
|
DocumentFrameFacePngExportResult face_pngs {};
|
|
};
|
|
|
|
[[nodiscard]] pp::foundation::Status composite_layer(
|
|
std::span<pp::paint::Rgba> destination,
|
|
pp::renderer::Extent2D extent,
|
|
LayerCompositeView layer) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFaceCompositeResult> composite_document_face(
|
|
DocumentFaceCompositeRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameCompositeResult> composite_document_frame(
|
|
DocumentFrameCompositeRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameUploadResult> upload_document_frame_faces(
|
|
pp::renderer::IRenderDevice& device,
|
|
DocumentFrameUploadRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<RecordedDocumentFrameUploadResult> record_document_frame_upload(
|
|
DocumentFrameUploadRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameFacePngExportResult> export_document_frame_face_pngs(
|
|
DocumentFrameCompositeRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameEquirectangularPngExportResult>
|
|
export_document_frame_equirectangular_png(const DocumentFrameCompositeResult& composite);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameEquirectangularPngExportResult>
|
|
export_document_frame_equirectangular_png(DocumentFrameCompositeRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentDepthExportRenderPlan> plan_document_depth_export_render(
|
|
DocumentDepthExportRenderPlanRequest request) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentLayerEquirectangularPngExportResult>
|
|
export_document_layers_equirectangular_pngs(DocumentLayerEquirectangularPngExportRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentAnimationFrameEquirectangularPngExportResult>
|
|
export_document_animation_frames_equirectangular_pngs(
|
|
DocumentAnimationFrameEquirectangularPngExportRequest request);
|
|
|
|
[[nodiscard]] pp::foundation::Result<DocumentFrameExportReadinessResult> prepare_document_frame_export_readiness(
|
|
DocumentFrameCompositeRequest request);
|
|
|
|
[[nodiscard]] bool stroke_composite_requires_feedback(
|
|
pp::paint::BlendMode layer_blend_mode,
|
|
pp::paint::StrokeBlendMode stroke_blend_mode,
|
|
bool dual_brush_blend,
|
|
bool pattern_blend) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<StrokeCompositePlan> plan_stroke_composite(
|
|
pp::renderer::RenderDeviceFeatures features,
|
|
StrokeCompositeRequest request) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
|
pp::renderer::RenderDeviceFeatures features,
|
|
CanvasBlendGateRequest request) noexcept;
|
|
|
|
[[nodiscard]] pp::foundation::Result<CanvasStrokeFeedbackPlan> plan_canvas_stroke_feedback(
|
|
pp::renderer::RenderDeviceFeatures features,
|
|
pp::renderer::Extent2D extent) noexcept;
|
|
|
|
[[nodiscard]] const char* stroke_composite_path_name(StrokeCompositePath path) noexcept;
|
|
|
|
}
|