| Message ID | 20260106170059.56193-2-bryan.odonoghue@linaro.org |
|---|---|
| State | Accepted |
| Commit | a1a6253ff93ebff81984e2eac778bad32f8c88c3 |
| Headers | show |
| Series |
|
| Related | show |
Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes: > Pass contrastExp as calculated in lut to debayer params not the raw > contrast. This way we calculate contrastExp once per frame in lut and pass > the calculated value into the shaders, instead of passing contrast and > calculating contrastExp once per pixel in the shaders. > > Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> From v10: Reviewed-by: Milan Zamazal <mzamazal@redhat.com> > --- > include/libcamera/internal/software_isp/debayer_params.h | 2 +- > src/ipa/simple/algorithms/lut.cpp | 7 ++++--- > src/ipa/simple/ipa_context.h | 1 + > src/libcamera/software_isp/debayer.cpp | 2 +- > 4 files changed, 7 insertions(+), 5 deletions(-) > > diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h > index 8033f7d5b..256c7d43d 100644 > --- a/include/libcamera/internal/software_isp/debayer_params.h > +++ b/include/libcamera/internal/software_isp/debayer_params.h > @@ -59,7 +59,7 @@ struct DebayerParams { > Matrix<float, 3, 3> ccm; > RGB<float> blackLevel; > float gamma; > - float contrast; > + double contrastExp; > }; > > } /* namespace libcamera */ > diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp > index 9aaab54f1..7d015ac89 100644 > --- a/src/ipa/simple/algorithms/lut.cpp > +++ b/src/ipa/simple/algorithms/lut.cpp > @@ -60,12 +60,13 @@ void Lut::updateGammaTable(IPAContext &context) > const auto blackLevel = context.activeState.blc.level; > const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; > const auto contrast = context.activeState.knobs.contrast.value_or(1.0); > + /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ > + double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); > > const float divisor = gammaTable.size() - blackIndex - 1.0; > for (unsigned int i = blackIndex; i < gammaTable.size(); i++) { > double normalized = (i - blackIndex) / divisor; > /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ > - double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); > /* Apply simple S-curve */ > if (normalized < 0.5) > normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); > @@ -84,7 +85,7 @@ void Lut::updateGammaTable(IPAContext &context) > gammaTable[blackIndex]); > > context.activeState.gamma.blackLevel = blackLevel; > - context.activeState.gamma.contrast = contrast; > + context.activeState.gamma.contrastExp = contrastExp; > } > > int16_t Lut::ccmValue(unsigned int i, float ccm) const > @@ -149,7 +150,7 @@ void Lut::prepare(IPAContext &context, > } > > params->gamma = context.configuration.gamma; > - params->contrast = context.activeState.gamma.contrast; > + params->contrastExp = context.activeState.gamma.contrastExp; > } > > void Lut::process([[maybe_unused]] IPAContext &context, > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h > index 26b60fb68..7837bb4dd 100644 > --- a/src/ipa/simple/ipa_context.h > +++ b/src/ipa/simple/ipa_context.h > @@ -59,6 +59,7 @@ struct IPAActiveState { > std::array<double, kGammaLookupSize> gammaTable; > uint8_t blackLevel; > double contrast; > + double contrastExp; > } gamma; > > struct { > diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp > index b33f818a7..4cb5b4da4 100644 > --- a/src/libcamera/software_isp/debayer.cpp > +++ b/src/libcamera/software_isp/debayer.cpp > @@ -116,7 +116,7 @@ namespace libcamera { > */ > > /** > - * \var DebayerParams::contrast > + * \var DebayerParams::contrastExp > * \brief Contrast value for GPUISP > */
diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h index 8033f7d5b..256c7d43d 100644 --- a/include/libcamera/internal/software_isp/debayer_params.h +++ b/include/libcamera/internal/software_isp/debayer_params.h @@ -59,7 +59,7 @@ struct DebayerParams { Matrix<float, 3, 3> ccm; RGB<float> blackLevel; float gamma; - float contrast; + double contrastExp; }; } /* namespace libcamera */ diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index 9aaab54f1..7d015ac89 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -60,12 +60,13 @@ void Lut::updateGammaTable(IPAContext &context) const auto blackLevel = context.activeState.blc.level; const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; const auto contrast = context.activeState.knobs.contrast.value_or(1.0); + /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ + double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); const float divisor = gammaTable.size() - blackIndex - 1.0; for (unsigned int i = blackIndex; i < gammaTable.size(); i++) { double normalized = (i - blackIndex) / divisor; /* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */ - double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001)); /* Apply simple S-curve */ if (normalized < 0.5) normalized = 0.5 * std::pow(normalized / 0.5, contrastExp); @@ -84,7 +85,7 @@ void Lut::updateGammaTable(IPAContext &context) gammaTable[blackIndex]); context.activeState.gamma.blackLevel = blackLevel; - context.activeState.gamma.contrast = contrast; + context.activeState.gamma.contrastExp = contrastExp; } int16_t Lut::ccmValue(unsigned int i, float ccm) const @@ -149,7 +150,7 @@ void Lut::prepare(IPAContext &context, } params->gamma = context.configuration.gamma; - params->contrast = context.activeState.gamma.contrast; + params->contrastExp = context.activeState.gamma.contrastExp; } void Lut::process([[maybe_unused]] IPAContext &context, diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h index 26b60fb68..7837bb4dd 100644 --- a/src/ipa/simple/ipa_context.h +++ b/src/ipa/simple/ipa_context.h @@ -59,6 +59,7 @@ struct IPAActiveState { std::array<double, kGammaLookupSize> gammaTable; uint8_t blackLevel; double contrast; + double contrastExp; } gamma; struct { diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index b33f818a7..4cb5b4da4 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -116,7 +116,7 @@ namespace libcamera { */ /** - * \var DebayerParams::contrast + * \var DebayerParams::contrastExp * \brief Contrast value for GPUISP */
Pass contrastExp as calculated in lut to debayer params not the raw contrast. This way we calculate contrastExp once per frame in lut and pass the calculated value into the shaders, instead of passing contrast and calculating contrastExp once per pixel in the shaders. Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> --- include/libcamera/internal/software_isp/debayer_params.h | 2 +- src/ipa/simple/algorithms/lut.cpp | 7 ++++--- src/ipa/simple/ipa_context.h | 1 + src/libcamera/software_isp/debayer.cpp | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-)