@@ -107,7 +107,11 @@ public:
int createInputDMABufTexture2D(eGLImage &eglImage, int fd);
int createOutputDMABufTexture2D(eGLImage &eglImage, int fd);
- void createTexture2D(eGLImage &eglImage, void *data, GLint filter);
+ void createTexture2D(eGLImage &eglImage,
+ GLint internalFormat,
+ GLenum type,
+ const void *data,
+ GLint filter);
void updateTexture2D(eGLImage &eglImage, void *data);
void createOutputTexture2D(eGLImage &eglImage);
@@ -29,6 +29,8 @@ struct DebayerParams {
static constexpr unsigned int kLscGridSize = 16;
static constexpr unsigned int kLscValuesPerCell = 3;
+ static constexpr unsigned int kLscBytesPerCell =
+ kLscValuesPerCell * sizeof(float);
using LscLookupTable =
std::array<float, kLscGridSize * kLscGridSize * kLscValuesPerCell>;
LscLookupTable lscLut{};
@@ -46,13 +46,16 @@ void Lsc::prepare([[maybe_unused]] IPAContext &context,
IPAFrameContext &frameContext,
DebayerParams *params)
{
- params->lscEnabled = frameContext.lsc.enabled;
-
unsigned int ct = frameContext.awb.colourTemperature;
constexpr unsigned int minTemperatureChange = 100;
- if (!frameContext.lsc.enabled ||
- utils::abs_diff(ct, lastAppliedCt_) < minTemperatureChange)
+ if (!frameContext.lsc.enabled) {
+ params->lscLut.fill(1.0);
+ lastAppliedCt_ = 0;
+ return;
+ }
+
+ if (utils::abs_diff(ct, lastAppliedCt_) < minTemperatureChange)
return;
const lsc::Components<uint8_t> &set = lscAlgo_.interpolateComponents(ct);
@@ -274,6 +274,8 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)
/**
* \brief Create a 2D texture from a memory buffer
* \param[in,out] eglImage EGL image to associate with the texture
+ * \param[in] internalFormat OpenGL internal storage format (e.g., GL_RGB8, GL_RGBA8)
+ * \param[in] type OpenGL pixel data type (e.g., GL_UNSIGNED_BYTE, GL_FLOAT)
* \param[in] data Pointer to pixel data, or nullptr for uninitialised texture
* \param[in] filter GL texture filter setting
*
@@ -282,14 +284,18 @@ int eGL::createOutputDMABufTexture2D(eGLImage &eglImage, int fd)
* is useful for uploading static data like lookup tables or uniform color
* matrices to the GPU.
*/
-void eGL::createTexture2D(eGLImage &eglImage, void *data, GLint filter)
+void eGL::createTexture2D(eGLImage &eglImage,
+ GLint internalFormat,
+ GLenum type,
+ const void *data,
+ GLint filter)
{
ASSERT(tid_ == Thread::currentId());
activateBindTexture(eglImage);
// Generate texture, bind, associate image to texture, configure, unbind
- glTexImage2D(GL_TEXTURE_2D, 0, eglImage.format_, eglImage.width_, eglImage.height_, 0, eglImage.format_, GL_UNSIGNED_BYTE, data);
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, eglImage.width_, eglImage.height_, 0, eglImage.format_, type, data);
// Nearest filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
@@ -370,7 +376,7 @@ void eGL::updateTexture2D(eGLImage &eglImage, void *data)
*/
void eGL::createOutputTexture2D(eGLImage &eglImage)
{
- createTexture2D(eglImage, NULL, GL_NEAREST);
+ createTexture2D(eglImage, eglImage.format_, GL_UNSIGNED_BYTE, NULL, GL_NEAREST);
attachTextureToFBO(eglImage);
}
@@ -53,6 +53,11 @@ namespace libcamera {
* \brief Number of pixel values per each of the lens shading grid areas
*/
+/**
+ * \var DebayerParams::kLscBytesPerCell
+ * \brief Number of bytes per each of the lens shading grid areas
+ */
+
/**
* \typedef DebayerParams::LscLookupTable
* \brief Lookup table for lens shading correction
@@ -128,6 +128,8 @@ int DebayerEGL::getShaderVariableLocations(void)
textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red");
textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix");
+ textureUniformLsc_ = glGetUniformLocation(programId_, "lsc_tex");
+
LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_
<< " tex_y " << textureUniformBayerDataIn_
<< " awb " << awbUniformDataIn_
@@ -139,7 +141,8 @@ int DebayerEGL::getShaderVariableLocations(void)
<< " tex_size " << textureUniformSize_
<< " stride_factor " << textureUniformStrideFactor_
<< " tex_bayer_first_red " << textureUniformBayerFirstRed_
- << " proj_matrix " << textureUniformProjMatrix_;
+ << " proj_matrix " << textureUniformProjMatrix_
+ << " tex_lsc " << textureUniformLsc_;
return 0;
}
@@ -156,6 +159,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm
/* Specify GL_OES_EGL_image_external */
egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable");
+ if (lscEnabled_)
+ egl_.pushEnv(shaderEnv, "#define APPLY_LSC");
+
/*
* Tell shaders how to re-order output taking account of how the pixels
* are actually stored by EGL.
@@ -351,6 +357,18 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg,
inputBufferCount_ = inputCfg.bufferCount;
outputBufferCount_ = outputCfg.bufferCount;
+ if (lscEnabled_) {
+ constexpr unsigned int gridSize = DebayerParams::kLscGridSize;
+ const unsigned int stride = gridSize * DebayerParams::kLscBytesPerCell;
+ eglImageLscLookup_ =
+ std::make_unique<eGLImage>(GL_RGB,
+ gridSize,
+ gridSize,
+ stride,
+ GL_TEXTURE2,
+ 2);
+ }
+
return 0;
}
@@ -486,6 +504,12 @@ void DebayerEGL::setShaderVariableValues(eGLImage &eglImageIn, const DebayerPara
glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_TRUE, params.combinedMatrix.data().data());
LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.combinedMatrix;
+ if (lscEnabled_) {
+ egl_.createTexture2D(*eglImageLscLookup_, GL_RGB16F, GL_FLOAT,
+ params.lscLut.data(), GL_LINEAR);
+ glUniform1i(textureUniformLsc_, eglImageLscLookup_->texture_unit_uniform_id_);
+ }
+
/*
* 0 = Red, 1 = Green, 2 = Blue
*/
@@ -552,7 +576,11 @@ eGLImage *DebayerEGL::getCachedInputFrameBuffer(FrameBuffer *input, std::optiona
return nullptr;
}
if (cache_miss)
- egl_.createTexture2D(*eglImageIn, inMapped->value().planes()[0].data(), GL_NEAREST);
+ egl_.createTexture2D(*eglImageIn,
+ eglImageIn->format_,
+ GL_UNSIGNED_BYTE,
+ inMapped->value().planes()[0].data(),
+ GL_NEAREST);
else
egl_.updateTexture2D(*eglImageIn, inMapped->value().planes()[0].data());
@@ -84,7 +84,10 @@ private:
unsigned int inputBufferCount_;
unsigned int outputBufferCount_;
+ /* LSC lookup table */
+ std::unique_ptr<eGLImage> eglImageLscLookup_;
bool lscEnabled_;
+
/* Shader parameters */
float firstRed_x_;
float firstRed_y_;
@@ -101,6 +104,9 @@ private:
/* Per-frame AWB gains */
GLint awbUniformDataIn_;
+ /* Lens shading correction */
+ GLint textureUniformLsc_;
+
/* Represent per-frame CCM as a uniform vector of floats 3 x 3 */
GLint ccmUniformDataIn_;