Plan stroke preview feedback copies
This commit is contained in:
@@ -6,7 +6,40 @@
|
||||
#include "bezier.h"
|
||||
#include "canvas.h"
|
||||
#include "app.h"
|
||||
#include "paint_renderer/compositor.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
pp::renderer::RenderDeviceFeatures stroke_preview_render_device_features() noexcept
|
||||
{
|
||||
return ShaderManager::render_device_features();
|
||||
}
|
||||
|
||||
pp::paint_renderer::CanvasStrokeFeedbackPlan stroke_preview_destination_feedback_plan(
|
||||
int width,
|
||||
int height) noexcept
|
||||
{
|
||||
const auto plan = pp::paint_renderer::plan_canvas_stroke_feedback(
|
||||
stroke_preview_render_device_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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::atomic_int NodeStrokePreview::s_instances{ 0 };
|
||||
std::atomic_bool NodeStrokePreview::s_running{ false };
|
||||
@@ -147,9 +180,12 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
|
||||
gl.restore();
|
||||
}
|
||||
|
||||
glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Texture2D& blend_tex)
|
||||
glm::vec4 NodeStrokePreview::stroke_draw_samples(
|
||||
std::array<vertex_t, 4>& P,
|
||||
Texture2D& blend_tex,
|
||||
bool copy_stroke_destination)
|
||||
{
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
|
||||
blend_tex.bind(); // bg, copy of framebuffer (copied before drawing)
|
||||
@@ -169,7 +205,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
|
||||
glm::vec2 pad(1);
|
||||
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad, { 0, 0 }, size);
|
||||
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz) + pad * 2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(size) - tex_pos));
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
// this is also used by the mixer
|
||||
glCopyTexSubImage2D(pp::renderer::gl::texture_2d_target(), 0, tex_pos.x, tex_pos.y,
|
||||
@@ -189,7 +225,7 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(std::array<vertex_t, 4>& P, Tex
|
||||
}
|
||||
m_brush_shape.draw_fill();
|
||||
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
|
||||
blend_tex.unbind();
|
||||
@@ -353,7 +389,9 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
glDisable(pp::renderer::gl::blend_state());
|
||||
ShaderManager::use(kShader::Stroke);
|
||||
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
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;
|
||||
if (copy_stroke_destination)
|
||||
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 2); // pattern
|
||||
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
|
||||
@@ -388,7 +426,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, f.flow);
|
||||
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
|
||||
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex_dual);
|
||||
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex_dual, copy_stroke_destination);
|
||||
}
|
||||
|
||||
// copy raw stroke to tex
|
||||
@@ -435,7 +473,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
|
||||
glActiveTexture(pp::renderer::gl::active_texture_unit(0U));
|
||||
b->m_tip_texture->bind();
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
glActiveTexture(pp::renderer::gl::active_texture_unit(1U));
|
||||
m_tex.bind(); // tmp swap for blending
|
||||
@@ -462,7 +500,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 } /*f.col*/);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, glm::max(f.flow, m_min_flow));
|
||||
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
|
||||
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex);
|
||||
/*auto rect =*/ stroke_draw_samples(f.shapes, m_tex, copy_stroke_destination);
|
||||
}
|
||||
glActiveTexture(pp::renderer::gl::active_texture_unit(3U));
|
||||
m_rtt_mixer.unbindTexture();
|
||||
|
||||
Reference in New Issue
Block a user