Share retained stroke sampler dispatch helpers
This commit is contained in:
@@ -18,6 +18,11 @@ 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` live-pass
|
||||||
|
sampler bind/unbind plus semantic texture-input dispatch now route through
|
||||||
|
retained stroke execution helpers; concrete GL object mapping, framebuffer
|
||||||
|
ownership, shader timing, and final draw execution remain retained in
|
||||||
|
`Canvas`.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_samples`
|
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_samples`
|
||||||
now routes destination bind/unbind, framebuffer copy callback wrapping,
|
now routes destination bind/unbind, framebuffer copy callback wrapping,
|
||||||
sample-point assembly, and brush-vertex upload/draw through one local helper;
|
sample-point assembly, and brush-vertex upload/draw through one local helper;
|
||||||
|
|||||||
@@ -3119,6 +3119,10 @@ Results:
|
|||||||
destination bind/unbind, framebuffer copy callback wrapping, sample-point
|
destination bind/unbind, framebuffer copy callback wrapping, sample-point
|
||||||
assembly, and brush-vertex upload/draw, while mixer-pass state execution and
|
assembly, and brush-vertex upload/draw, while mixer-pass state execution and
|
||||||
higher-level pass orchestration remain in the preview node.
|
higher-level pass orchestration remain in the preview node.
|
||||||
|
- `Canvas::stroke_draw` live-pass sampler bind/unbind plus semantic
|
||||||
|
texture-input dispatch now shares retained stroke execution helpers, while
|
||||||
|
concrete GL object mapping, framebuffer ownership, shader timing, and final
|
||||||
|
draw execution remain in the legacy Canvas path.
|
||||||
- `Canvas::stroke_draw` pad-pass destination bind/copy/unbind ordering now
|
- `Canvas::stroke_draw` pad-pass destination bind/copy/unbind ordering now
|
||||||
shares the retained stroke execution helper callback surface, while shader
|
shares the retained stroke execution helper callback surface, while shader
|
||||||
setup, pad color selection, framebuffer ownership, and final OpenGL draw
|
setup, pad color selection, framebuffer ownership, and final OpenGL draw
|
||||||
|
|||||||
@@ -509,6 +509,13 @@ Done Checks:
|
|||||||
|
|
||||||
Progress Notes:
|
Progress Notes:
|
||||||
|
|
||||||
|
- 2026-06-13: `Canvas::stroke_draw` live-pass sampler bind/unbind plus
|
||||||
|
semantic texture-input dispatch now routes through retained stroke execution
|
||||||
|
helpers; concrete GL object mapping, framebuffer ownership, shader timing,
|
||||||
|
and final draw execution remain local to `Canvas`. Next slice should target
|
||||||
|
the remaining live draw execution boundary inside `stroke_draw_samples()` or
|
||||||
|
the final temporary-texture composite setup without reopening the landed
|
||||||
|
dirty, face-framebuffer, pad, or texture-intent helpers.
|
||||||
- 2026-06-13: `NodeStrokePreview::stroke_draw_samples()` now routes
|
- 2026-06-13: `NodeStrokePreview::stroke_draw_samples()` now routes
|
||||||
destination bind/unbind, framebuffer copy callback wrapping, sample-point
|
destination bind/unbind, framebuffer copy callback wrapping, sample-point
|
||||||
assembly, and brush-vertex upload/draw through one local helper; mixer-pass
|
assembly, and brush-vertex upload/draw through one local helper; mixer-pass
|
||||||
|
|||||||
180
src/canvas.cpp
180
src/canvas.cpp
@@ -634,12 +634,6 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
apply_canvas_viewport(0, 0, m_width, m_height);
|
apply_canvas_viewport(0, 0, m_width, m_height);
|
||||||
|
|
||||||
m_sampler_brush.bind(0);
|
|
||||||
m_sampler_nearest.bind(1);
|
|
||||||
m_sampler_stencil.bind(2);
|
|
||||||
m_sampler.bind(3);
|
|
||||||
//m_sampler_linear.bind(5);
|
|
||||||
|
|
||||||
glm::vec2 patt_scale = glm::vec2(brush->m_pattern_scale);
|
glm::vec2 patt_scale = glm::vec2(brush->m_pattern_scale);
|
||||||
if (brush->m_pattern_flipx) patt_scale.x *= -1.f;
|
if (brush->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||||
if (brush->m_pattern_flipy) patt_scale.y *= -1.f;
|
if (brush->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||||
@@ -687,6 +681,24 @@ void Canvas::stroke_draw()
|
|||||||
.slot = 3,
|
.slot = 3,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
constexpr std::array live_pass_sampler_bindings {
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||||
|
.slot = 0,
|
||||||
|
},
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination,
|
||||||
|
.slot = 1,
|
||||||
|
},
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::pattern,
|
||||||
|
.slot = 2,
|
||||||
|
},
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||||
|
.slot = 3,
|
||||||
|
},
|
||||||
|
};
|
||||||
constexpr std::array main_pass_texture_unbindings {
|
constexpr std::array main_pass_texture_unbindings {
|
||||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||||
@@ -697,26 +709,60 @@ void Canvas::stroke_draw()
|
|||||||
.slot = 0,
|
.slot = 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const pp::panopainter::LegacyCanvasStrokeSamplerDispatch live_pass_sampler_dispatch {
|
||||||
|
.bind_brush_tip_sampler = [&](int slot) {
|
||||||
|
m_sampler_brush.bind(slot);
|
||||||
|
},
|
||||||
|
.unbind_brush_tip_sampler = [&] {
|
||||||
|
m_sampler_brush.unbind();
|
||||||
|
},
|
||||||
|
.bind_stroke_destination_sampler = [&](int slot) {
|
||||||
|
m_sampler_nearest.bind(slot);
|
||||||
|
},
|
||||||
|
.unbind_stroke_destination_sampler = [&] {
|
||||||
|
m_sampler_nearest.unbind();
|
||||||
|
},
|
||||||
|
.bind_pattern_sampler = [&](int slot) {
|
||||||
|
m_sampler_stencil.bind(slot);
|
||||||
|
},
|
||||||
|
.unbind_pattern_sampler = [&] {
|
||||||
|
m_sampler_stencil.unbind();
|
||||||
|
},
|
||||||
|
.bind_mixer_sampler = [&](int slot) {
|
||||||
|
m_sampler.bind(slot);
|
||||||
|
},
|
||||||
|
.unbind_mixer_sampler = [&] {
|
||||||
|
m_sampler.unbind();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const pp::panopainter::LegacyCanvasStrokeTextureInputDispatch main_pass_texture_dispatch {
|
||||||
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
|
set_active_texture_unit(texture_slot);
|
||||||
|
},
|
||||||
|
.bind_brush_tip = [&] {
|
||||||
|
brush->m_tip_texture->bind();
|
||||||
|
},
|
||||||
|
.unbind_brush_tip = [&] {
|
||||||
|
brush->m_tip_texture->unbind();
|
||||||
|
},
|
||||||
|
.bind_pattern = [&] {
|
||||||
|
brush->m_pattern_texture ?
|
||||||
|
brush->m_pattern_texture->bind() :
|
||||||
|
unbind_texture_2d();
|
||||||
|
},
|
||||||
|
.bind_mixer = [&] {
|
||||||
|
m_mixer.bindTexture();
|
||||||
|
},
|
||||||
|
.unbind_mixer = [&] {
|
||||||
|
m_mixer.unbindTexture();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
pp::panopainter::bind_legacy_canvas_stroke_sampler_inputs(
|
||||||
|
live_pass_sampler_bindings,
|
||||||
|
live_pass_sampler_dispatch);
|
||||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||||
main_pass_texture_bindings,
|
main_pass_texture_bindings,
|
||||||
[&](auto input, int texture_slot) {
|
main_pass_texture_dispatch);
|
||||||
set_active_texture_unit(texture_slot);
|
|
||||||
switch (input) {
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip:
|
|
||||||
brush->m_tip_texture->bind();
|
|
||||||
break;
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::pattern:
|
|
||||||
brush->m_pattern_texture ?
|
|
||||||
brush->m_pattern_texture->bind() :
|
|
||||||
unbind_texture_2d();
|
|
||||||
break;
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::mixer:
|
|
||||||
m_mixer.bindTexture();
|
|
||||||
break;
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
auto frames = stroke_draw_compute(*m_current_stroke);
|
auto frames = stroke_draw_compute(*m_current_stroke);
|
||||||
|
|
||||||
@@ -755,20 +801,7 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||||
main_pass_texture_unbindings,
|
main_pass_texture_unbindings,
|
||||||
[&](auto input, int texture_slot) {
|
main_pass_texture_dispatch);
|
||||||
set_active_texture_unit(texture_slot);
|
|
||||||
switch (input) {
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip:
|
|
||||||
brush->m_tip_texture->unbind();
|
|
||||||
break;
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::mixer:
|
|
||||||
m_mixer.unbindTexture();
|
|
||||||
break;
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::pattern:
|
|
||||||
case pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// pad stroke
|
// pad stroke
|
||||||
// In order to mitigate color bleeding at the edge of shapes in transparent layers
|
// In order to mitigate color bleeding at the edge of shapes in transparent layers
|
||||||
@@ -808,12 +841,13 @@ void Canvas::stroke_draw()
|
|||||||
.bind_destination_texture = [&](int face_index) {
|
.bind_destination_texture = [&](int face_index) {
|
||||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||||
pad_destination_texture_binding,
|
pad_destination_texture_binding,
|
||||||
[&](auto input, int texture_slot) {
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
if (input != pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination) {
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
return;
|
set_active_texture_unit(texture_slot);
|
||||||
}
|
},
|
||||||
set_active_texture_unit(texture_slot);
|
.bind_stroke_destination = [&] {
|
||||||
m_tex[face_index].bind();
|
m_tex[face_index].bind();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.copy_framebuffer_to_destination_texture =
|
.copy_framebuffer_to_destination_texture =
|
||||||
@@ -829,12 +863,13 @@ void Canvas::stroke_draw()
|
|||||||
.unbind_destination_texture = [&](int face_index) {
|
.unbind_destination_texture = [&](int face_index) {
|
||||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||||
pad_destination_texture_binding,
|
pad_destination_texture_binding,
|
||||||
[&](auto input, int texture_slot) {
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
if (input != pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination) {
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
return;
|
set_active_texture_unit(texture_slot);
|
||||||
}
|
},
|
||||||
set_active_texture_unit(texture_slot);
|
.unbind_stroke_destination = [&] {
|
||||||
m_tex[face_index].unbind();
|
m_tex[face_index].unbind();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.draw_pad = [&] {
|
.draw_pad = [&] {
|
||||||
@@ -860,14 +895,20 @@ void Canvas::stroke_draw()
|
|||||||
};
|
};
|
||||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||||
dual_pass_texture_bindings,
|
dual_pass_texture_bindings,
|
||||||
[&](auto input, int texture_slot) {
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
if (input != pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip) {
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
return;
|
set_active_texture_unit(texture_slot);
|
||||||
}
|
},
|
||||||
set_active_texture_unit(texture_slot);
|
.bind_brush_tip = [&] {
|
||||||
dual_brush->m_tip_texture ?
|
dual_brush->m_tip_texture ?
|
||||||
dual_brush->m_tip_texture->bind() :
|
dual_brush->m_tip_texture->bind() :
|
||||||
unbind_texture_2d();
|
unbind_texture_2d();
|
||||||
|
},
|
||||||
|
.unbind_brush_tip = [&] {
|
||||||
|
dual_brush->m_tip_texture ?
|
||||||
|
dual_brush->m_tip_texture->unbind() :
|
||||||
|
unbind_texture_2d();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
auto frames_dual = stroke_draw_compute(*m_dual_stroke);
|
auto frames_dual = stroke_draw_compute(*m_dual_stroke);
|
||||||
const std::array<bool, 6> include_dual_dirty =
|
const std::array<bool, 6> include_dual_dirty =
|
||||||
@@ -895,20 +936,21 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||||
dual_pass_texture_bindings,
|
dual_pass_texture_bindings,
|
||||||
[&](auto input, int texture_slot) {
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
if (input != pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip) {
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
return;
|
set_active_texture_unit(texture_slot);
|
||||||
}
|
},
|
||||||
set_active_texture_unit(texture_slot);
|
.unbind_brush_tip = [&] {
|
||||||
dual_brush->m_tip_texture ?
|
dual_brush->m_tip_texture ?
|
||||||
dual_brush->m_tip_texture->unbind() :
|
dual_brush->m_tip_texture->unbind() :
|
||||||
unbind_texture_2d();
|
unbind_texture_2d();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sampler_brush.unbind();
|
pp::panopainter::unbind_legacy_canvas_stroke_sampler_inputs(
|
||||||
m_sampler_nearest.unbind();
|
live_pass_sampler_bindings,
|
||||||
m_sampler_stencil.unbind();
|
live_pass_sampler_dispatch);
|
||||||
|
|
||||||
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
||||||
apply_canvas_clear_color(cc);
|
apply_canvas_clear_color(cc);
|
||||||
|
|||||||
@@ -49,6 +49,29 @@ struct LegacyCanvasStrokeTextureBinding {
|
|||||||
int slot = 0;
|
int slot = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeTextureInputDispatch {
|
||||||
|
std::function<void(int)> activate_texture_unit;
|
||||||
|
std::function<void()> bind_brush_tip;
|
||||||
|
std::function<void()> unbind_brush_tip;
|
||||||
|
std::function<void()> bind_stroke_destination;
|
||||||
|
std::function<void()> unbind_stroke_destination;
|
||||||
|
std::function<void()> bind_pattern;
|
||||||
|
std::function<void()> unbind_pattern;
|
||||||
|
std::function<void()> bind_mixer;
|
||||||
|
std::function<void()> unbind_mixer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LegacyCanvasStrokeSamplerDispatch {
|
||||||
|
std::function<void(int)> bind_brush_tip_sampler;
|
||||||
|
std::function<void()> unbind_brush_tip_sampler;
|
||||||
|
std::function<void(int)> bind_stroke_destination_sampler;
|
||||||
|
std::function<void()> unbind_stroke_destination_sampler;
|
||||||
|
std::function<void(int)> bind_pattern_sampler;
|
||||||
|
std::function<void()> unbind_pattern_sampler;
|
||||||
|
std::function<void(int)> bind_mixer_sampler;
|
||||||
|
std::function<void()> unbind_mixer_sampler;
|
||||||
|
};
|
||||||
|
|
||||||
struct LegacyCanvasStrokeFaceDirtyRequest {
|
struct LegacyCanvasStrokeFaceDirtyRequest {
|
||||||
pp::renderer::Extent2D extent {};
|
pp::renderer::Extent2D extent {};
|
||||||
glm::vec4 previous_accumulated_dirty_box {};
|
glm::vec4 previous_accumulated_dirty_box {};
|
||||||
@@ -232,6 +255,165 @@ inline void unbind_legacy_canvas_stroke_texture_inputs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void bind_legacy_canvas_stroke_texture_input(
|
||||||
|
LegacyCanvasStrokeTextureInput input,
|
||||||
|
const LegacyCanvasStrokeTextureInputDispatch& dispatch)
|
||||||
|
{
|
||||||
|
switch (input) {
|
||||||
|
case LegacyCanvasStrokeTextureInput::brush_tip:
|
||||||
|
if (dispatch.bind_brush_tip) {
|
||||||
|
dispatch.bind_brush_tip();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::stroke_destination:
|
||||||
|
if (dispatch.bind_stroke_destination) {
|
||||||
|
dispatch.bind_stroke_destination();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::pattern:
|
||||||
|
if (dispatch.bind_pattern) {
|
||||||
|
dispatch.bind_pattern();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::mixer:
|
||||||
|
if (dispatch.bind_mixer) {
|
||||||
|
dispatch.bind_mixer();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void unbind_legacy_canvas_stroke_texture_input(
|
||||||
|
LegacyCanvasStrokeTextureInput input,
|
||||||
|
const LegacyCanvasStrokeTextureInputDispatch& dispatch)
|
||||||
|
{
|
||||||
|
switch (input) {
|
||||||
|
case LegacyCanvasStrokeTextureInput::brush_tip:
|
||||||
|
if (dispatch.unbind_brush_tip) {
|
||||||
|
dispatch.unbind_brush_tip();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::stroke_destination:
|
||||||
|
if (dispatch.unbind_stroke_destination) {
|
||||||
|
dispatch.unbind_stroke_destination();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::pattern:
|
||||||
|
if (dispatch.unbind_pattern) {
|
||||||
|
dispatch.unbind_pattern();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::mixer:
|
||||||
|
if (dispatch.unbind_mixer) {
|
||||||
|
dispatch.unbind_mixer();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void bind_legacy_canvas_stroke_sampler_input(
|
||||||
|
LegacyCanvasStrokeTextureInput input,
|
||||||
|
int slot,
|
||||||
|
const LegacyCanvasStrokeSamplerDispatch& dispatch)
|
||||||
|
{
|
||||||
|
switch (input) {
|
||||||
|
case LegacyCanvasStrokeTextureInput::brush_tip:
|
||||||
|
if (dispatch.bind_brush_tip_sampler) {
|
||||||
|
dispatch.bind_brush_tip_sampler(slot);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::stroke_destination:
|
||||||
|
if (dispatch.bind_stroke_destination_sampler) {
|
||||||
|
dispatch.bind_stroke_destination_sampler(slot);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::pattern:
|
||||||
|
if (dispatch.bind_pattern_sampler) {
|
||||||
|
dispatch.bind_pattern_sampler(slot);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::mixer:
|
||||||
|
if (dispatch.bind_mixer_sampler) {
|
||||||
|
dispatch.bind_mixer_sampler(slot);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void unbind_legacy_canvas_stroke_sampler_input(
|
||||||
|
LegacyCanvasStrokeTextureInput input,
|
||||||
|
const LegacyCanvasStrokeSamplerDispatch& dispatch)
|
||||||
|
{
|
||||||
|
switch (input) {
|
||||||
|
case LegacyCanvasStrokeTextureInput::brush_tip:
|
||||||
|
if (dispatch.unbind_brush_tip_sampler) {
|
||||||
|
dispatch.unbind_brush_tip_sampler();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::stroke_destination:
|
||||||
|
if (dispatch.unbind_stroke_destination_sampler) {
|
||||||
|
dispatch.unbind_stroke_destination_sampler();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::pattern:
|
||||||
|
if (dispatch.unbind_pattern_sampler) {
|
||||||
|
dispatch.unbind_pattern_sampler();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LegacyCanvasStrokeTextureInput::mixer:
|
||||||
|
if (dispatch.unbind_mixer_sampler) {
|
||||||
|
dispatch.unbind_mixer_sampler();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t BindingCount>
|
||||||
|
inline void bind_legacy_canvas_stroke_texture_inputs(
|
||||||
|
const std::array<LegacyCanvasStrokeTextureBinding, BindingCount>& bindings,
|
||||||
|
const LegacyCanvasStrokeTextureInputDispatch& dispatch)
|
||||||
|
{
|
||||||
|
for (const auto& binding : bindings) {
|
||||||
|
if (dispatch.activate_texture_unit) {
|
||||||
|
dispatch.activate_texture_unit(binding.slot);
|
||||||
|
}
|
||||||
|
bind_legacy_canvas_stroke_texture_input(binding.input, dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t BindingCount>
|
||||||
|
inline void unbind_legacy_canvas_stroke_texture_inputs(
|
||||||
|
const std::array<LegacyCanvasStrokeTextureBinding, BindingCount>& bindings,
|
||||||
|
const LegacyCanvasStrokeTextureInputDispatch& dispatch)
|
||||||
|
{
|
||||||
|
for (const auto& binding : bindings) {
|
||||||
|
if (dispatch.activate_texture_unit) {
|
||||||
|
dispatch.activate_texture_unit(binding.slot);
|
||||||
|
}
|
||||||
|
unbind_legacy_canvas_stroke_texture_input(binding.input, dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t BindingCount>
|
||||||
|
inline void bind_legacy_canvas_stroke_sampler_inputs(
|
||||||
|
const std::array<LegacyCanvasStrokeTextureBinding, BindingCount>& bindings,
|
||||||
|
const LegacyCanvasStrokeSamplerDispatch& dispatch)
|
||||||
|
{
|
||||||
|
for (const auto& binding : bindings) {
|
||||||
|
bind_legacy_canvas_stroke_sampler_input(binding.input, binding.slot, dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t BindingCount>
|
||||||
|
inline void unbind_legacy_canvas_stroke_sampler_inputs(
|
||||||
|
const std::array<LegacyCanvasStrokeTextureBinding, BindingCount>& bindings,
|
||||||
|
const LegacyCanvasStrokeSamplerDispatch& dispatch)
|
||||||
|
{
|
||||||
|
for (const auto& binding : bindings) {
|
||||||
|
unbind_legacy_canvas_stroke_sampler_input(binding.input, dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Frames, typename BeginFrame, typename BeginFace, typename ExecuteSample, typename FinishFace>
|
template <typename Frames, typename BeginFrame, typename BeginFace, typename ExecuteSample, typename FinishFace>
|
||||||
std::size_t execute_legacy_canvas_stroke_frame_samples(
|
std::size_t execute_legacy_canvas_stroke_frame_samples(
|
||||||
Frames&& frames,
|
Frames&& frames,
|
||||||
|
|||||||
Reference in New Issue
Block a user