From 9cf4d113db584d3341a3da5ba26fa2b82428ef21 Mon Sep 17 00:00:00 2001 From: Oliver Duis Date: Thu, 11 Aug 2011 21:41:09 +0200 Subject: [PATCH] File browser stability enhancements see issue 898 --- rtgui/batchqueueentry.cc | 5 ++-- rtgui/batchqueueentry.h | 3 +-- rtgui/filebrowserentry.cc | 8 +++--- rtgui/filebrowserentry.h | 2 -- rtgui/thumbbrowserentrybase.cc | 16 +++++++++--- rtgui/thumbbrowserentrybase.h | 13 +++++++--- rtgui/thumbimageupdater.cc | 47 +++++++++++++++++----------------- rtgui/thumbimageupdater.h | 5 ++-- 8 files changed, 56 insertions(+), 43 deletions(-) diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 7487c22d6..8450e9f69 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -21,11 +21,12 @@ #include -BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail) +BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm) : ThumbBrowserEntryBase(fname), - opreview(previmg), origpw(prevw), origph(prevh), thumbnail(thumbnail), + opreview(previmg), origpw(prevw), origph(prevh), job(pjob), progress(0), outFileName("") { + thumbnail=thm; params = pparams; // The BatchQueueEntryIdleHelper tracks if diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index f4703ce7d..37ef74822 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -39,7 +39,6 @@ class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListen BatchQueueEntryIdleHelper* bqih; public: - Thumbnail* thumbnail; rtengine::ProcessingJob* job; rtengine::procparams::ProcParams params; Glib::ustring savedParamsFile; @@ -47,7 +46,7 @@ public: Glib::ustring outFileName; SaveFormat saveFormat; - BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thumbnail=NULL); + BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, guint8* previmg, int prevw, int prevh, Thumbnail* thm=NULL); ~BatchQueueEntry (); void refreshThumbnailImage (); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 1c8793e3b..8d24e56b7 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -33,7 +33,8 @@ Glib::RefPtr FileBrowserEntry::recentlySavedIcon; Glib::RefPtr FileBrowserEntry::enqueuedIcon; FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) - : ThumbBrowserEntryBase (fname), iatlistener(NULL), cropgl(NULL), state(SNormal), thumbnail(thm) { + : ThumbBrowserEntryBase (fname), iatlistener(NULL), cropgl(NULL), state(SNormal) { + thumbnail=thm; feih = new FileBrowserEntryIdleHelper; feih->fbentry = this; @@ -82,7 +83,7 @@ void FileBrowserEntry::refreshThumbnailImage () { if (!thumbnail) return; - thumbImageUpdater->add (thumbnail, thumbnail->getProcParams(), preh, &updatepriority, false, this); + thumbImageUpdater->add (this, &updatepriority, false, this); } void FileBrowserEntry::refreshQuickThumbnailImage () { @@ -90,7 +91,7 @@ void FileBrowserEntry::refreshQuickThumbnailImage () { if ( thumbnail && thumbnail->isQuick() && (!options.internalThumbIfUntouched || thumbnail->isPParamsValid()) ) { - thumbImageUpdater->add(thumbnail, thumbnail->getProcParams(), preh, &updatepriority, true, this); + thumbImageUpdater->add(this, &updatepriority, true, this); } } @@ -206,6 +207,7 @@ void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengi } void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) { + Glib::RWLock::WriterLock l(lockRW); redrawRequests--; scale = s; diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 349e98bf2..3c79f9072 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -66,8 +66,6 @@ public: static Glib::RefPtr recentlySavedIcon; static Glib::RefPtr enqueuedIcon; - Thumbnail* thumbnail; - FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); ~FileBrowserEntry (); void draw (); diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index de427204e..8f887fe7b 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -254,8 +254,10 @@ void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) { } void ThumbBrowserEntryBase::resize (int h) { + Glib::RWLock::WriterLock l(lockRW); + height = h; - int old_preh = preh; + int old_preh = preh, old_width = width; // dimensions of the button set int bsw=0, bsh=0; @@ -278,7 +280,8 @@ void ThumbBrowserEntryBase::resize (int h) { height = preh + (upperMargin + 2*borderWidth + lowerMargin)+ bsh + infoh; } - calcThumbnailSize (); + calcThumbnailSize (); // recalculates prew + width = prew + 2*sideMargin + 2*borderWidth; if (options.showFileNames && !options.overlayedFileNames) { width = prew + 2*sideMargin + 2*borderWidth; @@ -288,12 +291,13 @@ void ThumbBrowserEntryBase::resize (int h) { if (width < bsw + 2*sideMargin + 2*borderWidth) width = bsw + 2*sideMargin + 2*borderWidth; - if ( preh != old_preh ) + if ( preh != old_preh || width != old_width ) { delete [] preview; preview = NULL; refreshThumbnailImage (); - } + } // causes skewed thumb sometimes: else updateBackBuffer(); + drawable = true; } @@ -337,6 +341,8 @@ void ThumbBrowserEntryBase::draw () { if (!drawable) return; + Glib::RWLock::ReaderLock l(lockRW); + int bbWidth, bbHeight; if (backBuffer) backBuffer->get_size (bbWidth, bbHeight); @@ -372,6 +378,7 @@ void ThumbBrowserEntryBase::draw () { } void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { + Glib::RWLock::WriterLock l(lockRW); exp_width = w; exp_height = h; @@ -383,6 +390,7 @@ void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { } void ThumbBrowserEntryBase::setOffset (int x, int y) { + Glib::RWLock::WriterLock l(lockRW); ofsX = -x; ofsY = -y; diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 8cd043899..637b2dc9c 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -21,6 +21,7 @@ #include #include +#include class ThumbBrowserBase; class ThumbBrowserEntryBase { @@ -40,6 +41,9 @@ protected: int sideMargin; int lowerMargin; + + Glib::RWLock lockRW; // Locks access to all image thumb changing actions + guint8* preview; // holds the preview image. used in updateBackBuffer. TODO Olli: Make a cache to reduce mem significantly Glib::ustring dispname; @@ -72,6 +76,8 @@ protected: public: + Thumbnail* thumbnail; + // thumbnail preview properties: Glib::ustring filename; Glib::ustring shortname; @@ -102,9 +108,10 @@ protected: int getMinimalHeight () { return height; } int getMinimalWidth () { return width; } - int getEffectiveHeight () { return exp_height; } - int getStartX () { return startx; } - int getStartY () { return starty; } + int getEffectiveHeight () const { return exp_height; } + int getPreviewHeight () const { return preh; } + int getStartX () const { return startx; } + int getStartY () const { return starty; } bool inside (int x, int y); bool insideWindow (int x, int y, int w, int h); diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc index 1f87418a8..806baef94 100644 --- a/rtgui/thumbimageupdater.cc +++ b/rtgui/thumbimageupdater.cc @@ -36,25 +36,24 @@ public: struct Job { - Job(Thumbnail* thumbnail, const rtengine::procparams::ProcParams& pparams, - int height, bool* priority, bool upgrade, + Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* listener): - thumbnail_(thumbnail), - pparams_(pparams), - height_(height), + tbe_(tbe), + /*pparams_(pparams), + height_(height), */ priority_(priority), upgrade_(upgrade), listener_(listener) {} Job(): - thumbnail_(0), + tbe_(0), listener_(0) {} - Thumbnail* thumbnail_; - rtengine::procparams::ProcParams pparams_; - int height_; + ThumbBrowserEntryBase* tbe_; + /*rtengine::procparams::ProcParams pparams_; + int height_;*/ bool* priority_; bool upgrade_; ThumbImageUpdateListener* listener_; @@ -108,7 +107,7 @@ public: { if ( *(i->priority_) ) { - DEBUG("processing(priority) %s",i->thumbnail_->getFileName().c_str()); + DEBUG("processing(priority) %s",i->tbe_->thumbnail->getFileName().c_str()); break; } } @@ -120,7 +119,7 @@ public: { if ( !i->upgrade_ ) { - DEBUG("processing(not-upgrade) %s",i->thumbnail_->getFileName().c_str()); + DEBUG("processing(not-upgrade) %s",i->tbe_->thumbnail->getFileName().c_str()); break; } } @@ -130,7 +129,7 @@ public: if ( i == jobs_.end() ) { i = jobs_.begin(); - DEBUG("processing(first) %s",i->thumbnail_->getFileName().c_str()); + DEBUG("processing(first) %s",i->tbe_->thumbnail->getFileName().c_str()); } // copy found job @@ -146,23 +145,24 @@ public: // unlock and do processing; will relock on block exit, then call listener double scale = 1.0; rtengine::IImage8* img = 0; + Thumbnail* thm=j.tbe_->thumbnail; if ( j.upgrade_ ) { - if ( j.thumbnail_->isQuick() ) + if ( thm->isQuick() ) { - img = j.thumbnail_->upgradeThumbImage(j.pparams_, j.height_, scale); + img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale); } } else { - img = j.thumbnail_->processThumbImage(j.pparams_, j.height_, scale); + img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale); } if (img) { - DEBUG("pushing image %s",j.thumbnail_->getFileName().c_str()); - j.listener_->updateImage(img, scale, j.pparams_.crop); + DEBUG("pushing image %s",thm->getFileName().c_str()); + j.listener_->updateImage(img, scale, thm->getProcParams().crop); } { @@ -196,8 +196,7 @@ ThumbImageUpdater::ThumbImageUpdater(): } void -ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& params, - int height, bool* priority, bool upgrade, ThumbImageUpdateListener* l) +ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l) { // nobody listening? if ( l == 0 ) @@ -211,14 +210,14 @@ ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& par Impl::JobList::iterator i(impl_->jobs_.begin()); for ( ; i != impl_->jobs_.end(); ++i ) { - if ( i->thumbnail_ == t && + if ( i->tbe_ == tbe && i->listener_ == l && i->upgrade_ == upgrade ) { - DEBUG("updating job %s",t->getFileName().c_str()); + DEBUG("updating job %s",tbe->getFileName().c_str()); // we have one, update queue entry, will be picked up by thread when processed - i->pparams_ = params; - i->height_ = height; + /*i->pparams_ = params; + i->height_ = height; */ i->priority_ = priority; return; } @@ -226,7 +225,7 @@ ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& par // create a new job and append to queue DEBUG("queing job %s",t->getFileName().c_str()); - impl_->jobs_.push_back(Impl::Job(t,params,height,priority,upgrade,l)); + impl_->jobs_.push_back(Impl::Job(tbe,priority,upgrade,l)); DEBUG("adding run request %s",t->getFileName().c_str()); impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob)); diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h index 6fdce5bc1..28eee88d5 100644 --- a/rtgui/thumbimageupdater.h +++ b/rtgui/thumbimageupdater.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include class ThumbImageUpdateListener { @@ -63,8 +63,7 @@ class ThumbImageUpdater { * @param priority if \c true then run as soon as possible * @param l listener waiting on update */ - void add(Thumbnail* t, const rtengine::procparams::ProcParams& params, - int height, bool* priority, bool upgrade, ThumbImageUpdateListener* l); + void add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l); /** * @brief Remove jobs associated with listener \c l.