File browser stability enhancements

see issue 898
This commit is contained in:
Oliver Duis
2011-08-11 21:41:09 +02:00
parent 613f8308a3
commit 9cf4d113db
8 changed files with 56 additions and 43 deletions

View File

@@ -21,11 +21,12 @@
#include <cstring> #include <cstring>
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), : ThumbBrowserEntryBase(fname),
opreview(previmg), origpw(prevw), origph(prevh), thumbnail(thumbnail), opreview(previmg), origpw(prevw), origph(prevh),
job(pjob), progress(0), outFileName("") { job(pjob), progress(0), outFileName("") {
thumbnail=thm;
params = pparams; params = pparams;
// The BatchQueueEntryIdleHelper tracks if // The BatchQueueEntryIdleHelper tracks if

View File

@@ -39,7 +39,6 @@ class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListen
BatchQueueEntryIdleHelper* bqih; BatchQueueEntryIdleHelper* bqih;
public: public:
Thumbnail* thumbnail;
rtengine::ProcessingJob* job; rtengine::ProcessingJob* job;
rtengine::procparams::ProcParams params; rtengine::procparams::ProcParams params;
Glib::ustring savedParamsFile; Glib::ustring savedParamsFile;
@@ -47,7 +46,7 @@ public:
Glib::ustring outFileName; Glib::ustring outFileName;
SaveFormat saveFormat; 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 (); ~BatchQueueEntry ();
void refreshThumbnailImage (); void refreshThumbnailImage ();

View File

@@ -33,7 +33,8 @@ Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::recentlySavedIcon;
Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::enqueuedIcon; Glib::RefPtr<Gdk::Pixbuf> FileBrowserEntry::enqueuedIcon;
FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) 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 = new FileBrowserEntryIdleHelper;
feih->fbentry = this; feih->fbentry = this;
@@ -82,7 +83,7 @@ void FileBrowserEntry::refreshThumbnailImage () {
if (!thumbnail) if (!thumbnail)
return; return;
thumbImageUpdater->add (thumbnail, thumbnail->getProcParams(), preh, &updatepriority, false, this); thumbImageUpdater->add (this, &updatepriority, false, this);
} }
void FileBrowserEntry::refreshQuickThumbnailImage () { void FileBrowserEntry::refreshQuickThumbnailImage () {
@@ -90,7 +91,7 @@ void FileBrowserEntry::refreshQuickThumbnailImage () {
if ( thumbnail && if ( thumbnail &&
thumbnail->isQuick() && (!options.internalThumbIfUntouched || thumbnail->isPParamsValid()) ) 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) { void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) {
Glib::RWLock::WriterLock l(lockRW);
redrawRequests--; redrawRequests--;
scale = s; scale = s;

View File

@@ -66,8 +66,6 @@ public:
static Glib::RefPtr<Gdk::Pixbuf> recentlySavedIcon; static Glib::RefPtr<Gdk::Pixbuf> recentlySavedIcon;
static Glib::RefPtr<Gdk::Pixbuf> enqueuedIcon; static Glib::RefPtr<Gdk::Pixbuf> enqueuedIcon;
Thumbnail* thumbnail;
FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname);
~FileBrowserEntry (); ~FileBrowserEntry ();
void draw (); void draw ();

View File

@@ -254,8 +254,10 @@ void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) {
} }
void ThumbBrowserEntryBase::resize (int h) { void ThumbBrowserEntryBase::resize (int h) {
Glib::RWLock::WriterLock l(lockRW);
height = h; height = h;
int old_preh = preh; int old_preh = preh, old_width = width;
// dimensions of the button set // dimensions of the button set
int bsw=0, bsh=0; int bsw=0, bsh=0;
@@ -278,7 +280,8 @@ void ThumbBrowserEntryBase::resize (int h) {
height = preh + (upperMargin + 2*borderWidth + lowerMargin)+ bsh + infoh; height = preh + (upperMargin + 2*borderWidth + lowerMargin)+ bsh + infoh;
} }
calcThumbnailSize (); calcThumbnailSize (); // recalculates prew
width = prew + 2*sideMargin + 2*borderWidth; width = prew + 2*sideMargin + 2*borderWidth;
if (options.showFileNames && !options.overlayedFileNames) { if (options.showFileNames && !options.overlayedFileNames) {
width = prew + 2*sideMargin + 2*borderWidth; width = prew + 2*sideMargin + 2*borderWidth;
@@ -288,12 +291,13 @@ void ThumbBrowserEntryBase::resize (int h) {
if (width < bsw + 2*sideMargin + 2*borderWidth) if (width < bsw + 2*sideMargin + 2*borderWidth)
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; delete [] preview;
preview = NULL; preview = NULL;
refreshThumbnailImage (); refreshThumbnailImage ();
} } // causes skewed thumb sometimes: else updateBackBuffer();
drawable = true; drawable = true;
} }
@@ -337,6 +341,8 @@ void ThumbBrowserEntryBase::draw () {
if (!drawable) if (!drawable)
return; return;
Glib::RWLock::ReaderLock l(lockRW);
int bbWidth, bbHeight; int bbWidth, bbHeight;
if (backBuffer) if (backBuffer)
backBuffer->get_size (bbWidth, bbHeight); backBuffer->get_size (bbWidth, bbHeight);
@@ -372,6 +378,7 @@ void ThumbBrowserEntryBase::draw () {
} }
void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) {
Glib::RWLock::WriterLock l(lockRW);
exp_width = w; exp_width = w;
exp_height = h; 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) { void ThumbBrowserEntryBase::setOffset (int x, int y) {
Glib::RWLock::WriterLock l(lockRW);
ofsX = -x; ofsX = -x;
ofsY = -y; ofsY = -y;

View File

@@ -21,6 +21,7 @@
#include <gtkmm.h> #include <gtkmm.h>
#include <lwbuttonset.h> #include <lwbuttonset.h>
#include <thumbnail.h>
class ThumbBrowserBase; class ThumbBrowserBase;
class ThumbBrowserEntryBase { class ThumbBrowserEntryBase {
@@ -40,6 +41,9 @@ protected:
int sideMargin; int sideMargin;
int lowerMargin; 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 guint8* preview; // holds the preview image. used in updateBackBuffer. TODO Olli: Make a cache to reduce mem significantly
Glib::ustring dispname; Glib::ustring dispname;
@@ -72,6 +76,8 @@ protected:
public: public:
Thumbnail* thumbnail;
// thumbnail preview properties: // thumbnail preview properties:
Glib::ustring filename; Glib::ustring filename;
Glib::ustring shortname; Glib::ustring shortname;
@@ -102,9 +108,10 @@ protected:
int getMinimalHeight () { return height; } int getMinimalHeight () { return height; }
int getMinimalWidth () { return width; } int getMinimalWidth () { return width; }
int getEffectiveHeight () { return exp_height; } int getEffectiveHeight () const { return exp_height; }
int getStartX () { return startx; } int getPreviewHeight () const { return preh; }
int getStartY () { return starty; } int getStartX () const { return startx; }
int getStartY () const { return starty; }
bool inside (int x, int y); bool inside (int x, int y);
bool insideWindow (int x, int y, int w, int h); bool insideWindow (int x, int y, int w, int h);

View File

@@ -36,25 +36,24 @@ public:
struct Job struct Job
{ {
Job(Thumbnail* thumbnail, const rtengine::procparams::ProcParams& pparams, Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade,
int height, bool* priority, bool upgrade,
ThumbImageUpdateListener* listener): ThumbImageUpdateListener* listener):
thumbnail_(thumbnail), tbe_(tbe),
pparams_(pparams), /*pparams_(pparams),
height_(height), height_(height), */
priority_(priority), priority_(priority),
upgrade_(upgrade), upgrade_(upgrade),
listener_(listener) listener_(listener)
{} {}
Job(): Job():
thumbnail_(0), tbe_(0),
listener_(0) listener_(0)
{} {}
Thumbnail* thumbnail_; ThumbBrowserEntryBase* tbe_;
rtengine::procparams::ProcParams pparams_; /*rtengine::procparams::ProcParams pparams_;
int height_; int height_;*/
bool* priority_; bool* priority_;
bool upgrade_; bool upgrade_;
ThumbImageUpdateListener* listener_; ThumbImageUpdateListener* listener_;
@@ -108,7 +107,7 @@ public:
{ {
if ( *(i->priority_) ) if ( *(i->priority_) )
{ {
DEBUG("processing(priority) %s",i->thumbnail_->getFileName().c_str()); DEBUG("processing(priority) %s",i->tbe_->thumbnail->getFileName().c_str());
break; break;
} }
} }
@@ -120,7 +119,7 @@ public:
{ {
if ( !i->upgrade_ ) 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; break;
} }
} }
@@ -130,7 +129,7 @@ public:
if ( i == jobs_.end() ) if ( i == jobs_.end() )
{ {
i = jobs_.begin(); 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 // copy found job
@@ -146,23 +145,24 @@ public:
// unlock and do processing; will relock on block exit, then call listener // unlock and do processing; will relock on block exit, then call listener
double scale = 1.0; double scale = 1.0;
rtengine::IImage8* img = 0; rtengine::IImage8* img = 0;
Thumbnail* thm=j.tbe_->thumbnail;
if ( j.upgrade_ ) 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 else
{ {
img = j.thumbnail_->processThumbImage(j.pparams_, j.height_, scale); img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale);
} }
if (img) if (img)
{ {
DEBUG("pushing image %s",j.thumbnail_->getFileName().c_str()); DEBUG("pushing image %s",thm->getFileName().c_str());
j.listener_->updateImage(img, scale, j.pparams_.crop); j.listener_->updateImage(img, scale, thm->getProcParams().crop);
} }
{ {
@@ -196,8 +196,7 @@ ThumbImageUpdater::ThumbImageUpdater():
} }
void void
ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& params, ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l)
int height, bool* priority, bool upgrade, ThumbImageUpdateListener* l)
{ {
// nobody listening? // nobody listening?
if ( l == 0 ) if ( l == 0 )
@@ -211,14 +210,14 @@ ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& par
Impl::JobList::iterator i(impl_->jobs_.begin()); Impl::JobList::iterator i(impl_->jobs_.begin());
for ( ; i != impl_->jobs_.end(); ++i ) for ( ; i != impl_->jobs_.end(); ++i )
{ {
if ( i->thumbnail_ == t && if ( i->tbe_ == tbe &&
i->listener_ == l && i->listener_ == l &&
i->upgrade_ == upgrade ) 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 // we have one, update queue entry, will be picked up by thread when processed
i->pparams_ = params; /*i->pparams_ = params;
i->height_ = height; i->height_ = height; */
i->priority_ = priority; i->priority_ = priority;
return; return;
} }
@@ -226,7 +225,7 @@ ThumbImageUpdater::add(Thumbnail* t, const rtengine::procparams::ProcParams& par
// create a new job and append to queue // create a new job and append to queue
DEBUG("queing job %s",t->getFileName().c_str()); 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()); DEBUG("adding run request %s",t->getFileName().c_str());
impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob)); impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob));

View File

@@ -21,7 +21,7 @@
#include <glibmm.h> #include <glibmm.h>
#include <rtengine.h> #include <rtengine.h>
#include <thumbnail.h> #include <thumbbrowserentrybase.h>
#include <glib.h> #include <glib.h>
class ThumbImageUpdateListener { class ThumbImageUpdateListener {
@@ -63,8 +63,7 @@ class ThumbImageUpdater {
* @param priority if \c true then run as soon as possible * @param priority if \c true then run as soon as possible
* @param l listener waiting on update * @param l listener waiting on update
*/ */
void add(Thumbnail* t, const rtengine::procparams::ProcParams& params, void add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l);
int height, bool* priority, bool upgrade, ThumbImageUpdateListener* l);
/** /**
* @brief Remove jobs associated with listener \c l. * @brief Remove jobs associated with listener \c l.