diff --git a/graphics/display_list.cpp b/graphics/display_list.cpp index 11f37a46d8..d37a75af66 100644 --- a/graphics/display_list.cpp +++ b/graphics/display_list.cpp @@ -10,26 +10,17 @@ namespace graphics DisplayList::~DisplayList() { - for (list >::const_iterator it = m_discardStorageCmd.begin(); - it != m_discardStorageCmd.end(); - ++it) - m_parent->processCommand(*it); + set::const_iterator tit; + for (tit = m_textures.begin(); + tit != m_textures.end(); + ++tit) + m_parent->removeTextureRef(*tit); - m_discardStorageCmd.clear(); - - for (list >::const_iterator it = m_freeStorageCmd.begin(); - it != m_freeStorageCmd.end(); - ++it) - m_parent->processCommand(*it); - - m_freeStorageCmd.clear(); - - for (list >::const_iterator it = m_freeTextureCmd.begin(); - it != m_freeTextureCmd.end(); - ++it) - m_parent->processCommand(*it); - - m_freeTextureCmd.clear(); + set::const_iterator sit; + for (sit = m_storages.begin(); + sit != m_storages.end(); + ++sit) + m_parent->removeStorageRef(*sit); m_commands.clear(); } @@ -55,6 +46,26 @@ namespace graphics void DisplayList::drawGeometry(shared_ptr const & cmd) { cmd->setIsDebugging(m_isDebugging); + + shared_ptr const & texture = cmd->m_texture; + gl::Storage const & storage = cmd->m_storage; + + TextureRef tref(texture.get()); + + if (texture && (m_textures.find(tref) == m_textures.end())) + { + m_textures.insert(tref); + m_parent->addTextureRef(tref); + } + + StorageRef sref(storage.m_vertices.get(), storage.m_indices.get()); + + if (storage.isValid() && (m_storages.find(sref) == m_storages.end())) + { + m_storages.insert(sref); + m_parent->addStorageRef(sref); + } + m_commands.push_back(cmd); } @@ -66,20 +77,14 @@ namespace graphics void DisplayList::freeStorage(shared_ptr const & cmd) { - cmd->setIsDebugging(m_isDebugging); - m_freeStorageCmd.push_back(cmd); } void DisplayList::freeTexture(shared_ptr const & cmd) { - cmd->setIsDebugging(m_isDebugging); - m_freeTextureCmd.push_back(cmd); } void DisplayList::discardStorage(shared_ptr const & cmd) { - cmd->setIsDebugging(m_isDebugging); - m_discardStorageCmd.push_back(cmd); } void DisplayList::uploadResources(shared_ptr const & cmd) diff --git a/graphics/display_list.hpp b/graphics/display_list.hpp index 54042177b0..d87fd4a15a 100644 --- a/graphics/display_list.hpp +++ b/graphics/display_list.hpp @@ -2,6 +2,10 @@ #include "defines.hpp" #include "display_list_renderer.hpp" +#include "opengl/base_texture.hpp" +#include "opengl/buffer_object.hpp" + +#include "../std/set.hpp" namespace graphics { @@ -21,9 +25,11 @@ namespace graphics list > m_commands; - list > m_discardStorageCmd; - list > m_freeTextureCmd; - list > m_freeStorageCmd; + typedef DisplayListRenderer::TextureRef TextureRef; + typedef DisplayListRenderer::StorageRef StorageRef; + + set m_textures; + set m_storages; DisplayListRenderer * m_parent; bool m_isDebugging; diff --git a/graphics/display_list_renderer.cpp b/graphics/display_list_renderer.cpp index f894fc3281..ae7038d612 100644 --- a/graphics/display_list_renderer.cpp +++ b/graphics/display_list_renderer.cpp @@ -9,6 +9,52 @@ namespace graphics { } + void DisplayListRenderer::addStorageRef(StorageRef const & storage) + { + m_discardStorageCmds[storage].first++; + m_freeStorageCmds[storage].first++; + } + + void DisplayListRenderer::removeStorageRef(StorageRef const & storage) + { + CHECK(m_discardStorageCmds.find(storage) != m_discardStorageCmds.end(), ()); + pair > & dval = m_discardStorageCmds[storage]; + --dval.first; + if ((dval.first == 0) && dval.second) + { + dval.second->perform(); + dval.second.reset(); + } + + CHECK(m_freeStorageCmds.find(storage) != m_freeStorageCmds.end(), ()); + pair > & fval = m_freeStorageCmds[storage]; + --fval.first; + if ((fval.first == 0) && fval.second) + { + fval.second->perform(); + fval.second.reset(); + } + } + + void DisplayListRenderer::addTextureRef(TextureRef const & texture) + { + pair > & val = m_freeTextureCmds[texture]; + val.first++; + } + + void DisplayListRenderer::removeTextureRef(TextureRef const & texture) + { + CHECK(m_freeTextureCmds.find(texture) != m_freeTextureCmds.end(), ()); + pair > & val = m_freeTextureCmds[texture]; + + --val.first; + if ((val.first == 0) && val.second) + { + val.second->perform(); + val.second.reset(); + } + } + DisplayList * DisplayListRenderer::createDisplayList() { return new DisplayList(this); @@ -83,7 +129,9 @@ namespace graphics command->m_texture = texture; command->m_texturePool = texturePool; - m_displayList->freeTexture(command); + m_freeTextureCmds[texture.get()].second = command; + +// m_displayList->freeTexture(command); } else base_t::freeTexture(texture, texturePool); @@ -99,7 +147,10 @@ namespace graphics command->m_storage = storage; command->m_storagePool = storagePool; - m_displayList->freeStorage(command); + StorageRef sref(storage.m_vertices.get(), storage.m_indices.get()); + + m_freeStorageCmds[sref].second = command; +// m_displayList->freeStorage(command); } else base_t::freeStorage(storage, storagePool); @@ -127,7 +178,10 @@ namespace graphics cmd->m_storage = storage; - m_displayList->discardStorage(cmd); + StorageRef sref(storage.m_vertices.get(), storage.m_indices.get()); + + m_discardStorageCmds[sref].second = cmd; +// m_displayList->discardStorage(cmd); } else base_t::discardStorage(storage); diff --git a/graphics/display_list_renderer.hpp b/graphics/display_list_renderer.hpp index 8c9a9138e4..61e80cb719 100644 --- a/graphics/display_list_renderer.hpp +++ b/graphics/display_list_renderer.hpp @@ -1,5 +1,7 @@ #pragma once +#include "../std/map.hpp" + #include "opengl/storage.hpp" #include "opengl/base_texture.hpp" #include "opengl/geometry_renderer.hpp" @@ -19,6 +21,23 @@ namespace graphics typedef gl::GeometryRenderer base_t; typedef base_t::Params Params; + typedef base_t::FreeTexture FreeTextureCmd; + typedef base_t::FreeStorage FreeStorageCmd; + typedef base_t::DiscardStorage DiscardStorageCmd; + + typedef gl::BaseTexture const * TextureRef; + typedef pair StorageRef; + + map > > m_freeTextureCmds; + map > > m_freeStorageCmds; + map > > m_discardStorageCmds; + + void addStorageRef(StorageRef const & storage); + void removeStorageRef(StorageRef const & storage); + + void addTextureRef(TextureRef const & texture); + void removeTextureRef(TextureRef const & texture); + DisplayListRenderer(Params const & p); /// create display list