Improve performance of scopes
If a scope update is requested, don't recalculate scope data if it is already up-to-date. Eliminate double and triple scope rendering.
This commit is contained in:
@@ -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<float[]> a(new float[vectorscopeScale]);
|
||||
const std::unique_ptr<float[]> b(new float[vectorscopeScale]);
|
||||
const std::unique_ptr<float[]> 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<int> vectorscopeThr(size, size, ARRAY2D_CLEAR_DATA);
|
||||
{
|
||||
array2D<int> 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<float[]> a(new float[vectorscopeScale]);
|
||||
const std::unique_ptr<float[]> b(new float[vectorscopeScale]);
|
||||
const std::unique_ptr<float[]> 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<int> 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<int> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<int> vectorscope;
|
||||
bool vectorscope_hc_dirty, vectorscope_hs_dirty;
|
||||
array2D<int> vectorscope_hc, vectorscope_hs;
|
||||
/// Waveform's intensity. Same as height of reference image.
|
||||
int waveformScale;
|
||||
bool waveform_dirty;
|
||||
array2D<int> 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -334,7 +334,8 @@ public:
|
||||
const LUTu& histChroma,
|
||||
const LUTu& histLRETI,
|
||||
int vectorscopeScale,
|
||||
const array2D<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& 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;
|
||||
};
|
||||
|
||||
@@ -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<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,8 @@ public:
|
||||
const LUTu& histChroma,
|
||||
const LUTu& histLRETI,
|
||||
int vectorscopeScale,
|
||||
const array2D<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& 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;
|
||||
|
||||
@@ -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<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& 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<Cairo::Context> &cr,
|
||||
|
||||
void HistogramArea::drawVectorscope(Cairo::RefPtr<Cairo::Context> &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<Cairo::Context> &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<float>(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();
|
||||
|
||||
@@ -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<int> vect;
|
||||
std::vector<unsigned char> vect_buffer;
|
||||
bool vect_buffer_dirty;
|
||||
array2D<int> vect_hc, vect_hs;
|
||||
std::vector<unsigned char> vect_hc_buffer, vect_hs_buffer;
|
||||
bool vect_hc_buffer_dirty, vect_hs_buffer_dirty;
|
||||
int waveform_scale;
|
||||
array2D<int> rwave, gwave, bwave, lwave;
|
||||
std::vector<unsigned char> wave_buffer;
|
||||
@@ -208,7 +213,8 @@ public:
|
||||
const LUTu& histGreenRaw,
|
||||
const LUTu& histBlueRaw,
|
||||
int vectorscopeScale,
|
||||
const array2D<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& waveformGreen,
|
||||
@@ -216,6 +222,7 @@ public:
|
||||
const array2D<int>& 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<int>& vectorscope,
|
||||
const array2D<int>& vectorscopeHC,
|
||||
const array2D<int>& vectorscopeHS,
|
||||
int waveformScale,
|
||||
const array2D<int>& waveformRed,
|
||||
const array2D<int>& waveformGreen,
|
||||
@@ -321,7 +328,7 @@ public:
|
||||
const array2D<int>& 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;
|
||||
|
||||
Reference in New Issue
Block a user