Extract canvas stroke runtime and preview draw shells
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
#include "util.h"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <stop_token>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -360,39 +359,6 @@ void execute_stroke_preview_background_capture_pass(
|
||||
|
||||
}
|
||||
|
||||
std::atomic_int NodeStrokePreview::s_instances{ 0 };
|
||||
std::atomic_bool NodeStrokePreview::s_running{ false };
|
||||
std::mutex NodeStrokePreview::s_render_mutex;
|
||||
BlockingQueue<std::shared_ptr<NodeStrokePreview>> NodeStrokePreview::s_queue;
|
||||
|
||||
RTT NodeStrokePreview::m_rtt;
|
||||
RTT NodeStrokePreview::m_rtt_mixer;
|
||||
Texture2D NodeStrokePreview::m_tex; // blending tmp texture
|
||||
Texture2D NodeStrokePreview::m_tex_dual;
|
||||
Texture2D NodeStrokePreview::m_tex_background;
|
||||
Sampler NodeStrokePreview::m_sampler_linear;
|
||||
Sampler NodeStrokePreview::m_sampler_linear_repeat;
|
||||
Sampler NodeStrokePreview::m_sampler_mipmap;
|
||||
DynamicShape NodeStrokePreview::m_brush_shape;
|
||||
std::jthread NodeStrokePreview::s_renderer;
|
||||
|
||||
|
||||
void NodeStrokePreview::terminate_renderer()
|
||||
{
|
||||
if (!s_renderer.joinable())
|
||||
return;
|
||||
|
||||
s_running = false;
|
||||
s_renderer.request_stop();
|
||||
s_queue.UnlockGetters();
|
||||
s_renderer.join();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::empty_queue()
|
||||
{
|
||||
s_queue.q.clear();
|
||||
}
|
||||
|
||||
Node* NodeStrokePreview::clone_instantiate() const
|
||||
{
|
||||
return new NodeStrokePreview();
|
||||
@@ -420,21 +386,6 @@ void NodeStrokePreview::init_controls()
|
||||
// Canvas::I->m_current_brush.m_tex_id = const_hash("data/thumbs/Round-Hard.png");
|
||||
}
|
||||
|
||||
void NodeStrokePreview::restore_context()
|
||||
{
|
||||
NodeBorder::restore_context();
|
||||
init_controls();
|
||||
if (m_size.x > 0 && m_size.y > 0)
|
||||
m_tex_preview.create(static_cast<int>(m_size.x), static_cast<int>(m_size.y));
|
||||
draw_stroke();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::clear_context()
|
||||
{
|
||||
NodeBorder::clear_context();
|
||||
m_tex_preview.destroy();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||
{
|
||||
const auto& b = m_brush;
|
||||
@@ -701,121 +652,3 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
apply_stroke_preview_viewport(vp.x, vp.y, vp.width, vp.height);
|
||||
apply_stroke_preview_clear_color(cc);
|
||||
}
|
||||
|
||||
Image NodeStrokePreview::render_to_image()
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(s_render_mutex);
|
||||
|
||||
App::I->render_task([this] {
|
||||
draw_stroke_immediate();
|
||||
});
|
||||
return m_tex_preview.get_image();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::draw_stroke()
|
||||
{
|
||||
if (m_size.x == 0 || m_size.y == 0)
|
||||
return;
|
||||
std::unique_lock<std::mutex> queue_lock(s_queue.mutex);
|
||||
if (!s_renderer.joinable())
|
||||
{
|
||||
s_running = true;
|
||||
s_renderer = std::jthread([](std::stop_token stop_token) {
|
||||
BT_SetTerminate();
|
||||
|
||||
m_sampler_linear.create();
|
||||
m_sampler_linear_repeat.create(
|
||||
pp::renderer::gl::linear_texture_filter(),
|
||||
pp::renderer::gl::repeat_texture_wrap());
|
||||
m_sampler_mipmap.create();
|
||||
m_sampler_mipmap.set_filter(
|
||||
pp::renderer::gl::linear_mipmap_linear_texture_filter(),
|
||||
pp::renderer::gl::linear_texture_filter());
|
||||
m_brush_shape.create();
|
||||
while (s_running && !stop_token.stop_requested())
|
||||
{
|
||||
auto node = s_queue.Get();
|
||||
if (node)
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(s_render_mutex);
|
||||
|
||||
// if the brush is not already loaded, load it and then destroy it
|
||||
bool to_unload = (node->m_brush->m_tip_texture == nullptr);
|
||||
node->m_brush->preload();
|
||||
|
||||
App::I->render_task([node, to_unload]
|
||||
{
|
||||
gl_state gl;
|
||||
gl.save();
|
||||
|
||||
node->m_brush->load();
|
||||
node->draw_stroke_immediate();
|
||||
if (to_unload)
|
||||
node->m_brush->unload();
|
||||
|
||||
gl.restore();
|
||||
});
|
||||
|
||||
node->app_redraw();
|
||||
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
m_rtt.destroy();
|
||||
m_rtt_mixer.destroy();
|
||||
m_tex.destroy();
|
||||
m_tex_dual.destroy();
|
||||
m_tex_background.destroy();
|
||||
m_brush_shape.destroy();
|
||||
s_running = false;
|
||||
});
|
||||
}
|
||||
queue_lock.unlock();
|
||||
s_queue.PostUnique(std::static_pointer_cast<NodeStrokePreview>(shared_from_this()), m_draw_first);
|
||||
}
|
||||
|
||||
void NodeStrokePreview::draw()
|
||||
{
|
||||
pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader(
|
||||
pp::panopainter::LegacyCanvasDrawMergeTextureUniforms {
|
||||
.mvp = m_mvp,
|
||||
.texture_slot = 0,
|
||||
});
|
||||
m_tex_preview.bind();
|
||||
m_sampler_linear.bind(0);
|
||||
m_plane.draw_fill();
|
||||
m_sampler_linear.unbind();
|
||||
m_tex_preview.unbind();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
||||
{
|
||||
if (m_preview_size == (new_size * root()->m_zoom) || !m_brush)
|
||||
return;
|
||||
|
||||
m_preview_size = new_size * root()->m_zoom;
|
||||
|
||||
if (m_on_screen)
|
||||
draw_stroke();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::destroy()
|
||||
{
|
||||
m_tex_preview.destroy();
|
||||
Node::destroy();
|
||||
}
|
||||
|
||||
void NodeStrokePreview::handle_on_screen(bool old_visibility, bool new_visibility)
|
||||
{
|
||||
parent::handle_on_screen(old_visibility, new_visibility);
|
||||
if (new_visibility)
|
||||
{
|
||||
draw_stroke();
|
||||
}
|
||||
else
|
||||
{
|
||||
s_queue.Remove(std::static_pointer_cast<NodeStrokePreview>(shared_from_this()));
|
||||
m_tex_preview.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user