From b0a7b5fed33d58d7df676a459d03bfa4666ec3a7 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 9 Mar 2019 18:47:02 +0100 Subject: [PATCH] tiles per thread for some more tiled algorithms, #5203 --- rtdata/languages/default | 5 ++ rtengine/CA_correct_RT.cc | 13 ++++- rtengine/amaze_demosaic_RT.cc | 13 +++-- rtengine/dual_demosaic_RT.cc | 16 +++--- rtengine/improcfun.cc | 17 ++++-- rtengine/improcfun.h | 4 +- rtengine/pixelshift.cc | 8 +-- rtengine/rawimagesource.cc | 18 +++--- rtengine/rawimagesource.h | 11 ++-- rtengine/rcd_demosaic.cc | 10 +++- rtengine/simpleprocess.cc | 2 +- rtengine/xtrans_demosaic.cc | 14 ++++- rtgui/options.cc | 25 +++++++++ rtgui/options.h | 4 ++ rtgui/preferences.cc | 102 +++++++++++++++------------------- rtgui/preferences.h | 4 ++ 16 files changed, 161 insertions(+), 105 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 804ae1624..09f6fe9c1 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1065,8 +1065,11 @@ PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries PREFERENCES_CACHEOPTS;Cache Options PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height PREFERENCES_CHUNKSIZES;Tiles per thread +PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction PREFERENCES_CHUNKSIZE_RAW_RCD;RCD demosaic +PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic +PREFERENCES_CHUNKSIZE_RGB;RGB processing PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -1183,6 +1186,8 @@ PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. +PREFERENCES_PERFORMANCE_MEASURE;Measure +PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console PREFERENCES_PERFORMANCE_THREADS;Threads PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic) PREFERENCES_PREVDEMO;Preview Demosaic Method diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index 0d150c5c4..76bd31f1e 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -27,7 +27,6 @@ #include "rt_math.h" #include "gauss.h" #include "median.h" -#define BENCHMARK #include "StopWatch.h" namespace { @@ -122,10 +121,18 @@ float* RawImageSource::CA_correct_RT( bool fitParamsOut, float* buffer, bool freeBuffer, - size_t chunkSize + size_t chunkSize, + bool measure ) { - BENCHFUN + + std::unique_ptr stop; + + if (measure) { + std::cout << "CA correcting " << W << "x" << H << " image with " << chunkSize << " tiles per thread" << std::endl; + stop.reset(new StopWatch("CA correction")); + } + // multithreaded and vectorized by Ingo Weyrich constexpr int ts = 128; constexpr int tsh = ts / 2; diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index 3aafbd448..fc36ff8b5 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -33,15 +33,20 @@ #include "sleef.c" #include "opthelper.h" #include "median.h" -#define BENCHMARK #include "StopWatch.h" namespace rtengine { -void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue) +void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, size_t chunkSize, bool measure) { - BENCHFUN + + std::unique_ptr stop; + + if (measure) { + std::cout << "Demosaicing " << W << "x" << H << " image using AMaZE with " << chunkSize << " Tiles per Thread" << std::endl; + stop.reset(new StopWatch("amaze demosaic")); + } volatile double progress = 0.0; @@ -177,7 +182,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c // Main algorithm: Tile loop // use collapse(2) to collapse the 2 loops to one large loop, so there is better scaling #ifdef _OPENMP - #pragma omp for schedule(dynamic, 8) collapse(2) nowait + #pragma omp for schedule(dynamic, chunkSize) collapse(2) nowait #endif for (int top = winy - 16; top < winy + height; top += ts - 32) { diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index e6397fe17..d7f3a4c14 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -44,17 +44,17 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi // contrast == 0.0 means only first demosaicer will be used if(isBayer) { if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) ) { - amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue); + amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) { - rcd_demosaic(options.chunkSizeCA); + rcd_demosaic(options.chunkSizeRCD, options.measure); } } else { if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) { - xtrans_interpolate (3, true); + xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); } else { - xtrans_interpolate (1, false); + xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); } } @@ -70,17 +70,17 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT)) { - amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue); + amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4) ) { - rcd_demosaic(options.chunkSizeCA); + rcd_demosaic(options.chunkSizeRCD, options.measure); } } else { if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) ) { - xtrans_interpolate (3, true); + xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); } else { - xtrans_interpolate (1, false); + xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); } fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 465e3ffe8..ab5260e94 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2052,17 +2052,24 @@ filmlike_clip (float *r, float *g, float *b) void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve, - const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve ) + const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure) { - rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve); + rgbProc (working, lab, pipetteBuffer, hltonecurve, shtonecurve, tonecurve, sat, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf, asIn, histToneCurve, chunkSize, measure); } // Process RGB image and convert to LAB space void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve, LUTf & cl2Toningcurve, - const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve ) + const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize, bool measure) { - BENCHFUN + + std::unique_ptr stop; + + if (measure) { + std::cout << "rgb processing " << working->getWidth() << "x" << working->getHeight() << " image with " << chunkSize << " tiles per thread" << std::endl; + stop.reset(new StopWatch("rgb processing")); + } + Imagefloat *tmpImage = nullptr; Imagefloat* editImgFloat = nullptr; @@ -2432,7 +2439,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer } #ifdef _OPENMP - #pragma omp for schedule(dynamic) collapse(2) + #pragma omp for schedule(dynamic, chunkSize) collapse(2) #endif for (int ii = 0; ii < working->getHeight(); ii += TS) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 3e583958b..129cef533 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -207,11 +207,11 @@ public: void updateColorProfiles(const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck); void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, - const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve); + const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false); void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, - double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve); + double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf, const DCPProfile::ApplyState &asIn, LUTu &histToneCurve, size_t chunkSize = 1, bool measure = false); void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, LUTf & clToningcurve, LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 76d1f836c..befa0d4c6 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -299,7 +299,7 @@ void RawImageSource::pixelshift(int winx, int winy, int winw, int winh, const RA { BENCHFUN if(numFrames != 4) { // fallback for non pixelshift files - amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue); + amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); return; } @@ -328,7 +328,7 @@ BENCHFUN } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[0]), red, green, blue, bayerParams.dualDemosaicContrast, true); } else { - amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[0]), red, green, blue); + amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[0]), red, green, blue, options.chunkSizeAMAZE, options.measure); } multi_array2D redTmp(winw, winh); multi_array2D greenTmp(winw, winh); @@ -340,7 +340,7 @@ BENCHFUN } else if (bayerParams.pixelShiftDemosaicMethod == bayerParams.getPSDemosaicMethodString(RAWParams::BayerSensor::PSDemosaicMethod::AMAZEVNG4)) { dual_demosaic_RT (true, rawParamsIn, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], bayerParams.dualDemosaicContrast, true); } else { - amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i]); + amaze_demosaic_RT(winx, winy, winw, winh, *(rawDataFrames[i + 1]), redTmp[i], greenTmp[i], blueTmp[i], options.chunkSizeAMAZE, options.measure); } } @@ -369,7 +369,7 @@ BENCHFUN rawParamsTmp.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4); dual_demosaic_RT (true, rawParamsTmp, winw, winh, rawData, red, green, blue, bayerParams.dualDemosaicContrast, true); } else { - amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue); + amaze_demosaic_RT(winx, winy, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } } } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index d6cffda26..f529d52f2 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -2031,13 +2031,13 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } if(numFrames == 4) { double fitParams[64]; - float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA); + float *buffer = CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[0], fitParams, false, true, nullptr, false, options.chunkSizeCA, options.measure); for(int i = 1; i < 3; ++i) { - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[i], fitParams, true, false, buffer, false, options.chunkSizeCA, options.measure); } - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, *rawDataFrames[3], fitParams, true, false, buffer, true, options.chunkSizeCA, options.measure); } else { - CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA); + CA_correct_RT(raw.ca_autocorrect, raw.caautoiterations, raw.cared, raw.cablue, raw.ca_avoidcolourshift, rawData, nullptr, false, false, nullptr, true, options.chunkSizeCA, options.measure); } } @@ -2078,7 +2078,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AHD) ) { ahd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE) ) { - amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue); + amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) { @@ -2091,7 +2091,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) { pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCB) ) { - dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); + dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance, options.chunkSizeRCD, options.measure); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::EAHD)) { eahd_demosaic (); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::IGV)) { @@ -2103,7 +2103,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO) ) { nodemosaic(true); } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCD) ) { - rcd_demosaic(options.chunkSizeRCD); + rcd_demosaic(options.chunkSizeRCD, options.measure); } else { nodemosaic(false); } @@ -2111,9 +2111,9 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST) ) { fast_xtrans_interpolate(rawData, red, green, blue); } else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::ONE_PASS)) { - xtrans_interpolate(1, false); + xtrans_interpolate(1, false, options.chunkSizeXT, options.measure); } else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::THREE_PASS) ) { - xtrans_interpolate(3, true); + xtrans_interpolate(3, true, options.chunkSizeXT, options.measure); } else if (raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FOUR_PASS) || raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::TWO_PASS)) { if (!autoContrast) { double threshold = raw.xtranssensor.dualDemosaicContrast; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 5fb233c2b..6d633c2a9 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -250,7 +250,8 @@ protected: bool fitParamsOut, float* buffer, bool freeBuffer, - size_t chunkSize = 1 + size_t chunkSize = 1, + bool measure = false ); void ddct8x8s(int isgn, float a[8][8]); @@ -272,12 +273,12 @@ protected: void jdl_interpolate_omp(); void igv_interpolate(int winw, int winh); void lmmse_interpolate_omp(int winw, int winh, array2D &rawData, array2D &red, array2D &green, array2D &blue, int iterations); - void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue);//Emil's code for AMaZE + void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, size_t chunkSize = 1, bool measure = false);//Emil's code for AMaZE void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D &rawData, array2D &red, array2D &green, array2D &blue, double &contrast, bool autoContrast = false); void fast_demosaic();//Emil's code for fast demosaicing - void dcb_demosaic(int iterations, bool dcb_enhance); + void dcb_demosaic(int iterations, bool dcb_enhance, size_t chunkSize = 1, bool measure = false); void ahd_demosaic(); - void rcd_demosaic(size_t chunkSize = 1); + void rcd_demosaic(size_t chunkSize = 1, bool measure = false); void border_interpolate(unsigned int border, float (*image)[4], unsigned int start = 0, unsigned int end = 0); void border_interpolate2(int winw, int winh, int lborders, const array2D &rawData, array2D &red, array2D &green, array2D &blue); void dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border); @@ -296,7 +297,7 @@ protected: void dcb_color_full(float (*image)[3], int x0, int y0, float (*chroma)[2]); void cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]); void xtransborder_interpolate (int border, array2D &red, array2D &green, array2D &blue); - void xtrans_interpolate (const int passes, const bool useCieLab); + void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false); void fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue); void pixelshift(int winx, int winy, int winw, int winh, const RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection); void hflip (Imagefloat* im); diff --git a/rtengine/rcd_demosaic.cc b/rtengine/rcd_demosaic.cc index 137c98c18..5b6e1a164 100644 --- a/rtengine/rcd_demosaic.cc +++ b/rtengine/rcd_demosaic.cc @@ -22,7 +22,6 @@ #include "rt_math.h" #include "../rtgui/multilangmgr.h" #include "opthelper.h" -#define BENCHMARK #include "StopWatch.h" using namespace std; @@ -40,9 +39,14 @@ namespace rtengine * Licensed under the GNU GPL version 3 */ // Tiled version by Ingo Weyrich (heckflosse67@gmx.de) -void RawImageSource::rcd_demosaic(size_t chunkSize) +void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) { - BENCHFUN + std::unique_ptr stop; + + if (measure) { + std::cout << "Demosaicing " << W << "x" << H << " image using rcd with " << chunkSize << " tiles per thread" << std::endl; + stop.reset(new StopWatch("rcd demosaic")); + } volatile double progress = 0.0; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 8fa79241b..dddc3d6c3 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -991,7 +991,7 @@ private: LUTu histToneCurve; - ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve); + ipf.rgbProc (baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve, options.chunkSizeRGB, options.measure); if (settings->verbose) { printf ("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index f32969d17..cb65db092 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -43,6 +43,7 @@ void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b if (!rgb) { if(!cbrtinit) { + #pragma omp parallel for for (int i = 0; i < 0x14000; i++) { double r = i / 65535.0; cbrt[i] = r > Color::eps ? std::cbrt(r) : (Color::kappa * r + 16.0) / 116.0; @@ -173,9 +174,16 @@ void RawImageSource::xtransborder_interpolate (int border, array2D &red, */ // override CLIP function to test unclipped output #define CLIP(x) (x) -void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) +void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize, bool measure) { - BENCHFUN + + std::unique_ptr stop; + + if (measure) { + std::cout << passes << "-pass Xtrans Demosaicing " << W << "x" << H << " image with " << chunkSize << " tiles per thread" << std::endl; + stop.reset(new StopWatch("xtrans demosaic")); + } + constexpr int ts = 114; /* Tile Size */ constexpr int tsh = ts / 2; /* half of Tile Size */ @@ -296,7 +304,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab) uint8_t (*homosummax)[ts] = (uint8_t (*)[ts]) homo[ndir - 1]; // we can reuse the homo-buffer because they are not used together #ifdef _OPENMP - #pragma omp for collapse(2) schedule(dynamic) nowait + #pragma omp for collapse(2) schedule(dynamic, chunkSize) nowait #endif for (int top = 3; top < height - 19; top += ts - 16) diff --git a/rtgui/options.cc b/rtgui/options.cc index 8f7fbbc50..2819497de 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -448,8 +448,12 @@ void Options::setDefaults() maxInspectorBuffers = 2; // a rather conservative value for low specced systems... inspectorDelay = 0; serializeTiffRead = true; + measure = false; + chunkSizeAMAZE = 1; chunkSizeCA = 1; chunkSizeRCD = 1; + chunkSizeRGB = 1; + chunkSizeXT = 1; FileBrowserToolbarSingleRow = false; hideTPVScrollbar = false; whiteBalanceSpotSize = 8; @@ -1080,6 +1084,14 @@ void Options::readFromFile(Glib::ustring fname) serializeTiffRead = keyFile.get_boolean("Performance", "SerializeTiffRead"); } + if (keyFile.has_key("Performance", "Measure")) { + measure = keyFile.get_boolean("Performance", "Measure"); + } + + if (keyFile.has_key("Performance", "ChunkSizeAMAZE")) { + chunkSizeAMAZE = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeAMAZE"))); + } + if (keyFile.has_key("Performance", "ChunkSizeCA")) { chunkSizeCA = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeCA"))); } @@ -1088,6 +1100,14 @@ void Options::readFromFile(Glib::ustring fname) chunkSizeRCD = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeRCD"))); } + if (keyFile.has_key("Performance", "ChunkSizeRGB")) { + chunkSizeRGB = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeRGB"))); + } + + if (keyFile.has_key("Performance", "ChunkSizeXT")) { + chunkSizeXT = std::min(16, std::max(1, keyFile.get_integer("Performance", "ChunkSizeXT"))); + } + if (keyFile.has_key("Performance", "ThumbnailInspectorMode")) { rtSettings.thumbnail_inspector_mode = static_cast(keyFile.get_integer("Performance", "ThumbnailInspectorMode")); } @@ -1958,7 +1978,12 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("Performance", "InspectorDelay", inspectorDelay); keyFile.set_integer("Performance", "PreviewDemosaicFromSidecar", prevdemo); keyFile.set_boolean("Performance", "SerializeTiffRead", serializeTiffRead); + keyFile.set_integer("Performance", "Measure", measure); + keyFile.set_integer("Performance", "ChunkSizeAMAZE", chunkSizeAMAZE); keyFile.set_integer("Performance", "ChunkSizeRCD", chunkSizeRCD); + keyFile.set_integer("Performance", "ChunkSizeRGB", chunkSizeRGB); + keyFile.set_integer("Performance", "ChunkSizeXT", chunkSizeXT); + keyFile.set_integer("Performance", "ChunkSizeCA", chunkSizeCA); keyFile.set_integer("Performance", "ThumbnailInspectorMode", int(rtSettings.thumbnail_inspector_mode)); keyFile.set_string("Output", "Format", saveFormat.format); diff --git a/rtgui/options.h b/rtgui/options.h index 042889337..06c49ed07 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -314,8 +314,12 @@ public: bool filledProfile; // Used as reminder for the ProfilePanel "mode" prevdemo_t prevdemo; // Demosaicing method used for the <100% preview bool serializeTiffRead; + bool measure; + size_t chunkSizeAMAZE; size_t chunkSizeCA; size_t chunkSizeRCD; + size_t chunkSizeRGB; + size_t chunkSizeXT; bool menuGroupRank; bool menuGroupLabel; bool menuGroupFileOperations; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f9724a15c..e23775bf9 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -31,6 +31,25 @@ #include #endif +namespace { +void placeSpinBox(Gtk::Container* where, Gtk::SpinButton* &spin, const std::string &labelText, int digits, int inc0, int inc1, int maxLength, int range0, int range1, const std::string &toolTip = "") { + Gtk::HBox* HB = Gtk::manage ( new Gtk::HBox () ); + HB->set_spacing (4); + if (!toolTip.empty()) { + HB->set_tooltip_text (M (toolTip)); + } + Gtk::Label* label = Gtk::manage ( new Gtk::Label (M (labelText) + ":", Gtk::ALIGN_START)); + spin = Gtk::manage ( new Gtk::SpinButton () ); + spin->set_digits (digits); + spin->set_increments (inc0, inc1); + spin->set_max_length (maxLength); // Will this be sufficient? :) + spin->set_range (range0, range1); + HB->pack_start (*label, Gtk::PACK_SHRINK, 0); + HB->pack_end (*spin, Gtk::PACK_SHRINK, 0); + where->add(*HB); +} +} + extern Options options; extern Glib::ustring argv0; Glib::RefPtr themecss; @@ -649,68 +668,36 @@ Gtk::Widget* Preferences::getPerformancePanel () vbPerformance->pack_start (*ftiffserialize, Gtk::PACK_SHRINK, 4); Gtk::Frame* fclut = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_CLUTSCACHE")) ); - Gtk::HBox* clutCacheSizeHB = Gtk::manage ( new Gtk::HBox () ); - clutCacheSizeHB->set_spacing (4); - Gtk::Label* CLUTLl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_CLUTSCACHE_LABEL") + ":", Gtk::ALIGN_START)); - clutCacheSizeSB = Gtk::manage ( new Gtk::SpinButton () ); - clutCacheSizeSB->set_digits (0); - clutCacheSizeSB->set_increments (1, 5); - clutCacheSizeSB->set_max_length (2); // Will this be sufficient? :) #ifdef _OPENMP - clutCacheSizeSB->set_range (1, 3 * omp_get_num_procs()); + placeSpinBox(fclut, clutCacheSizeSB, "PREFERENCES_CLUTSCACHE_LABEL", 0, 1, 5, 2, 1, 3 * omp_get_num_procs()); #else - clutCacheSizeSB->set_range (1, 12); + placeSpinBox(fclut, clutCacheSizeSB, "PREFERENCES_CLUTSCACHE_LABEL", 0, 1, 5, 2, 1, 12); #endif - clutCacheSizeHB->pack_start (*CLUTLl, Gtk::PACK_SHRINK, 0); - clutCacheSizeHB->pack_end (*clutCacheSizeSB, Gtk::PACK_SHRINK, 0); - fclut->add (*clutCacheSizeHB); vbPerformance->pack_start (*fclut, Gtk::PACK_SHRINK, 4); Gtk::Frame* fchunksize = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_CHUNKSIZES")) ); Gtk::VBox* chunkSizeVB = Gtk::manage ( new Gtk::VBox () ); - Gtk::HBox* cachunkSizeHB = Gtk::manage ( new Gtk::HBox () ); - cachunkSizeHB->set_spacing (4); - Gtk::Label* CALl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_CHUNKSIZE_RAW_CA") + ":", Gtk::ALIGN_START)); - chunkSizeCASB = Gtk::manage ( new Gtk::SpinButton () ); - chunkSizeCASB->set_digits (0); - chunkSizeCASB->set_increments (1, 5); - chunkSizeCASB->set_max_length (2); // Will this be sufficient? :) - chunkSizeCASB->set_range (1, 16); - cachunkSizeHB->pack_start (*CALl, Gtk::PACK_SHRINK, 0); - cachunkSizeHB->pack_end (*chunkSizeCASB, Gtk::PACK_SHRINK, 0); - chunkSizeVB->add(*cachunkSizeHB); - Gtk::HBox* rcdchunkSizeHB = Gtk::manage ( new Gtk::HBox () ); - rcdchunkSizeHB->set_spacing (4); - Gtk::Label* RCDLl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_CHUNKSIZE_RAW_RCD") + ":", Gtk::ALIGN_START)); - chunkSizeRCDSB = Gtk::manage ( new Gtk::SpinButton () ); - chunkSizeRCDSB->set_digits (0); - chunkSizeRCDSB->set_increments (1, 5); - chunkSizeRCDSB->set_max_length (2); // Will this be sufficient? :) - chunkSizeRCDSB->set_range (1, 16); - rcdchunkSizeHB->pack_start (*RCDLl, Gtk::PACK_SHRINK, 0); - rcdchunkSizeHB->pack_end (*chunkSizeRCDSB, Gtk::PACK_SHRINK, 0); - chunkSizeVB->add(*rcdchunkSizeHB); + Gtk::HBox* measureHB = Gtk::manage ( new Gtk::HBox () ); + measureHB->set_spacing (4); + measureCB = Gtk::manage ( new Gtk::CheckButton (M ("PREFERENCES_PERFORMANCE_MEASURE")) ); + measureCB->set_tooltip_text (M ("PREFERENCES_PERFORMANCE_MEASURE_HINT")); + measureHB->pack_start(*measureCB, Gtk::PACK_SHRINK, 0); + chunkSizeVB->add(*measureHB); + + placeSpinBox(chunkSizeVB, chunkSizeAMSB, "PREFERENCES_CHUNKSIZE_RAW_AMAZE", 0, 1, 5, 2, 1, 16); + placeSpinBox(chunkSizeVB, chunkSizeCASB, "PREFERENCES_CHUNKSIZE_RAW_CA", 0, 1, 5, 2, 1, 16); + placeSpinBox(chunkSizeVB, chunkSizeRCDSB, "PREFERENCES_CHUNKSIZE_RAW_RCD", 0, 1, 5, 2, 1, 16); + placeSpinBox(chunkSizeVB, chunkSizeRGBSB, "PREFERENCES_CHUNKSIZE_RGB", 0, 1, 5, 2, 1, 16); + placeSpinBox(chunkSizeVB, chunkSizeXTSB, "PREFERENCES_CHUNKSIZE_RAW_XT", 0, 1, 5, 2, 1, 16); fchunksize->add (*chunkSizeVB); vbPerformance->pack_start (*fchunksize, Gtk::PACK_SHRINK, 4); Gtk::Frame* finspect = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_INSPECT_LABEL")) ); - Gtk::HBox* maxIBuffersHB = Gtk::manage ( new Gtk::HBox () ); - maxIBuffersHB->set_spacing (4); - maxIBuffersHB->set_tooltip_text (M ("PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP")); - Gtk::Label* maxIBufferLbl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_INSPECT_MAXBUFFERS_LABEL") + ":", Gtk::ALIGN_START)); - maxInspectorBuffersSB = Gtk::manage ( new Gtk::SpinButton () ); - maxInspectorBuffersSB->set_digits (0); - maxInspectorBuffersSB->set_increments (1, 5); - maxInspectorBuffersSB->set_max_length (2); - maxInspectorBuffersSB->set_range (1, 12); // ... we have to set a limit, 12 seem to be enough even for systems with tons of RAM - maxIBuffersHB->pack_start (*maxIBufferLbl, Gtk::PACK_SHRINK, 0); - maxIBuffersHB->pack_end (*maxInspectorBuffersSB, Gtk::PACK_SHRINK, 0); - Gtk::VBox *inspectorvb = Gtk::manage(new Gtk::VBox()); - inspectorvb->add(*maxIBuffersHB); + placeSpinBox(inspectorvb, maxInspectorBuffersSB, "PREFERENCES_INSPECT_MAXBUFFERS_LABEL", 0, 1, 5, 2, 1, 12, "PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP"); Gtk::HBox *insphb = Gtk::manage(new Gtk::HBox()); thumbnailInspectorMode = Gtk::manage(new Gtk::ComboBoxText()); @@ -726,23 +713,14 @@ Gtk::Widget* Preferences::getPerformancePanel () Gtk::Frame* threadsFrame = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_PERFORMANCE_THREADS")) ); Gtk::VBox* threadsVBox = Gtk::manage ( new Gtk::VBox (Gtk::PACK_SHRINK, 4) ); - Gtk::HBox* threadsHBox = Gtk::manage (new Gtk::HBox (Gtk::PACK_SHRINK, 4)); - Gtk::Label* threadsLbl = Gtk::manage ( new Gtk::Label (M ("PREFERENCES_PERFORMANCE_THREADS_LABEL") + ":", Gtk::ALIGN_START)); - threadsSpinBtn = Gtk::manage ( new Gtk::SpinButton () ); - threadsSpinBtn->set_digits (0); - threadsSpinBtn->set_increments (1, 5); - threadsSpinBtn->set_max_length (2); // Will this be sufficient? :) #ifdef _OPENMP int maxThreadNumber = omp_get_max_threads(); #else int maxThreadNumber = 10; #endif - threadsSpinBtn->set_range (0, maxThreadNumber); - threadsHBox->pack_start (*threadsLbl, Gtk::PACK_SHRINK, 2); - threadsHBox->pack_end (*threadsSpinBtn, Gtk::PACK_SHRINK, 2); + placeSpinBox(threadsVBox, threadsSpinBtn, "PREFERENCES_PERFORMANCE_THREADS_LABEL", 0, 1, 5, 2, 0, maxThreadNumber); - threadsVBox->pack_start (*threadsHBox, Gtk::PACK_SHRINK); threadsFrame->add (*threadsVBox); vbPerformance->pack_start (*threadsFrame, Gtk::PACK_SHRINK, 4); @@ -1813,8 +1791,12 @@ void Preferences::storePreferences () moptions.rgbDenoiseThreadLimit = threadsSpinBtn->get_value_as_int(); moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int(); + moptions.measure = measureCB->get_active(); + moptions.chunkSizeAMAZE = chunkSizeAMSB->get_value_as_int(); moptions.chunkSizeCA = chunkSizeCASB->get_value_as_int(); - moptions.chunkSizeRCD= chunkSizeRCDSB->get_value_as_int(); + moptions.chunkSizeRCD = chunkSizeRCDSB->get_value_as_int(); + moptions.chunkSizeRGB = chunkSizeRGBSB->get_value_as_int(); + moptions.chunkSizeXT = chunkSizeXTSB->get_value_as_int(); moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int(); moptions.rtSettings.thumbnail_inspector_mode = static_cast(thumbnailInspectorMode->get_active_row_number()); @@ -2019,8 +2001,12 @@ void Preferences::fillPreferences () threadsSpinBtn->set_value (moptions.rgbDenoiseThreadLimit); clutCacheSizeSB->set_value (moptions.clutCacheSize); + measureCB->set_active (moptions.measure); + chunkSizeAMSB->set_value (moptions.chunkSizeAMAZE); chunkSizeCASB->set_value (moptions.chunkSizeCA); + chunkSizeRGBSB->set_value (moptions.chunkSizeRGB); chunkSizeRCDSB->set_value (moptions.chunkSizeRCD); + chunkSizeXTSB->set_value (moptions.chunkSizeXT); maxInspectorBuffersSB->set_value (moptions.maxInspectorBuffers); thumbnailInspectorMode->set_active(int(moptions.rtSettings.thumbnail_inspector_mode)); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 60ed04a51..6f434c477 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -161,8 +161,12 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::SpinButton* threadsSpinBtn; Gtk::SpinButton* clutCacheSizeSB; + Gtk::CheckButton* measureCB; + Gtk::SpinButton* chunkSizeAMSB; Gtk::SpinButton* chunkSizeCASB; Gtk::SpinButton* chunkSizeRCDSB; + Gtk::SpinButton* chunkSizeRGBSB; + Gtk::SpinButton* chunkSizeXTSB; Gtk::SpinButton* maxInspectorBuffersSB; Gtk::ComboBoxText *thumbnailInspectorMode;