I'm fiddling a little with the graphics loader, and I started to implement a pseudo threaded version of it (patch attached).
It works as follows: there is this LoaderQueue class (I think every BufferView should have one, right now is simply a global class), which implements a queue with a twist: 1) Elements are unique 2) Reinserting an element reprioritizes it to the top I.e. it sort of works like the 'touch' command. Right now it's implemented as a queue + a set, so it's O(ln n) for the 'first time insert' case, and O(n) for the 'already have it' case. I plan to make it O(ln n) always. His loadNext method should run in an independent thread, right now it runs with a timer that comes back every .1 seconds. I've put a minimal locking mecanism. Should be trivial to convert to a real thread once boost.threads is installed on the LyX tree. This LoaderQueue is called from Loader::startLoading, i.e. from there we 'touch' the graphic. Nothing is really loaded on screen yet. The real loading is done on the loadNext method (the 'threaded' one). It works pretty nicely I think (except for the O(n) thingie and some other details). And the patch is very minimal. I know that the coding style is broken, please correct me without mercy. Anyway of course it's not to be applied, It's only a proof of concept. I have some questions about when these Loadings are called, so if someone thinks that this is not a complete trash then I go on and ask them. Please be nice. Regards, Alfredo
? patch.diff Index: GraphicsLoader.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/GraphicsLoader.C,v retrieving revision 1.12 diff -u -r1.12 GraphicsLoader.C --- GraphicsLoader.C 2003/02/13 16:53:00 1.12 +++ GraphicsLoader.C 2003/02/19 08:11:58 @@ -28,9 +28,60 @@ #include <boost/signals/trackable.hpp> #include <list> +#include <set> namespace grfx { +class LoaderQueue { +public: + LoaderQueue():timer( 100 , Timeout::ONETIME ) + { + timer.timeout.connect( boost::bind( &LoaderQueue::loadNext, this)); + locked = false; + timer.start(); + } + void touch(Cache::ItemPtr item) { + + if(locked) + return; + + locked = true; + + if( !cache_set_.insert(item).second ) { + + list<Cache::ItemPtr>::iterator + it = cache_queue_.begin(); + list<Cache::ItemPtr>::iterator + end = cache_queue_.end(); + + it = std::find( it, end, item ); + cache_queue_.erase( it ); + } + cache_queue_.push_front( item ); + locked = false; + } +private: + bool locked; + std::list<Cache::ItemPtr> cache_queue_; + std::set<Cache::ItemPtr> cache_set_; + Timeout timer; + void loadNext() { + if(locked) + return; + locked = true; + int counter = 10; + while (cache_queue_.size() && --counter) { + cout << cache_queue_.size() + << " items in the queue" << endl; + cache_queue_.front()->startLoading(); + cache_set_.erase(cache_queue_.front()); + cache_queue_.pop_front(); + } + locked = false; + timer.start(); + }; +} LQ; + struct Loader::Impl : boost::signals::trackable { /// Impl(Params const &); @@ -66,8 +117,6 @@ /// Params params_; - /// - Timeout timer; // Multiple Insets can share the same image typedef std::list<Inset const *> InsetList; /// @@ -196,10 +245,8 @@ Loader::Impl::Impl(Params const & params) - : status_(WaitingToLoad), params_(params), - timer(2000, Timeout::ONETIME) + : status_(WaitingToLoad), params_(params) { - timer.timeout.connect(boost::bind(&Impl::checkedLoading, this)); } @@ -266,7 +313,6 @@ signal_(); } - void Loader::Impl::createPixmap() { if (!cached_item_.get() || @@ -293,7 +339,7 @@ void Loader::Impl::startLoading(Inset const & inset, BufferView const & bv) { - if (status_ != WaitingToLoad || timer.running()) + if (status_ != WaitingToLoad) return; InsetList::const_iterator it = insets.begin(); @@ -302,8 +348,7 @@ if (it == end) insets.push_back(&inset); view = bv.owner()->view(); - - timer.start(); + LQ.touch(cached_item_); } Index: GraphicsSupport.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/GraphicsSupport.C,v retrieving revision 1.7 diff -u -r1.7 GraphicsSupport.C --- GraphicsSupport.C 2003/02/13 16:53:00 1.7 +++ GraphicsSupport.C 2003/02/19 08:11:58 @@ -33,7 +33,7 @@ VPList vps; Row const * last_row = 0; - for (int height = 0; row && height < bv_height; row = row->next()) { + for (int height = 0; row && height < 2 *bv_height; row = row->next()) { height += row->height(); if (vps.empty() || vps.back().par != row->par()) { Index: PreviewImage.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/PreviewImage.C,v retrieving revision 1.11 diff -u -r1.11 PreviewImage.C --- PreviewImage.C 2003/02/13 16:53:00 1.11 +++ PreviewImage.C 2003/02/19 08:11:58 @@ -33,7 +33,6 @@ Image const * image(Inset const &, BufferView const &); /// void statusChanged(); - /// PreviewImage const & parent_; ///