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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user