Plan stroke commit sequencing
This commit is contained in:
@@ -18,6 +18,14 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
|
|
||||||
## Recent Reductions
|
## Recent Reductions
|
||||||
|
|
||||||
|
- 2026-06-13: DEBT-0036 was narrowed again. `pp_paint_renderer` now owns a
|
||||||
|
tested `CanvasStrokeCommitSequencePlan` for `Canvas::stroke_commit`
|
||||||
|
readback, dirty-state, scratch-copy, erase/composite draw, committed-copy,
|
||||||
|
dilate order, and commit texture slot roles. A retained
|
||||||
|
`legacy_canvas_stroke_commit_services.h` adapter skeleton consumes the
|
||||||
|
semantic plan through callbacks, but the live Canvas commit body still owns
|
||||||
|
history/layer mutation, RTT/framebuffer binding, sampler binding, and final
|
||||||
|
OpenGL execution until the adapter is wired.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_mix`
|
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_mix`
|
||||||
now reuses `legacy_canvas_stroke_composite_services.h` for mixer-pass
|
now reuses `legacy_canvas_stroke_composite_services.h` for mixer-pass
|
||||||
`kShader::CompDraw` binding and composite/pattern/dual uniform writes.
|
`kShader::CompDraw` binding and composite/pattern/dual uniform writes.
|
||||||
|
|||||||
@@ -2974,6 +2974,12 @@ Results:
|
|||||||
`pp_paint_renderer` stroke-feedback plan to decide whether framebuffer fetch
|
`pp_paint_renderer` stroke-feedback plan to decide whether framebuffer fetch
|
||||||
supplies destination color or the legacy OpenGL path must copy the target
|
supplies destination color or the legacy OpenGL path must copy the target
|
||||||
texture before drawing.
|
texture before drawing.
|
||||||
|
- Canvas stroke commit ordering now has a tested `pp_paint_renderer`
|
||||||
|
`CanvasStrokeCommitSequencePlan` for history readback, dirty-state update,
|
||||||
|
scratch copies, erase/composite draw selection, dilate, and texture slot
|
||||||
|
roles. A retained commit adapter skeleton consumes that semantic sequence,
|
||||||
|
while the live Canvas body still owns history/layer mutation and OpenGL
|
||||||
|
execution until the next wiring slice.
|
||||||
- Canvas thumbnail layer blending now uses the same canvas destination-feedback
|
- Canvas thumbnail layer blending now uses the same canvas destination-feedback
|
||||||
plan for framebuffer-fetch versus texture-copy decisions; the thumbnail draw
|
plan for framebuffer-fetch versus texture-copy decisions; the thumbnail draw
|
||||||
itself still executes through retained OpenGL canvas code under DEBT-0036.
|
itself still executes through retained OpenGL canvas code under DEBT-0036.
|
||||||
|
|||||||
@@ -507,6 +507,13 @@ Done Checks:
|
|||||||
- Retained stroke OpenGL execution is deleted or isolated as an OpenGL backend
|
- Retained stroke OpenGL execution is deleted or isolated as an OpenGL backend
|
||||||
implementation.
|
implementation.
|
||||||
|
|
||||||
|
Progress Notes:
|
||||||
|
|
||||||
|
- 2026-06-13: `pp_paint_renderer` owns tested Canvas stroke commit sequencing
|
||||||
|
and commit texture slot intent. Next slice should wire
|
||||||
|
`legacy_canvas_stroke_commit_services.h` into `Canvas::stroke_commit` while
|
||||||
|
keeping history/layer mutation local.
|
||||||
|
|
||||||
### LATER-004 - Remove Catch-All Platform Legacy Adapter
|
### LATER-004 - Remove Catch-All Platform Legacy Adapter
|
||||||
|
|
||||||
Status: Blocked
|
Status: Blocked
|
||||||
|
|||||||
129
src/legacy_canvas_stroke_commit_services.h
Normal file
129
src/legacy_canvas_stroke_commit_services.h
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "paint_renderer/compositor.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeCommitFace {
|
||||||
|
int index = 0;
|
||||||
|
bool dirty = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeCommitCallbacks {
|
||||||
|
std::function<void()> mark_commit_started;
|
||||||
|
std::function<void()> capture_render_state;
|
||||||
|
std::function<void()> prepare_render_state;
|
||||||
|
std::function<void()> restore_render_state;
|
||||||
|
std::function<void()> publish_history;
|
||||||
|
std::function<void()> capture_timelapse_frame;
|
||||||
|
|
||||||
|
std::function<void(int)> bind_layer_framebuffer;
|
||||||
|
std::function<void(int)> capture_history_region;
|
||||||
|
std::function<void(int)> apply_layer_dirty_region;
|
||||||
|
std::function<void(int)> copy_layer_to_commit_destination;
|
||||||
|
std::function<void(int)> bind_commit_inputs;
|
||||||
|
std::function<void(int)> execute_erase_composite;
|
||||||
|
std::function<void(int)> execute_paint_composite;
|
||||||
|
std::function<void(int)> copy_committed_to_dilate_source;
|
||||||
|
std::function<void(int)> execute_commit_dilate;
|
||||||
|
std::function<void(int)> unbind_layer_framebuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeCommitRequest {
|
||||||
|
std::string_view context;
|
||||||
|
std::array<LegacyCanvasStrokeCommitFace, 6> faces {};
|
||||||
|
pp::paint_renderer::CanvasStrokeCommitSequencePlan sequence;
|
||||||
|
LegacyCanvasStrokeCommitCallbacks callbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeCommitResult {
|
||||||
|
bool ok = false;
|
||||||
|
int committed_faces = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline bool legacy_canvas_stroke_commit_callbacks_ready(
|
||||||
|
const LegacyCanvasStrokeCommitCallbacks& callbacks) noexcept
|
||||||
|
{
|
||||||
|
return callbacks.mark_commit_started &&
|
||||||
|
callbacks.capture_render_state &&
|
||||||
|
callbacks.prepare_render_state &&
|
||||||
|
callbacks.restore_render_state &&
|
||||||
|
callbacks.publish_history &&
|
||||||
|
callbacks.capture_timelapse_frame &&
|
||||||
|
callbacks.bind_layer_framebuffer &&
|
||||||
|
callbacks.capture_history_region &&
|
||||||
|
callbacks.apply_layer_dirty_region &&
|
||||||
|
callbacks.copy_layer_to_commit_destination &&
|
||||||
|
callbacks.bind_commit_inputs &&
|
||||||
|
callbacks.execute_erase_composite &&
|
||||||
|
callbacks.execute_paint_composite &&
|
||||||
|
callbacks.copy_committed_to_dilate_source &&
|
||||||
|
callbacks.execute_commit_dilate &&
|
||||||
|
callbacks.unbind_layer_framebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline LegacyCanvasStrokeCommitResult execute_legacy_canvas_stroke_commit_sequence(
|
||||||
|
const LegacyCanvasStrokeCommitRequest& request)
|
||||||
|
{
|
||||||
|
LegacyCanvasStrokeCommitResult result;
|
||||||
|
if (!legacy_canvas_stroke_commit_callbacks_ready(request.callbacks)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.callbacks.mark_commit_started();
|
||||||
|
request.callbacks.capture_render_state();
|
||||||
|
request.callbacks.prepare_render_state();
|
||||||
|
|
||||||
|
for (const auto& face : request.faces) {
|
||||||
|
if (!face.dirty) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.callbacks.bind_layer_framebuffer(face.index);
|
||||||
|
|
||||||
|
for (std::size_t step_index = 0; step_index < request.sequence.step_count; ++step_index) {
|
||||||
|
switch (request.sequence.steps[step_index]) {
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::readback_history_region:
|
||||||
|
request.callbacks.capture_history_region(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::update_layer_dirty_state:
|
||||||
|
request.callbacks.apply_layer_dirty_region(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::copy_layer_rtt_to_scratch:
|
||||||
|
request.callbacks.copy_layer_to_commit_destination(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::bind_commit_inputs:
|
||||||
|
request.callbacks.bind_commit_inputs(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::erase_draw:
|
||||||
|
request.callbacks.execute_erase_composite(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::composite_draw:
|
||||||
|
request.callbacks.execute_paint_composite(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::copy_committed_rtt_to_scratch:
|
||||||
|
request.callbacks.copy_committed_to_dilate_source(face.index);
|
||||||
|
break;
|
||||||
|
case pp::paint_renderer::CanvasStrokeCommitStep::dilate_edges_draw:
|
||||||
|
request.callbacks.execute_commit_dilate(face.index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.callbacks.unbind_layer_framebuffer(face.index);
|
||||||
|
++result.committed_faces;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.callbacks.restore_render_state();
|
||||||
|
request.callbacks.publish_history();
|
||||||
|
request.callbacks.capture_timelapse_frame();
|
||||||
|
|
||||||
|
result.ok = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
@@ -1445,6 +1445,55 @@ pp::foundation::Result<CanvasStrokeRasterizationPlan> plan_canvas_stroke_rasteri
|
|||||||
return pp::foundation::Result<CanvasStrokeRasterizationPlan>::success(plan);
|
return pp::foundation::Result<CanvasStrokeRasterizationPlan>::success(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CanvasStrokeCommitSequencePlan plan_canvas_stroke_commit_sequence(CanvasStrokeCommitRequest request) noexcept
|
||||||
|
{
|
||||||
|
CanvasStrokeCommitSequencePlan plan;
|
||||||
|
plan.erase_mode = request.erase_mode;
|
||||||
|
plan.alpha_locked = request.alpha_locked;
|
||||||
|
plan.selection_mask_active = request.selection_mask_active;
|
||||||
|
plan.uses_dual_stroke = !request.erase_mode && request.dual_stroke_enabled;
|
||||||
|
plan.uses_pattern = !request.erase_mode && request.pattern_enabled;
|
||||||
|
plan.updates_layer_bounds = !request.alpha_locked;
|
||||||
|
|
||||||
|
auto append_step = [&plan](CanvasStrokeCommitStep step) noexcept {
|
||||||
|
if (plan.step_count >= plan.steps.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
plan.steps[plan.step_count] = step;
|
||||||
|
++plan.step_count;
|
||||||
|
};
|
||||||
|
auto bind = [&plan](CanvasStrokeCommitTextureRole role, std::uint8_t slot) noexcept {
|
||||||
|
if (plan.texture_binding_count >= plan.texture_bindings.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
plan.texture_bindings[plan.texture_binding_count] = CanvasStrokeCommitTextureBindingPlan {
|
||||||
|
.role = role,
|
||||||
|
.slot = slot,
|
||||||
|
};
|
||||||
|
++plan.texture_binding_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
append_step(CanvasStrokeCommitStep::readback_history_region);
|
||||||
|
append_step(CanvasStrokeCommitStep::update_layer_dirty_state);
|
||||||
|
append_step(CanvasStrokeCommitStep::copy_layer_rtt_to_scratch);
|
||||||
|
append_step(CanvasStrokeCommitStep::bind_commit_inputs);
|
||||||
|
append_step(request.erase_mode ? CanvasStrokeCommitStep::erase_draw : CanvasStrokeCommitStep::composite_draw);
|
||||||
|
append_step(CanvasStrokeCommitStep::copy_committed_rtt_to_scratch);
|
||||||
|
append_step(CanvasStrokeCommitStep::dilate_edges_draw);
|
||||||
|
|
||||||
|
bind(CanvasStrokeCommitTextureRole::layer_scratch, 0);
|
||||||
|
bind(CanvasStrokeCommitTextureRole::stroke, 1);
|
||||||
|
bind(CanvasStrokeCommitTextureRole::selection_mask, 2);
|
||||||
|
if (plan.uses_dual_stroke) {
|
||||||
|
bind(CanvasStrokeCommitTextureRole::dual_stroke, 3);
|
||||||
|
}
|
||||||
|
if (plan.uses_pattern) {
|
||||||
|
bind(CanvasStrokeCommitTextureRole::pattern, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
|
||||||
CanvasStrokeSampleBoundsPlan plan_canvas_stroke_sample_bounds(
|
CanvasStrokeSampleBoundsPlan plan_canvas_stroke_sample_bounds(
|
||||||
CanvasStrokeSampleBoundsRequest request) noexcept
|
CanvasStrokeSampleBoundsRequest request) noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -187,6 +187,55 @@ struct CanvasStrokeRasterizationPlan {
|
|||||||
bool compatibility_fallback = false;
|
bool compatibility_fallback = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CanvasStrokeCommitStep : std::uint8_t {
|
||||||
|
readback_history_region,
|
||||||
|
update_layer_dirty_state,
|
||||||
|
copy_layer_rtt_to_scratch,
|
||||||
|
bind_commit_inputs,
|
||||||
|
erase_draw,
|
||||||
|
composite_draw,
|
||||||
|
copy_committed_rtt_to_scratch,
|
||||||
|
dilate_edges_draw,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CanvasStrokeCommitTextureRole : std::uint8_t {
|
||||||
|
layer_scratch,
|
||||||
|
stroke,
|
||||||
|
selection_mask,
|
||||||
|
dual_stroke,
|
||||||
|
pattern,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CanvasStrokeCommitTextureBindingPlan {
|
||||||
|
CanvasStrokeCommitTextureRole role = CanvasStrokeCommitTextureRole::layer_scratch;
|
||||||
|
std::uint8_t slot = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CanvasStrokeCommitRequest {
|
||||||
|
bool erase_mode = false;
|
||||||
|
bool alpha_locked = false;
|
||||||
|
bool selection_mask_active = false;
|
||||||
|
bool dual_stroke_enabled = false;
|
||||||
|
bool pattern_enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CanvasStrokeCommitSequencePlan {
|
||||||
|
std::array<CanvasStrokeCommitStep, 8> steps {};
|
||||||
|
std::size_t step_count = 0;
|
||||||
|
std::array<CanvasStrokeCommitTextureBindingPlan, 5> texture_bindings {};
|
||||||
|
std::size_t texture_binding_count = 0;
|
||||||
|
bool erase_mode = false;
|
||||||
|
bool alpha_locked = false;
|
||||||
|
bool selection_mask_active = false;
|
||||||
|
bool uses_dual_stroke = false;
|
||||||
|
bool uses_pattern = false;
|
||||||
|
bool requires_history_readback = true;
|
||||||
|
bool updates_layer_bounds = true;
|
||||||
|
bool requires_layer_scratch_copy = true;
|
||||||
|
bool requires_committed_scratch_copy = true;
|
||||||
|
bool requires_dilate = true;
|
||||||
|
};
|
||||||
|
|
||||||
struct CanvasStrokePoint {
|
struct CanvasStrokePoint {
|
||||||
float x = 0.0F;
|
float x = 0.0F;
|
||||||
float y = 0.0F;
|
float y = 0.0F;
|
||||||
@@ -493,6 +542,9 @@ export_document_animation_frames_equirectangular_pngs(
|
|||||||
pp::renderer::RenderDeviceFeatures features,
|
pp::renderer::RenderDeviceFeatures features,
|
||||||
pp::renderer::Extent2D extent) noexcept;
|
pp::renderer::Extent2D extent) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] CanvasStrokeCommitSequencePlan plan_canvas_stroke_commit_sequence(
|
||||||
|
CanvasStrokeCommitRequest request) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] CanvasStrokeSampleBoundsPlan plan_canvas_stroke_sample_bounds(
|
[[nodiscard]] CanvasStrokeSampleBoundsPlan plan_canvas_stroke_sample_bounds(
|
||||||
CanvasStrokeSampleBoundsRequest request) noexcept;
|
CanvasStrokeSampleBoundsRequest request) noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ using pp::paint::StrokeBlendMode;
|
|||||||
using pp::assets::decode_png_rgba8;
|
using pp::assets::decode_png_rgba8;
|
||||||
using pp::paint_renderer::CanvasBlendGateRequest;
|
using pp::paint_renderer::CanvasBlendGateRequest;
|
||||||
using pp::paint_renderer::CanvasStrokeBox;
|
using pp::paint_renderer::CanvasStrokeBox;
|
||||||
|
using pp::paint_renderer::CanvasStrokeCommitRequest;
|
||||||
|
using pp::paint_renderer::CanvasStrokeCommitStep;
|
||||||
|
using pp::paint_renderer::CanvasStrokeCommitTextureRole;
|
||||||
using pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest;
|
using pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest;
|
||||||
using pp::paint_renderer::CanvasStrokeMaterialRequest;
|
using pp::paint_renderer::CanvasStrokeMaterialRequest;
|
||||||
using pp::paint_renderer::CanvasStrokePadRegionRequest;
|
using pp::paint_renderer::CanvasStrokePadRegionRequest;
|
||||||
@@ -37,6 +40,7 @@ using pp::paint_renderer::export_document_depth_pngs;
|
|||||||
using pp::paint_renderer::plan_canvas_blend_gate;
|
using pp::paint_renderer::plan_canvas_blend_gate;
|
||||||
using pp::paint_renderer::plan_canvas_stroke_face_dirty_update;
|
using pp::paint_renderer::plan_canvas_stroke_face_dirty_update;
|
||||||
using pp::paint_renderer::plan_canvas_stroke_feedback;
|
using pp::paint_renderer::plan_canvas_stroke_feedback;
|
||||||
|
using pp::paint_renderer::plan_canvas_stroke_commit_sequence;
|
||||||
using pp::paint_renderer::plan_canvas_stroke_material;
|
using pp::paint_renderer::plan_canvas_stroke_material;
|
||||||
using pp::paint_renderer::plan_canvas_stroke_pad_region;
|
using pp::paint_renderer::plan_canvas_stroke_pad_region;
|
||||||
using pp::paint_renderer::plan_canvas_stroke_rasterization;
|
using pp::paint_renderer::plan_canvas_stroke_rasterization;
|
||||||
@@ -91,6 +95,19 @@ bool has_preview_texture_slot(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_commit_texture_binding(
|
||||||
|
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& plan,
|
||||||
|
CanvasStrokeCommitTextureRole role,
|
||||||
|
std::uint8_t slot)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < plan.texture_binding_count; ++i) {
|
||||||
|
if (plan.texture_bindings[i].role == role && plan.texture_bindings[i].slot == slot) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void expect_preview_sequence(pp::tests::Harness& h, const pp::paint_renderer::StrokePreviewCompositePlan& plan)
|
void expect_preview_sequence(pp::tests::Harness& h, const pp::paint_renderer::StrokePreviewCompositePlan& plan)
|
||||||
{
|
{
|
||||||
PP_EXPECT(h, plan.step_count == 5U);
|
PP_EXPECT(h, plan.step_count == 5U);
|
||||||
@@ -101,6 +118,17 @@ void expect_preview_sequence(pp::tests::Harness& h, const pp::paint_renderer::St
|
|||||||
PP_EXPECT(h, plan.steps[4] == StrokePreviewCompositeStep::copy_preview_texture);
|
PP_EXPECT(h, plan.steps[4] == StrokePreviewCompositeStep::copy_preview_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void expect_commit_prefix(pp::tests::Harness& h, const pp::paint_renderer::CanvasStrokeCommitSequencePlan& plan)
|
||||||
|
{
|
||||||
|
PP_EXPECT(h, plan.step_count == 7U);
|
||||||
|
PP_EXPECT(h, plan.steps[0] == CanvasStrokeCommitStep::readback_history_region);
|
||||||
|
PP_EXPECT(h, plan.steps[1] == CanvasStrokeCommitStep::update_layer_dirty_state);
|
||||||
|
PP_EXPECT(h, plan.steps[2] == CanvasStrokeCommitStep::copy_layer_rtt_to_scratch);
|
||||||
|
PP_EXPECT(h, plan.steps[3] == CanvasStrokeCommitStep::bind_commit_inputs);
|
||||||
|
PP_EXPECT(h, plan.steps[5] == CanvasStrokeCommitStep::copy_committed_rtt_to_scratch);
|
||||||
|
PP_EXPECT(h, plan.steps[6] == CanvasStrokeCommitStep::dilate_edges_draw);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::uint8_t> solid_rgba8(
|
std::vector<std::uint8_t> solid_rgba8(
|
||||||
std::uint32_t width,
|
std::uint32_t width,
|
||||||
std::uint32_t height,
|
std::uint32_t height,
|
||||||
@@ -1692,6 +1720,62 @@ void plans_canvas_stroke_dual_material_intent(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, has_texture_binding(dual_composite_pattern, CanvasStrokeTextureRole::pattern, 2));
|
PP_EXPECT(h, has_texture_binding(dual_composite_pattern, CanvasStrokeTextureRole::pattern, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plans_canvas_stroke_commit_erase_sequence(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto plan = plan_canvas_stroke_commit_sequence(
|
||||||
|
CanvasStrokeCommitRequest {
|
||||||
|
.erase_mode = true,
|
||||||
|
.alpha_locked = true,
|
||||||
|
.selection_mask_active = true,
|
||||||
|
.dual_stroke_enabled = true,
|
||||||
|
.pattern_enabled = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect_commit_prefix(h, plan);
|
||||||
|
PP_EXPECT(h, plan.steps[4] == CanvasStrokeCommitStep::erase_draw);
|
||||||
|
PP_EXPECT(h, plan.erase_mode);
|
||||||
|
PP_EXPECT(h, plan.alpha_locked);
|
||||||
|
PP_EXPECT(h, plan.selection_mask_active);
|
||||||
|
PP_EXPECT(h, !plan.uses_dual_stroke);
|
||||||
|
PP_EXPECT(h, !plan.uses_pattern);
|
||||||
|
PP_EXPECT(h, plan.requires_history_readback);
|
||||||
|
PP_EXPECT(h, !plan.updates_layer_bounds);
|
||||||
|
PP_EXPECT(h, plan.requires_layer_scratch_copy);
|
||||||
|
PP_EXPECT(h, plan.requires_committed_scratch_copy);
|
||||||
|
PP_EXPECT(h, plan.requires_dilate);
|
||||||
|
PP_EXPECT(h, plan.texture_binding_count == 3U);
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::layer_scratch, 0));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::stroke, 1));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::selection_mask, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void plans_canvas_stroke_commit_composite_sequence(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto plan = plan_canvas_stroke_commit_sequence(
|
||||||
|
CanvasStrokeCommitRequest {
|
||||||
|
.erase_mode = false,
|
||||||
|
.alpha_locked = false,
|
||||||
|
.selection_mask_active = true,
|
||||||
|
.dual_stroke_enabled = true,
|
||||||
|
.pattern_enabled = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect_commit_prefix(h, plan);
|
||||||
|
PP_EXPECT(h, plan.steps[4] == CanvasStrokeCommitStep::composite_draw);
|
||||||
|
PP_EXPECT(h, !plan.erase_mode);
|
||||||
|
PP_EXPECT(h, !plan.alpha_locked);
|
||||||
|
PP_EXPECT(h, plan.selection_mask_active);
|
||||||
|
PP_EXPECT(h, plan.uses_dual_stroke);
|
||||||
|
PP_EXPECT(h, plan.uses_pattern);
|
||||||
|
PP_EXPECT(h, plan.updates_layer_bounds);
|
||||||
|
PP_EXPECT(h, plan.texture_binding_count == 5U);
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::layer_scratch, 0));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::stroke, 1));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::selection_mask, 2));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::dual_stroke, 3));
|
||||||
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::pattern, 4));
|
||||||
|
}
|
||||||
|
|
||||||
void plans_stroke_preview_composite_for_simple_brush(pp::tests::Harness& h)
|
void plans_stroke_preview_composite_for_simple_brush(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const auto plan = plan_stroke_preview_composite(StrokePreviewCompositeRequest {});
|
const auto plan = plan_stroke_preview_composite(StrokePreviewCompositeRequest {});
|
||||||
@@ -2178,6 +2262,8 @@ int main()
|
|||||||
harness.run("rejects_bad_stroke_composite_plans", rejects_bad_stroke_composite_plans);
|
harness.run("rejects_bad_stroke_composite_plans", rejects_bad_stroke_composite_plans);
|
||||||
harness.run("plans_canvas_stroke_material_passes", plans_canvas_stroke_material_passes);
|
harness.run("plans_canvas_stroke_material_passes", plans_canvas_stroke_material_passes);
|
||||||
harness.run("plans_canvas_stroke_dual_material_intent", plans_canvas_stroke_dual_material_intent);
|
harness.run("plans_canvas_stroke_dual_material_intent", plans_canvas_stroke_dual_material_intent);
|
||||||
|
harness.run("plans_canvas_stroke_commit_erase_sequence", plans_canvas_stroke_commit_erase_sequence);
|
||||||
|
harness.run("plans_canvas_stroke_commit_composite_sequence", plans_canvas_stroke_commit_composite_sequence);
|
||||||
harness.run("plans_stroke_preview_composite_for_simple_brush", plans_stroke_preview_composite_for_simple_brush);
|
harness.run("plans_stroke_preview_composite_for_simple_brush", plans_stroke_preview_composite_for_simple_brush);
|
||||||
harness.run("plans_stroke_preview_composite_with_mixer_input", plans_stroke_preview_composite_with_mixer_input);
|
harness.run("plans_stroke_preview_composite_with_mixer_input", plans_stroke_preview_composite_with_mixer_input);
|
||||||
harness.run("plans_stroke_preview_composite_with_dual_input", plans_stroke_preview_composite_with_dual_input);
|
harness.run("plans_stroke_preview_composite_with_dual_input", plans_stroke_preview_composite_with_dual_input);
|
||||||
|
|||||||
Reference in New Issue
Block a user