unload brush texture from main memory, preload brush on preview to free render thread

This commit is contained in:
2019-03-01 23:28:30 +01:00
parent 0be47c7fb6
commit 1edbc27ae6
5 changed files with 84 additions and 13 deletions

View File

@@ -1,6 +1,7 @@
#include "pch.h"
#include "log.h"
#include "brush.h"
#include "asset.h"
void BrushMesh::draw(const std::vector<StrokeSample>& samples, const glm::mat4& proj)
{
@@ -325,6 +326,8 @@ void Stroke::start(const std::shared_ptr<Brush>& 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<Texture2D>();
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<Texture2D>();
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<Texture2D>();
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<Texture2D>();
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<Texture2D>();
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<Texture2D>();
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<Image>();
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<Image>();
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<Image>();
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;
}

View File

@@ -5,6 +5,9 @@
class Brush
{
std::shared_ptr<Image> m_tip_img;
std::shared_ptr<Image> m_pattern_img;
std::shared_ptr<Image> 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

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();