From 1edbc27ae6157ee2f9197ca8c483513759f68284 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Fri, 1 Mar 2019 23:28:30 +0100 Subject: [PATCH] unload brush texture from main memory, preload brush on preview to free render thread --- src/brush.cpp | 72 +++++++++++++++++++++++++++++++++---- src/brush.h | 6 ++++ src/node_panel_brush.cpp | 7 +--- src/node_panel_stroke.cpp | 3 +- src/node_stroke_preview.cpp | 9 +++++ 5 files changed, 84 insertions(+), 13 deletions(-) diff --git a/src/brush.cpp b/src/brush.cpp index a3325e6..be31218 100644 --- a/src/brush.cpp +++ b/src/brush.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "log.h" #include "brush.h" +#include "asset.h" void BrushMesh::draw(const std::vector& samples, const glm::mat4& proj) { @@ -325,6 +326,8 @@ void Stroke::start(const std::shared_ptr& brush) bool Brush::load_tip(const std::string& path, const std::string& thumb) { + if (m_tip_texture) + return true; m_tip_texture = std::make_shared(); if (!m_tip_texture->load(path)) { @@ -342,6 +345,8 @@ bool Brush::load_tip(const std::string& path, const std::string& thumb) bool Brush::load_dual(const std::string& path, const std::string& thumb) { + if (m_dual_texture) + return true; m_dual_texture = std::make_shared(); if (!m_dual_texture->load(path)) { @@ -357,6 +362,8 @@ bool Brush::load_dual(const std::string& path, const std::string& thumb) bool Brush::load_pattern(const std::string& path, const std::string& thumb) { + if (m_pattern_texture) + return true; m_pattern_texture = std::make_shared(); if (!m_pattern_texture->load(path)) { @@ -372,10 +379,13 @@ bool Brush::load_pattern(const std::string& path, const std::string& thumb) bool Brush::load() { - if (!m_brush_path.empty()) + if (!m_brush_path.empty() && !m_tip_texture) { m_tip_texture = std::make_shared(); - if (!m_tip_texture->load(m_brush_path)) + auto loaded = m_tip_img ? + m_tip_texture->create(*m_tip_img) : + m_tip_texture->load(m_brush_path); + if (!loaded) { LOG("failed to load %s", m_brush_path.c_str()); m_tip_texture = nullptr; @@ -384,10 +394,13 @@ bool Brush::load() m_tip_texture->create_mipmaps(); m_tip_texture->auto_destroy = true; } - if (!m_dual_path.empty()) + if (!m_dual_path.empty() && !m_dual_texture) { m_dual_texture = std::make_shared(); - if (!m_dual_texture->load(m_dual_path)) + auto loaded = m_dual_img ? + m_dual_texture->create(*m_dual_img) : + m_dual_texture->load(m_dual_path); + if (!loaded) { LOG("failed to load %s", m_dual_path.c_str()); m_tip_texture = nullptr; @@ -397,10 +410,13 @@ bool Brush::load() m_dual_texture->create_mipmaps(); m_dual_texture->auto_destroy = true; } - if (!m_pattern_path.empty()) + if (!m_pattern_path.empty() && !m_pattern_texture) { m_pattern_texture = std::make_shared(); - if (!m_pattern_texture->load(m_pattern_path)) + auto loaded = m_pattern_img ? + m_pattern_texture->create(*m_pattern_img) : + m_pattern_texture->load(m_pattern_path); + if (!loaded) { LOG("failed to load %s", m_pattern_path.c_str()); m_tip_texture = nullptr; @@ -413,3 +429,47 @@ bool Brush::load() } return true; } + +bool Brush::preload() +{ + if (!m_brush_path.empty() && !m_tip_texture && !m_tip_img) + { + m_tip_img = std::make_shared(); + if (!m_tip_img->load(m_brush_path)) + return false; + } + if (!m_dual_path.empty() && !m_dual_texture && !m_dual_img) + { + m_dual_img = std::make_shared(); + if (!m_dual_img->load(m_dual_path)) + return false; + } + if (!m_pattern_path.empty() && !m_pattern_texture && !m_pattern_img) + { + m_pattern_img = std::make_shared(); + if (!m_pattern_img->load(m_pattern_path)) + return false; + } + return true; +} + +void Brush::unload() +{ + m_tip_texture = nullptr; + m_tip_img = nullptr; + m_dual_texture = nullptr; + m_dual_img = nullptr; + m_pattern_texture = nullptr; + m_pattern_img = nullptr; +} + +bool Brush::valid() +{ + if (!m_brush_path.empty() && !Asset::exist(m_brush_path)) + return false; + if (!m_dual_path.empty() && !Asset::exist(m_dual_path)) + return false; + if (!m_pattern_path.empty() && !Asset::exist(m_pattern_path)) + return false; + return true; +} diff --git a/src/brush.h b/src/brush.h index bc9139e..6c895f9 100644 --- a/src/brush.h +++ b/src/brush.h @@ -5,6 +5,9 @@ class Brush { + std::shared_ptr m_tip_img; + std::shared_ptr m_pattern_img; + std::shared_ptr m_dual_img; public: //Brush() = default; //Brush(const Brush& brush) = default; @@ -94,6 +97,9 @@ public: bool load_dual(const std::string& path, const std::string& thumb); bool load_pattern(const std::string& path, const std::string& thumb); bool load(); + bool preload(); + void unload(); + bool valid(); }; struct StrokeSample diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 4764531..fe2ba2d 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -662,13 +662,8 @@ bool NodePanelBrushPreset::restore() fread((char*)b->m_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp); fread((char*)b->m_pattern_thumb_path.c_str(), 1, b->m_pattern_thumb_path.size(), fp); - if (b->load_tip(b->m_brush_path, b->m_brush_thumb_path)) + if (b->valid()) { - if (!b->m_pattern_path.empty()) - b->load_pattern(b->m_pattern_path, b->m_pattern_thumb_path); - if (!b->m_dual_path.empty()) - b->load_dual(b->m_dual_path, b->m_dual_thumb_path); - NodeBrushPresetItem* brush = new NodeBrushPresetItem; m_container->add_child(brush); brush->init(); diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index 38b0681..7ea46dd 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -121,7 +121,7 @@ bool NodePanelStroke::import_abr(const std::string& path) { auto presets = App::I.stroke->m_presets_popup; async_start(); - if (pr->load()) + if (pr->valid()) { LOG("add preset %s", pr->m_name.c_str()); presets->add_brush(pr); @@ -303,6 +303,7 @@ void NodePanelStroke::init_controls() auto old_color = Canvas::I->m_current_brush->m_tip_color; *Canvas::I->m_current_brush = *b; Canvas::I->m_current_brush->m_tip_color = old_color; + Canvas::I->m_current_brush->load(); m_preview->draw_stroke(); m_brush_thumb->set_image(b->m_brush_thumb_path); m_dual_brush_thumb->set_image(b->m_dual_thumb_path); diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index bda593c..7cf39ea 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -487,10 +487,19 @@ void NodeStrokePreview::draw_stroke() auto node = s_queue.Get(); if (node) { + // 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(); + node->async_start(); 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(); node->async_end();