diff --git a/src/core/Core.cpp b/src/core/Core.cpp index 8000752258142b5fd5831fae73dd5439bd1e2a54..64cd79a1b3f39f89e5a6327cd4b76dc599402f14 100644 --- a/src/core/Core.cpp +++ b/src/core/Core.cpp @@ -369,6 +369,7 @@ int Core::get_options(int &argc, char **argv) **********************************/ bool Core::draw_trace(const string & filename, const int format) { + delete parser; parser = nullptr; DrawTrace drawing_ogl; bool killed=false; diff --git a/src/core/Core.hpp b/src/core/Core.hpp index d5d57b109013546bf7bafde1433ed543155be420..c543adb7f3f46fce543145cd28044b3df7e2bf42 100644 --- a/src/core/Core.hpp +++ b/src/core/Core.hpp @@ -313,7 +313,7 @@ protected: Trace* _trace; QMutex* _mutex; - Parser* parser; + Parser* parser = nullptr; QWaitCondition* _finished; QWaitCondition* _closed; diff --git a/src/render/vbo/Render_alternate.cpp b/src/render/vbo/Render_alternate.cpp index 32c296da83c28f4480a9cc3ac267b44651ea1c41..eb3d18ad7fa508eb7c238a8de9b9eb45b276bc21 100644 --- a/src/render/vbo/Render_alternate.cpp +++ b/src/render/vbo/Render_alternate.cpp @@ -146,6 +146,7 @@ Render_alternate::Render_alternate(Core* core, QWidget *parent, const QGLFormat& Render_alternate::~Render_alternate(){ delete _wait; + delete _wait_shader; delete _shader; } @@ -196,6 +197,7 @@ void Render_alternate::initializeGL() { std::cout << "Version GLSL : " << version << std::endl; _glsl = (version[0]-'0')*100 + (version[2]-'0')*10 + version[3]-'0'; + delete _shader; _shader = new Shader(_glsl); _shader->charger(); draw_wait(); @@ -770,13 +772,34 @@ bool Render_alternate::unbuild(){ _text_value.clear(); clear_text(); _links.clear(); + for (auto& x : _states) delete x.second; _states.clear(); + for (auto& x : _arrows) { delete x.second.first; delete x.second.second; } _arrows.clear(); + for (auto& x : _events) { delete x.second.first; delete x.second.second; } _events.clear(); + // >SHADER_POOL + // We need a shader pool here because VBO used to own heir shader so they used to delete it + // Then when we do "for (auto& x : _arrows) { delete x.second.first; delete x.second.second; }" + // we try to delete the same shader twice (second.first and second.second share the same shader) + // So we removed the shader from the hands of the VBO and we need to have a shader pool. + + // Having a shader pool allows us to not manually allocate a shader for each VBO and to not + // fragment our memory. We need to use a special data structure that don't allocate a lot + // and that have stable pointer. For this we want an array of array basically a Bucket Array + // The implementation of this in the stl is std::deque, but... it's kind of bad we can't even + // specify the bucket sizes, we might want to implement it ourself. + _shader_pool.clear(); + return true; } +template<typename... Args> +Shader* new_shader(std::deque<Shader>& _shader_pool, Args&&... args) noexcept { + _shader_pool.emplace_back(std::forward<Args>(args)...); + return &_shader_pool.back(); +} @@ -795,11 +818,11 @@ bool Render_alternate::unbuild(){ GLuint Render_alternate::draw_wait() { if (_wait == nullptr) { - Shader *s = new Shader(_glsl, 0); + _wait_shader = new Shader(_glsl, 0); _wait = new Vbo(); - s->charger(); - _wait->set_shader(s); + _wait_shader->charger(); + _wait->set_shader(_wait_shader); glGenTextures(1, &_textureID); glBindTexture(GL_TEXTURE_2D, _textureID); @@ -962,7 +985,7 @@ void Render_alternate::start_draw(){ void Render_alternate::start_draw_containers(){ _draw_container = true; - Shader *s = new Shader(_glsl); + Shader *s = new_shader(_shader_pool, _glsl); s->charger(); _containers.set_shader(s); _containers.setNbVertex(0); @@ -994,7 +1017,7 @@ void Render_alternate::draw_state( const Element_pos x, { if( _states.count(value) == 0 ) { //if there is no vbo corresponding to value //we create a new vbo and a new shader corresponding to the current color*/ - Shader *s = new Shader(_glsl, _r, _g, _b, true); + Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, true); s->charger(); //assert(value); // TODO: check why busy state exists and uncomment this assert Vbo *v = new Vbo(s); @@ -1037,7 +1060,7 @@ void Render_alternate::draw_arrow( const Element_pos start_time, { if(_arrows.count(value) == 0){ //if there is no vbo corresponding to value /* Create a new vbo and a new shader*/ - Shader *s = new Shader(_glsl, _r, _g, _b, false); + Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, false); s->charger(); Vbo* v1 = new Vbo(s); Vbo* v2 = new Vbo(s); @@ -1108,7 +1131,7 @@ void Render_alternate::start_draw_events(){ void Render_alternate::draw_event(const Element_pos time, const Element_pos height, const Element_pos container_height, EntityValue* value){ if(_events.count(value) == 0){ - Shader *s = new Shader(_glsl, _r, _g, _b, false); + Shader *s = new_shader(_shader_pool, _glsl, _r, _g, _b, false); s->charger(); Vbo* v1 = new Vbo(s); Vbo* v2 = new Vbo(s); @@ -1144,7 +1167,7 @@ void Render_alternate::end_draw_events(){ void Render_alternate::start_draw_counter(){ _draw_counter = true; /* create shader for counters : all vertex are white */ - Shader *s = new Shader(_glsl, 1, 1, 1, false); + Shader *s = new_shader(_shader_pool, _glsl, 1, 1, 1, false); s->charger(); _counters.set_shader(s); } @@ -1270,7 +1293,7 @@ Render_alternate::update_ev_single( EntityValue *ev, vbo->delete_shader(); //create and load the new shader*/ - Shader *s = new Shader(_glsl, + Shader *s = new_shader(_shader_pool, _glsl, c->get_red(), c->get_green(), c->get_blue(), @@ -1293,11 +1316,15 @@ Render_alternate::update_ev_couple( EntityValue *ev, Vbo *vbo2 = it->second.second; Color *c = ev->get_used_color(); + // >TODO + // Because now we have a shader pool we might just prefer to update the shader of vbo1 in + // in place. But i'm keeping this merge request short. + //delete previous shader vbo1->delete_shader(); //create and load the new shader*/ - Shader *s = new Shader(_glsl, + Shader *s = new_shader(_shader_pool, _glsl, c->get_red(), c->get_green(), c->get_blue(), @@ -1348,7 +1375,7 @@ void Render_alternate::change_color(const std::string &entity, //delete previous shader it->second->delete_shader(); //create and load the new shader*/ - Shader *s = new Shader(_glsl, r, g, b, true); + Shader *s = new_shader(_shader_pool, _glsl, r, g, b, true); s->charger(); it->second->set_shader(s); break; @@ -1367,7 +1394,7 @@ void Render_alternate::change_event_color(const std::string &event, Element_col Color *c = new Color(r, g, b); it->first->set_used_color(c); it->second.first->delete_shader(); - Shader *s = new Shader(_glsl, r, g, b, false); + Shader *s = new_shader(_shader_pool, _glsl, r, g, b, false); s->charger(); it->second.first->set_shader(s); it->second.second->set_shader(s); @@ -1387,7 +1414,7 @@ void Render_alternate::change_link_color(const std::string &link, Element_col r, Color *c = new Color(r, g, b); it->first->set_used_color(c); it->second.first->delete_shader(); - Shader *s = new Shader(_glsl, r, g, b, false); + Shader *s = new_shader(_shader_pool, _glsl, r, g, b, false); s->charger(); it->second.first->set_shader(s); it->second.second->set_shader(s); @@ -1444,7 +1471,7 @@ void Render_alternate::reload_states(){ it->first->reload_file_color(); it->first->set_visible(true); it->second->delete_shader(); - Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(), + Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(), it->first->get_used_color()->get_green(), it->first->get_used_color()->get_blue(), true); @@ -1461,7 +1488,7 @@ void Render_alternate::reload_links(){ it->first->reload_file_color(); it->first->set_visible(true); it->second.first->delete_shader(); - Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(), + Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(), it->first->get_used_color()->get_green(), it->first->get_used_color()->get_blue(), false); @@ -1480,7 +1507,7 @@ void Render_alternate::reload_events(){ it->first->reload_file_color(); it->first->set_visible(true); it->second.first->delete_shader(); - Shader* s = new Shader(_glsl, it->first->get_used_color()->get_red(), + Shader* s = new_shader(_shader_pool, _glsl, it->first->get_used_color()->get_red(), it->first->get_used_color()->get_green(), it->first->get_used_color()->get_blue(), false); diff --git a/src/render/vbo/Render_alternate.hpp b/src/render/vbo/Render_alternate.hpp index 06a5780c13ba62a4d5c9992a15134b67dd6fe25d..d533b58582f97a20f173a8d7b8718b1728ca32bb 100644 --- a/src/render/vbo/Render_alternate.hpp +++ b/src/render/vbo/Render_alternate.hpp @@ -49,6 +49,7 @@ #include <stack> #include <cmath> +#include <deque> #include <sstream> /* -- */ #include <QObject> @@ -110,7 +111,13 @@ private: //FT_Face face; //int atlas_width; int _glsl; //version of OpenGL Shading Language - Shader* _shader; + Shader* _shader = nullptr; + Shader* _wait_shader = nullptr; + + // Here we are sad that we can't specify the bucket size :(. + // We might want to implement the Bucket Array data structure ourself. + // see >SHADER_POOL + std::deque<Shader> _shader_pool; //Shader* _wait_shader; Element_pos _container_height; Element_col _r; diff --git a/src/render/vbo/vbo.cpp b/src/render/vbo/vbo.cpp index f16efcba3f91f5c971cb3f5881677abfd6711ea6..34c3cb605e3400c19cac0dd5786239ef43d37f0b 100644 --- a/src/render/vbo/vbo.cpp +++ b/src/render/vbo/vbo.cpp @@ -88,7 +88,8 @@ Vbo::~Vbo(){ _vboID = 0; glDeleteVertexArrays(1, &_vaoID); _vaoID = 0; - delete _shader; + // see >SHADER_POOL + // delete _shader; } @@ -283,7 +284,8 @@ Shader * Vbo::get_shader(){ void Vbo::delete_shader(){ if (_shader != nullptr) { - delete _shader; + // see >SHADER_POOL + // delete _shader; } _shader = nullptr; } @@ -292,7 +294,8 @@ void Vbo::delete_shader(){ if precedent is not used anymore, delete_shader should be called before this function*/ void Vbo::set_shader(Shader *s){ if ( _shader != nullptr ) { - delete _shader; + // see >SHADER_POOL + // delete _shader; } _shader = s; } diff --git a/src/trace/DrawTrace.hpp b/src/trace/DrawTrace.hpp index 69c80da398318385f7ed57584e6ddb9898c0cbf5..37376358c96f1f74819f7b82f6bbd3838a1cb717 100644 --- a/src/trace/DrawTrace.hpp +++ b/src/trace/DrawTrace.hpp @@ -199,11 +199,14 @@ public: _link_containers.clear(); _variable_containers.clear(); + thread_local std::vector<const Container*> local_container; + local_container.clear(); std::vector<const Container *> *container = trace->get_selected_container(); if( (container == nullptr) || container->empty() ) { - container = new std::vector<const Container *>(); + if (!container) container = &local_container; + container->clear(); trace->set_filter(0);