Use blend gate plan for canvas copy decisions
This commit is contained in:
@@ -49,7 +49,7 @@ pp::renderer::RenderDeviceFeatures canvas_stroke_composite_features() noexcept
|
||||
return ShaderManager::render_device_features();
|
||||
}
|
||||
|
||||
bool draw_merge_needs_shader_blend(
|
||||
pp::paint_renderer::CanvasBlendGatePlan draw_merge_blend_gate_plan(
|
||||
int width,
|
||||
int height,
|
||||
const std::vector<std::shared_ptr<Layer>>& layers,
|
||||
@@ -75,7 +75,15 @@ bool draw_merge_needs_shader_blend(
|
||||
.has_stroke_blend_mode = brush != nullptr,
|
||||
.stroke_blend_mode = brush ? brush->m_blend_mode : 0,
|
||||
});
|
||||
return plan ? plan.value().shader_blend : true;
|
||||
if (plan) {
|
||||
return plan.value();
|
||||
}
|
||||
|
||||
pp::paint_renderer::CanvasBlendGatePlan fallback;
|
||||
fallback.shader_blend = true;
|
||||
fallback.complex_blend = true;
|
||||
fallback.compatibility_fallback = true;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
GLenum unsigned_byte_component_type()
|
||||
@@ -1121,11 +1129,13 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
auto ortho = glm::ortho<float>(-0.5f, 0.5f, -0.5f, 0.5f, -1.f, 1.f);
|
||||
const auto& b = m_current_stroke->m_brush;
|
||||
|
||||
const bool use_blend = draw_merge_needs_shader_blend(
|
||||
const auto blend_gate = draw_merge_blend_gate_plan(
|
||||
m_width,
|
||||
m_height,
|
||||
m_layers,
|
||||
m_current_stroke ? m_current_stroke->m_brush.get() : nullptr);
|
||||
const bool use_blend = blend_gate.shader_blend;
|
||||
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
|
||||
|
||||
// if not using shader blend, use gl rasterizer blend
|
||||
glDisable(depth_test_state());
|
||||
@@ -1289,7 +1299,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
{
|
||||
m_sampler.bind(2);
|
||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||
@@ -1297,7 +1307,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
|
||||
set_active_texture_unit(0);
|
||||
m_merge_rtt.bindTexture();
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
{
|
||||
set_active_texture_unit(2);
|
||||
m_merge_tex.bind();
|
||||
@@ -1306,7 +1316,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
|
||||
m_plane.draw_fill();
|
||||
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
{
|
||||
set_active_texture_unit(2);
|
||||
m_merge_tex.unbind();
|
||||
|
||||
@@ -32,7 +32,7 @@ pp::renderer::RenderDeviceFeatures node_canvas_stroke_composite_features() noexc
|
||||
return ShaderManager::render_device_features();
|
||||
}
|
||||
|
||||
bool node_canvas_needs_shader_blend(
|
||||
pp::paint_renderer::CanvasBlendGatePlan node_canvas_blend_gate_plan(
|
||||
int width,
|
||||
int height,
|
||||
const std::vector<std::shared_ptr<Layer>>& layers,
|
||||
@@ -58,7 +58,15 @@ bool node_canvas_needs_shader_blend(
|
||||
.has_stroke_blend_mode = brush != nullptr,
|
||||
.stroke_blend_mode = brush ? brush->m_blend_mode : 0,
|
||||
});
|
||||
return plan ? plan.value().shader_blend : true;
|
||||
if (plan) {
|
||||
return plan.value();
|
||||
}
|
||||
|
||||
pp::paint_renderer::CanvasBlendGatePlan fallback;
|
||||
fallback.shader_blend = true;
|
||||
fallback.complex_blend = true;
|
||||
fallback.compatibility_fallback = true;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
void run_history_undo_if_available()
|
||||
@@ -290,11 +298,13 @@ void NodeCanvas::draw()
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool use_blend = node_canvas_needs_shader_blend(
|
||||
const auto blend_gate = node_canvas_blend_gate_plan(
|
||||
m_cache_rtt.getWidth(),
|
||||
m_cache_rtt.getHeight(),
|
||||
m_canvas->m_layers,
|
||||
m_canvas->m_current_stroke ? m_canvas->m_current_stroke->m_brush.get() : nullptr);
|
||||
const bool use_blend = blend_gate.shader_blend;
|
||||
const bool copy_blend_destination = use_blend && !blend_gate.reads_destination_color;
|
||||
|
||||
if (use_blend)
|
||||
{
|
||||
@@ -485,7 +495,7 @@ void NodeCanvas::draw()
|
||||
|
||||
ShaderManager::use(kShader::TextureBlend);
|
||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||
@@ -493,7 +503,7 @@ void NodeCanvas::draw()
|
||||
|
||||
set_active_texture_unit(0);
|
||||
m_blender_rtt.bindTexture();
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
{
|
||||
set_active_texture_unit(2);
|
||||
m_blender_bg.bind();
|
||||
@@ -503,7 +513,7 @@ void NodeCanvas::draw()
|
||||
|
||||
m_face_plane.draw_fill();
|
||||
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_blend_destination)
|
||||
{
|
||||
set_active_texture_unit(2);
|
||||
m_blender_bg.unbind();
|
||||
|
||||
@@ -116,11 +116,22 @@ void apply_stroke_plan(CanvasBlendGatePlan& gate, const StrokeCompositePlan& str
|
||||
gate.requires_render_target_blit = stroke.requires_render_target_blit;
|
||||
}
|
||||
|
||||
void mark_shader_blend_fallback(CanvasBlendGatePlan& gate) noexcept
|
||||
void mark_shader_blend_fallback(
|
||||
CanvasBlendGatePlan& gate,
|
||||
pp::renderer::RenderDeviceFeatures features) noexcept
|
||||
{
|
||||
gate.shader_blend = true;
|
||||
gate.complex_blend = true;
|
||||
gate.compatibility_fallback = true;
|
||||
if (features.framebuffer_fetch) {
|
||||
gate.path = StrokeCompositePath::framebuffer_fetch;
|
||||
gate.reads_destination_color = true;
|
||||
} else if (features.texture_copy || features.render_target_blit) {
|
||||
gate.path = StrokeCompositePath::ping_pong_textures;
|
||||
gate.requires_auxiliary_texture = true;
|
||||
gate.requires_texture_copy = features.texture_copy;
|
||||
gate.requires_render_target_blit = !features.texture_copy && features.render_target_blit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -227,7 +238,7 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
if (!paint_blend_mode_from_persisted_index(request.layer_blend_modes[i], layer_blend)) {
|
||||
if (request.layer_blend_modes[i] != 0) {
|
||||
gate.first_complex_layer_index = static_cast<int>(i);
|
||||
mark_shader_blend_fallback(gate);
|
||||
mark_shader_blend_fallback(gate, features);
|
||||
return pp::foundation::Result<CanvasBlendGatePlan>::success(gate);
|
||||
}
|
||||
continue;
|
||||
@@ -259,7 +270,7 @@ pp::foundation::Result<CanvasBlendGatePlan> plan_canvas_blend_gate(
|
||||
if (!stroke_blend_mode_from_persisted_index(request.stroke_blend_mode, stroke_blend)) {
|
||||
if (request.stroke_blend_mode != 0) {
|
||||
gate.stroke_complex = true;
|
||||
mark_shader_blend_fallback(gate);
|
||||
mark_shader_blend_fallback(gate, features);
|
||||
return pp::foundation::Result<CanvasBlendGatePlan>::success(gate);
|
||||
}
|
||||
} else if (stroke_blend != pp::paint::StrokeBlendMode::normal) {
|
||||
|
||||
Reference in New Issue
Block a user