diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 204f457cd..293c30a58 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -53,16 +53,16 @@ Crop::~Crop () { void Crop::setListener (DetailedCropListener* il) { // We can make reads in the IF, because the mProcessing lock is only needed for change if (cropImageListener!=il) { - parent->mProcessing.lock(); + + Glib::Mutex::Lock lock(cropMutex); cropImageListener = il; - parent->mProcessing.unlock(); } } void Crop::update (int todo) { + Glib::Mutex::Lock lock(cropMutex); ProcParams& params = parent->params; - cropMutex.lock (); parent->ipf.setScale (skip); @@ -178,8 +178,6 @@ void Crop::update (int todo) { cropImageListener->setDetailedCrop (final, params.crop, rqcropx, rqcropy, rqcropw, rqcroph, skip); delete final; } - - cropMutex.unlock (); } void Crop::freeAll () { @@ -306,14 +304,21 @@ if (settings->verbose) printf ("setcropsizes before lock\n"); return changed; } -void Crop::fullUpdate () { +// Try a simple, threadless update flag first +bool Crop::tryUpdate() { + bool needsFullUpdate = true; + // If there are more update request, the following WHILE will collect it if (updating) { needsNext = true; - return; + needsFullUpdate = false; + } else updating = true; + + return needsFullUpdate; } - updating = true; +// Full update, should be called via thread +void Crop::fullUpdate () { parent->updaterThreadStart.lock (); if (parent->updaterRunning && parent->thread) { @@ -324,7 +329,7 @@ void Crop::fullUpdate () { } if (parent->plistener) - parent->plistener->setProgressState (1); + parent->plistener->setProgressState (true); needsNext = true; while (needsNext) { @@ -333,10 +338,10 @@ void Crop::fullUpdate () { } updating = false; - if (parent->plistener) - parent->plistener->setProgressState (0); - parent->updaterThreadStart.unlock (); + + if (parent->plistener) + parent->plistener->setProgressState (false); } } diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 3569b7679..d39714344 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -66,7 +66,10 @@ class Crop : public DetailedCrop { bool hasListener () { return cropImageListener; } void update (int todo); void setWindow (int cx, int cy, int cw, int ch, int skip) { setCropSizes (cx, cy, cw, ch, skip, false); } - void fullUpdate (); + + bool tryUpdate (); // First try, only make fullUpdate if this returns false + void fullUpdate (); // called via thread + void setListener (DetailedCropListener* il); void destroy () { delete this; } int get_skip () { return skip;} diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index eff7ac1a1..b33c8dc4b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -135,7 +135,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { imgsrc->demosaic( rp ); } if (todo & M_INIT) { - minit.lock (); + Glib::Mutex::Lock lock(minit); + if (settings->verbose) printf ("Applying white balance, color correction & sRBG conversion...\n"); currWB = ColorTemp (params.wb.temperature, params.wb.green); if (params.wb.method=="Camera") @@ -163,7 +164,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { progress ("Sample ...",45); imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw); ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); - minit.unlock (); } progress ("Rotate / Distortion...",50); @@ -569,7 +569,7 @@ void ImProcCoordinator::startProcessing () { void ImProcCoordinator::process () { if (plistener) - plistener->setProgressState (1); + plistener->setProgressState (true); paramsUpdateMutex.lock (); while (changeSinceLast) { @@ -585,7 +585,7 @@ void ImProcCoordinator::process () { updaterRunning = false; if (plistener) - plistener->setProgressState (0); + plistener->setProgressState (false); } ProcParams* ImProcCoordinator::getParamsForUpdate (ProcEvent change) { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 78af6df12..38e05bb50 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -104,8 +104,8 @@ namespace rtengine { * @param str is the textual information corresponding to the progress */ virtual void setProgressStr (Glib::ustring str) {} /** This member function is called when the state of the processing has been changed. - * @param state =1 if the processing has been started, =0 if it has been stopped */ - virtual void setProgressState (int state) {} + * @param inProcessing =true if the processing has been started, =false if it has been stopped */ + virtual void setProgressState (bool inProcessing) {} /** This member function is called when an error occurs during the operation. * @param descr is the error message */ virtual void error (Glib::ustring descr) {} @@ -221,6 +221,9 @@ namespace rtengine { public: /** Sets the window defining the crop. */ virtual void setWindow (int cx, int cy, int cw, int ch, int skip) {} + + /** First try to update (threadless update). If it returns false, make a full update */ + virtual bool tryUpdate () { return false; } /** Perform a full recalculation of the part of the image corresponding to the crop. */ virtual void fullUpdate () {} /** Sets the listener of the crop. */ diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 2fa622309..cede66dad 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -52,6 +52,12 @@ void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) { void BatchQueue::addEntries ( std::vector &entries, bool head) { + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif + for( std::vector::iterator entry = entries.begin(); entry != entries.end();entry++ ){ (*entry)->setParent (this); (*entry)->resize (options.thumbSize); @@ -82,6 +88,8 @@ void BatchQueue::addEntries ( std::vector &entries, bool head) (*entry)->addButtonSet (bqbs); } saveBatchQueue( ); + } + arrangeFiles (); queue_draw (); notifyListener (); @@ -96,6 +104,7 @@ bool BatchQueue::saveBatchQueue( ) if (f==NULL) return false; + // method is already running with entryLock, so no need to lock again for (std::vector::iterator pos=fd.begin(); pos!=fd.end(); pos++){ BatchQueueEntry* bqe = reinterpret_cast(*pos); fprintf(f,"%s;%s\n", bqe->filename.c_str(),bqe->savedParamsFile.c_str() ); @@ -106,6 +115,11 @@ bool BatchQueue::saveBatchQueue( ) bool BatchQueue::loadBatchQueue( ) { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif + Glib::ustring savedQueueFile; savedQueueFile = options.rtdir+"/batch/queue"; FILE *f = safe_g_fopen (savedQueueFile, "rt"); @@ -190,6 +204,11 @@ int deleteitem (void* data) } void BatchQueue::cancelItems (std::vector* items) { + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif for (int i=0; isize(); i++) { BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; @@ -210,13 +229,17 @@ void BatchQueue::cancelItems (std::vector* items) { selected.clear (); saveBatchQueue( ); - + } redraw (); notifyListener (); } void BatchQueue::headItems (std::vector* items) { - + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif for (int i=items->size()-1; i>=0; i--) { BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; if (entry->processing) @@ -233,11 +256,16 @@ void BatchQueue::headItems (std::vector* items) { } } saveBatchQueue( ); + } redraw (); } void BatchQueue::tailItems (std::vector* items) { - + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif for (int i=0; isize(); i++) { BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; if (entry->processing) @@ -249,10 +277,15 @@ void BatchQueue::tailItems (std::vector* items) { } } saveBatchQueue( ); + } redraw (); } void BatchQueue::selectAll () { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif lastClicked = NULL; selected.clear (); @@ -265,7 +298,10 @@ void BatchQueue::selectAll () { queue_draw (); } void BatchQueue::startProcessing () { - + // TODO: Check for Linux + #ifdef WIN32 + entryMutex.lock(); + #endif if (!processing && fd.size()>0) { BatchQueueEntry* next = (BatchQueueEntry*)fd[0]; // tag it as processing @@ -278,6 +314,12 @@ void BatchQueue::startProcessing () { selected.erase (pos); processing->selected = false; } + + // TODO: Check for Linux + #ifdef WIN32 + entryMutex.unlock(); + #endif + // remove button set next->removeButtonSet (); // start batch processing @@ -335,6 +377,12 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { // delete from the queue delete processing; processing = NULL; + { + // TODO: Check for Linux + #ifdef WIN32 + Glib::Mutex::Lock lock(entryMutex); + #endif + fd.erase (fd.begin()); // return next job @@ -369,6 +417,8 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { safe_g_remove( *iter ); } } + } + redraw (); notifyListener (); gdk_threads_leave (); diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index f8a6ca5d6..3661880bd 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -41,7 +41,7 @@ class BatchQueue : public ThumbBrowserBase, protected: - BatchQueueEntry* processing; + BatchQueueEntry* processing; // holds the currently processed image Glib::ustring nameTemplate; diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 2c0f97a9e..a8acadebc 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -26,6 +26,7 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine: params = pparams; + // The BatchQueueEntryIdleHelper tracks if bqih = new BatchQueueEntryIdleHelper; bqih->bqentry = this; bqih->destroyed = false; @@ -98,19 +99,21 @@ void BatchQueueEntry::removeButtonSet () { delete buttonSet; buttonSet = NULL; } -struct bqupdate { + +struct BQUpdateParam { BatchQueueEntryIdleHelper* bqih; guint8* img; int w,h; }; -int bqeupdate (void* data) { +int updateImageUIThread (void* data) { gdk_threads_enter (); - bqupdate* params = (bqupdate*)data; + BQUpdateParam* params = (BQUpdateParam*)data; BatchQueueEntryIdleHelper* bqih = params->bqih; + // If the BQEntry was destroyed meanwhile, remove all the IdleHelper if all entries came through if (bqih->destroyed) { if (bqih->pending == 1) delete bqih; @@ -130,16 +133,17 @@ int bqeupdate (void* data) { return 0; } +// Starts a copy of img->preview via GTK thread void BatchQueueEntry::updateImage (guint8* img, int w, int h) { bqih->pending++; - bqupdate* param = new bqupdate (); + BQUpdateParam* param = new BQUpdateParam (); param->bqih = bqih; param->img = img; param->w = w; param->h = h; - g_idle_add (bqeupdate, param); + g_idle_add (updateImageUIThread, param); } void BatchQueueEntry::_updateImage (guint8* img, int w, int h) { diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc index 02697831c..327e70009 100644 --- a/rtgui/crophandler.cc +++ b/rtgui/crophandler.cc @@ -205,12 +205,13 @@ bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) cww = cropW; cwh = cropH; + /* // hack: if called before first size allocation the size will be 0 if (cww<10) cww = 10; if (cwh<32) cwh = 32; - + */ cskip = zoom>=1000 ? 1 : zoom; return true; @@ -222,7 +223,14 @@ void CropHandler::update () { // crop->setWindow (cropX, cropY, cropW, cropH, zoom>=1000 ? 1 : zoom); --> we use the "getWindow" hook instead of setting the size before crop->setListener (this); cropPixbuf.clear (); + + // To save threads, try to mark "needUpdate" without a thread first + if (!crop->tryUpdate()) { + if (isLowUpdatePriority) Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), 0, false, true, Glib::THREAD_PRIORITY_LOW); + else + Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), false ); + } } } diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h index 8ae97b568..d95a15d37 100644 --- a/rtgui/crophandler.h +++ b/rtgui/crophandler.h @@ -44,6 +44,7 @@ class CropHandler : public rtengine::DetailedCropListener, public rtengine::Size unsigned char* cropimg; int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis; bool initial; + bool isLowUpdatePriority; rtengine::StagedImageProcessor* ipc; rtengine::DetailedCrop* crop; @@ -75,6 +76,8 @@ class CropHandler : public rtengine::DetailedCropListener, public rtengine::Size void setEnabled (bool e); bool getEnabled (); + void setIsLowUpdatePriority(bool p) { isLowUpdatePriority=p; } + // DetailedCropListener interface void setDetailedCrop (rtengine::IImage8* im, rtengine::procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip); bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip); diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index e5da4ba24..1d6cea1aa 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -49,12 +49,12 @@ ZoomStep zoomSteps[] = {{" 10%", 0.1, 10}, #define MAXZOOMSTEPS 14 #define ZOOM11INDEX 7 -CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_) +CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_) : onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), backColor(options.bgcolor), decorated(true), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), imgX(0), imgY(0), imgW(1), imgH(1), iarea(parent), - cropZoom(0), cropgl(NULL), pmlistener(NULL), observedCropWin(NULL) { + cropZoom(0), cropgl(NULL), pmlistener(NULL), observedCropWin(NULL), isLowUpdatePriority(isLowUpdatePriority_) { Glib::RefPtr context = parent->get_pango_context () ; Pango::FontDescription fontd = context->get_font_description (); @@ -195,7 +195,7 @@ void CropWindow::setSize (int w, int h, bool norefresh) { if (!norefresh) cropHandler.setWSize (imgAreaW, imgAreaH); - iarea->redraw (); + //iarea->redraw (); } void CropWindow::getSize (int& w, int& h) { @@ -466,13 +466,13 @@ void CropWindow::pointerMoved (int x, int y) { if (!onArea (CropImage, x, y) || !cropHandler.cropPixbuf) pmlistener->pointerMoved (false, mx, my, -1, -1, -1); else { - cropHandler.cimg.lock (); + Glib::Mutex::Lock lock(cropHandler.cimg); + int vx = x - xpos - imgX; int vy = y - ypos - imgY; guint8* pix = cropHandler.cropPixbuf->get_pixels() + vy*cropHandler.cropPixbuf->get_rowstride() + vx*3; if (vx < cropHandler.cropPixbuf->get_width() && vy < cropHandler.cropPixbuf->get_height()) pmlistener->pointerMoved (true, mx, my, pix[0], pix[1], pix[2]); - cropHandler.cimg.unlock (); } } } @@ -588,6 +588,7 @@ void CropWindow::updateCursor (int x, int y) { } void CropWindow::expose (Cairo::RefPtr cr) { + Glib::Mutex::Lock lock(cropHandler.cimg); //MyTime t1, t2, t3, t4; @@ -613,7 +614,7 @@ void CropWindow::expose (Cairo::RefPtr cr) { cr->stroke_preserve (); cr->fill (); - cropHandler.cimg.lock (); + // draw image if (state==SCropImgMove || state==SCropWinResize) { // draw a rough image @@ -718,7 +719,7 @@ void CropWindow::expose (Cairo::RefPtr cr) { drawSpotWBRectangle (cr); //t2.set (); - cropHandler.cimg.unlock (); + // printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3)); } diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 99d816b8b..87f8f19f0 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -50,6 +50,7 @@ class CropWindow : public LWButtonListener, public CropHandlerListener { bool deleted; bool fitZoomEnabled; bool fitZoom; + bool isLowUpdatePriority; // decoration Cairo::RefPtr resizeSurface; @@ -93,7 +94,7 @@ class CropWindow : public LWButtonListener, public CropHandlerListener { public: CropHandler cropHandler; - CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_); + CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_); ~CropWindow (); void setDecorated (bool decorated) { this->decorated = decorated; } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index cb7664aa2..c7b6db864 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -361,7 +361,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { ipc = rtengine::StagedImageProcessor::create (isrc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); - ipc->setPreviewScale (10); + ipc->setPreviewScale (10); // Important tpc->initImage (ipc, tmb->getType()==FT_Raw); ipc->setHistogramListener (this); @@ -498,7 +498,7 @@ void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, r } struct spsparams { - bool state; + bool inProcessing; EditorPanelIdleHelper* epih; }; @@ -517,19 +517,19 @@ int setProgressStateUIThread (void* data) { return 0; } - p->epih->epanel->refreshProcessingState (p->state); + p->epih->epanel->refreshProcessingState (p->inProcessing); p->epih->pending--; delete p; gdk_threads_leave (); return 0; } -void EditorPanel::setProgressState (int state) { +void EditorPanel::setProgressState (bool inProcessing) { epih->pending++; spsparams* p = new spsparams; - p->state = state; + p->inProcessing = inProcessing; p->epih = epih; g_idle_add (setProgressStateUIThread, p); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 0d9574bcf..8eeeba0eb 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -134,7 +134,7 @@ class EditorPanel : public Gtk::VBox, // progresslistener interface void setProgress (double p); void setProgressStr (Glib::ustring str); - void setProgressState (int state); + void setProgressState (bool inProcessing); void error (Glib::ustring descr); void displayError (Glib::ustring descr); // this is called by error in the gtk thread void refreshProcessingState (bool inProcessing); // this is called by setProcessingState in the gtk thread diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 9420d49d7..f8a9f0edb 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 05795896d..839fcf919 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -61,14 +61,14 @@ void ImageArea::on_realize() void ImageArea::on_resized (Gtk::Allocation& req) { if (ipc && get_width()>1) { // sometimes on_resize is called in some init state, causing wrong sizes if (!mainCropWindow) { - mainCropWindow = new CropWindow (this, ipc); + mainCropWindow = new CropWindow (this, ipc, false); mainCropWindow->setDecorated (false); mainCropWindow->setFitZoomEnabled (true); - mainCropWindow->setPosition (0, 0); - mainCropWindow->setSize (get_width(), get_height()); mainCropWindow->addCropWindowListener (this); mainCropWindow->setCropGUIListener (cropgl); mainCropWindow->setPointerMotionListener (pmlistener); + mainCropWindow->setPosition (0, 0); + mainCropWindow->setSize (get_width(), get_height(), false); // this execute the refresh itself } else { mainCropWindow->setSize (get_width(), get_height()); @@ -246,7 +246,7 @@ void ImageArea::unGrabFocus () { void ImageArea::addCropWindow () { if (!mainCropWindow) return; // if called but no image is loaded, it would crash - CropWindow* cw = new CropWindow (this, ipc); + CropWindow* cw = new CropWindow (this, ipc, true); cw->zoom11(); cw->setCropGUIListener (cropgl); cw->setPointerMotionListener (pmlistener); diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc index a93337625..f660b8caf 100644 --- a/rtgui/previewhandler.cc +++ b/rtgui/previewhandler.cc @@ -183,9 +183,10 @@ void PreviewHandler::imageReady (CropParams cp) { } Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) { + Glib::Mutex::Lock lock(previewImgMutex); Glib::RefPtr resPixbuf; - previewImgMutex.lock (); + if (previewImg) { double totalZoom = zoom*previewScale; if (w>previewImg->get_width()*totalZoom) @@ -206,14 +207,15 @@ Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, in resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h); previewImg->scale (resPixbuf, 0, 0, w, h, -ix, -iy, totalZoom, totalZoom, Gdk::INTERP_NEAREST); } - previewImgMutex.unlock (); + return resPixbuf; } Glib::RefPtr PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) { + Glib::Mutex::Lock lock(previewImgMutex); Glib::RefPtr resPixbuf; - previewImgMutex.lock (); + if (previewImg) { double zoom1 = (double)desiredW / previewImg->get_width(); double zoom2 = (double)desiredH / previewImg->get_height(); @@ -223,7 +225,7 @@ Glib::RefPtr PreviewHandler::getRoughImage (int desiredW, int desir previewImg->scale (resPixbuf, 0, 0, previewImg->get_width()*zoom, previewImg->get_height()*zoom, 0, 0, zoom, zoom, Gdk::INTERP_NEAREST); zoom_ = zoom / previewScale; } - previewImgMutex.unlock (); + return resPixbuf; } diff --git a/rtgui/procthread.h b/rtgui/procthread.h deleted file mode 100644 index fe0d0a90f..000000000 --- a/rtgui/procthread.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _PROCTHREAD_ -#define _PROCTHREAD_ - -#include - -template -class ProcessingThread { - - protected: - bool tostop; - bool stopped; - std::list jqueue; - Glib::Thread* thread; - bool fifo; - - public: - ProcessingThread () : tostop(false), stopped(true), fifo(true) {} - void init () { tostop = false; stopped = true; } - void add (T de) { jqueue.push_back (de); } - void removejobs () { while (!jqueue.empty()) jqueue.pop_front (); } - void stop () { if (stopped) { tostop = true; return; } gdk_threads_leave(); tostop = true; Glib::Thread::self()->yield(); if (!stopped) thread->join (); gdk_threads_enter();} - - virtual void start () {} - virtual void process (T& e) {} - virtual void processCustomOrder () {} - virtual void end () {} - - void process () { - if (stopped){ - #undef THREAD_PRIORITY_NORMAL - thread = Glib::Thread::create(sigc::mem_fun(*this, &ProcessingThread::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL); - } - } - void process_ () { - stopped = false; - tostop = false; - - start (); // jqueue.sort (); - - - while (!tostop && !jqueue.empty ()) { - if (fifo) { - T current = jqueue.front (); - jqueue.pop_front (); - process (current); - } - else - processCustomOrder (); - } - stopped = true; - end (); - } - - bool runs () { return !stopped; } - - void terminate () { stop (); removejobs (); } - - int numOfJobs () { return jqueue.size(); } -}; - -#endif diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h index 15e5ea08e..4d2facdf2 100644 --- a/rtgui/progressconnector.h +++ b/rtgui/progressconnector.h @@ -47,9 +47,9 @@ class PLDBridge : public rtengine::ProgressListener { gdk_threads_leave (); } - void setProgressState (int state){ + void setProgressState (bool inProcessing){ gdk_threads_enter (); - pl->setProgressState(state); + pl->setProgressState(inProcessing); gdk_threads_leave (); } diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index a9d3479dd..5200fc2e0 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -385,13 +385,12 @@ void RTWindow::setProgressStr (Glib::ustring str) { prProgBar.set_text ( str ); } -void RTWindow::setProgressState (int state) { - if (state) { +void RTWindow::setProgressState (bool inProcessing) { + if (inProcessing) prProgBar.show(); - } else { + else prProgBar.hide(); } -} void RTWindow::toggle_fullscreen () { if (is_fullscreen) { diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index c29e797da..7f076c70c 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -66,7 +66,7 @@ class RTWindow : public Gtk::Window, public rtengine::ProgressListener{ void toggle_fullscreen (); void setProgress (double p); void setProgressStr (Glib::ustring str); - void setProgressState (int state); + void setProgressState (bool inProcessing); void error (Glib::ustring descr); rtengine::ProgressListener* getProgressListener () { return pldBridge; }