Extract stroke dirty bounds planning
This commit is contained in:
@@ -84,6 +84,29 @@ pp::paint_renderer::CanvasStrokeMaterialPlan canvas_stroke_material_plan(
|
||||
});
|
||||
}
|
||||
|
||||
pp::renderer::Extent2D canvas_stroke_extent(int width, int height) noexcept
|
||||
{
|
||||
return pp::renderer::Extent2D {
|
||||
.width = static_cast<std::uint32_t>(std::max(width, 0)),
|
||||
.height = static_cast<std::uint32_t>(std::max(height, 0)),
|
||||
};
|
||||
}
|
||||
|
||||
pp::paint_renderer::CanvasStrokeBox 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,
|
||||
};
|
||||
}
|
||||
|
||||
glm::vec4 glm_box(pp::paint_renderer::CanvasStrokeBox box) noexcept
|
||||
{
|
||||
return glm::vec4(box.min_x, box.min_y, box.max_x, box.max_y);
|
||||
}
|
||||
|
||||
pp::paint_renderer::CanvasBlendGatePlan draw_merge_blend_gate_plan(
|
||||
int width,
|
||||
int height,
|
||||
@@ -530,11 +553,21 @@ glm::vec4 Canvas::stroke_draw_samples(
|
||||
P = triangulate_simple(P);
|
||||
}
|
||||
|
||||
std::vector<pp::paint_renderer::CanvasStrokePoint> sample_points;
|
||||
sample_points.reserve(P.size());
|
||||
for (const auto& vertex : P) {
|
||||
sample_points.push_back(pp::paint_renderer::CanvasStrokePoint {
|
||||
.x = vertex.pos.x,
|
||||
.y = vertex.pos.y,
|
||||
});
|
||||
}
|
||||
|
||||
const auto result = pp::panopainter::execute_legacy_canvas_stroke_sample(
|
||||
pp::panopainter::LegacyStrokeSampleExecutionRequest {
|
||||
.context = "Canvas::stroke_draw_samples",
|
||||
.target_size = { m_width, m_height },
|
||||
.vertices = P,
|
||||
.sample_points = sample_points,
|
||||
.copy_stroke_destination = copy_stroke_destination,
|
||||
.bind_destination_texture = [&] {
|
||||
set_active_texture_unit(1);
|
||||
@@ -676,6 +709,7 @@ void Canvas::stroke_draw()
|
||||
const auto stroke_rasterization = canvas_stroke_rasterization_plan(m_width, m_height);
|
||||
const bool copy_stroke_destination = stroke_rasterization.copy_stroke_destination;
|
||||
const auto stroke_material = canvas_stroke_material_plan(*brush, copy_stroke_destination);
|
||||
const auto stroke_extent = canvas_stroke_extent(m_width, m_height);
|
||||
|
||||
apply_canvas_capability(blend_state(), false);
|
||||
pp::panopainter::setup_legacy_stroke_shader(
|
||||
@@ -745,8 +779,16 @@ void Canvas::stroke_draw()
|
||||
|
||||
m_tmp[i].unbindFramebuffer();
|
||||
|
||||
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], box_sample), glm::vec4(0), glm::vec4(m_width));
|
||||
box_face[i] = box_union(box_face[i], box_sample);
|
||||
const auto dirty_update = pp::paint_renderer::plan_canvas_stroke_face_dirty_update(
|
||||
pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest {
|
||||
.extent = stroke_extent,
|
||||
.previous_accumulated_dirty_box = canvas_stroke_box(m_dirty_box[i]),
|
||||
.previous_pass_dirty_box = canvas_stroke_box(box_face[i]),
|
||||
.sample_dirty_box = canvas_stroke_box(box_sample),
|
||||
.include_in_committed_dirty_box = true,
|
||||
});
|
||||
m_dirty_box[i] = glm_box(dirty_update.accumulated_dirty_box);
|
||||
box_face[i] = glm_box(dirty_update.pass_dirty_box);
|
||||
// TODO: maybe average color?
|
||||
pad_color = f.col;
|
||||
}
|
||||
@@ -779,34 +821,37 @@ void Canvas::stroke_draw()
|
||||
{
|
||||
if (!box_dirty[i])
|
||||
continue;
|
||||
const auto& b = box_face[i];
|
||||
glm::vec2 box_size = zw(b) - xy(b);
|
||||
glm::vec2 pad = { 20, 20 }; // pixels padding
|
||||
glm::vec4 pad_box = {
|
||||
glm::max({0, 0}, xy(b) - pad) * 2.f / m_size - 1.f,
|
||||
glm::min(m_size, zw(b) + pad) * 2.f / m_size - 1.f
|
||||
};
|
||||
const auto pad_region = pp::paint_renderer::plan_canvas_stroke_pad_region(
|
||||
pp::paint_renderer::CanvasStrokePadRegionRequest {
|
||||
.extent = stroke_extent,
|
||||
.pass_dirty_box = canvas_stroke_box(box_face[i]),
|
||||
});
|
||||
if (!pad_region.has_pixels)
|
||||
continue;
|
||||
// B(xw)--(zw)C box
|
||||
// | // | coordinates
|
||||
// A(xy)--(zy)D mapping
|
||||
std::array<vertex_t, 6> pad_quad = {
|
||||
vertex_t({pad_box.x, pad_box.y}), // A
|
||||
vertex_t({pad_box.x, pad_box.w}), // B
|
||||
vertex_t({pad_box.z, pad_box.w}), // C
|
||||
vertex_t({pad_box.x, pad_box.y}), // A
|
||||
vertex_t({pad_box.z, pad_box.w}), // C
|
||||
vertex_t({pad_box.z, pad_box.y}), // D
|
||||
vertex_t({pad_region.ndc_quad[0].x, pad_region.ndc_quad[0].y}), // A
|
||||
vertex_t({pad_region.ndc_quad[1].x, pad_region.ndc_quad[1].y}), // B
|
||||
vertex_t({pad_region.ndc_quad[2].x, pad_region.ndc_quad[2].y}), // C
|
||||
vertex_t({pad_region.ndc_quad[3].x, pad_region.ndc_quad[3].y}), // A
|
||||
vertex_t({pad_region.ndc_quad[4].x, pad_region.ndc_quad[4].y}), // C
|
||||
vertex_t({pad_region.ndc_quad[5].x, pad_region.ndc_quad[5].y}), // D
|
||||
};
|
||||
m_brush_shape.update_vertices(pad_quad.data(), pad_quad.size());
|
||||
|
||||
m_tmp[i].bindFramebuffer();
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
glm::vec2 o = glm::max({0, 0}, xy(b) - pad);
|
||||
glm::vec2 sz = glm::min(m_size, zw(b) + pad) - o;
|
||||
m_tex[i].bind();
|
||||
if (sz.x > 0 && sz.y > 0)
|
||||
copy_framebuffer_to_texture_2d(o.x, o.y, o.x, o.y, sz.x, sz.y);
|
||||
copy_framebuffer_to_texture_2d(
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.width,
|
||||
pad_region.copy_region.height);
|
||||
}
|
||||
m_brush_shape.draw_fill();
|
||||
m_tmp[i].unbindFramebuffer();
|
||||
@@ -845,8 +890,16 @@ void Canvas::stroke_draw()
|
||||
m_tmp_dual[i].unbindFramebuffer();
|
||||
|
||||
// this mode overflows the main brush boundries
|
||||
if (stroke_material.composite_pass.dual_blend_mode == 0)
|
||||
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], box_sample), glm::vec4(0), glm::vec4(m_width));
|
||||
const auto dirty_update = pp::paint_renderer::plan_canvas_stroke_face_dirty_update(
|
||||
pp::paint_renderer::CanvasStrokeFaceDirtyUpdateRequest {
|
||||
.extent = stroke_extent,
|
||||
.previous_accumulated_dirty_box = canvas_stroke_box(m_dirty_box[i]),
|
||||
.previous_pass_dirty_box = canvas_stroke_box(box_sample),
|
||||
.sample_dirty_box = canvas_stroke_box(box_sample),
|
||||
.include_in_committed_dirty_box =
|
||||
stroke_material.composite_pass.dual_blend_mode == 0,
|
||||
});
|
||||
m_dirty_box[i] = glm_box(dirty_update.accumulated_dirty_box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user