Plan canvas stroke feedback copies

This commit is contained in:
2026-06-03 18:52:37 +02:00
parent b576143afb
commit 2ac2c45b11
8 changed files with 174 additions and 14 deletions

View File

@@ -110,12 +110,21 @@ namespace {
void apply_stroke_plan(CanvasBlendGatePlan& gate, const StrokeCompositePlan& stroke) noexcept
{
gate.path = stroke.path;
gate.reads_destination_color = stroke.reads_destination_color;
gate.reads_destination_color = stroke.path == StrokeCompositePath::framebuffer_fetch;
gate.requires_auxiliary_texture = stroke.requires_auxiliary_texture;
gate.requires_texture_copy = stroke.requires_texture_copy;
gate.requires_render_target_blit = stroke.requires_render_target_blit;
}
void apply_feedback_plan(CanvasStrokeFeedbackPlan& plan, const pp::renderer::PaintFeedbackPlan& feedback) noexcept
{
plan.path = composite_path_from_feedback(feedback.path);
plan.reads_destination_color = plan.path == StrokeCompositePath::framebuffer_fetch;
plan.requires_auxiliary_texture = feedback.requires_auxiliary_texture;
plan.requires_texture_copy = feedback.requires_texture_copy;
plan.requires_render_target_blit = feedback.requires_render_target_blit;
}
void mark_shader_blend_fallback(
CanvasBlendGatePlan& gate,
pp::renderer::RenderDeviceFeatures features) noexcept
@@ -303,6 +312,45 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
return pp::foundation::Result<CanvasBlendGatePlan>::success(gate);
}
pp::foundation::Result<CanvasStrokeFeedbackPlan> plan_canvas_stroke_feedback(
pp::renderer::RenderDeviceFeatures features,
pp::renderer::Extent2D extent) noexcept
{
const auto extent_status = pp::renderer::validate_extent(extent);
if (!extent_status.ok()) {
return pp::foundation::Result<CanvasStrokeFeedbackPlan>::failure(extent_status);
}
const pp::renderer::TextureDesc target_desc {
.extent = extent,
.format = pp::renderer::TextureFormat::rgba8,
.usage = pp::renderer::TextureUsage::render_target
| pp::renderer::TextureUsage::sampled
| pp::renderer::TextureUsage::copy_source
| pp::renderer::TextureUsage::copy_destination,
.debug_name = "canvas-stroke-feedback-target",
};
const auto feedback = pp::renderer::plan_paint_feedback(features, target_desc, true);
if (feedback) {
CanvasStrokeFeedbackPlan plan;
apply_feedback_plan(plan, feedback.value());
return pp::foundation::Result<CanvasStrokeFeedbackPlan>::success(plan);
}
CanvasStrokeFeedbackPlan fallback;
fallback.compatibility_fallback = true;
if (features.framebuffer_fetch) {
fallback.path = StrokeCompositePath::framebuffer_fetch;
fallback.reads_destination_color = true;
} else {
fallback.path = StrokeCompositePath::ping_pong_textures;
fallback.requires_auxiliary_texture = true;
fallback.requires_texture_copy = features.texture_copy;
fallback.requires_render_target_blit = !features.texture_copy && features.render_target_blit;
}
return pp::foundation::Result<CanvasStrokeFeedbackPlan>::success(fallback);
}
const char* stroke_composite_path_name(StrokeCompositePath path) noexcept
{
switch (path) {

View File

@@ -74,6 +74,15 @@ struct CanvasBlendGatePlan {
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;
};
[[nodiscard]] pp::foundation::Status composite_layer(
std::span<pp::paint::Rgba> destination,
pp::renderer::Extent2D extent,
@@ -93,6 +102,10 @@ struct CanvasBlendGatePlan {
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;
}