From c57bc0c15f7df5d0362cf7f9a6de28eb5beaea1a Mon Sep 17 00:00:00 2001 From: Oliver Duis Date: Sat, 20 Aug 2011 21:26:52 +0200 Subject: [PATCH] Filter for unnecessary slow demosaicing when switch between history states see issue 923 --- rtengine/ex2simple.cc | 8 +++--- rtengine/improccoordinator.cc | 14 ++++++---- rtengine/improccoordinator.h | 5 ++-- rtengine/refreshmap.h | 1 + rtengine/rtengine.h | 7 ++--- rtgui/editorpanel.cc | 4 +-- rtgui/paramsedited.cc | 50 +++++++++++++++++++---------------- rtgui/paramsedited.h | 3 ++- rtgui/toolpanelcoord.cc | 27 ++++++++++++++++--- 9 files changed, 75 insertions(+), 44 deletions(-) diff --git a/rtengine/ex2simple.cc b/rtengine/ex2simple.cc index 7ce0b1ffd..032993151 100644 --- a/rtengine/ex2simple.cc +++ b/rtengine/ex2simple.cc @@ -121,17 +121,17 @@ int main (int argc, char* argv[]) { // if you want to change the settings you have to ask for the procparams structure of the staged image processor // you have to tell it what has changed. At the first time tell it EvPhotoLoaded so a full processing will be performed - rtengine::procparams::ProcParams* params = ipc->getParamsForUpdate (rtengine::EvPhotoLoaded); + rtengine::procparams::ProcParams* params = ipc->beginUpdateParams (); // change this and that... params->toneCurve.brightness = 1.0; // you can load it, too, from a file: params->load (argv[2]); // finally you have to call this non-blocking method, and the image processing starts in the background. When finished, the preview image listener will be notified - ipc->paramsUpdateReady (); + ipc->endUpdateParams (rtengine::EvPhotoLoaded); // you can go on with changing of the settings, following the gui actions // now we know that only the brightness has changed compared to the previous settings, to only a part of the processing has to be repeated - params = ipc->getParamsForUpdate (rtengine::EvBrightness); + params = ipc->beginUpdateParams (); params->toneCurve.brightness = 1.2; - ipc->paramsUpdateReady (); + ipc->endUpdateParams (rtengine::EvBrightness); // ... and so on. If you dont need it any more, you can destroy it (make sure that no processing is happening when you destroy it!) StagedImageProcessor::destroy (ipc); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 42e24908b..bbc237a44 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -615,17 +615,21 @@ void ImProcCoordinator::process () { plistener->setProgressState (false); } -ProcParams* ImProcCoordinator::getParamsForUpdate (ProcEvent change) { - +ProcParams* ImProcCoordinator::beginUpdateParams () { paramsUpdateMutex.lock (); - changeSinceLast |= refreshmap[(int)change]; + return &nextParams; } -void ImProcCoordinator::paramsUpdateReady () { +void ImProcCoordinator::endUpdateParams (ProcEvent change) { + endUpdateParams( refreshmap[(int)change] ); +} + +void ImProcCoordinator::endUpdateParams (int changeFlags) { + changeSinceLast |= changeFlags; paramsUpdateMutex.unlock (); - startProcessing (); // Executes what has been requested with getParamsForUpdate + startProcessing (); } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index f37785080..08daee83f 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -126,8 +126,9 @@ class ImProcCoordinator : public StagedImageProcessor { void getParams (procparams::ProcParams* dst) { *dst = params; } void startProcessing(int changeCode); - ProcParams* getParamsForUpdate (ProcEvent change); - void paramsUpdateReady (); // must be called after getParamsForUpdate, triggers full update + ProcParams* beginUpdateParams (); + void endUpdateParams (ProcEvent change); // must be called after beginUpdateParams, triggers update + void endUpdateParams (int changeFlags); void stopProcessing (); diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index d1235bfc2..9a2f37b07 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -64,6 +64,7 @@ #define IPTC M_VOID #define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) #define NONE 0 +#define ALLNORAW (M_INIT|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) extern int refreshmap[]; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index da7b50e8c..15354737f 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -250,12 +250,13 @@ namespace rtengine { * processing parameters, that you have to update to reflect the changed situation. When ready, call the paramsUpdateReady * function to start the image update. * @param change is the ID of the changed setting */ - virtual procparams::ProcParams* getParamsForUpdate (ProcEvent change) =0; + virtual procparams::ProcParams* beginUpdateParams () =0; /** An essential member function. This indicates that you are ready with the update of the processing parameters you got - * with the getParamsForUpdate call, so the image can be updated. This function returns immediately. + * with the beginUpdateParams call, so the image can be updated. This function returns immediately. * The image update starts immediately in the background. If it is ready, the result is passed to a PreviewImageListener * and to a DetailedCropListener (if enabled). */ - virtual void paramsUpdateReady () =0; + virtual void endUpdateParams (ProcEvent change) =0; + virtual void endUpdateParams (int changeFlags) =0; // Starts a minimal update virtual void startProcessing(int changeCode) =0; /** Stops image processing. When it returns, the image processing is already stopped. */ diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 1541d08de..2aac8aafd 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1199,9 +1199,9 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { if (beforeIpc) { - ProcParams* pparams = beforeIpc->getParamsForUpdate (rtengine::EvProfileChanged); + ProcParams* pparams = beforeIpc->beginUpdateParams (); *pparams = params; - beforeIpc->paramsUpdateReady (); // starts the IPC processinp + beforeIpc->endUpdateParams (rtengine::EvProfileChanged); // starts the IPC processing } } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index f5b20660c..fa9ad829a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -157,26 +157,26 @@ void ParamsEdited::set (bool v) { raw.dcbIterations = v; raw.dcbEnhance = v; raw.allEnhance = v; - raw.dfAuto = v; raw.caCorrection = v; - raw.hotDeadPixel = v; raw.caBlue = v; raw.caRed = v; + raw.greenEq = v; + raw.hotDeadPixel = v; + raw.linenoise = v; raw.darkFrame = v; + raw.dfAuto = v; + raw.ff_file = v; + raw.ff_AutoSelect = v; + raw.ff_BlurRadius = v; + raw.ff_BlurType = v; raw.exPos = v; - raw.exCorrection = v; raw.exPreser = v; raw.exBlackzero = v; raw.exBlackone = v; raw.exBlacktwo = v; raw.exBlackthree = v; raw.exTwoGreen=v; - raw.greenEq = v; - raw.linenoise = v; - raw.ff_file = v; - raw.ff_AutoSelect = v; - raw.ff_BlurRadius = v; - raw.ff_BlurType = v; + dirpyrequalizer.enabled = v; for(int i = 0; i < 5; i++) { dirpyrequalizer.mult[i] = v; @@ -328,31 +328,29 @@ void ParamsEdited::initFrom (const std::vector icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; icm.slpos = icm.slpos && p.icm.slpos == other.icm.slpos; raw.ccSteps = raw.ccSteps && p.raw.ccSteps == other.raw.ccSteps; + raw.dmethod = raw.dmethod && p.raw.dmethod == other.raw.dmethod; + raw.dcbIterations = raw.dcbIterations && p.raw.dcb_iterations == other.raw.dcb_iterations; raw.dcbEnhance = raw.dcbEnhance && p.raw.dcb_enhance == other.raw.dcb_enhance; raw.allEnhance = raw.allEnhance && p.raw.all_enhance == other.raw.all_enhance; - - raw.dcbIterations = raw.dcbIterations && p.raw.dcb_iterations == other.raw.dcb_iterations; - raw.dmethod = raw.dmethod && p.raw.dmethod == other.raw.dmethod; raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect; raw.caRed = raw.caRed && p.raw.cared == other.raw.cared; raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue; - raw.exPos = raw.exPos && p.raw.expos == other.raw.expos; - raw.exPreser = raw.exPreser && p.raw.preser == other.raw.preser; //exposi - raw.exBlackzero = raw.exBlackzero && p.raw.blackzero == other.raw.blackzero; //black - raw.exBlackone = raw.exBlackone && p.raw.blackone == other.raw.blackone; //black - raw.exBlacktwo = raw.exBlacktwo && p.raw.blacktwo == other.raw.blacktwo; //black - raw.exBlackthree = raw.exBlackthree && p.raw.blackthree == other.raw.blackthree; //black - raw.exTwoGreen = raw.exTwoGreen && p.raw.twogreen == other.raw.twogreen; //black 2 green - + raw.greenEq = raw.greenEq && p.raw.greenthresh == other.raw.greenthresh; + raw.hotDeadPixel = raw.hotDeadPixel && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt; + raw.linenoise = raw.linenoise && p.raw.linenoise == other.raw.linenoise; raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame; raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect; raw.ff_file = raw.ff_file && p.raw.ff_file == other.raw.ff_file; raw.ff_AutoSelect = raw.ff_AutoSelect && p.raw.ff_AutoSelect == other.raw.ff_AutoSelect; raw.ff_BlurRadius = raw.ff_BlurRadius && p.raw.ff_BlurRadius == other.raw.ff_BlurRadius; raw.ff_BlurType = raw.ff_BlurType && p.raw.ff_BlurType == other.raw.ff_BlurType; - raw.greenEq = raw.greenEq && p.raw.greenthresh == other.raw.greenthresh; - raw.hotDeadPixel = raw.hotDeadPixel && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt; - raw.linenoise = raw.linenoise && p.raw.linenoise == other.raw.linenoise; + raw.exPos = raw.exPos && p.raw.expos == other.raw.expos; + raw.exPreser = raw.exPreser && p.raw.preser == other.raw.preser; + raw.exBlackzero = raw.exBlackzero && p.raw.blackzero == other.raw.blackzero; + raw.exBlackone = raw.exBlackone && p.raw.blackone == other.raw.blackone; + raw.exBlacktwo = p.raw.blacktwo == other.raw.blacktwo; + raw.exBlackthree = p.raw.blackthree == other.raw.blackthree; + raw.exTwoGreen = p.raw.twogreen == other.raw.twogreen; dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; for(int i = 0; i < 8; i++) { @@ -533,3 +531,9 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten // if (exif) toEdit.exif==mo.exif = mods.exif==other.exif; // if (iptc;) toEdit.iptc==other.iptc; = mods.iptc==other.iptc;; } + +bool RAWParamsEdited::isUnchanged() const { + return ccSteps && dmethod && dcbIterations && dcbEnhance && allEnhance && caCorrection && caRed && caBlue && greenEq + && hotDeadPixel && linenoise && darkFrame && dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType + && exPos && exPreser && exBlackzero && exBlackone && exBlacktwo && exBlackthree && exTwoGreen; +} \ No newline at end of file diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index fb012ccc2..f94a34a29 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -305,7 +305,6 @@ class RAWParamsEdited { bool ff_AutoSelect; bool ff_BlurRadius; bool ff_BlurType; - bool exCorrection; bool exPos; bool exPreser; bool exBlackzero; @@ -313,6 +312,8 @@ class RAWParamsEdited { bool exBlacktwo; bool exBlackthree; bool exTwoGreen; + + bool isUnchanged() const; }; class ExifPairEdited { diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index c1d027fba..f985d4ed7 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -24,6 +24,8 @@ #include #include #include +#include +#include using namespace rtengine::procparams; @@ -236,7 +238,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: if (!ipc) return; - ProcParams* params = ipc->getParamsForUpdate (event); + ProcParams* params = ipc->beginUpdateParams (); for (int i=0; iwrite (params); @@ -260,7 +262,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: resize->write (params); } - ipc->paramsUpdateReady (); // starts the IPC processinp + ipc->endUpdateParams (event); // starts the IPC processing hasChanged = true; @@ -273,7 +275,20 @@ void ToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine:: int fw, fh, tr; if (!ipc) return; - ProcParams *params = ipc->getParamsForUpdate (event); + ProcParams *params = ipc->beginUpdateParams (); + + // Derive the effective changes, if it's a profile change, to prevent slow RAW rerendering if not necessary + bool filterRawRefresh=false; + if (event!=rtengine::EvPhotoLoaded) { + ParamsEdited pe; + std::vector lParams(2); + lParams[0]=*params; lParams[1]=*nparams; + pe.set(true); + pe.initFrom (lParams); + + filterRawRefresh=pe.raw.isUnchanged(); + } + *params = *nparams; tr = TR_NONE; @@ -290,7 +305,11 @@ void ToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine:: for (unsigned int i=0; iread (params); - ipc->paramsUpdateReady (); // starts the IPC processinp + // start the IPC processing + if (filterRawRefresh) { + ipc->endUpdateParams ( refreshmap[(int)event] & ALLNORAW ); + } else + ipc->endUpdateParams (event); hasChanged = event != rtengine::EvProfileChangeNotification;