Narrow stroke execution planning helpers
This commit is contained in:
@@ -18,6 +18,13 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
|
|
||||||
## Recent Reductions
|
## Recent Reductions
|
||||||
|
|
||||||
|
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_draw` face
|
||||||
|
dirty-box planning now routes through a retained stroke execution helper
|
||||||
|
wrapping `pp_paint_renderer`, retained stroke commit step dispatch clamps
|
||||||
|
malformed step counts to the fixed plan array, and compositor coverage now
|
||||||
|
exercises malformed retained commit plans plus all-input stroke-preview
|
||||||
|
composite planning. Live stroke rasterization, callback execution, texture
|
||||||
|
binding, and history mutation remain retained.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. Remaining live shader setup
|
- 2026-06-13: DEBT-0036 was narrowed again. Remaining live shader setup
|
||||||
outside retained helper headers now routes through retained helper surfaces
|
outside retained helper headers now routes through retained helper surfaces
|
||||||
for canvas modes, equirect layer export, `NodeCanvas` debug dirty bounds,
|
for canvas modes, equirect layer export, `NodeCanvas` debug dirty bounds,
|
||||||
|
|||||||
@@ -3073,6 +3073,12 @@ Results:
|
|||||||
`NodeCanvas` debug dirty bounds, atlas image drawing, and text drawing, while
|
`NodeCanvas` debug dirty bounds, atlas image drawing, and text drawing, while
|
||||||
geometry, framebuffer flow, texture/sampler binding, blend/depth state,
|
geometry, framebuffer flow, texture/sampler binding, blend/depth state,
|
||||||
readback, and draw execution remain retained.
|
readback, and draw execution remain retained.
|
||||||
|
- `Canvas::stroke_draw` face dirty-box planning now shares a retained stroke
|
||||||
|
execution helper wrapping `pp_paint_renderer`, retained stroke commit step
|
||||||
|
dispatch clamps malformed step counts to the fixed plan array, and
|
||||||
|
compositor coverage now includes malformed retained commit plans plus
|
||||||
|
all-input stroke-preview composite planning. Live stroke rasterization,
|
||||||
|
callback execution, texture binding, and history mutation remain retained.
|
||||||
- Remaining simple color, hue, color-quad, grid heightmap, and pen/line
|
- Remaining simple color, hue, color-quad, grid heightmap, and pen/line
|
||||||
preview shader setup in UI nodes and canvas modes now shares retained helper
|
preview shader setup in UI nodes and canvas modes now shares retained helper
|
||||||
surfaces, while geometry, texture/sampler binding, blend/depth state,
|
surfaces, while geometry, texture/sampler binding, blend/depth state,
|
||||||
|
|||||||
@@ -780,16 +780,16 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
|
||||||
const auto dirty_update = pp::paint_renderer::plan_canvas_stroke_face_dirty_update(
|
const auto dirty_update = pp::panopainter::plan_legacy_canvas_stroke_face_dirty_update(
|
||||||
pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest {
|
pp::panopainter::LegacyCanvasStrokeFaceDirtyRequest {
|
||||||
.extent = stroke_extent,
|
.extent = stroke_extent,
|
||||||
.previous_accumulated_dirty_box = canvas_stroke_box(m_dirty_box[i]),
|
.previous_accumulated_dirty_box = m_dirty_box[i],
|
||||||
.previous_pass_dirty_box = canvas_stroke_box(box_face[i]),
|
.previous_pass_dirty_box = box_face[i],
|
||||||
.sample_dirty_box = canvas_stroke_box(box_sample),
|
.sample_dirty_box = box_sample,
|
||||||
.include_in_committed_dirty_box = true,
|
.include_in_committed_dirty_box = true,
|
||||||
});
|
});
|
||||||
m_dirty_box[i] = glm_box(dirty_update.accumulated_dirty_box);
|
m_dirty_box[i] = dirty_update.accumulated_dirty_box;
|
||||||
box_face[i] = glm_box(dirty_update.pass_dirty_box);
|
box_face[i] = dirty_update.pass_dirty_box;
|
||||||
// TODO: maybe average color?
|
// TODO: maybe average color?
|
||||||
pad_color = f.col;
|
pad_color = f.col;
|
||||||
}
|
}
|
||||||
@@ -891,16 +891,16 @@ void Canvas::stroke_draw()
|
|||||||
m_tmp_dual[i].unbindFramebuffer();
|
m_tmp_dual[i].unbindFramebuffer();
|
||||||
|
|
||||||
// this mode overflows the main brush boundries
|
// this mode overflows the main brush boundries
|
||||||
const auto dirty_update = pp::paint_renderer::plan_canvas_stroke_face_dirty_update(
|
const auto dirty_update = pp::panopainter::plan_legacy_canvas_stroke_face_dirty_update(
|
||||||
pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest {
|
pp::panopainter::LegacyCanvasStrokeFaceDirtyRequest {
|
||||||
.extent = stroke_extent,
|
.extent = stroke_extent,
|
||||||
.previous_accumulated_dirty_box = canvas_stroke_box(m_dirty_box[i]),
|
.previous_accumulated_dirty_box = m_dirty_box[i],
|
||||||
.previous_pass_dirty_box = canvas_stroke_box(box_sample),
|
.previous_pass_dirty_box = box_sample,
|
||||||
.sample_dirty_box = canvas_stroke_box(box_sample),
|
.sample_dirty_box = box_sample,
|
||||||
.include_in_committed_dirty_box =
|
.include_in_committed_dirty_box =
|
||||||
stroke_material.composite_pass.dual_blend_mode == 0,
|
stroke_material.composite_pass.dual_blend_mode == 0,
|
||||||
});
|
});
|
||||||
m_dirty_box[i] = glm_box(dirty_update.accumulated_dirty_box);
|
m_dirty_box[i] = dirty_update.accumulated_dirty_box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -45,6 +46,12 @@ struct LegacyCanvasStrokeCommitResult {
|
|||||||
int committed_faces = 0;
|
int committed_faces = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline std::size_t legacy_canvas_stroke_commit_step_count(
|
||||||
|
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& sequence) noexcept
|
||||||
|
{
|
||||||
|
return std::min(sequence.step_count, sequence.steps.size());
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline bool legacy_canvas_stroke_commit_callbacks_ready(
|
[[nodiscard]] inline bool legacy_canvas_stroke_commit_callbacks_ready(
|
||||||
const LegacyCanvasStrokeCommitCallbacks& callbacks) noexcept
|
const LegacyCanvasStrokeCommitCallbacks& callbacks) noexcept
|
||||||
{
|
{
|
||||||
@@ -85,7 +92,8 @@ struct LegacyCanvasStrokeCommitResult {
|
|||||||
|
|
||||||
request.callbacks.bind_layer_framebuffer(face.index);
|
request.callbacks.bind_layer_framebuffer(face.index);
|
||||||
|
|
||||||
for (std::size_t step_index = 0; step_index < request.sequence.step_count; ++step_index) {
|
const auto step_count = legacy_canvas_stroke_commit_step_count(request.sequence);
|
||||||
|
for (std::size_t step_index = 0; step_index < step_count; ++step_index) {
|
||||||
switch (request.sequence.steps[step_index]) {
|
switch (request.sequence.steps[step_index]) {
|
||||||
case pp::paint_renderer::CanvasStrokeCommitStep::readback_history_region:
|
case pp::paint_renderer::CanvasStrokeCommitStep::readback_history_region:
|
||||||
request.callbacks.capture_history_region(face.index);
|
request.callbacks.capture_history_region(face.index);
|
||||||
|
|||||||
@@ -30,6 +30,60 @@ struct LegacyStrokeSampleExecutionResult {
|
|||||||
glm::vec4 dirty_bounds {};
|
glm::vec4 dirty_bounds {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeFaceDirtyRequest {
|
||||||
|
pp::renderer::Extent2D extent {};
|
||||||
|
glm::vec4 previous_accumulated_dirty_box {};
|
||||||
|
glm::vec4 previous_pass_dirty_box {};
|
||||||
|
glm::vec4 sample_dirty_box {};
|
||||||
|
bool include_in_committed_dirty_box = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeFaceDirtyResult {
|
||||||
|
glm::vec4 accumulated_dirty_box {};
|
||||||
|
glm::vec4 pass_dirty_box {};
|
||||||
|
bool has_dirty_pixels = false;
|
||||||
|
bool committed_dirty = false;
|
||||||
|
bool pass_dirty = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline pp::paint_renderer::CanvasStrokeBox legacy_canvas_stroke_box(glm::vec4 box) noexcept
|
||||||
|
{
|
||||||
|
return pp::paint_renderer::CanvasStrokeBox {
|
||||||
|
.min_x = box.x,
|
||||||
|
.min_y = box.y,
|
||||||
|
.max_x = box.z,
|
||||||
|
.max_y = box.w,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline glm::vec4 legacy_canvas_stroke_glm_box(
|
||||||
|
pp::paint_renderer::CanvasStrokeBox box) noexcept
|
||||||
|
{
|
||||||
|
return glm::vec4(box.min_x, box.min_y, box.max_x, box.max_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline LegacyCanvasStrokeFaceDirtyResult plan_legacy_canvas_stroke_face_dirty_update(
|
||||||
|
const LegacyCanvasStrokeFaceDirtyRequest& request) noexcept
|
||||||
|
{
|
||||||
|
const auto plan = pp::paint_renderer::plan_canvas_stroke_face_dirty_update(
|
||||||
|
pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest {
|
||||||
|
.extent = request.extent,
|
||||||
|
.previous_accumulated_dirty_box =
|
||||||
|
legacy_canvas_stroke_box(request.previous_accumulated_dirty_box),
|
||||||
|
.previous_pass_dirty_box = legacy_canvas_stroke_box(request.previous_pass_dirty_box),
|
||||||
|
.sample_dirty_box = legacy_canvas_stroke_box(request.sample_dirty_box),
|
||||||
|
.include_in_committed_dirty_box = request.include_in_committed_dirty_box,
|
||||||
|
});
|
||||||
|
|
||||||
|
return LegacyCanvasStrokeFaceDirtyResult {
|
||||||
|
.accumulated_dirty_box = legacy_canvas_stroke_glm_box(plan.accumulated_dirty_box),
|
||||||
|
.pass_dirty_box = legacy_canvas_stroke_glm_box(plan.pass_dirty_box),
|
||||||
|
.has_dirty_pixels = plan.has_dirty_pixels,
|
||||||
|
.committed_dirty = plan.committed_dirty,
|
||||||
|
.pass_dirty = plan.pass_dirty,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline LegacyStrokeSampleExecutionResult execute_legacy_canvas_stroke_sample(
|
[[nodiscard]] inline LegacyStrokeSampleExecutionResult execute_legacy_canvas_stroke_sample(
|
||||||
const LegacyStrokeSampleExecutionRequest& request)
|
const LegacyStrokeSampleExecutionRequest& request)
|
||||||
{
|
{
|
||||||
|
|||||||
46
src/legacy_node_stroke_preview_execution_services.h
Normal file
46
src/legacy_node_stroke_preview_execution_services.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "paint_renderer/compositor.h"
|
||||||
|
#include "renderer_api/renderer_api.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace pp::panopainter {
|
||||||
|
|
||||||
|
[[nodiscard]] inline pp::paint_renderer::CanvasStrokeFeedbackPlan plan_legacy_node_stroke_preview_feedback(
|
||||||
|
pp::renderer::RenderDeviceFeatures features,
|
||||||
|
int width,
|
||||||
|
int height) noexcept
|
||||||
|
{
|
||||||
|
const auto plan = pp::paint_renderer::plan_canvas_stroke_feedback(
|
||||||
|
features,
|
||||||
|
pp::renderer::Extent2D {
|
||||||
|
.width = static_cast<std::uint32_t>(std::max(width, 0)),
|
||||||
|
.height = static_cast<std::uint32_t>(std::max(height, 0)),
|
||||||
|
});
|
||||||
|
if (plan) {
|
||||||
|
return plan.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
pp::paint_renderer::CanvasStrokeFeedbackPlan fallback;
|
||||||
|
fallback.compatibility_fallback = true;
|
||||||
|
fallback.path = pp::paint_renderer::StrokeCompositePath::ping_pong_textures;
|
||||||
|
fallback.requires_auxiliary_texture = true;
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline pp::paint_renderer::StrokePreviewCompositePlan plan_legacy_node_stroke_preview_composite(
|
||||||
|
bool uses_mixer,
|
||||||
|
bool uses_dual,
|
||||||
|
bool uses_pattern) noexcept
|
||||||
|
{
|
||||||
|
return pp::paint_renderer::plan_stroke_preview_composite(
|
||||||
|
pp::paint_renderer::StrokePreviewCompositeRequest {
|
||||||
|
.uses_mixer = uses_mixer,
|
||||||
|
.uses_dual = uses_dual,
|
||||||
|
.uses_pattern = uses_pattern,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pp::panopainter
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
#include "legacy_canvas_stroke_preview_services.h"
|
#include "legacy_canvas_stroke_preview_services.h"
|
||||||
#include "legacy_canvas_stroke_shader_services.h"
|
#include "legacy_canvas_stroke_shader_services.h"
|
||||||
#include "legacy_canvas_stroke_services.h"
|
#include "legacy_canvas_stroke_services.h"
|
||||||
|
#include "legacy_node_stroke_preview_execution_services.h"
|
||||||
#include "legacy_ui_gl_dispatch.h"
|
#include "legacy_ui_gl_dispatch.h"
|
||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
#include "renderer_gl/opengl_capabilities.h"
|
#include "renderer_gl/opengl_capabilities.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -31,21 +31,10 @@ pp::paint_renderer::CanvasStrokeFeedbackPlan stroke_preview_destination_feedback
|
|||||||
int width,
|
int width,
|
||||||
int height) noexcept
|
int height) noexcept
|
||||||
{
|
{
|
||||||
const auto plan = pp::paint_renderer::plan_canvas_stroke_feedback(
|
return pp::panopainter::plan_legacy_node_stroke_preview_feedback(
|
||||||
stroke_preview_render_device_features(),
|
stroke_preview_render_device_features(),
|
||||||
pp::renderer::Extent2D {
|
width,
|
||||||
.width = static_cast<std::uint32_t>(std::max(width, 0)),
|
height);
|
||||||
.height = static_cast<std::uint32_t>(std::max(height, 0)),
|
|
||||||
});
|
|
||||||
if (plan) {
|
|
||||||
return plan.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeFeedbackPlan fallback;
|
|
||||||
fallback.compatibility_fallback = true;
|
|
||||||
fallback.path = pp::paint_renderer::StrokeCompositePath::ping_pong_textures;
|
|
||||||
fallback.requires_auxiliary_texture = true;
|
|
||||||
return fallback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pp::paint_renderer::CanvasStrokeMaterialPlan stroke_preview_material_plan(
|
pp::paint_renderer::CanvasStrokeMaterialPlan stroke_preview_material_plan(
|
||||||
@@ -452,12 +441,10 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
const auto stroke_feedback = stroke_preview_destination_feedback_plan(m_rtt.getWidth(), m_rtt.getHeight());
|
const auto stroke_feedback = stroke_preview_destination_feedback_plan(m_rtt.getWidth(), m_rtt.getHeight());
|
||||||
const bool copy_stroke_destination = !stroke_feedback.reads_destination_color;
|
const bool copy_stroke_destination = !stroke_feedback.reads_destination_color;
|
||||||
const auto material = stroke_preview_material_plan(*b, copy_stroke_destination);
|
const auto material = stroke_preview_material_plan(*b, copy_stroke_destination);
|
||||||
const auto preview_composite_plan = pp::paint_renderer::plan_stroke_preview_composite(
|
const auto preview_composite_plan = pp::panopainter::plan_legacy_node_stroke_preview_composite(
|
||||||
pp::paint_renderer::StrokePreviewCompositeRequest {
|
b->m_tip_mix > 0.0f,
|
||||||
.uses_mixer = b->m_tip_mix > 0.0f,
|
material.composite_pass.use_dual,
|
||||||
.uses_dual = material.composite_pass.use_dual,
|
material.composite_pass.use_pattern);
|
||||||
.uses_pattern = material.composite_pass.use_pattern,
|
|
||||||
});
|
|
||||||
pp::panopainter::setup_legacy_stroke_shader(
|
pp::panopainter::setup_legacy_stroke_shader(
|
||||||
pp::panopainter::LegacyStrokeShaderSetupUniforms {
|
pp::panopainter::LegacyStrokeShaderSetupUniforms {
|
||||||
.resolution = size,
|
.resolution = size,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "assets/image_pixels.h"
|
#include "assets/image_pixels.h"
|
||||||
|
#include "legacy_canvas_stroke_commit_services.h"
|
||||||
#include "paint_renderer/compositor.h"
|
#include "paint_renderer/compositor.h"
|
||||||
#include "renderer_api/recording_renderer.h"
|
#include "renderer_api/recording_renderer.h"
|
||||||
#include "test_harness.h"
|
#include "test_harness.h"
|
||||||
@@ -1776,6 +1777,61 @@ void plans_canvas_stroke_commit_composite_sequence(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::pattern, 4));
|
PP_EXPECT(h, has_commit_texture_binding(plan, CanvasStrokeCommitTextureRole::pattern, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void retained_stroke_commit_runner_clamps_malformed_step_count(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
pp::paint_renderer::CanvasStrokeCommitSequencePlan sequence;
|
||||||
|
sequence.step_count = 99U;
|
||||||
|
sequence.steps[0] = CanvasStrokeCommitStep::bind_commit_inputs;
|
||||||
|
sequence.steps[1] = CanvasStrokeCommitStep::composite_draw;
|
||||||
|
|
||||||
|
int bind_inputs = 0;
|
||||||
|
int paint_draws = 0;
|
||||||
|
int erase_draws = 0;
|
||||||
|
int started = 0;
|
||||||
|
int restored = 0;
|
||||||
|
int published = 0;
|
||||||
|
int timelapse = 0;
|
||||||
|
|
||||||
|
const auto result = pp::panopainter::execute_legacy_canvas_stroke_commit_sequence(
|
||||||
|
pp::panopainter::LegacyCanvasStrokeCommitRequest {
|
||||||
|
.context = "test",
|
||||||
|
.faces = {
|
||||||
|
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 0, .dirty = true },
|
||||||
|
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 1, .dirty = false },
|
||||||
|
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 2, .dirty = true },
|
||||||
|
},
|
||||||
|
.sequence = sequence,
|
||||||
|
.callbacks = {
|
||||||
|
.mark_commit_started = [&]() { ++started; },
|
||||||
|
.capture_render_state = []() {},
|
||||||
|
.prepare_render_state = []() {},
|
||||||
|
.restore_render_state = [&]() { ++restored; },
|
||||||
|
.publish_history = [&]() { ++published; },
|
||||||
|
.capture_timelapse_frame = [&]() { ++timelapse; },
|
||||||
|
.bind_layer_framebuffer = [](int) {},
|
||||||
|
.capture_history_region = [](int) {},
|
||||||
|
.apply_layer_dirty_region = [](int) {},
|
||||||
|
.copy_layer_to_commit_destination = [](int) {},
|
||||||
|
.bind_commit_inputs = [&](int) { ++bind_inputs; },
|
||||||
|
.execute_erase_composite = [&](int) { ++erase_draws; },
|
||||||
|
.execute_paint_composite = [&](int) { ++paint_draws; },
|
||||||
|
.copy_committed_to_dilate_source = [](int) {},
|
||||||
|
.execute_commit_dilate = [](int) {},
|
||||||
|
.unbind_layer_framebuffer = [](int) {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, result.ok);
|
||||||
|
PP_EXPECT(h, result.committed_faces == 2);
|
||||||
|
PP_EXPECT(h, bind_inputs == 2);
|
||||||
|
PP_EXPECT(h, paint_draws == 2);
|
||||||
|
PP_EXPECT(h, erase_draws == 0);
|
||||||
|
PP_EXPECT(h, started == 1);
|
||||||
|
PP_EXPECT(h, restored == 1);
|
||||||
|
PP_EXPECT(h, published == 1);
|
||||||
|
PP_EXPECT(h, timelapse == 1);
|
||||||
|
}
|
||||||
|
|
||||||
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 {});
|
||||||
@@ -1841,6 +1897,27 @@ void plans_stroke_preview_composite_with_pattern_input(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::pattern, 4));
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::pattern, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plans_stroke_preview_composite_with_all_retained_inputs(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto plan = plan_stroke_preview_composite(
|
||||||
|
StrokePreviewCompositeRequest {
|
||||||
|
.uses_mixer = true,
|
||||||
|
.uses_dual = true,
|
||||||
|
.uses_pattern = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect_preview_sequence(h, plan);
|
||||||
|
PP_EXPECT(h, plan.uses_mixer);
|
||||||
|
PP_EXPECT(h, plan.uses_dual);
|
||||||
|
PP_EXPECT(h, plan.uses_pattern);
|
||||||
|
PP_EXPECT(h, plan.texture_slot_count == 5U);
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::background, 0));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::stroke, 1));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::dual, 3));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::pattern, 4));
|
||||||
|
PP_EXPECT(h, has_preview_texture_slot(plan, StrokePreviewTextureRole::mixer, 3));
|
||||||
|
}
|
||||||
|
|
||||||
void plans_canvas_blend_gate_from_persisted_indices(pp::tests::Harness& h)
|
void plans_canvas_blend_gate_from_persisted_indices(pp::tests::Harness& h)
|
||||||
{
|
{
|
||||||
const std::vector<int> normal_layers { 0, 0, 0 };
|
const std::vector<int> normal_layers { 0, 0, 0 };
|
||||||
@@ -2264,10 +2341,16 @@ int main()
|
|||||||
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_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_canvas_stroke_commit_composite_sequence", plans_canvas_stroke_commit_composite_sequence);
|
||||||
|
harness.run(
|
||||||
|
"retained_stroke_commit_runner_clamps_malformed_step_count",
|
||||||
|
retained_stroke_commit_runner_clamps_malformed_step_count);
|
||||||
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);
|
||||||
harness.run("plans_stroke_preview_composite_with_pattern_input", plans_stroke_preview_composite_with_pattern_input);
|
harness.run("plans_stroke_preview_composite_with_pattern_input", plans_stroke_preview_composite_with_pattern_input);
|
||||||
|
harness.run(
|
||||||
|
"plans_stroke_preview_composite_with_all_retained_inputs",
|
||||||
|
plans_stroke_preview_composite_with_all_retained_inputs);
|
||||||
harness.run("plans_canvas_blend_gate_from_persisted_indices", plans_canvas_blend_gate_from_persisted_indices);
|
harness.run("plans_canvas_blend_gate_from_persisted_indices", plans_canvas_blend_gate_from_persisted_indices);
|
||||||
harness.run("canvas_blend_gate_preserves_legacy_fallbacks", canvas_blend_gate_preserves_legacy_fallbacks);
|
harness.run("canvas_blend_gate_preserves_legacy_fallbacks", canvas_blend_gate_preserves_legacy_fallbacks);
|
||||||
harness.run("plans_canvas_stroke_feedback_paths", plans_canvas_stroke_feedback_paths);
|
harness.run("plans_canvas_stroke_feedback_paths", plans_canvas_stroke_feedback_paths);
|
||||||
|
|||||||
Reference in New Issue
Block a user