From: Mikko Rasa Date: Sat, 11 Jan 2014 18:05:15 +0000 (+0200) Subject: Reuse meshes in PartCache to avoid buffer create/delete spam X-Git-Url: http://git.tdb.fi/?p=libs%2Fgltk.git;a=commitdiff_plain;h=2a665655a15f73d59083fd5cc7e5a58ae5f4d377 Reuse meshes in PartCache to avoid buffer create/delete spam --- diff --git a/source/partcache.cpp b/source/partcache.cpp index 5589b0d..4747cb5 100644 --- a/source/partcache.cpp +++ b/source/partcache.cpp @@ -18,9 +18,10 @@ CachedPart::~CachedPart() } -void PartCache::clear() +void PartCache::begin_rebuild() { - parts.clear(); + next = parts.begin(); + current = parts.end(); } void PartCache::insert_special(const Part &part) @@ -28,21 +29,54 @@ void PartCache::insert_special(const Part &part) if(part.get_name().empty()) throw invalid_argument("PartCache::insert_special"); - parts.push_back(CachedPart()); - parts.back().part = ∂ + for(current=next; current!=parts.end(); ++current) + if(current->part==&part) + { + parts.erase(next, current); + break; + } + + if(current==parts.end()) + current = parts.insert(next, CachedPart()); + else + *current = CachedPart(); + current->part = ∂ + + next = current; + ++next; } GL::Mesh &PartCache::create_mesh(const Part &part, const GL::Texture2D &tex) { - if(!parts.empty() && parts.back().texture==&tex) - return *parts.back().mesh; - - parts.push_back(CachedPart()); - CachedPart &cpart = parts.back(); - cpart.part = ∂ - cpart.texture = &tex; - cpart.mesh = new GL::Mesh((GL::TEXCOORD2, GL::COLOR4_UBYTE, GL::VERTEX2)); - return *cpart.mesh; + if(current!=parts.end() && current->texture==&tex) + return *current->mesh; + + for(current=next; current!=parts.end(); ++current) + if(current->texture==&tex) + { + parts.erase(next, current); + break; + } + + if(current==parts.end()) + { + current = parts.insert(next, CachedPart()); + current->texture = &tex; + current->mesh = new GL::Mesh((GL::TEXCOORD2, GL::COLOR4_UBYTE, GL::VERTEX2)); + } + else + current->mesh->clear(); + current->part = ∂ + + next = current; + ++next; + + return *current->mesh; +} + +void PartCache::end_rebuild() +{ + parts.erase(next, parts.end()); } } // namespace GLtk diff --git a/source/partcache.h b/source/partcache.h index 86a3f36..90d1c94 100644 --- a/source/partcache.h +++ b/source/partcache.h @@ -26,11 +26,14 @@ public: private: PartList parts; + PartList::iterator next; + PartList::iterator current; public: - void clear(); + void begin_rebuild(); void insert_special(const Part &); GL::Mesh &create_mesh(const Part &, const GL::Texture2D &); + void end_rebuild(); const PartList &get_parts() const { return parts; } }; diff --git a/source/widget.cpp b/source/widget.cpp index 8b7f1cb..76b6e61 100644 --- a/source/widget.cpp +++ b/source/widget.cpp @@ -193,7 +193,7 @@ void Widget::rebuild() if(!style) return; - part_cache.clear(); + part_cache.begin_rebuild(); const Style::PartSeq &parts = style->get_parts(); for(Style::PartSeq::const_iterator i=parts.begin(); i!=parts.end(); ++i) { @@ -202,6 +202,7 @@ void Widget::rebuild() else rebuild_special(*i); } + part_cache.end_rebuild(); } void Widget::rebuild_special(const Part &part)