@@ -26,6 +26,15 @@ DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats)
DebayerEGL::~DebayerEGL()
{
+ if (eglImageBlueLookup_)
+ delete eglImageBlueLookup_;
+
+ if (eglImageGreenLookup_)
+ delete eglImageGreenLookup_;
+
+ if (eglImageRedLookup_)
+ delete eglImageRedLookup_;
+
if (eglImageBayerIn_)
delete eglImageBayerIn_;
}
@@ -87,9 +96,11 @@ int DebayerEGL::getShaderVariableLocations(void)
attributeVertex_ = glGetAttribLocation(programId_, "vertexIn");
attributeTexture_ = glGetAttribLocation(programId_, "textureIn");
- textureUniformY_ = glGetUniformLocation(programId_, "tex_y");
- textureUniformU_ = glGetUniformLocation(programId_, "tex_u");
- textureUniformV_ = glGetUniformLocation(programId_, "tex_v");
+ textureUniformBayerDataIn_ = glGetUniformLocation(programId_, "tex_y");
+ textureUniformRedLookupDataIn_ = glGetUniformLocation(programId_, "red_param");
+ textureUniformGreenLookupDataIn_ = glGetUniformLocation(programId_, "green_param");
+ textureUniformBlueLookupDataIn_ = glGetUniformLocation(programId_, "blue_param");
+
textureUniformStep_ = glGetUniformLocation(programId_, "tex_step");
textureUniformSize_ = glGetUniformLocation(programId_, "tex_size");
textureUniformStrideFactor_ = glGetUniformLocation(programId_, "stride_factor");
@@ -97,9 +108,10 @@ int DebayerEGL::getShaderVariableLocations(void)
textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix");
LOG(Debayer, Info) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_
- << " tex_y " << textureUniformY_
- << " tex_u " << textureUniformU_
- << " tex_v " << textureUniformV_
+ << " tex_y " << textureUniformBayerDataIn_
+ << " red_param " << textureUniformRedLookupDataIn_
+ << " red_param " << textureUniformGreenLookupDataIn_
+ << " red_param " << textureUniformBlueLookupDataIn_
<< " tex_step " << textureUniformStep_
<< " tex_size " << textureUniformSize_
<< " stride_factor " << textureUniformStrideFactor_
@@ -202,6 +214,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm
break;
};
+ // Flag to shaders that we have parameter gain tables
+ egl_.pushEnv(shaderEnv, "#define APPLY_BAYER_PARAMETERS");
+
if (egl_.compileVertexShader(vertexShaderId_, vertexShaderData, vertexShaderDataLen, shaderEnv))
goto compile_fail;
@@ -285,7 +300,24 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg,
if (egl_.initEGLContext(&gbmSurface_))
return -ENODEV;
- eglImageBayerIn_ = new eGLImage(width_, height_, 32);
+ // Raw bayer input as texture
+ eglImageBayerIn_ = new eGLImage(width_, height_, 32, GL_TEXTURE0, 0);
+ if (!eglImageBayerIn_)
+ return -ENOMEM;
+
+ /// RGB correction tables as 2d textures
+ // eGL doesn't support glTexImage2D so we do a little hack with 2D to compensate
+ eglImageRedLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE1, 1);
+ if (!eglImageRedLookup_)
+ return -ENOMEM;
+
+ eglImageGreenLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE2, 2);
+ if (!eglImageGreenLookup_)
+ return -ENOMEM;
+
+ eglImageBlueLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE3, 3);
+ if (!eglImageBlueLookup_)
+ return -ENOMEM;
// Create a single BO (calling gbm_surface_lock_front_buffer() again before gbm_surface_release_buffer() would create another BO)
if (gbmSurface_.mapSurface())
@@ -394,7 +426,14 @@ void DebayerEGL::setShaderVariableValues(void)
glVertexAttribPointer(attributeTexture_, 2, GL_FLOAT, GL_TRUE,
2 * sizeof(GLfloat), tcoordinates);
- glUniform1i(textureUniformY_, 0); // tex_y - bayer_8.vert - set for no reason
+ // Set the sampler2D to the respective texture unit for each texutre
+ // To simultaneously sample multiple textures we need to use multiple
+ // texture units
+ glUniform1i(textureUniformBayerDataIn_, eglImageBayerIn_->texture_unit_uniform_id_);
+ glUniform1i(textureUniformRedLookupDataIn_, eglImageRedLookup_->texture_unit_uniform_id_);
+ glUniform1i(textureUniformGreenLookupDataIn_, eglImageGreenLookup_->texture_unit_uniform_id_);
+ glUniform1i(textureUniformBlueLookupDataIn_, eglImageBlueLookup_->texture_unit_uniform_id_);
+
glUniform2fv(textureUniformBayerFirstRed_, 1, firstRed); // tex_bayer_first_red - bayer_8.vert
glUniform2fv(textureUniformSize_, 1, imgSize); // tex_size - bayer_8.vert
glUniform2fv(textureUniformStep_, 1, Step); // tex_step - bayer_8.vert
@@ -403,9 +442,10 @@ void DebayerEGL::setShaderVariableValues(void)
GL_FALSE, projIdentityMatrix); // No scaling
LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_
- << " tex_y " << textureUniformY_
- << " tex_u " << textureUniformU_
- << " tex_v " << textureUniformV_
+ << " tex_y " << textureUniformBayerDataIn_
+ << " red_param " << textureUniformRedLookupDataIn_
+ << " red_param " << textureUniformGreenLookupDataIn_
+ << " red_param " << textureUniformBlueLookupDataIn_
<< " tex_step " << textureUniformStep_
<< " tex_size " << textureUniformSize_
<< " stride_factor " << textureUniformStrideFactor_
@@ -423,7 +463,7 @@ void DebayerEGL::setShaderVariableValues(void)
return;
}
-void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out)
+void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, DebayerParams ¶ms)
{
LOG(Debayer, Debug)
<< "Input height " << height_
@@ -433,13 +473,15 @@ void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out)
// eGL context switch
egl_.makeCurrent();
- // make texture unit 0 explicit this doesn't really matter probably remove ?
- glActiveTexture(GL_TEXTURE0);
-
// Greate a standard texture
// we will replace this with the DMA version at some point
egl_.createTexture2D(eglImageBayerIn_, inputConfig_.stride, height_, in.planes()[0].data());
+ // Populate bayer parameters
+ egl_.createTexture2D(eglImageRedLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.red);
+ egl_.createTexture2D(eglImageGreenLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.green);
+ egl_.createTexture2D(eglImageBlueLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.blue);
+
// Setup the scene
setShaderVariableValues();
glViewport(0, 0, width_, height_);
@@ -482,7 +524,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output
return;
}
- debayerGPU(in, out);
+ debayerGPU(in, out, params);
dmaSyncers.clear();
@@ -110,7 +110,7 @@ private:
int getShaderVariableLocations();
void setShaderVariableValues(void);
void configureTexture(GLuint &texture);
- void debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out);
+ void debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, DebayerParams ¶ms);
// Shader program identifiers
GLuint vertexShaderId_;
@@ -125,20 +125,27 @@ private:
// Pointer to object representing input texture
eGLImage *eglImageBayerIn_;
+ eGLImage *eglImageRedLookup_;
+ eGLImage *eglImageGreenLookup_;
+ eGLImage *eglImageBlueLookup_;
+
// Shader parameters
float firstRed_x_;
float firstRed_y_;
GLint attributeVertex_;
GLint attributeTexture_;
- GLint textureUniformY_;
- GLint textureUniformU_;
- GLint textureUniformV_;
GLint textureUniformStep_;
GLint textureUniformSize_;
GLint textureUniformStrideFactor_;
GLint textureUniformBayerFirstRed_;
GLint textureUniformProjMatrix_;
+ #define DEBAYER_EGL_MIN_TEXTURE_UNITS 4
+ GLint textureUniformBayerDataIn_;
+ GLint textureUniformRedLookupDataIn_;
+ GLint textureUniformGreenLookupDataIn_;
+ GLint textureUniformBlueLookupDataIn_;
+
Rectangle window_;
std::unique_ptr<SwStatsCpu> stats_;
eGL egl_;
The existing SoftISP calculates RGB gain values as a lookup table of 256 values which shifts for each frame depending on the required correction. We can pass the required tables into the debayer shaders as textures, one texture for R, G and B respectively. The debayer shader will do its debayer interpolation and then if the appropriate define is specified use the calculated R, G and B values as indexes into our bayer colour gain table. TODO: - Validate the number of available texture units and bail out if < 4 In reality ~ all hardware has at least 16 units - Rename the debayer class to something like eglDebayer to reflect the fact its eGL based. - Add in the CCM tables too. Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> --- src/libcamera/software_isp/debayer_egl.cpp | 74 +++++++++++++++++----- src/libcamera/software_isp/debayer_egl.h | 15 +++-- 2 files changed, 69 insertions(+), 20 deletions(-)