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:
Lawrence Lee
2020-08-28 22:33:52 -07:00
parent 6d8a31961f
commit b2942fd949
7 changed files with 259 additions and 147 deletions

View File

@@ -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();
}
}

View File

@@ -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;
};

View File

@@ -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;
};

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;