diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index f25395c2d..ea4c8a92b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -131,7 +131,8 @@ ImProcCoordinator::ImProcCoordinator() : histLRETI(256), vectorscopeScale(0), - vectorscope(VECTORSCOPE_SIZE, VECTORSCOPE_SIZE), + vectorscope_hc(VECTORSCOPE_SIZE, VECTORSCOPE_SIZE), + vectorscope_hs(VECTORSCOPE_SIZE, VECTORSCOPE_SIZE), waveformScale(0), waveformRed(0, 0), waveformGreen(0, 0), @@ -1644,12 +1645,16 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) imageListener->imageReady(params->crop); } + hist_lrgb_dirty = vectorscope_hc_dirty = vectorscope_hs_dirty = waveform_dirty = true; if (hListener) { if (hListener->updateHistogram()) { updateLRGBHistograms(); } - if (hListener->updateVectorscope()) { - updateVectorscope(); + if (hListener->updateVectorscopeHC()) { + updateVectorscopeHC(); + } + if (hListener->updateVectorscopeHS()) { + updateVectorscopeHS(); } if (hListener->updateWaveform()) { updateWaveforms(); @@ -1774,7 +1779,8 @@ void ImProcCoordinator::notifyHistogramChanged() histChroma, histLRETI, vectorscopeScale, - vectorscope, + vectorscope_hc, + vectorscope_hs, waveformScale, waveformRed, waveformGreen, @@ -1784,9 +1790,13 @@ void ImProcCoordinator::notifyHistogramChanged() } } -void ImProcCoordinator::updateLRGBHistograms() +bool ImProcCoordinator::updateLRGBHistograms() { + if (!hist_lrgb_dirty) { + return false; + } + int x1, y1, x2, y2; params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); @@ -1843,86 +1853,109 @@ void ImProcCoordinator::updateLRGBHistograms() } } + hist_lrgb_dirty = false; + return true; + } -void ImProcCoordinator::updateVectorscope() +bool ImProcCoordinator::updateVectorscopeHC() { - if (!workimg) { - return; + if (!workimg || !vectorscope_hc_dirty) { + return false; } int x1, y1, x2, y2; params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); constexpr int size = VECTORSCOPE_SIZE; - vectorscope.fill(0); + vectorscope_hc.fill(0); vectorscopeScale = (x2 - x1) * (y2 - y1); - if (hListener->vectorscopeType() == 0) { // HS + + const std::unique_ptr a(new float[vectorscopeScale]); + const std::unique_ptr b(new float[vectorscopeScale]); + const std::unique_ptr L(new float[vectorscopeScale]); + ipf.rgb2lab(*workimg, x1, y1, x2 - x1, y2 - y1, L.get(), a.get(), b.get(), params->icm); #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel #endif - { - array2D vectorscopeThr(size, size, ARRAY2D_CLEAR_DATA); + { + array2D vectorscopeThr(size, size, ARRAY2D_CLEAR_DATA); #ifdef _OPENMP - #pragma omp for nowait + #pragma omp for nowait #endif - for (int i = y1; i < y2; ++i) { - int ofs = (i * pW + x1) * 3; - for (int j = x1; j < x2; ++j) { - const float red = 257.f * workimg->data[ofs++]; - const float green = 257.f * workimg->data[ofs++]; - const float blue = 257.f * workimg->data[ofs++]; - float h, s, l; - Color::rgb2hslfloat(red, green, blue, h, s, l); - const auto sincosval = xsincosf(2.f * RT_PI_F * h); - const int col = s * sincosval.y * (size / 2) + size / 2; - const int row = s * sincosval.x * (size / 2) + size / 2; - if (col >= 0 && col < size && row >= 0 && row < size) { - vectorscopeThr[row][col]++; - } + for (int i = y1; i < y2; ++i) { + for (int j = x1, ofs_lab = (i - y1) * (x2 - x1); j < x2; ++j, ++ofs_lab) { + const int col = (size / 96000.f) * a[ofs_lab] + size / 2; + const int row = (size / 96000.f) * b[ofs_lab] + size / 2; + if (col >= 0 && col < size && row >= 0 && row < size) { + vectorscopeThr[row][col]++; } } -#ifdef _OPENMP - #pragma omp critical -#endif - { - vectorscope += vectorscopeThr; - } } - } else if (hListener->vectorscopeType() == 1) { // CH - const std::unique_ptr a(new float[vectorscopeScale]); - const std::unique_ptr b(new float[vectorscopeScale]); - const std::unique_ptr L(new float[vectorscopeScale]); - ipf.rgb2lab(*workimg, x1, y1, x2 - x1, y2 - y1, L.get(), a.get(), b.get(), params->icm); #ifdef _OPENMP - #pragma omp parallel + #pragma omp critical #endif { - array2D vectorscopeThr(size, size, ARRAY2D_CLEAR_DATA); -#ifdef _OPENMP - #pragma omp for nowait -#endif - for (int i = y1; i < y2; ++i) { - for (int j = x1, ofs_lab = (i - y1) * (x2 - x1); j < x2; ++j, ++ofs_lab) { - const int col = (size / 96000.f) * a[ofs_lab] + size / 2; - const int row = (size / 96000.f) * b[ofs_lab] + size / 2; - if (col >= 0 && col < size && row >= 0 && row < size) { - vectorscopeThr[row][col]++; - } - } - } -#ifdef _OPENMP - #pragma omp critical -#endif - { - vectorscope += vectorscopeThr; - } + vectorscope_hc += vectorscopeThr; } } + + vectorscope_hc_dirty = false; + return true; } -void ImProcCoordinator::updateWaveforms() +bool ImProcCoordinator::updateVectorscopeHS() +{ + if (!workimg || !vectorscope_hs_dirty) { + return false; + } + + int x1, y1, x2, y2; + params->crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + + constexpr int size = VECTORSCOPE_SIZE; + vectorscope_hs.fill(0); + + vectorscopeScale = (x2 - x1) * (y2 - y1); + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + array2D vectorscopeThr(size, size, ARRAY2D_CLEAR_DATA); +#ifdef _OPENMP + #pragma omp for nowait +#endif + for (int i = y1; i < y2; ++i) { + int ofs = (i * pW + x1) * 3; + for (int j = x1; j < x2; ++j) { + const float red = 257.f * workimg->data[ofs++]; + const float green = 257.f * workimg->data[ofs++]; + const float blue = 257.f * workimg->data[ofs++]; + float h, s, l; + Color::rgb2hslfloat(red, green, blue, h, s, l); + const auto sincosval = xsincosf(2.f * RT_PI_F * h); + const int col = s * sincosval.y * (size / 2) + size / 2; + const int row = s * sincosval.x * (size / 2) + size / 2; + if (col >= 0 && col < size && row >= 0 && row < size) { + vectorscopeThr[row][col]++; + } + } + } +#ifdef _OPENMP + #pragma omp critical +#endif + { + vectorscope_hs += vectorscopeThr; + } + } + + vectorscope_hs_dirty = false; + return true; +} + +bool ImProcCoordinator::updateWaveforms() { if (!workimg) { // free memory @@ -1930,7 +1963,11 @@ void ImProcCoordinator::updateWaveforms() waveformGreen.free(); waveformBlue.free(); waveformLuma.free(); - return; + return true; + } + + if (!waveform_dirty) { + return false; } int x1, y1, x2, y2; @@ -1966,6 +2003,8 @@ void ImProcCoordinator::updateWaveforms() } waveformScale = y2 - y1; + waveform_dirty = false; + return true; } bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, double tempBias) @@ -2412,24 +2451,44 @@ void ImProcCoordinator::setHighQualComputed() void ImProcCoordinator::requestUpdateWaveform() { - if (hListener) { - updateWaveforms(); + if (!hListener) { + return; + } + bool updated = updateWaveforms(); + if (updated) { notifyHistogramChanged(); } } void ImProcCoordinator::requestUpdateHistogram() { - if (hListener) { - updateLRGBHistograms(); + if (!hListener) { + return; + } + bool updated = updateLRGBHistograms(); + if (updated) { notifyHistogramChanged(); } } -void ImProcCoordinator::requestUpdateVectorscope() +void ImProcCoordinator::requestUpdateVectorscopeHC() { - if (hListener) { - updateVectorscope(); + if (!hListener) { + return; + } + bool updated = updateVectorscopeHC(); + if (updated) { + notifyHistogramChanged(); + } +} + +void ImProcCoordinator::requestUpdateVectorscopeHS() +{ + if (!hListener) { + return; + } + bool updated = updateVectorscopeHS(); + if (updated) { notifyHistogramChanged(); } } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 8a112b270..791679678 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -126,10 +126,13 @@ protected: LUTu histBlue, histBlueRaw; LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve; LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI; + bool hist_lrgb_dirty; int vectorscopeScale; - array2D vectorscope; + bool vectorscope_hc_dirty, vectorscope_hs_dirty; + array2D vectorscope_hc, vectorscope_hs; /// Waveform's intensity. Same as height of reference image. int waveformScale; + bool waveform_dirty; array2D waveformRed, waveformGreen, waveformBlue, waveformLuma; LUTf CAMBrightCurveJ, CAMBrightCurveQ; @@ -200,9 +203,14 @@ protected: void notifyHistogramChanged(); void reallocAll(); - void updateLRGBHistograms(); - void updateVectorscope(); - void updateWaveforms(); + /// Updates L, R, G, and B histograms. Returns true unless not updated. + bool updateLRGBHistograms(); + /// Updates the H-C vectorscope. Returns true unless not updated. + bool updateVectorscopeHC(); + /// Updates the H-S vectorscope. Returns true unless not updated. + bool updateVectorscopeHS(); + /// Updates all waveforms. Returns true unless not updated. + bool updateWaveforms(); void setScale(int prevscale); void updatePreviewImage (int todo, bool panningRelatedChange); @@ -561,7 +569,8 @@ public: } denoiseInfoStore; void requestUpdateHistogram() override; - void requestUpdateVectorscope() override; + void requestUpdateVectorscopeHC() override; + void requestUpdateVectorscopeHS() override; void requestUpdateWaveform() override; }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index e6749a9f0..43848e70c 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -334,7 +334,8 @@ public: const LUTu& histChroma, const LUTu& histLRETI, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -345,12 +346,12 @@ public: virtual void setObservable(HistogramObservable* observable) = 0; /** Returns if the listener wants the histogram to be updated. */ virtual bool updateHistogram(void) const = 0; - /** Returns if the listener wants the vectorscope to be updated. */ - virtual bool updateVectorscope(void) const = 0; + /** Returns if the listener wants the H-C vectorscope to be updated. */ + virtual bool updateVectorscopeHC(void) const = 0; + /** Returns if the listener wants the H-S vectorscope to be updated. */ + virtual bool updateVectorscopeHS(void) const = 0; /** Returns if the listener wants the waveform to be updated. */ virtual bool updateWaveform(void) const = 0; - /** Returns the vectorscope type: 0 for H-S and 1 for H-C. */ - virtual int vectorscopeType(void) const = 0; }; class HistogramObservable @@ -358,8 +359,10 @@ class HistogramObservable public: /** Tells the observable to update the histogram data. */ virtual void requestUpdateHistogram() = 0; - /** Tells the observable to update the vectorscope data. */ - virtual void requestUpdateVectorscope() = 0; + /** Tells the observable to update the H-C vectorscope data. */ + virtual void requestUpdateVectorscopeHC() = 0; + /** Tells the observable to update the H-S vectorscope data. */ + virtual void requestUpdateVectorscopeHS() = 0; /** Tells the observable to update the waveform data. */ virtual void requestUpdateWaveform() = 0; }; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index d3d339783..c53877736 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -472,7 +472,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) beforeIarea (nullptr), beforeBox (nullptr), afterBox (nullptr), beforeLabel (nullptr), afterLabel (nullptr), beforeHeaderBox (nullptr), afterHeaderBox (nullptr), parent (nullptr), parentWindow (nullptr), openThm (nullptr), selectedFrame(0), isrc (nullptr), ipc (nullptr), beforeIpc (nullptr), err (0), isProcessing (false), - histogram_observable(nullptr), histogram_scope_type(HistogramPanelListener::NONE) + histogram_observable(nullptr), histogram_scope_type(ScopeType::NONE) { epih = new EditorPanelIdleHelper; @@ -2249,7 +2249,8 @@ void EditorPanel::histogramChanged( const LUTu& histChroma, const LUTu& histLRETI, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -2258,7 +2259,7 @@ void EditorPanel::histogramChanged( ) { if (histogramPanel) { - histogramPanel->histogramChanged(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, vectorscopeScale, vectorscope, waveformScale, waveformRed, waveformGreen, waveformBlue, waveformLuma); + histogramPanel->histogramChanged(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, vectorscopeScale, vectorscopeHC, vectorscopeHS, waveformScale, waveformRed, waveformGreen, waveformBlue, waveformLuma); } tpc->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI); @@ -2271,34 +2272,28 @@ void EditorPanel::setObservable(rtengine::HistogramObservable* observable) bool EditorPanel::updateHistogram(void) const { - return histogram_scope_type == HistogramPanelListener::HISTOGRAM - || histogram_scope_type == HistogramPanelListener::NONE; + return histogram_scope_type == ScopeType::HISTOGRAM + || histogram_scope_type == ScopeType::NONE; } -bool EditorPanel::updateVectorscope(void) const +bool EditorPanel::updateVectorscopeHC(void) const { return - histogram_scope_type == HistogramPanelListener::VECTORSCOPE_HS - || histogram_scope_type == HistogramPanelListener::VECTORSCOPE_CH - || histogram_scope_type == HistogramPanelListener::NONE; + histogram_scope_type == ScopeType::VECTORSCOPE_HC + || histogram_scope_type == ScopeType::NONE; +} + +bool EditorPanel::updateVectorscopeHS(void) const +{ + return + histogram_scope_type == ScopeType::VECTORSCOPE_HS + || histogram_scope_type == ScopeType::NONE; } bool EditorPanel::updateWaveform(void) const { - return histogram_scope_type == HistogramPanelListener::WAVEFORM - || histogram_scope_type == HistogramPanelListener::NONE; -} - -int EditorPanel::vectorscopeType(void) const -{ - switch (histogram_scope_type) { - case HistogramPanelListener::VECTORSCOPE_HS: - return 0; - case HistogramPanelListener::VECTORSCOPE_CH: - return 1; - default: - return -1; - } + return histogram_scope_type == ScopeType::WAVEFORM + || histogram_scope_type == ScopeType::NONE; } void EditorPanel::scopeTypeChanged(ScopeType new_type) @@ -2311,14 +2306,22 @@ void EditorPanel::scopeTypeChanged(ScopeType new_type) // Make sure the new scope is updated since we only actively update the // current scope. - if (new_type == HistogramPanelListener::HISTOGRAM) { - histogram_observable->requestUpdateHistogram(); - } else if (new_type == HistogramPanelListener::VECTORSCOPE_HS) { - histogram_observable->requestUpdateVectorscope(); - } else if (new_type == HistogramPanelListener::VECTORSCOPE_CH) { - histogram_observable->requestUpdateVectorscope(); - } else if (new_type == HistogramPanelListener::WAVEFORM) { - histogram_observable->requestUpdateWaveform(); + switch (new_type) { + case ScopeType::HISTOGRAM: + histogram_observable->requestUpdateHistogram(); + break; + case ScopeType::VECTORSCOPE_HC: + histogram_observable->requestUpdateVectorscopeHC(); + break; + case ScopeType::VECTORSCOPE_HS: + histogram_observable->requestUpdateVectorscopeHS(); + break; + case ScopeType::WAVEFORM: + histogram_observable->requestUpdateWaveform(); + break; + case ScopeType::HISTOGRAM_RAW: + case ScopeType::NONE: + break; } } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 9f0ebf8cb..f6bc0b606 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -135,7 +135,8 @@ public: const LUTu& histChroma, const LUTu& histLRETI, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -144,9 +145,9 @@ public: ) override; void setObservable(rtengine::HistogramObservable* observable) override; bool updateHistogram(void) const override; - bool updateVectorscope(void) const override; + bool updateVectorscopeHC(void) const override; + bool updateVectorscopeHS(void) const override; bool updateWaveform(void) const override; - int vectorscopeType(void) const override; // HistogramPanelListener void scopeTypeChanged(ScopeType new_type) override; diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 2c9d6bb0e..a07133204 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -309,8 +309,10 @@ void HistogramPanel::showRGBBar() void HistogramPanel::resized (Gtk::Allocation& req) { - histogramArea->updateBackBuffer (); - histogramArea->queue_draw (); + if (!histogramArea->updatePending()) { + histogramArea->updateBackBuffer (); + histogramArea->queue_draw (); + } // set histogramRGBArea invalid; if (histogramRGBArea) { @@ -394,7 +396,10 @@ void HistogramPanel::type_pressed() scopeType->set_image(*vectHcImage); } type_changed(); - rgbv_toggled(); + updateHistAreaOptions(); + if (histogramRGBArea) { + updateHistRGBAreaOptions(); + } } void HistogramPanel::type_changed() @@ -415,7 +420,7 @@ void HistogramPanel::type_changed() histogramRGBArea = histogramRGBAreaHori.get(); if (panel_listener) { updateHistAreaOptions(); - panel_listener->scopeTypeChanged(HistogramPanelListener::HISTOGRAM); + panel_listener->scopeTypeChanged(ScopeType::HISTOGRAM); } } else if (options.histogramScopeType == 1) { showRed->set_sensitive(); @@ -428,7 +433,7 @@ void HistogramPanel::type_changed() histogramRGBArea = histogramRGBAreaVert.get(); if (panel_listener) { updateHistAreaOptions(); - panel_listener->scopeTypeChanged(HistogramPanelListener::WAVEFORM); + panel_listener->scopeTypeChanged(ScopeType::WAVEFORM); } } else { showRed->set_sensitive(false); @@ -441,13 +446,13 @@ void HistogramPanel::type_changed() histogramRGBArea = nullptr; if (panel_listener) { updateHistAreaOptions(); - HistogramPanelListener::ScopeType type = HistogramPanelListener::NONE; + ScopeType type = ScopeType::NONE; switch (options.histogramScopeType) { case 2: - type = HistogramPanelListener::VECTORSCOPE_HS; + type = ScopeType::VECTORSCOPE_HS; break; case 3: - type = HistogramPanelListener::VECTORSCOPE_CH; + type = ScopeType::VECTORSCOPE_HC; break; } panel_listener->scopeTypeChanged(type); @@ -479,7 +484,7 @@ void HistogramPanel::rgbv_toggled () histogramArea->queue_draw (); if (histogramRGBArea) { - histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showChro->get_active(), showRAW->get_active(), showBAR->get_active() && options.histogramScopeType < 2); + updateHistRGBAreaOptions(); histogramRGBArea->updateBackBuffer (0, 0, 0); histogramRGBArea->queue_draw (); } @@ -532,17 +537,17 @@ void HistogramPanel::setPanelListener(HistogramPanelListener* listener) panel_listener = listener; if (listener) { - HistogramPanelListener::ScopeType type; + ScopeType type; if (options.histogramScopeType == 0) { - type = HistogramPanelListener::HISTOGRAM; + type = ScopeType::HISTOGRAM; } else if (options.histogramScopeType == 1) { - type = HistogramPanelListener::WAVEFORM; + type = ScopeType::WAVEFORM; } else if (options.histogramScopeType == 2) { - type = HistogramPanelListener::VECTORSCOPE_HS; + type = ScopeType::VECTORSCOPE_HS; } else if (options.histogramScopeType == 3) { - type = HistogramPanelListener::VECTORSCOPE_CH; + type = ScopeType::VECTORSCOPE_HC; } else { - type = HistogramPanelListener::NONE; + type = ScopeType::NONE; } listener->scopeTypeChanged(type); } @@ -563,6 +568,19 @@ void HistogramPanel::updateHistAreaOptions() ); } +void HistogramPanel::updateHistRGBAreaOptions() +{ + histogramRGBArea->updateOptions( + showRed->get_active(), + showGreen->get_active(), + showBlue->get_active(), + showValue->get_active(), + showChro->get_active(), + showRAW->get_active(), + showBAR->get_active() && options.histogramScopeType < 2 + ); +} + // // // @@ -897,8 +915,8 @@ void HistogramRGBAreaVert::get_preferred_width_for_height_vfunc (int height, int // HistogramArea HistogramArea::HistogramArea (DrawModeListener *fml) : vectorscope_scale(0), - vect(0, 0), - vect_buffer_dirty(true), + vect_hc(0, 0), vect_hs(0, 0), + vect_hc_buffer_dirty(true), vect_hs_buffer_dirty(true), waveform_scale(0), rwave(0, 0), gwave(0, 0),bwave(0, 0), lwave(0, 0), wave_buffer_dirty(true), @@ -986,6 +1004,11 @@ void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool wave_buffer_dirty = true; } +bool HistogramArea::updatePending(void) +{ + return haih->pending > 0 && !haih->destroyed; +} + void HistogramArea::update( const LUTu& histRed, const LUTu& histGreen, @@ -996,7 +1019,8 @@ void HistogramArea::update( const LUTu& histGreenRaw, const LUTu& histBlueRaw, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -1021,10 +1045,14 @@ void HistogramArea::update( bwave = waveformBlue; lwave = waveformLuma; wave_buffer_dirty = true; - } else if (scopeType >= 2) { + } else if (scopeType == 2) { vectorscope_scale = vectorscopeScale; - vect = vectorscope; - vect_buffer_dirty = true; + vect_hs = vectorscopeHS; + vect_hs_buffer_dirty = true; + } else if (scopeType == 3) { + vectorscope_scale = vectorscopeScale; + vect_hc = vectorscopeHC; + vect_hc_buffer_dirty = true; } valid = true; } else { @@ -1060,7 +1088,6 @@ void HistogramArea::update( void HistogramArea::updateBackBuffer () { - if (!get_realized ()) { return; } @@ -1333,6 +1360,10 @@ void HistogramArea::drawMarks(Cairo::RefPtr &cr, void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, int h) { + const auto& vect = (scopeType == 3) ? vect_hc : vect_hs; + auto& vect_buffer = (scopeType == 3) ? vect_hc_buffer : vect_hs_buffer; + auto& vect_buffer_dirty = (scopeType == 3) ? vect_hc_buffer_dirty : vect_hs_buffer_dirty; + const int vect_width = vect.getWidth(); const int vect_height = vect.getHeight(); // Arbitrary scale factor multiplied by vectorscope area and divided by @@ -1582,7 +1613,7 @@ void HistogramArea::drawWaveform(Cairo::RefPtr &cr, int w, int h bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - if (get_width() != oldwidth || get_height() != oldheight || isDirty ()) { + if (!updatePending() && (get_width() != oldwidth || get_height() != oldheight || isDirty())) { updateBackBuffer (); } @@ -1651,8 +1682,7 @@ bool HistogramArea::on_motion_notify_event (GdkEventMotion* event) double dx = (event->x - movingPosition) / get_width(); float new_brightness = LIM(trace_brightness * pow(RANGE, dx), MIN_BRIGHT, MAX_BRIGHT); if (new_brightness != trace_brightness) { - wave_buffer_dirty = true; - vect_buffer_dirty = true; + wave_buffer_dirty = vect_hc_buffer_dirty = vect_hs_buffer_dirty = true; trace_brightness = new_brightness; setDirty(true); queue_draw(); diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index 935a30bfd..975a6d8ab 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -36,6 +36,11 @@ class HistogramArea; +enum ScopeType +{ + HISTOGRAM, HISTOGRAM_RAW, VECTORSCOPE_HC, VECTORSCOPE_HS, WAVEFORM, NONE +}; + struct HistogramAreaIdleHelper { HistogramArea* harea; bool destroyed; @@ -161,9 +166,9 @@ protected: LUTu rhist, ghist, bhist, lhist, chist; LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused? int vectorscope_scale; - array2D vect; - std::vector vect_buffer; - bool vect_buffer_dirty; + array2D vect_hc, vect_hs; + std::vector vect_hc_buffer, vect_hs_buffer; + bool vect_hc_buffer_dirty, vect_hs_buffer_dirty; int waveform_scale; array2D rwave, gwave, bwave, lwave; std::vector wave_buffer; @@ -208,7 +213,8 @@ public: const LUTu& histGreenRaw, const LUTu& histBlueRaw, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -216,6 +222,7 @@ public: const array2D& waveformLuma ); void updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode, int type, bool pointer); + bool updatePending(); void on_realize() override; bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; bool on_button_press_event (GdkEventButton* event) override; @@ -238,8 +245,6 @@ private: class HistogramPanelListener { public: - enum ScopeType {HISTOGRAM, VECTORSCOPE_CH, VECTORSCOPE_HS, WAVEFORM, NONE}; - virtual void scopeTypeChanged(ScopeType new_type) = 0; }; @@ -297,6 +302,7 @@ protected: void setHistInvalid (); void showRGBBar(); void updateHistAreaOptions(); + void updateHistRGBAreaOptions(); public: @@ -313,7 +319,8 @@ public: const LUTu& histGreenRaw, const LUTu& histBlueRaw, int vectorscopeScale, - const array2D& vectorscope, + const array2D& vectorscopeHC, + const array2D& vectorscopeHS, int waveformScale, const array2D& waveformRed, const array2D& waveformGreen, @@ -321,7 +328,7 @@ public: const array2D& waveformLuma ) { - histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, vectorscopeScale, vectorscope, waveformScale, waveformRed, waveformGreen, waveformBlue, waveformLuma); + histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, vectorscopeScale, vectorscopeHC, vectorscopeHS, waveformScale, waveformRed, waveformGreen, waveformBlue, waveformLuma); } // pointermotionlistener interface void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) override;