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

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