@@ -38,15 +38,8 @@ void Awb::prepare(IPAContext &context,
DebayerParams *params)
{
auto &gains = context.activeState.awb.gains;
- Matrix<float, 3, 3> gainMatrix = { { gains.r(), 0, 0,
- 0, gains.g(), 0,
- 0, 0, gains.b() } };
- context.activeState.combinedMatrix =
- gainMatrix * context.activeState.combinedMatrix;
-
- frameContext.gains.red = gains.r();
- frameContext.gains.blue = gains.b();
+ frameContext.gains = gains;
params->gains = gains;
}
@@ -59,11 +52,8 @@ void Awb::process(IPAContext &context,
const SwIspStats::Histogram &histogram = stats->yHistogram;
const uint8_t blackLevel = context.activeState.blc.level;
- const float mdGains[] = {
- static_cast<float>(frameContext.gains.red),
- static_cast<float>(frameContext.gains.blue)
- };
- metadata.set(controls::ColourGains, mdGains);
+ metadata.set(controls::ColourGains, { frameContext.gains.r(),
+ frameContext.gains.b() });
if (!stats->valid)
return;
@@ -71,10 +71,7 @@ struct IPAFrameContext : public FrameContext {
double gain;
} sensor;
- struct {
- double red;
- double blue;
- } gains;
+ RGB<float> gains;
float gamma;
std::optional<float> contrast;
@@ -65,6 +65,7 @@ uniform vec2 tex_step;
uniform vec2 tex_bayer_first_red;
uniform sampler2D tex_y;
+uniform vec3 awb;
uniform mat3 ccm;
uniform vec3 blacklevel;
uniform float gamma;
@@ -231,6 +232,9 @@ void main(void)
*/
rgb = (rgb - blacklevel) / (1.0 - blacklevel);
+ /* Apply AWB gains, and saturate each channel at sensor range */
+ rgb = clamp(rgb * awb, vec3(0.0), vec3(1.0));
+
/*
* CCM is a 3x3 in the format
*
@@ -24,6 +24,7 @@ uniform sampler2D tex_y;
varying vec4 center;
varying vec4 yCoord;
varying vec4 xCoord;
+uniform vec3 awb;
uniform mat3 ccm;
uniform vec3 blacklevel;
uniform float gamma;
@@ -134,6 +135,9 @@ void main(void) {
*/
rgb = (rgb - blacklevel) / (1.0 - blacklevel);
+ /* Apply AWB gains, and saturate each channel at sensor range */
+ rgb = clamp(rgb * awb, vec3(0.0), vec3(1.0));
+
/*
* CCM is a 3x3 in the format
*
@@ -1011,20 +1011,22 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
const unsigned int gammaTableSize = gammaTable_.size();
const RGB<float> blackIndex = params.blackLevel * kRGBLookupSize;
+ const RGB<float> gains = params.gains;
const RGB<float> div = (RGB<float>(kRGBLookupSize) - blackIndex).max(1.0);
if (ccmEnabled_) {
if (gammaUpdateNeeded ||
- matrixChanged(params.combinedMatrix, params_.combinedMatrix)) {
+ matrixChanged(params.combinedMatrix, params_.combinedMatrix) ||
+ params.gains != params_.gains) {
auto &red = swapRedBlueGains_ ? blueCcm_ : redCcm_;
auto &green = greenCcm_;
auto &blue = swapRedBlueGains_ ? redCcm_ : blueCcm_;
const unsigned int redIndex = swapRedBlueGains_ ? 2 : 0;
const unsigned int greenIndex = 1;
const unsigned int blueIndex = swapRedBlueGains_ ? 0 : 2;
-
for (unsigned int i = 0; i < kRGBLookupSize; i++) {
- const RGB<float> rgb = ((RGB<float>(i) - blackIndex) * kRGBLookupSize / div).max(0.0);
+ const RGB<float> rgb = (gains * (RGB<float>(i) - blackIndex) * kRGBLookupSize / div)
+ .clamp(0.0, kRGBLookupSize - 1);
red[i].r = std::round(rgb.r() * params.combinedMatrix[redIndex][0]);
red[i].g = std::round(rgb.r() * params.combinedMatrix[greenIndex][0]);
red[i].b = std::round(rgb.r() * params.combinedMatrix[blueIndex][0]);
@@ -1039,11 +1041,9 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
}
} else {
if (gammaUpdateNeeded || params.gains != params_.gains) {
- auto &gains = params.gains;
auto &red = swapRedBlueGains_ ? blue_ : red_;
auto &green = green_;
auto &blue = swapRedBlueGains_ ? red_ : blue_;
-
for (unsigned int i = 0; i < kRGBLookupSize; i++) {
const RGB<float> lutGains =
(gains * (RGB<float>(i) - blackIndex) * gammaTableSize / div)
@@ -115,6 +115,7 @@ int DebayerEGL::getShaderVariableLocations(void)
attributeTexture_ = glGetAttribLocation(programId_, "textureIn");
textureUniformBayerDataIn_ = glGetUniformLocation(programId_, "tex_y");
+ awbUniformDataIn_ = glGetUniformLocation(programId_, "awb");
ccmUniformDataIn_ = glGetUniformLocation(programId_, "ccm");
blackLevelUniformDataIn_ = glGetUniformLocation(programId_, "blacklevel");
gammaUniformDataIn_ = glGetUniformLocation(programId_, "gamma");
@@ -128,6 +129,7 @@ int DebayerEGL::getShaderVariableLocations(void)
LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_
<< " tex_y " << textureUniformBayerDataIn_
+ << " awb " << awbUniformDataIn_
<< " ccm " << ccmUniformDataIn_
<< " blacklevel " << blackLevelUniformDataIn_
<< " gamma " << gammaUniformDataIn_
@@ -504,6 +506,9 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms)
glUniform3f(blackLevelUniformDataIn_, params.blackLevel[0], params.blackLevel[1], params.blackLevel[2]);
LOG(Debayer, Debug) << " blackLevelUniformDataIn_ " << blackLevelUniformDataIn_ << " data " << params.blackLevel;
+ glUniform3f(awbUniformDataIn_, params.gains[0], params.gains[1], params.gains[2]);
+ LOG(Debayer, Debug) << " awbUniformDataIn_ " << awbUniformDataIn_ << " data " << params.gains;
+
/*
* Gamma
*/
@@ -90,6 +90,9 @@ private:
GLint textureUniformBayerDataIn_;
+ /* Per-frame AWB gains */
+ GLint awbUniformDataIn_;
+
/* Represent per-frame CCM as a uniform vector of floats 3 x 3 */
GLint ccmUniformDataIn_;