Clean retained stroke extraction build
This commit is contained in:
336
src/canvas.cpp
336
src/canvas.cpp
@@ -247,6 +247,11 @@ void delete_canvas_renderbuffer(GLuint renderbuffer)
|
||||
}
|
||||
|
||||
|
||||
pp::panopainter::LegacyCanvasStrokeMixPassShell make_canvas_stroke_mix_pass_shell(
|
||||
Canvas& canvas,
|
||||
const glm::vec2& bb_min,
|
||||
const glm::vec2& bb_sz);
|
||||
|
||||
Canvas* Canvas::I;
|
||||
std::vector<CanvasMode*> Canvas::modes[] = {
|
||||
{ new CanvasModePen, new CanvasModeBasicCamera }, // brush
|
||||
@@ -508,19 +513,44 @@ static void execute_canvas_draw_merge_final_plane_composite(
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_final_plane_composite(uniforms, execution);
|
||||
}
|
||||
|
||||
static void execute_canvas_draw_merge_temporary_erase_dispatch(
|
||||
Canvas& canvas,
|
||||
int plane_index,
|
||||
int layer_index,
|
||||
const std::shared_ptr<Layer>& layer,
|
||||
const glm::mat4& ortho);
|
||||
|
||||
static pp::panopainter::LegacyCanvasDrawMergeTemporaryCompositeExecution
|
||||
make_canvas_draw_merge_temporary_paint_request(
|
||||
Canvas& canvas,
|
||||
int layer_index,
|
||||
int plane_index,
|
||||
const std::shared_ptr<Layer>& layer,
|
||||
const Brush& brush,
|
||||
const glm::mat4& ortho);
|
||||
|
||||
static pp::panopainter::LegacyCanvasDrawMergeLayerTextureExecution
|
||||
make_canvas_draw_merge_layer_texture_dispatch(
|
||||
Canvas& canvas,
|
||||
int plane_index,
|
||||
int layer_index);
|
||||
|
||||
static pp::panopainter::LegacyCanvasDrawMergeLayerBlendExecution
|
||||
make_canvas_draw_merge_layer_blend_dispatch(Canvas& canvas);
|
||||
|
||||
static pp::panopainter::LegacyCanvasDrawMergeFinalPlaneCompositeExecution
|
||||
make_canvas_draw_merge_final_plane_composite_execution(Canvas& canvas)
|
||||
{
|
||||
return {
|
||||
.bind_merged_texture_copy_target = [&] {
|
||||
canvas.set_active_texture_unit(2);
|
||||
set_active_texture_unit(2);
|
||||
canvas.m_merge_tex.bind();
|
||||
},
|
||||
.copy_merged_framebuffer = [&] {
|
||||
canvas.copy_framebuffer_to_texture_2d(0, 0, 0, 0, canvas.m_width, canvas.m_height);
|
||||
copy_framebuffer_to_texture_2d(0, 0, 0, 0, canvas.m_width, canvas.m_height);
|
||||
},
|
||||
.enable_blend = [&] {
|
||||
canvas.apply_canvas_capability(canvas.blend_state(), true);
|
||||
apply_canvas_capability(blend_state(), true);
|
||||
},
|
||||
.draw = [&] {
|
||||
canvas.m_plane.draw_fill();
|
||||
@@ -529,7 +559,7 @@ make_canvas_draw_merge_final_plane_composite_execution(Canvas& canvas)
|
||||
canvas.m_sampler.bind(0);
|
||||
},
|
||||
.bind_merged_texture = [&] {
|
||||
canvas.set_active_texture_unit(0);
|
||||
set_active_texture_unit(0);
|
||||
canvas.m_merge_tex.bind();
|
||||
},
|
||||
.unbind_merged_texture = [&] {
|
||||
@@ -616,14 +646,15 @@ static pp::panopainter::LegacyCanvasDrawMergeLayerCompositeExecution make_canvas
|
||||
ortho);
|
||||
},
|
||||
.execute_temporary_paint = [&] {
|
||||
canvas.draw_merge_temporary_paint_branch(
|
||||
layer_index,
|
||||
plane_index,
|
||||
layer,
|
||||
brush,
|
||||
ortho,
|
||||
copy_blend_destination,
|
||||
draw_checkerboard);
|
||||
(void)draw_checkerboard;
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_temporary_composite(
|
||||
make_canvas_draw_merge_temporary_paint_request(
|
||||
canvas,
|
||||
layer_index,
|
||||
plane_index,
|
||||
layer,
|
||||
brush,
|
||||
ortho));
|
||||
},
|
||||
.execute_layer_texture = [&] {
|
||||
execute_canvas_draw_merge_layer_texture(
|
||||
@@ -700,8 +731,24 @@ static auto make_canvas_draw_merge_temporary_erase_dispatch(
|
||||
canvas.m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
});
|
||||
}
|
||||
static void execute_canvas_draw_merge_temporary_erase_dispatch(
|
||||
Canvas& canvas,
|
||||
int plane_index,
|
||||
int layer_index,
|
||||
const std::shared_ptr<Layer>& layer,
|
||||
const glm::mat4& ortho)
|
||||
{
|
||||
pp::panopainter::execute_legacy_canvas_draw_merge_temporary_composite(
|
||||
make_canvas_draw_merge_temporary_erase_dispatch(
|
||||
canvas,
|
||||
plane_index,
|
||||
layer_index,
|
||||
layer,
|
||||
ortho));
|
||||
}
|
||||
|
||||
static auto make_canvas_draw_merge_layer_texture_dispatch(
|
||||
static pp::panopainter::LegacyCanvasDrawMergeLayerTextureExecution
|
||||
make_canvas_draw_merge_layer_texture_dispatch(
|
||||
Canvas& canvas,
|
||||
int plane_index,
|
||||
int layer_index)
|
||||
@@ -723,7 +770,8 @@ static auto make_canvas_draw_merge_layer_texture_dispatch(
|
||||
};
|
||||
}
|
||||
|
||||
static auto make_canvas_draw_merge_layer_blend_dispatch(Canvas& canvas)
|
||||
static pp::panopainter::LegacyCanvasDrawMergeLayerBlendExecution
|
||||
make_canvas_draw_merge_layer_blend_dispatch(Canvas& canvas)
|
||||
{
|
||||
return pp::panopainter::LegacyCanvasDrawMergeLayerBlendExecution {
|
||||
.unbind_merge_framebuffer = [&] {
|
||||
@@ -822,7 +870,8 @@ static void execute_canvas_draw_merge_plane_dispatch(
|
||||
|
||||
for (int layer_index = 0; layer_index < layers.size(); layer_index++)
|
||||
{
|
||||
canvas.draw_merge_branch_orchestration(
|
||||
execute_canvas_draw_merge_branch_body(
|
||||
canvas,
|
||||
plane_index,
|
||||
layer_index,
|
||||
layers[layer_index],
|
||||
@@ -845,23 +894,48 @@ static void execute_canvas_draw_merge_plane_final_composite(
|
||||
{
|
||||
if (use_blend)
|
||||
{
|
||||
canvas.draw_merge_final_plane_composite(ortho, draw_checkerboard);
|
||||
execute_canvas_draw_merge_final_plane_composite(
|
||||
pp::panopainter::LegacyCanvasDrawMergeFinalPlaneCompositeUniforms {
|
||||
.checkerboard = {
|
||||
.mvp = ortho,
|
||||
.colorize = false,
|
||||
},
|
||||
.texture = {
|
||||
.mvp = ortho,
|
||||
.texture_slot = 0,
|
||||
},
|
||||
.draw_checkerboard = draw_checkerboard,
|
||||
},
|
||||
make_canvas_draw_merge_final_plane_composite_execution(canvas));
|
||||
}
|
||||
}
|
||||
|
||||
static auto make_canvas_stroke_mix_pass_shell(
|
||||
pp::panopainter::LegacyCanvasStrokeMixPassShell make_canvas_stroke_mix_pass_shell(
|
||||
Canvas& canvas,
|
||||
const glm::vec2& bb_min,
|
||||
const glm::vec2& bb_sz)
|
||||
{
|
||||
const auto layer_index = canvas.m_current_layer_idx;
|
||||
auto& current_layer = *canvas.m_layers[layer_index];
|
||||
std::array<glm::mat4, 6> plane_transform {};
|
||||
std::copy(std::begin(Canvas::m_plane_transform), std::end(Canvas::m_plane_transform), plane_transform.begin());
|
||||
const auto mix_planes = pp::panopainter::plan_legacy_canvas_stroke_mix_pass_planes(
|
||||
current_layer.m_visible,
|
||||
current_layer.m_opacity,
|
||||
glm::scale(glm::vec3(1, -1, 1)) * canvas.m_proj * canvas.m_mv,
|
||||
plane_transform,
|
||||
[&](int plane_index) {
|
||||
return current_layer.face(plane_index);
|
||||
});
|
||||
const auto& b = canvas.m_current_stroke->m_brush;
|
||||
return pp::panopainter::make_legacy_canvas_stroke_mix_pass_shell(
|
||||
[&] {
|
||||
canvas.m_mixer.bindFramebuffer();
|
||||
canvas.apply_canvas_viewport(0, 0, canvas.m_mixer.getWidth(), canvas.m_mixer.getHeight());
|
||||
canvas.apply_canvas_capability(canvas.depth_test_state(), false);
|
||||
canvas.apply_canvas_capability(canvas.scissor_test_state(), true);
|
||||
canvas.apply_canvas_capability(canvas.blend_state(), false);
|
||||
canvas.apply_canvas_scissor(
|
||||
apply_canvas_viewport(0, 0, canvas.m_mixer.getWidth(), canvas.m_mixer.getHeight());
|
||||
apply_canvas_capability(depth_test_state(), false);
|
||||
apply_canvas_capability(scissor_test_state(), true);
|
||||
apply_canvas_capability(blend_state(), false);
|
||||
apply_canvas_scissor(
|
||||
static_cast<std::int32_t>(bb_min.x),
|
||||
static_cast<std::int32_t>(bb_min.y),
|
||||
static_cast<std::int32_t>(bb_sz.x),
|
||||
@@ -869,20 +943,91 @@ static auto make_canvas_stroke_mix_pass_shell(
|
||||
},
|
||||
[&] {
|
||||
canvas.m_mixer.unbindFramebuffer();
|
||||
},
|
||||
"Canvas::stroke_draw_mix",
|
||||
canvas.m_size,
|
||||
mix_planes,
|
||||
[&] {
|
||||
canvas.m_sampler.bind(0);
|
||||
canvas.m_sampler.bind(1);
|
||||
canvas.m_sampler.bind(2);
|
||||
},
|
||||
[&] {
|
||||
canvas.m_sampler.unbind();
|
||||
},
|
||||
[&](int plane_index, const glm::mat4& plane_mvp_z) {
|
||||
(void)plane_index;
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = canvas.m_size,
|
||||
.mvp = plane_mvp_z,
|
||||
.pattern_texture_slot = 3,
|
||||
.layer_alpha = 1.0f,
|
||||
.alpha_lock = false,
|
||||
.mask_enabled = false,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = b->m_blend_mode,
|
||||
.use_dual = false,
|
||||
.use_pattern = false,
|
||||
});
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(0);
|
||||
current_layer.rtt(plane_index).bindTexture();
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(1);
|
||||
canvas.m_tmp[plane_index].bindTexture();
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(2);
|
||||
canvas.m_smask.rtt(plane_index).bindTexture();
|
||||
},
|
||||
[&] {
|
||||
canvas.m_node->m_face_plane.draw_fill();
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(2);
|
||||
canvas.m_smask.rtt(plane_index).unbindTexture();
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(1);
|
||||
canvas.m_tmp[plane_index].unbindTexture();
|
||||
},
|
||||
[&](int plane_index) {
|
||||
set_active_texture_unit(0);
|
||||
current_layer.rtt(plane_index).unbindTexture();
|
||||
});
|
||||
}
|
||||
|
||||
static void stamp_canvas_stroke_commit_action(
|
||||
Canvas& canvas,
|
||||
ActionStroke* action);
|
||||
|
||||
static void capture_canvas_stroke_commit_layer_state(
|
||||
Canvas& canvas,
|
||||
ActionStroke* action,
|
||||
int i);
|
||||
|
||||
static void apply_canvas_stroke_commit_dirty_mutation(
|
||||
Canvas& canvas,
|
||||
int i);
|
||||
|
||||
static void copy_canvas_stroke_commit_layer_image(
|
||||
Canvas& canvas,
|
||||
int i);
|
||||
|
||||
template <typename SetActiveTextureUnit>
|
||||
static auto make_canvas_stroke_commit_callbacks(
|
||||
Canvas& canvas,
|
||||
const glm::vec4& vp,
|
||||
const glm::vec4& cc,
|
||||
pp::renderer::gl::OpenGlViewportRect vp,
|
||||
std::array<float, 4> cc,
|
||||
bool blend,
|
||||
SetActiveTextureUnit&& set_active_texture_unit,
|
||||
ActionStroke* action,
|
||||
const Stroke* current_stroke,
|
||||
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& sequence,
|
||||
const pp::paint_renderer::CanvasStrokeCommitMaterialPlan& stroke_material)
|
||||
const pp::paint_renderer::CanvasStrokeMaterialPlan& stroke_material)
|
||||
{
|
||||
const auto& b = current_stroke->m_brush;
|
||||
auto bind_commit_inputs = [&](int i) {
|
||||
@@ -938,19 +1083,20 @@ static auto make_canvas_stroke_commit_callbacks(
|
||||
},
|
||||
[]() {},
|
||||
[&]() {
|
||||
canvas.apply_canvas_viewport(0, 0, canvas.m_width, canvas.m_height);
|
||||
canvas.apply_canvas_capability(canvas.blend_state(), false);
|
||||
apply_canvas_viewport(0, 0, canvas.m_width, canvas.m_height);
|
||||
apply_canvas_capability(blend_state(), false);
|
||||
},
|
||||
[&]() {
|
||||
blend ? canvas.apply_canvas_capability(canvas.blend_state(), true) : canvas.apply_canvas_capability(canvas.blend_state(), false);
|
||||
canvas.apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
||||
canvas.apply_canvas_clear_color(cc);
|
||||
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
|
||||
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
|
||||
apply_canvas_clear_color(cc);
|
||||
set_active_texture_unit(0);
|
||||
},
|
||||
[&]() { stamp_canvas_stroke_commit_action(canvas, action); },
|
||||
[&]() {
|
||||
canvas.stroke_commit_timelapse();
|
||||
},
|
||||
[](int) {},
|
||||
[&](int i) { capture_canvas_stroke_commit_layer_state(canvas, action, i); },
|
||||
[&](int i) { apply_canvas_stroke_commit_dirty_mutation(canvas, i); },
|
||||
[&](int i) { copy_canvas_stroke_commit_layer_image(canvas, i); },
|
||||
@@ -1082,7 +1228,7 @@ pp::panopainter::LegacyCanvasStrokeTextureInputDispatch Canvas::make_stroke_draw
|
||||
pp::panopainter::LegacyStrokeFaceSamplePolygonExecutionRequest Canvas::make_stroke_draw_samples_request(
|
||||
int face_index,
|
||||
std::vector<vertex_t>& polygon_vertices,
|
||||
bool copy_stroke_destination) const
|
||||
bool copy_stroke_destination)
|
||||
{
|
||||
return pp::panopainter::LegacyStrokeFaceSamplePolygonExecutionRequest {
|
||||
.context = "Canvas::stroke_draw_samples",
|
||||
@@ -1122,14 +1268,14 @@ static auto execute_canvas_stroke_commit_sequence(
|
||||
template <typename SetActiveTextureUnit>
|
||||
static auto make_canvas_stroke_commit_request(
|
||||
Canvas& canvas,
|
||||
const glm::vec4& vp,
|
||||
const glm::vec4& cc,
|
||||
pp::renderer::gl::OpenGlViewportRect vp,
|
||||
std::array<float, 4> cc,
|
||||
bool blend,
|
||||
SetActiveTextureUnit&& set_active_texture_unit,
|
||||
ActionStroke* action,
|
||||
const Stroke* current_stroke,
|
||||
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& sequence,
|
||||
const pp::paint_renderer::CanvasStrokeCommitMaterialPlan& stroke_material)
|
||||
const pp::paint_renderer::CanvasStrokeMaterialPlan& stroke_material)
|
||||
{
|
||||
const auto commit_callbacks = make_canvas_stroke_commit_callbacks(
|
||||
canvas,
|
||||
@@ -1157,14 +1303,14 @@ static auto make_canvas_stroke_commit_request(
|
||||
template <typename SetActiveTextureUnit>
|
||||
static auto execute_canvas_stroke_commit_request(
|
||||
Canvas& canvas,
|
||||
const glm::vec4& vp,
|
||||
const glm::vec4& cc,
|
||||
pp::renderer::gl::OpenGlViewportRect vp,
|
||||
std::array<float, 4> cc,
|
||||
bool blend,
|
||||
SetActiveTextureUnit&& set_active_texture_unit,
|
||||
ActionStroke* action,
|
||||
const Stroke* current_stroke,
|
||||
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& sequence,
|
||||
const pp::paint_renderer::CanvasStrokeCommitMaterialPlan& stroke_material)
|
||||
const pp::paint_renderer::CanvasStrokeMaterialPlan& stroke_material)
|
||||
{
|
||||
return execute_canvas_stroke_commit_sequence([&]() {
|
||||
return make_canvas_stroke_commit_request(
|
||||
@@ -1183,14 +1329,14 @@ static auto execute_canvas_stroke_commit_request(
|
||||
template <typename SetActiveTextureUnit>
|
||||
static auto execute_canvas_stroke_commit_dispatch(
|
||||
Canvas& canvas,
|
||||
const glm::vec4& vp,
|
||||
const glm::vec4& cc,
|
||||
pp::renderer::gl::OpenGlViewportRect vp,
|
||||
std::array<float, 4> cc,
|
||||
bool blend,
|
||||
SetActiveTextureUnit&& set_active_texture_unit,
|
||||
ActionStroke* action,
|
||||
const Stroke* current_stroke,
|
||||
const pp::paint_renderer::CanvasStrokeCommitSequencePlan& sequence,
|
||||
const pp::paint_renderer::CanvasStrokeCommitMaterialPlan& stroke_material)
|
||||
const pp::paint_renderer::CanvasStrokeMaterialPlan& stroke_material)
|
||||
{
|
||||
return execute_canvas_stroke_commit_request(
|
||||
canvas,
|
||||
@@ -1204,13 +1350,32 @@ static auto execute_canvas_stroke_commit_dispatch(
|
||||
stroke_material);
|
||||
}
|
||||
|
||||
struct CanvasStrokeCommitPrelude {
|
||||
pp::renderer::gl::OpenGlViewportRect viewport;
|
||||
std::array<float, 4> clear_color;
|
||||
bool blend;
|
||||
ActionStroke* action;
|
||||
};
|
||||
|
||||
static CanvasStrokeCommitPrelude make_canvas_stroke_commit_prelude(Canvas& canvas)
|
||||
{
|
||||
CanvasStrokeCommitPrelude prelude {
|
||||
.viewport = query_canvas_viewport(),
|
||||
.clear_color = query_canvas_clear_color(),
|
||||
.blend = query_canvas_capability(blend_state()),
|
||||
.action = new ActionStroke,
|
||||
};
|
||||
prelude.action->was_saved = !canvas.m_unsaved;
|
||||
return prelude;
|
||||
}
|
||||
|
||||
static pp::paint_renderer::CanvasStrokeCommitSequencePlan
|
||||
make_canvas_stroke_commit_sequence_plan(
|
||||
const Canvas& canvas,
|
||||
kCanvasMode current_mode,
|
||||
int current_layer_idx,
|
||||
bool smask_active,
|
||||
const pp::paint_renderer::CanvasStrokeCommitMaterialPlan& stroke_material)
|
||||
const pp::paint_renderer::CanvasStrokeMaterialPlan& stroke_material)
|
||||
{
|
||||
return pp::paint_renderer::plan_canvas_stroke_commit_sequence(
|
||||
pp::paint_renderer::CanvasStrokeCommitRequest {
|
||||
@@ -1340,7 +1505,9 @@ void Canvas::stroke_draw_pad_pass(
|
||||
[&](const pp::paint_renderer::CanvasStrokeCopyRegion& copy_region) {
|
||||
pp::panopainter::execute_legacy_canvas_stroke_pad_copy_region(
|
||||
copy_region,
|
||||
copy_framebuffer_to_texture_2d);
|
||||
[](int src_x, int src_y, int dst_x, int dst_y, int width, int height) {
|
||||
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
||||
});
|
||||
},
|
||||
[&](int) {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||
@@ -1410,7 +1577,8 @@ void Canvas::stroke_draw_pad_face_callback_body(
|
||||
pad_color);
|
||||
}
|
||||
|
||||
static auto make_canvas_draw_merge_temporary_paint_request(
|
||||
static pp::panopainter::LegacyCanvasDrawMergeTemporaryCompositeExecution
|
||||
make_canvas_draw_merge_temporary_paint_request(
|
||||
Canvas& canvas,
|
||||
int layer_index,
|
||||
int plane_index,
|
||||
@@ -1418,10 +1586,10 @@ static auto make_canvas_draw_merge_temporary_paint_request(
|
||||
const Brush& brush,
|
||||
const glm::mat4& ortho)
|
||||
{
|
||||
const auto stroke_material = canvas_stroke_material_plan(*brush, false);
|
||||
glm::vec2 patt_scale = glm::vec2(brush->m_pattern_scale);
|
||||
if (brush->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||
if (brush->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||
const auto stroke_material = canvas_stroke_material_plan(brush, false);
|
||||
glm::vec2 patt_scale = glm::vec2(brush.m_pattern_scale);
|
||||
if (brush.m_pattern_flipx) patt_scale.x *= -1.f;
|
||||
if (brush.m_pattern_flipy) patt_scale.y *= -1.f;
|
||||
|
||||
return pp::panopainter::make_legacy_canvas_draw_merge_temporary_paint_composite(
|
||||
[&] {
|
||||
@@ -1430,11 +1598,11 @@ static auto make_canvas_draw_merge_temporary_paint_request(
|
||||
.resolution = Canvas::I->m_size,
|
||||
.pattern = {
|
||||
.scale = patt_scale,
|
||||
.invert = static_cast<float>(brush->m_pattern_invert),
|
||||
.brightness = brush->m_pattern_brightness,
|
||||
.contrast = brush->m_pattern_contrast,
|
||||
.depth = brush->m_pattern_depth,
|
||||
.blend_mode = brush->m_pattern_blend_mode,
|
||||
.invert = static_cast<float>(brush.m_pattern_invert),
|
||||
.brightness = brush.m_pattern_brightness,
|
||||
.contrast = brush.m_pattern_contrast,
|
||||
.depth = brush.m_pattern_depth,
|
||||
.blend_mode = brush.m_pattern_blend_mode,
|
||||
.offset = Canvas::I->m_pattern_offset,
|
||||
},
|
||||
.mvp = ortho,
|
||||
@@ -1442,7 +1610,7 @@ static auto make_canvas_draw_merge_temporary_paint_request(
|
||||
.alpha_lock = layer->m_alpha_locked,
|
||||
.mask_enabled = canvas.m_smask_active,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = brush->m_blend_mode,
|
||||
.blend_mode = brush.m_blend_mode,
|
||||
.use_dual = stroke_material.composite_pass.use_dual,
|
||||
.dual_blend_mode = stroke_material.composite_pass.dual_blend_mode,
|
||||
.dual_alpha = stroke_material.composite_pass.dual_alpha,
|
||||
@@ -1467,7 +1635,7 @@ static auto make_canvas_draw_merge_temporary_paint_request(
|
||||
if (stroke_material.composite_pass.use_dual)
|
||||
canvas.m_tmp_dual[plane_index].bindTexture();
|
||||
set_active_texture_unit(4);
|
||||
brush->m_pattern_texture ? brush->m_pattern_texture->bind() : unbind_texture_2d();
|
||||
brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d();
|
||||
},
|
||||
[&] {
|
||||
canvas.m_plane.draw_fill();
|
||||
@@ -1572,6 +1740,22 @@ void Canvas::stroke_draw_dual_pass(
|
||||
copy_stroke_destination));
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyCanvasStrokeMainPassExecutionRequest Canvas::make_stroke_draw_main_pass_request(
|
||||
std::function<void()> bind_samplers,
|
||||
std::function<void()> bind_textures,
|
||||
std::function<void()> execute_frame_pass,
|
||||
std::function<void()> unbind_textures,
|
||||
std::function<void()> unbind_samplers)
|
||||
{
|
||||
return pp::panopainter::make_legacy_canvas_stroke_main_pass_execution_request(
|
||||
"Canvas::stroke_draw",
|
||||
std::move(bind_samplers),
|
||||
std::move(bind_textures),
|
||||
std::move(execute_frame_pass),
|
||||
std::move(unbind_textures),
|
||||
std::move(unbind_samplers));
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyCanvasStrokeDualPassRequest Canvas::make_stroke_draw_dual_pass_request(
|
||||
const std::vector<StrokeFrame>& frames_dual,
|
||||
const std::array<pp::panopainter::LegacyCanvasStrokeTextureBinding, 1>& dual_pass_texture_bindings,
|
||||
@@ -1628,8 +1812,9 @@ void Canvas::stroke_draw_dual_pass_frame_pass(
|
||||
});
|
||||
},
|
||||
[](auto&, int, auto&) {},
|
||||
[&](auto&, int i, auto& P) {
|
||||
return stroke_draw_samples(i, P, copy_stroke_destination);
|
||||
[&](auto&, int i, auto&& P) {
|
||||
auto polygon = std::move(P);
|
||||
return stroke_draw_samples(i, polygon, copy_stroke_destination);
|
||||
},
|
||||
m_tmp_dual,
|
||||
true);
|
||||
@@ -1784,19 +1969,18 @@ void Canvas::stroke_draw()
|
||||
glm::vec4 pad_color;
|
||||
[[maybe_unused]] const auto main_pass_result =
|
||||
pp::panopainter::execute_legacy_canvas_stroke_main_pass(
|
||||
pp::panopainter::LegacyCanvasStrokeMainPassExecutionRequest {
|
||||
.context = "Canvas::stroke_draw",
|
||||
.bind_samplers = [&] {
|
||||
make_stroke_draw_main_pass_request(
|
||||
[&] {
|
||||
pp::panopainter::bind_legacy_canvas_stroke_sampler_inputs(
|
||||
live_pass_sampler_bindings,
|
||||
live_pass_sampler_dispatch);
|
||||
},
|
||||
.bind_textures = [&] {
|
||||
[&] {
|
||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_bindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
.execute_frame_pass = [&] {
|
||||
[&] {
|
||||
pp::panopainter::execute_legacy_canvas_stroke_main_pass_frame_callbacks(
|
||||
frames,
|
||||
stroke_extent,
|
||||
@@ -1821,22 +2005,22 @@ void Canvas::stroke_draw()
|
||||
.color = f.col,
|
||||
.alpha = f.flow,
|
||||
.opacity = f.opacity,
|
||||
});
|
||||
});
|
||||
return stroke_draw_samples(i, P, copy_stroke_destination);
|
||||
},
|
||||
m_tmp);
|
||||
},
|
||||
.unbind_textures = [&] {
|
||||
[&] {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_unbindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
.unbind_samplers = [&] {
|
||||
[&] {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_sampler_inputs(
|
||||
live_pass_sampler_bindings,
|
||||
live_pass_sampler_dispatch);
|
||||
},
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
// pad stroke
|
||||
// In order to mitigate color bleeding at the edge of shapes in transparent layers
|
||||
@@ -2003,15 +2187,7 @@ void Canvas::stroke_commit()
|
||||
{
|
||||
if (!m_dirty || m_layers.empty())
|
||||
return;
|
||||
|
||||
// save viewport and clear color states
|
||||
const auto vp = query_canvas_viewport();
|
||||
const auto cc = query_canvas_clear_color();
|
||||
auto blend = query_canvas_capability(blend_state());
|
||||
|
||||
// allocate action to add to history
|
||||
auto action = new ActionStroke;
|
||||
action->was_saved = !m_unsaved;
|
||||
const auto prelude = make_canvas_stroke_commit_prelude(*this);
|
||||
|
||||
const auto& b = m_current_stroke->m_brush;
|
||||
const auto stroke_material = canvas_stroke_material_plan(*b, false);
|
||||
@@ -2023,14 +2199,14 @@ void Canvas::stroke_commit()
|
||||
stroke_material);
|
||||
[[maybe_unused]] const auto commit_result = execute_canvas_stroke_commit_dispatch(
|
||||
*this,
|
||||
vp,
|
||||
cc,
|
||||
blend,
|
||||
prelude.viewport,
|
||||
prelude.clear_color,
|
||||
prelude.blend,
|
||||
[&](int texture_slot) {
|
||||
set_active_texture_unit(texture_slot);
|
||||
},
|
||||
action,
|
||||
m_current_stroke,
|
||||
prelude.action,
|
||||
m_current_stroke.get(),
|
||||
stroke_commit_sequence,
|
||||
stroke_material);
|
||||
}
|
||||
|
||||
11
src/canvas.h
11
src/canvas.h
@@ -7,6 +7,7 @@
|
||||
#include "canvas_layer.h"
|
||||
#include "canvas_actions.h"
|
||||
#include "canvas_modes.h"
|
||||
#include "legacy_canvas_stroke_execution_services.h"
|
||||
#include <stack>
|
||||
#include "mp4enc.h"
|
||||
|
||||
@@ -282,7 +283,7 @@ private:
|
||||
pp::panopainter::LegacyStrokeFaceSamplePolygonExecutionRequest make_stroke_draw_samples_request(
|
||||
int face_index,
|
||||
std::vector<vertex_t>& polygon_vertices,
|
||||
bool copy_stroke_destination) const;
|
||||
bool copy_stroke_destination);
|
||||
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch make_stroke_draw_samples_destination_texture_dispatch(
|
||||
int face_index);
|
||||
void stroke_draw_dual_pass(
|
||||
@@ -293,6 +294,12 @@ private:
|
||||
const std::array<bool, 6>& include_dual_dirty,
|
||||
bool uses_pattern,
|
||||
bool copy_stroke_destination);
|
||||
pp::panopainter::LegacyCanvasStrokeMainPassExecutionRequest make_stroke_draw_main_pass_request(
|
||||
std::function<void()> bind_samplers,
|
||||
std::function<void()> bind_textures,
|
||||
std::function<void()> execute_frame_pass,
|
||||
std::function<void()> unbind_textures,
|
||||
std::function<void()> unbind_samplers);
|
||||
pp::panopainter::LegacyCanvasStrokeDualPassRequest make_stroke_draw_dual_pass_request(
|
||||
const std::vector<StrokeFrame>& frames_dual,
|
||||
const std::array<pp::panopainter::LegacyCanvasStrokeTextureBinding, 1>& dual_pass_texture_bindings,
|
||||
@@ -306,6 +313,8 @@ private:
|
||||
const pp::renderer::Extent2D& stroke_extent,
|
||||
const std::array<bool, 6>& include_dual_dirty,
|
||||
bool copy_stroke_destination);
|
||||
|
||||
public:
|
||||
Image thumbnail_read(std::string file_path);
|
||||
void draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)>, int frame, bool save_history);
|
||||
void draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)>, Layer& layer, int frame, bool save_history);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
void setup_legacy_stroke_dual_shader(bool uses_pattern);
|
||||
|
||||
struct LegacyStrokeSampleExecutionRequest {
|
||||
std::string_view context;
|
||||
glm::vec2 target_size {};
|
||||
@@ -192,6 +194,24 @@ struct LegacyCanvasStrokeMainPassExecutionRequest {
|
||||
std::function<void()> unbind_samplers;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline LegacyCanvasStrokeMainPassExecutionRequest make_legacy_canvas_stroke_main_pass_execution_request(
|
||||
std::string_view context,
|
||||
std::function<void()> bind_samplers,
|
||||
std::function<void()> bind_textures,
|
||||
std::function<void()> execute_frame_pass,
|
||||
std::function<void()> unbind_textures,
|
||||
std::function<void()> unbind_samplers)
|
||||
{
|
||||
return LegacyCanvasStrokeMainPassExecutionRequest {
|
||||
.context = context,
|
||||
.bind_samplers = std::move(bind_samplers),
|
||||
.bind_textures = std::move(bind_textures),
|
||||
.execute_frame_pass = std::move(execute_frame_pass),
|
||||
.unbind_textures = std::move(unbind_textures),
|
||||
.unbind_samplers = std::move(unbind_samplers),
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline LegacyCanvasStrokeSamplerDispatch make_legacy_canvas_stroke_live_pass_sampler_dispatch(
|
||||
std::function<void(int)> bind_brush_tip_sampler,
|
||||
std::function<void()> unbind_brush_tip_sampler,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../libs/glm/glm/ext/matrix_clip_space.hpp"
|
||||
|
||||
#include "legacy_canvas_stroke_shader_services.h"
|
||||
#include "legacy_canvas_stroke_preview_services.h"
|
||||
#include "legacy_canvas_stroke_services.h"
|
||||
#include "paint_renderer/compositor.h"
|
||||
#include "texture.h"
|
||||
|
||||
@@ -93,6 +93,30 @@ struct StrokePreviewCompositePassInputs {
|
||||
Sampler& linear_sampler;
|
||||
Sampler& repeat_sampler;
|
||||
std::function<void()> draw_composite;
|
||||
|
||||
StrokePreviewCompositePassInputs(
|
||||
glm::vec2 resolution_in,
|
||||
glm::vec2 pattern_scale_in,
|
||||
const Brush& brush_in,
|
||||
const pp::paint_renderer::CanvasStrokeCompositePassPlan& composite_pass_in,
|
||||
Texture2D& background_texture_in,
|
||||
Texture2D& stroke_texture_in,
|
||||
Texture2D& dual_texture_in,
|
||||
Sampler& linear_sampler_in,
|
||||
Sampler& repeat_sampler_in,
|
||||
std::function<void()> draw_composite_in)
|
||||
: resolution(resolution_in)
|
||||
, pattern_scale(pattern_scale_in)
|
||||
, brush(brush_in)
|
||||
, composite_pass(composite_pass_in)
|
||||
, background_texture(background_texture_in)
|
||||
, stroke_texture(stroke_texture_in)
|
||||
, dual_texture(dual_texture_in)
|
||||
, linear_sampler(linear_sampler_in)
|
||||
, repeat_sampler(repeat_sampler_in)
|
||||
, draw_composite(std::move(draw_composite_in))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewMixPassRequest make_stroke_preview_mix_pass_request(
|
||||
@@ -384,6 +408,8 @@ std::array<pp::paint_renderer::CanvasStrokePoint, 4> make_stroke_preview_sample_
|
||||
};
|
||||
}
|
||||
|
||||
void upload_stroke_preview_brush_vertices(DynamicShape& brush_shape, std::span<const vertex_t> vertices);
|
||||
|
||||
pp::panopainter::LegacyStrokeSampleExecutionRequest make_stroke_preview_sample_request(
|
||||
std::array<vertex_t, 4>& vertices,
|
||||
const std::array<pp::paint_renderer::CanvasStrokePoint, 4>& sample_points,
|
||||
@@ -768,6 +794,8 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
|
||||
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_pass_sequence(
|
||||
make_stroke_draw_immediate_pass_sequence_request(
|
||||
m_stroke,
|
||||
m_dual_stroke,
|
||||
*b,
|
||||
pass_orchestration,
|
||||
dual_brush,
|
||||
@@ -784,6 +812,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
|
||||
NodeStrokePreview::StrokeMainLivePassRequest
|
||||
NodeStrokePreview::make_stroke_draw_immediate_main_live_pass_request(
|
||||
Stroke& stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
bool copy_stroke_destination,
|
||||
@@ -810,7 +839,7 @@ NodeStrokePreview::make_stroke_draw_immediate_main_live_pass_request(
|
||||
m_rtt.clear();
|
||||
},
|
||||
.compute_frames = [&] {
|
||||
return stroke_draw_compute(m_stroke, zoom);
|
||||
return stroke_draw_compute(stroke, zoom);
|
||||
},
|
||||
.before_frame = [&](auto& frame) {
|
||||
if (brush.m_tip_mix > 0.f)
|
||||
@@ -844,6 +873,7 @@ NodeStrokePreview::make_stroke_draw_immediate_main_live_pass_request(
|
||||
}
|
||||
|
||||
void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass(
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
@@ -858,7 +888,7 @@ void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass(
|
||||
m_rtt.clear();
|
||||
},
|
||||
[&] {
|
||||
return stroke_draw_compute(m_dual_stroke, zoom);
|
||||
return stroke_draw_compute(dual_stroke, zoom);
|
||||
},
|
||||
[](auto& frame) {
|
||||
frame.col = { 0, 0, 0, 1 };
|
||||
@@ -885,6 +915,8 @@ void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass(
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest
|
||||
NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request(
|
||||
Stroke& stroke,
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
@@ -901,6 +933,7 @@ NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request(
|
||||
},
|
||||
.execute_dual_pass = [&] {
|
||||
execute_stroke_draw_immediate_dual_pass(
|
||||
dual_stroke,
|
||||
brush,
|
||||
pass_orchestration,
|
||||
dual_brush,
|
||||
@@ -922,6 +955,7 @@ NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request(
|
||||
[[maybe_unused]] const bool main_live_ok =
|
||||
pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass(
|
||||
make_stroke_draw_immediate_main_live_pass_request(
|
||||
stroke,
|
||||
brush,
|
||||
pass_orchestration,
|
||||
copy_stroke_destination,
|
||||
@@ -930,21 +964,21 @@ NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request(
|
||||
},
|
||||
.finish_main_pass = [&] {},
|
||||
.execute_final_composite = [&] {
|
||||
std::function<void()> draw_composite = [&] {
|
||||
m_plane.draw_fill();
|
||||
};
|
||||
execute_stroke_preview_final_composite_and_copy(
|
||||
StrokePreviewCompositePassInputs {
|
||||
.resolution = size,
|
||||
.pattern_scale = brush.m_pattern_scale,
|
||||
.brush = brush,
|
||||
.composite_pass = material.composite_pass,
|
||||
.background_texture = m_tex_background,
|
||||
.stroke_texture = m_tex,
|
||||
.dual_texture = m_tex_dual,
|
||||
.linear_sampler = m_sampler_linear,
|
||||
.repeat_sampler = m_sampler_linear_repeat,
|
||||
.draw_composite = [&] {
|
||||
m_plane.draw_fill();
|
||||
},
|
||||
},
|
||||
StrokePreviewCompositePassInputs(
|
||||
size,
|
||||
glm::vec2(brush.m_pattern_scale),
|
||||
brush,
|
||||
material.composite_pass,
|
||||
m_tex_background,
|
||||
m_tex,
|
||||
m_tex_dual,
|
||||
m_sampler_linear,
|
||||
m_sampler_linear_repeat,
|
||||
std::move(draw_composite)),
|
||||
m_tex_preview,
|
||||
size);
|
||||
},
|
||||
@@ -983,7 +1017,7 @@ NodeStrokePreview::make_stroke_draw_mix_execution_request(
|
||||
*m_brush,
|
||||
m_sampler_linear,
|
||||
m_tex_background,
|
||||
m_rtt,
|
||||
m_tex,
|
||||
m_tex_dual,
|
||||
gl,
|
||||
bb_min,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "rtt.h"
|
||||
#include "brush.h"
|
||||
#include "texture.h"
|
||||
#include "legacy_node_stroke_preview_execution_services.h"
|
||||
|
||||
class NodeStrokePreview : public NodeBorder
|
||||
{
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
glm::vec4 stroke_draw_samples(std::array<vertex_t, 4>& P, Texture2D& blend_tex, bool copy_stroke_destination);
|
||||
std::vector<StrokeFrame> stroke_draw_compute(Stroke& stroke, float zoom) const;
|
||||
StrokeMainLivePassRequest make_stroke_draw_immediate_main_live_pass_request(
|
||||
Stroke& stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
bool copy_stroke_destination,
|
||||
@@ -65,6 +67,7 @@ public:
|
||||
const StrokeFrame& frame,
|
||||
const glm::vec2& size);
|
||||
void execute_stroke_draw_immediate_dual_pass(
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
@@ -72,6 +75,8 @@ public:
|
||||
float zoom,
|
||||
const glm::vec2& size);
|
||||
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest make_stroke_draw_immediate_pass_sequence_request(
|
||||
Stroke& stroke,
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
|
||||
@@ -1315,6 +1315,7 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
CanvasBlendGateRequest request) noexcept
|
||||
{
|
||||
CanvasBlendGatePlan gate;
|
||||
pp::paint::BlendMode first_complex_layer_blend = pp::paint::BlendMode::normal;
|
||||
|
||||
for (std::size_t i = 0; i < request.layer_blend_modes.size(); ++i) {
|
||||
pp::paint::BlendMode layer_blend = pp::paint::BlendMode::normal;
|
||||
@@ -1331,21 +1332,10 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
continue;
|
||||
}
|
||||
|
||||
gate.shader_blend = true;
|
||||
gate.complex_blend = true;
|
||||
gate.first_complex_layer_index = static_cast<int>(i);
|
||||
const auto stroke = plan_stroke_composite(
|
||||
features,
|
||||
StrokeCompositeRequest {
|
||||
.extent = request.extent,
|
||||
.layer_blend_mode = layer_blend,
|
||||
});
|
||||
if (stroke) {
|
||||
apply_stroke_plan(gate, stroke.value());
|
||||
} else {
|
||||
gate.compatibility_fallback = true;
|
||||
if (gate.first_complex_layer_index < 0) {
|
||||
gate.first_complex_layer_index = static_cast<int>(i);
|
||||
first_complex_layer_blend = layer_blend;
|
||||
}
|
||||
return pp::foundation::Result<CanvasBlendGatePlan>::success(gate);
|
||||
}
|
||||
|
||||
pp::paint::StrokeBlendMode stroke_blend = pp::paint::StrokeBlendMode::normal;
|
||||
@@ -1363,7 +1353,8 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
|
||||
gate.dual_brush_complex = request.dual_brush_blend;
|
||||
gate.pattern_complex = request.pattern_blend;
|
||||
if (!gate.stroke_complex && !gate.dual_brush_complex && !gate.pattern_complex) {
|
||||
const bool layer_complex = gate.first_complex_layer_index >= 0;
|
||||
if (!layer_complex && !gate.stroke_complex && !gate.dual_brush_complex && !gate.pattern_complex) {
|
||||
return pp::foundation::Result<CanvasBlendGatePlan>::success(gate);
|
||||
}
|
||||
|
||||
@@ -1373,6 +1364,7 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
features,
|
||||
StrokeCompositeRequest {
|
||||
.extent = request.extent,
|
||||
.layer_blend_mode = first_complex_layer_blend,
|
||||
.stroke_blend_mode = stroke_blend,
|
||||
.dual_brush_blend = request.dual_brush_blend,
|
||||
.pattern_blend = request.pattern_blend,
|
||||
|
||||
@@ -249,9 +249,11 @@ public:
|
||||
|
||||
[[nodiscard]] std::string clipboard_text() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
const auto family = pp::platform::current_platform_family();
|
||||
if (family == pp::platform::PlatformFamily::ios || family == pp::platform::PlatformFamily::macos)
|
||||
return active_apple_document_platform_services().clipboard_text();
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
return android_get_clipboard();
|
||||
#else
|
||||
@@ -261,9 +263,11 @@ public:
|
||||
|
||||
[[nodiscard]] bool set_clipboard_text(std::string_view text) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
const auto family = pp::platform::current_platform_family();
|
||||
if (family == pp::platform::PlatformFamily::ios || family == pp::platform::PlatformFamily::macos)
|
||||
return active_apple_document_platform_services().set_clipboard_text(text);
|
||||
#endif
|
||||
const std::string value(text);
|
||||
#ifdef __ANDROID__
|
||||
return android_set_clipboard(value);
|
||||
@@ -275,7 +279,11 @@ public:
|
||||
|
||||
void set_cursor_visible(bool visible) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().set_cursor_visible(visible);
|
||||
#else
|
||||
(void)visible;
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_virtual_keyboard_visible(bool visible) override
|
||||
@@ -450,7 +458,9 @@ public:
|
||||
{
|
||||
if (!pp::platform::platform_saves_native_ui_state(pp::platform::current_platform_family()))
|
||||
return;
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().save_ui_state();
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard]] bool enables_live_asset_reloading() override
|
||||
@@ -629,12 +639,20 @@ public:
|
||||
|
||||
void display_file(std::string_view path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().display_file(path);
|
||||
#else
|
||||
(void)path;
|
||||
#endif
|
||||
}
|
||||
|
||||
void share_file(std::string_view path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().share_file(path);
|
||||
#else
|
||||
(void)path;
|
||||
#endif
|
||||
}
|
||||
|
||||
void request_app_close() override
|
||||
|
||||
Reference in New Issue
Block a user