lazy stroke preview rendering

This commit is contained in:
2019-04-23 12:17:46 +02:00
parent 042ad503d2
commit b4a9061cc4
7 changed files with 71 additions and 34 deletions

View File

@@ -590,8 +590,6 @@ void App::update(float dt)
{
auto box = n->m_clip_uncut;
Node* p = n->m_parent;
if (dynamic_cast<NodeBrushPresetItem*>(n))
p = p;
while (p)
{
float pt = YGNodeLayoutGetPadding(p->y_node, YGEdgeTop);
@@ -607,7 +605,21 @@ void App::update(float dt)
//auto box = n->m_clip;
//glm::ivec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
if (box.z <= 0.f || box.w <= 0.f)
{
if (n->m_on_screen)
{
if (dynamic_cast<NodeStrokePreview*>(n))
p = p;
n->handle_on_screen(true, false);
n->m_on_screen = false;
}
return false;
}
if (!n->m_on_screen)
{
n->handle_on_screen(false, true);
n->m_on_screen = true;
}
glm::ivec4 c = glm::vec4((int)box.x, (int)(height / zoom - box.y - box.w), (int)box.z, (int)box.w) * zoom;
glScissor(c.x + off_x, c.y + off_y, c.z, c.w);
n->draw();

View File

@@ -63,7 +63,7 @@ void Node::watch(std::function<bool(Node*)> observer)
{
for (auto& c : m_children)
{
if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
//if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
c->watch(observer);
}
}
@@ -268,6 +268,21 @@ void Node::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
}
void Node::handle_on_screen(bool old_visibility, bool new_visibility)
{
if (new_visibility == false)
{
for (auto& c : m_children)
{
if (c->m_on_screen)
{
c->handle_on_screen(true, false);
c->m_on_screen = false;
}
}
}
}
void Node::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size)
{

View File

@@ -132,6 +132,8 @@ public:
glm::vec4 m_clip_uncut{ 0, 0, 0, 0 };
std::string m_name;
bool m_display = true;
// it's actually rendering
bool m_on_screen = false;
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
@@ -251,6 +253,7 @@ public:
virtual kEventResult on_event(Event* e);
virtual kEventResult handle_event(Event* e);
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size);
virtual void handle_on_screen(bool old_visibility, bool new_visibility);
virtual void handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size);
virtual void create();
virtual void init();

View File

@@ -37,20 +37,6 @@ class NodePanelBrush : public Node
NodeButtonCustom* m_btn_down;
NodeButtonCustom* m_btn_remove;
bool m_interacted = false;
struct header_t {
char magic[5]{ 'P', 'P', 'B', 'R', 0 };
uint16_t version = 0;
uint16_t build = g_version_build;
uint16_t brushes = 0;
uint16_t deleted = 0;
};
struct item_t {
int m_name_len = 0;
int m_high_len = 0;
int m_thumb_len = 0;
bool m_deleted = false;
bool m_user_brush = false;
};
public:
NodeScroll* m_container;
std::string m_dir_name;
@@ -94,12 +80,6 @@ class NodePanelBrushPreset : public Node
NodeButtonCustom* m_btn_down;
NodeButtonCustom* m_btn_delete;
NodeButtonCustom* m_btn_save;
struct header_t {
char magic[5]{ 'P', 'P', 'P', 'R', 0 };
uint16_t version = 0;
uint16_t count = 0;
};
public:
Node* m_container;
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed;

View File

@@ -38,6 +38,8 @@ void NodeStrokePreview::empty_queue()
s_queue.q.clear();
}
int NodeStrokePreview::instances = 0;
Node* NodeStrokePreview::clone_instantiate() const
{
return new NodeStrokePreview();
@@ -271,7 +273,10 @@ void NodeStrokePreview::draw_stroke_immediate()
m_sampler_linear.bind(4);
const auto& b = m_brush;
Stroke m_stroke;
Stroke m_dual_stroke;
m_stroke.m_filter_points = false;
m_stroke.m_max_size = m_max_size > 0 ? m_max_size : m_size.y * .75f;
m_stroke.m_camera.fov = Canvas::I->m_cam_fov;
@@ -518,10 +523,13 @@ void NodeStrokePreview::draw_stroke()
node->m_brush->preload();
node->async_start();
gl_state gl;
gl.save();
auto new_size = node->m_tex_preview.size();
auto new_size = node->m_preview_size;
if (!node->m_tex_preview.ready() || node->m_tex_preview.size() != new_size)
node->m_tex_preview.create((int)new_size.x, (int)new_size.y);
if (m_tex.size() != new_size)
{
m_rtt.create((int)new_size.x, (int)new_size.y);
@@ -558,7 +566,6 @@ void NodeStrokePreview::draw_stroke()
void NodeStrokePreview::draw()
{
//glEnable(GL_BLEND);
ShaderManager::use(kShader::Texture);
ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
ShaderManager::u_int(kShaderUniform::Tex, 0);
@@ -574,11 +581,10 @@ void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
if (m_tex_preview.size() == new_size || !m_brush)
return;
new_size *= root()->m_zoom;
m_preview_size = new_size * root()->m_zoom;
m_tex_preview.create((int)new_size.x, (int)new_size.y);
draw_stroke();
if (m_on_screen)
draw_stroke();
}
void NodeStrokePreview::destroy_immediate()
@@ -586,3 +592,17 @@ void NodeStrokePreview::destroy_immediate()
Node::destroy_immediate();
m_tex_preview.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();
}
}

View File

@@ -26,6 +26,7 @@ class NodeStrokePreview : public NodeBorder
static DynamicShape m_brush_shape;
Texture2D m_tex_preview;
public:
using parent = NodeBorder;
static std::atomic_int s_instances;
static std::atomic_bool s_running;
static std::thread s_renderer;
@@ -33,11 +34,8 @@ public:
static void terminate_renderer();
static void empty_queue();
std::shared_ptr<Brush> m_brush;
std::shared_ptr<Brush> m_dual_brush;
bool m_draw_first = false;
Stroke m_stroke;
Stroke m_dual_stroke;
std::vector<glm::vec2> m_bez_points;
glm::vec2 m_preview_size = { 0, 0 };
float m_min_flow = 0.f;
float m_max_size = 0.f;
float m_pad_override = NAN;
@@ -57,4 +55,5 @@ public:
virtual void draw() override;
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) override;
virtual void destroy_immediate() override;
virtual void handle_on_screen(bool old_visibility, bool new_visibility) override;
};

View File

@@ -198,6 +198,14 @@ public:
}
get_cv.notify_one();
}
void Remove(T pkt)
{
std::unique_lock<std::mutex> lock(mutex);
auto it = std::find_if(q.begin(), q.end(), [&pkt](auto const& x) { return x.first == pkt; });
if (it != q.end())
q.erase(it);
if (Max > 0) post_cv.notify_all();
}
T Get()
{
static T emptyT{};