Message ID | 20210803092310.11956-1-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Laurent, On 03/08/2021 10:23, Laurent Pinchart wrote: > The GL_RG and GL_RED texture formats are not supported in OpenGL ES > prior to 3.0. In order to be compatible with OpenGL ES 2.0, use > GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be > updated accordingly for GL_RG, as the second component is now stored in /in alpha/in the alpha/ > alpha component instead of the green component. Usage of the red > component is fine, the luminance value is stored in the red, green and > blue components. > So these seem to be just fairly arbitrary identifiers of the texture maps to use, which as long as they are consistently referenced that's all that matters? > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > --- > Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should > cover all code paths. > --- > src/qcam/assets/shader/YUV_2_planes.frag | 4 +-- > src/qcam/viewfinder_gl.cpp | 40 ++++++++++++------------ > 2 files changed, 22 insertions(+), 22 deletions(-) > > diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag > index 125f1c850a33..254463c05cac 100644 > --- a/src/qcam/assets/shader/YUV_2_planes.frag > +++ b/src/qcam/assets/shader/YUV_2_planes.frag > @@ -26,9 +26,9 @@ void main(void) > yuv.x = texture2D(tex_y, textureOut).r - 0.063; > #if defined(YUV_PATTERN_UV) > yuv.y = texture2D(tex_u, textureOut).r - 0.500; > - yuv.z = texture2D(tex_u, textureOut).g - 0.500; > + yuv.z = texture2D(tex_u, textureOut).a - 0.500; > #elif defined(YUV_PATTERN_VU) > - yuv.y = texture2D(tex_u, textureOut).g - 0.500; > + yuv.y = texture2D(tex_u, textureOut).a - 0.500; > yuv.z = texture2D(tex_u, textureOut).r - 0.500; > #else > #error Invalid pattern > diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp > index e7c8620c7024..77a6437e56fd 100644 > --- a/src/qcam/viewfinder_gl.cpp > +++ b/src/qcam/viewfinder_gl.cpp > @@ -481,11 +481,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[0]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width(), > size_.height(), > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_); > shaderProgram_.setUniformValue(textureUniformY_, 0); > @@ -495,11 +495,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[1]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RG, > + GL_LUMINANCE_ALPHA, > size_.width() / horzSubSample_, > size_.height() / vertSubSample_, > 0, > - GL_RG, > + GL_LUMINANCE_ALPHA, > GL_UNSIGNED_BYTE, > data_ + size_.width() * size_.height()); > shaderProgram_.setUniformValue(textureUniformU_, 1); > @@ -511,11 +511,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[0]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width(), > size_.height(), > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_); > shaderProgram_.setUniformValue(textureUniformY_, 0); > @@ -525,11 +525,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[1]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width() / horzSubSample_, > size_.height() / vertSubSample_, > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_ + size_.width() * size_.height()); > shaderProgram_.setUniformValue(textureUniformU_, 1); > @@ -539,11 +539,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[2]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width() / horzSubSample_, > size_.height() / vertSubSample_, > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_ + size_.width() * size_.height() * 5 / 4); > shaderProgram_.setUniformValue(textureUniformV_, 2); > @@ -555,11 +555,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[0]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width(), > size_.height(), > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_); > shaderProgram_.setUniformValue(textureUniformY_, 0); > @@ -569,11 +569,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[2]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width() / horzSubSample_, > size_.height() / vertSubSample_, > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_ + size_.width() * size_.height()); > shaderProgram_.setUniformValue(textureUniformV_, 2); > @@ -583,11 +583,11 @@ void ViewFinderGL::doRender() > configureTexture(*textures_[1]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > size_.width() / horzSubSample_, > size_.height() / vertSubSample_, > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_ + size_.width() * size_.height() * 5 / 4); > shaderProgram_.setUniformValue(textureUniformU_, 1); > @@ -674,18 +674,18 @@ void ViewFinderGL::doRender() > case libcamera::formats::SRGGB12_CSI2P: > /* > * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats > - * are stored in GL_RED texture. > - * The texture width is equal to the stride. > + * are stored in GL_LUMINANCE texture. The texture width is I know you're modifying an existing sentence, but should this read either: - are stored in a GL_LUMINANCE texture or - are stored in the GL_LUMINANCE texture depending on if there is only one GL_LUMINANCE texture, or if there might be more and this is specifically allocated. (That extra clarification would help me understand those identifiers too... such power from a single word addition). Anyway, aside from / with that: Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > + * equal to the stride. > */ > glActiveTexture(GL_TEXTURE0); > configureTexture(*textures_[0]); > glTexImage2D(GL_TEXTURE_2D, > 0, > - GL_RED, > + GL_LUMINANCE, > stride_, > size_.height(), > 0, > - GL_RED, > + GL_LUMINANCE, > GL_UNSIGNED_BYTE, > data_); > shaderProgram_.setUniformValue(textureUniformY_, 0); >
Hi Kieran, On Tue, Aug 03, 2021 at 10:31:23AM +0100, Kieran Bingham wrote: > On 03/08/2021 10:23, Laurent Pinchart wrote: > > The GL_RG and GL_RED texture formats are not supported in OpenGL ES > > prior to 3.0. In order to be compatible with OpenGL ES 2.0, use > > GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be > > updated accordingly for GL_RG, as the second component is now stored in > > /in alpha/in the alpha/ > > > alpha component instead of the green component. Usage of the red > > component is fine, the luminance value is stored in the red, green and > > blue components. > > So these seem to be just fairly arbitrary identifiers of the texture > maps to use, which as long as they are consistently referenced that's > all that matters? They describe how the texture is stored in memory, and how it's converted to RGBA before going through the shaders. See https://docs.gl/es2/glTexImage2D for more information. In particular, GL_LUMINANCE Each element is a single luminance value. The GL converts it to floating point, then assembles it into an RGBA element by replicating the luminance value three times for red, green, and blue and attaching 1 for alpha. Each component is then clamped to the range [0,1]. GL_LUMINANCE_ALPHA Each element is a luminance/alpha pair. The GL converts it to floating point, then assembles it into an RGBA element by replicating the luminance value three times for red, green, and blue. Each component is then clamped to the range [0,1]. In ES3, we additionally have (https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml), GL_RED Each element is a single red component. For fixed point normalized components, the GL converts it to floating point, clamps to the range [0,1], and assembles it into an RGBA element by attaching 0.0 for green and blue, and 1.0 for alpha. GL_RG Each element is a red/green double. For fixed point normalized components, the GL converts each component to floating point, clamps to the range [0,1], and assembles them into an RGBA element by attaching 0.0 for blue, and 1.0 for alpha. GL_RED maps the value to [v, 0.0, 0.0, 1.0] while GL_LUMINANCE maps it to [v, v, v, 1.0]. As the shaders use the red component only, they're equivalent. For GL_RG, however, when moving to GL_LUMINANCE_ALPHA, we need to replace usage for the green component with the alpha component. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > > --- > > Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should > > cover all code paths. > > --- > > src/qcam/assets/shader/YUV_2_planes.frag | 4 +-- > > src/qcam/viewfinder_gl.cpp | 40 ++++++++++++------------ > > 2 files changed, 22 insertions(+), 22 deletions(-) > > > > diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag > > index 125f1c850a33..254463c05cac 100644 > > --- a/src/qcam/assets/shader/YUV_2_planes.frag > > +++ b/src/qcam/assets/shader/YUV_2_planes.frag > > @@ -26,9 +26,9 @@ void main(void) > > yuv.x = texture2D(tex_y, textureOut).r - 0.063; > > #if defined(YUV_PATTERN_UV) > > yuv.y = texture2D(tex_u, textureOut).r - 0.500; > > - yuv.z = texture2D(tex_u, textureOut).g - 0.500; > > + yuv.z = texture2D(tex_u, textureOut).a - 0.500; > > #elif defined(YUV_PATTERN_VU) > > - yuv.y = texture2D(tex_u, textureOut).g - 0.500; > > + yuv.y = texture2D(tex_u, textureOut).a - 0.500; > > yuv.z = texture2D(tex_u, textureOut).r - 0.500; > > #else > > #error Invalid pattern > > diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp > > index e7c8620c7024..77a6437e56fd 100644 > > --- a/src/qcam/viewfinder_gl.cpp > > +++ b/src/qcam/viewfinder_gl.cpp > > @@ -481,11 +481,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[0]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width(), > > size_.height(), > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_); > > shaderProgram_.setUniformValue(textureUniformY_, 0); > > @@ -495,11 +495,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[1]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RG, > > + GL_LUMINANCE_ALPHA, > > size_.width() / horzSubSample_, > > size_.height() / vertSubSample_, > > 0, > > - GL_RG, > > + GL_LUMINANCE_ALPHA, > > GL_UNSIGNED_BYTE, > > data_ + size_.width() * size_.height()); > > shaderProgram_.setUniformValue(textureUniformU_, 1); > > @@ -511,11 +511,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[0]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width(), > > size_.height(), > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_); > > shaderProgram_.setUniformValue(textureUniformY_, 0); > > @@ -525,11 +525,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[1]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width() / horzSubSample_, > > size_.height() / vertSubSample_, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_ + size_.width() * size_.height()); > > shaderProgram_.setUniformValue(textureUniformU_, 1); > > @@ -539,11 +539,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[2]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width() / horzSubSample_, > > size_.height() / vertSubSample_, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_ + size_.width() * size_.height() * 5 / 4); > > shaderProgram_.setUniformValue(textureUniformV_, 2); > > @@ -555,11 +555,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[0]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width(), > > size_.height(), > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_); > > shaderProgram_.setUniformValue(textureUniformY_, 0); > > @@ -569,11 +569,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[2]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width() / horzSubSample_, > > size_.height() / vertSubSample_, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_ + size_.width() * size_.height()); > > shaderProgram_.setUniformValue(textureUniformV_, 2); > > @@ -583,11 +583,11 @@ void ViewFinderGL::doRender() > > configureTexture(*textures_[1]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > size_.width() / horzSubSample_, > > size_.height() / vertSubSample_, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_ + size_.width() * size_.height() * 5 / 4); > > shaderProgram_.setUniformValue(textureUniformU_, 1); > > @@ -674,18 +674,18 @@ void ViewFinderGL::doRender() > > case libcamera::formats::SRGGB12_CSI2P: > > /* > > * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats > > - * are stored in GL_RED texture. > > - * The texture width is equal to the stride. > > + * are stored in GL_LUMINANCE texture. The texture width is > > I know you're modifying an existing sentence, but should this read either: > > - are stored in a GL_LUMINANCE texture > or > - are stored in the GL_LUMINANCE texture > > depending on if there is only one GL_LUMINANCE texture, or if there > might be more and this is specifically allocated. I'll fix it, using "a GL_LUMINANCE texture". > (That extra clarification would help me understand those identifiers > too... such power from a single word addition). > > Anyway, aside from / with that: > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > > + * equal to the stride. > > */ > > glActiveTexture(GL_TEXTURE0); > > configureTexture(*textures_[0]); > > glTexImage2D(GL_TEXTURE_2D, > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > stride_, > > size_.height(), > > 0, > > - GL_RED, > > + GL_LUMINANCE, > > GL_UNSIGNED_BYTE, > > data_); > > shaderProgram_.setUniformValue(textureUniformY_, 0); > >
Hi Laurent, Making qcam to work with OpenGL ES 2.0 is a nice improvement! On 03.08.2021 12:41, Laurent Pinchart wrote: > Hi Kieran, > > On Tue, Aug 03, 2021 at 10:31:23AM +0100, Kieran Bingham wrote: >> On 03/08/2021 10:23, Laurent Pinchart wrote: >>> The GL_RG and GL_RED texture formats are not supported in OpenGL ES >>> prior to 3.0. In order to be compatible with OpenGL ES 2.0, use >>> GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be >>> updated accordingly for GL_RG, as the second component is now stored in >> >> /in alpha/in the alpha/ >> >>> alpha component instead of the green component. Usage of the red >>> component is fine, the luminance value is stored in the red, green and >>> blue components. >> >> So these seem to be just fairly arbitrary identifiers of the texture >> maps to use, which as long as they are consistently referenced that's >> all that matters? > > They describe how the texture is stored in memory, and how it's > converted to RGBA before going through the shaders. See > https://docs.gl/es2/glTexImage2D for more information. In particular, > > GL_LUMINANCE > > Each element is a single luminance value. The GL converts it to > floating point, then assembles it into an RGBA element by > replicating the luminance value three times for red, green, and blue > and attaching 1 for alpha. Each component is then clamped to the > range [0,1]. > > GL_LUMINANCE_ALPHA > > Each element is a luminance/alpha pair. The GL converts it to > floating point, then assembles it into an RGBA element by > replicating the luminance value three times for red, green, and > blue. Each component is then clamped to the range [0,1]. > > In ES3, we additionally have > (https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml), > > GL_RED > > Each element is a single red component. For fixed point normalized > components, the GL converts it to floating point, clamps to the > range [0,1], and assembles it into an RGBA element by attaching 0.0 > for green and blue, and 1.0 for alpha. > > GL_RG > > Each element is a red/green double. For fixed point normalized > components, the GL converts each component to floating point, clamps > to the range [0,1], and assembles them into an RGBA element by > attaching 0.0 for blue, and 1.0 for alpha. > > GL_RED maps the value to [v, 0.0, 0.0, 1.0] while GL_LUMINANCE maps it > to [v, v, v, 1.0]. As the shaders use the red component only, they're > equivalent. For GL_RG, however, when moving to GL_LUMINANCE_ALPHA, we > need to replace usage for the green component with the alpha component. Thanks for the explanation and the docs links! >>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> >>> --- >>> Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should >>> cover all code paths. Reviewed-by: Andrey Konovalov <andrey.konovalov@linaro.org> (Tested on RB3 board with camss using SGRBG10_CSI2P - just in case) Thanks, Andrey >>> --- >>> src/qcam/assets/shader/YUV_2_planes.frag | 4 +-- >>> src/qcam/viewfinder_gl.cpp | 40 ++++++++++++------------ >>> 2 files changed, 22 insertions(+), 22 deletions(-) >>> >>> diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag >>> index 125f1c850a33..254463c05cac 100644 >>> --- a/src/qcam/assets/shader/YUV_2_planes.frag >>> +++ b/src/qcam/assets/shader/YUV_2_planes.frag >>> @@ -26,9 +26,9 @@ void main(void) >>> yuv.x = texture2D(tex_y, textureOut).r - 0.063; >>> #if defined(YUV_PATTERN_UV) >>> yuv.y = texture2D(tex_u, textureOut).r - 0.500; >>> - yuv.z = texture2D(tex_u, textureOut).g - 0.500; >>> + yuv.z = texture2D(tex_u, textureOut).a - 0.500; >>> #elif defined(YUV_PATTERN_VU) >>> - yuv.y = texture2D(tex_u, textureOut).g - 0.500; >>> + yuv.y = texture2D(tex_u, textureOut).a - 0.500; >>> yuv.z = texture2D(tex_u, textureOut).r - 0.500; >>> #else >>> #error Invalid pattern >>> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp >>> index e7c8620c7024..77a6437e56fd 100644 >>> --- a/src/qcam/viewfinder_gl.cpp >>> +++ b/src/qcam/viewfinder_gl.cpp >>> @@ -481,11 +481,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[0]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width(), >>> size_.height(), >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_); >>> shaderProgram_.setUniformValue(textureUniformY_, 0); >>> @@ -495,11 +495,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[1]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RG, >>> + GL_LUMINANCE_ALPHA, >>> size_.width() / horzSubSample_, >>> size_.height() / vertSubSample_, >>> 0, >>> - GL_RG, >>> + GL_LUMINANCE_ALPHA, >>> GL_UNSIGNED_BYTE, >>> data_ + size_.width() * size_.height()); >>> shaderProgram_.setUniformValue(textureUniformU_, 1); >>> @@ -511,11 +511,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[0]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width(), >>> size_.height(), >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_); >>> shaderProgram_.setUniformValue(textureUniformY_, 0); >>> @@ -525,11 +525,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[1]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width() / horzSubSample_, >>> size_.height() / vertSubSample_, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_ + size_.width() * size_.height()); >>> shaderProgram_.setUniformValue(textureUniformU_, 1); >>> @@ -539,11 +539,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[2]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width() / horzSubSample_, >>> size_.height() / vertSubSample_, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_ + size_.width() * size_.height() * 5 / 4); >>> shaderProgram_.setUniformValue(textureUniformV_, 2); >>> @@ -555,11 +555,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[0]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width(), >>> size_.height(), >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_); >>> shaderProgram_.setUniformValue(textureUniformY_, 0); >>> @@ -569,11 +569,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[2]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width() / horzSubSample_, >>> size_.height() / vertSubSample_, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_ + size_.width() * size_.height()); >>> shaderProgram_.setUniformValue(textureUniformV_, 2); >>> @@ -583,11 +583,11 @@ void ViewFinderGL::doRender() >>> configureTexture(*textures_[1]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> size_.width() / horzSubSample_, >>> size_.height() / vertSubSample_, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_ + size_.width() * size_.height() * 5 / 4); >>> shaderProgram_.setUniformValue(textureUniformU_, 1); >>> @@ -674,18 +674,18 @@ void ViewFinderGL::doRender() >>> case libcamera::formats::SRGGB12_CSI2P: >>> /* >>> * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats >>> - * are stored in GL_RED texture. >>> - * The texture width is equal to the stride. >>> + * are stored in GL_LUMINANCE texture. The texture width is >> >> I know you're modifying an existing sentence, but should this read either: >> >> - are stored in a GL_LUMINANCE texture >> or >> - are stored in the GL_LUMINANCE texture >> >> depending on if there is only one GL_LUMINANCE texture, or if there >> might be more and this is specifically allocated. > > I'll fix it, using "a GL_LUMINANCE texture". > >> (That extra clarification would help me understand those identifiers >> too... such power from a single word addition). >> >> Anyway, aside from / with that: >> >> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> >> >>> + * equal to the stride. >>> */ >>> glActiveTexture(GL_TEXTURE0); >>> configureTexture(*textures_[0]); >>> glTexImage2D(GL_TEXTURE_2D, >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> stride_, >>> size_.height(), >>> 0, >>> - GL_RED, >>> + GL_LUMINANCE, >>> GL_UNSIGNED_BYTE, >>> data_); >>> shaderProgram_.setUniformValue(textureUniformY_, 0); >>> >
Hi Andrey, On Tue, Aug 03, 2021 at 11:28:30PM +0300, Andrey Konovalov wrote: > Hi Laurent, > > Making qcam to work with OpenGL ES 2.0 is a nice improvement! > > On 03.08.2021 12:41, Laurent Pinchart wrote: > > On Tue, Aug 03, 2021 at 10:31:23AM +0100, Kieran Bingham wrote: > >> On 03/08/2021 10:23, Laurent Pinchart wrote: > >>> The GL_RG and GL_RED texture formats are not supported in OpenGL ES > >>> prior to 3.0. In order to be compatible with OpenGL ES 2.0, use > >>> GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be > >>> updated accordingly for GL_RG, as the second component is now stored in > >> > >> /in alpha/in the alpha/ > >> > >>> alpha component instead of the green component. Usage of the red > >>> component is fine, the luminance value is stored in the red, green and > >>> blue components. > >> > >> So these seem to be just fairly arbitrary identifiers of the texture > >> maps to use, which as long as they are consistently referenced that's > >> all that matters? > > > > They describe how the texture is stored in memory, and how it's > > converted to RGBA before going through the shaders. See > > https://docs.gl/es2/glTexImage2D for more information. In particular, > > > > GL_LUMINANCE > > > > Each element is a single luminance value. The GL converts it to > > floating point, then assembles it into an RGBA element by > > replicating the luminance value three times for red, green, and blue > > and attaching 1 for alpha. Each component is then clamped to the > > range [0,1]. > > > > GL_LUMINANCE_ALPHA > > > > Each element is a luminance/alpha pair. The GL converts it to > > floating point, then assembles it into an RGBA element by > > replicating the luminance value three times for red, green, and > > blue. Each component is then clamped to the range [0,1]. > > > > In ES3, we additionally have > > (https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml), > > > > GL_RED > > > > Each element is a single red component. For fixed point normalized > > components, the GL converts it to floating point, clamps to the > > range [0,1], and assembles it into an RGBA element by attaching 0.0 > > for green and blue, and 1.0 for alpha. > > > > GL_RG > > > > Each element is a red/green double. For fixed point normalized > > components, the GL converts each component to floating point, clamps > > to the range [0,1], and assembles them into an RGBA element by > > attaching 0.0 for blue, and 1.0 for alpha. > > > > GL_RED maps the value to [v, 0.0, 0.0, 1.0] while GL_LUMINANCE maps it > > to [v, v, v, 1.0]. As the shaders use the red component only, they're > > equivalent. For GL_RG, however, when moving to GL_LUMINANCE_ALPHA, we > > need to replace usage for the green component with the alpha component. > > Thanks for the explanation and the docs links! > > >>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > >>> --- > >>> Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should > >>> cover all code paths. > > Reviewed-by: Andrey Konovalov <andrey.konovalov@linaro.org> > > (Tested on RB3 board with camss using SGRBG10_CSI2P - just in case) That's the only format family that I haven't been able to test :-) Thanks. > >>> --- > >>> src/qcam/assets/shader/YUV_2_planes.frag | 4 +-- > >>> src/qcam/viewfinder_gl.cpp | 40 ++++++++++++------------ > >>> 2 files changed, 22 insertions(+), 22 deletions(-) > >>> > >>> diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag > >>> index 125f1c850a33..254463c05cac 100644 > >>> --- a/src/qcam/assets/shader/YUV_2_planes.frag > >>> +++ b/src/qcam/assets/shader/YUV_2_planes.frag > >>> @@ -26,9 +26,9 @@ void main(void) > >>> yuv.x = texture2D(tex_y, textureOut).r - 0.063; > >>> #if defined(YUV_PATTERN_UV) > >>> yuv.y = texture2D(tex_u, textureOut).r - 0.500; > >>> - yuv.z = texture2D(tex_u, textureOut).g - 0.500; > >>> + yuv.z = texture2D(tex_u, textureOut).a - 0.500; > >>> #elif defined(YUV_PATTERN_VU) > >>> - yuv.y = texture2D(tex_u, textureOut).g - 0.500; > >>> + yuv.y = texture2D(tex_u, textureOut).a - 0.500; > >>> yuv.z = texture2D(tex_u, textureOut).r - 0.500; > >>> #else > >>> #error Invalid pattern > >>> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp > >>> index e7c8620c7024..77a6437e56fd 100644 > >>> --- a/src/qcam/viewfinder_gl.cpp > >>> +++ b/src/qcam/viewfinder_gl.cpp > >>> @@ -481,11 +481,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[0]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width(), > >>> size_.height(), > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_); > >>> shaderProgram_.setUniformValue(textureUniformY_, 0); > >>> @@ -495,11 +495,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[1]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RG, > >>> + GL_LUMINANCE_ALPHA, > >>> size_.width() / horzSubSample_, > >>> size_.height() / vertSubSample_, > >>> 0, > >>> - GL_RG, > >>> + GL_LUMINANCE_ALPHA, > >>> GL_UNSIGNED_BYTE, > >>> data_ + size_.width() * size_.height()); > >>> shaderProgram_.setUniformValue(textureUniformU_, 1); > >>> @@ -511,11 +511,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[0]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width(), > >>> size_.height(), > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_); > >>> shaderProgram_.setUniformValue(textureUniformY_, 0); > >>> @@ -525,11 +525,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[1]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width() / horzSubSample_, > >>> size_.height() / vertSubSample_, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_ + size_.width() * size_.height()); > >>> shaderProgram_.setUniformValue(textureUniformU_, 1); > >>> @@ -539,11 +539,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[2]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width() / horzSubSample_, > >>> size_.height() / vertSubSample_, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_ + size_.width() * size_.height() * 5 / 4); > >>> shaderProgram_.setUniformValue(textureUniformV_, 2); > >>> @@ -555,11 +555,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[0]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width(), > >>> size_.height(), > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_); > >>> shaderProgram_.setUniformValue(textureUniformY_, 0); > >>> @@ -569,11 +569,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[2]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width() / horzSubSample_, > >>> size_.height() / vertSubSample_, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_ + size_.width() * size_.height()); > >>> shaderProgram_.setUniformValue(textureUniformV_, 2); > >>> @@ -583,11 +583,11 @@ void ViewFinderGL::doRender() > >>> configureTexture(*textures_[1]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> size_.width() / horzSubSample_, > >>> size_.height() / vertSubSample_, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_ + size_.width() * size_.height() * 5 / 4); > >>> shaderProgram_.setUniformValue(textureUniformU_, 1); > >>> @@ -674,18 +674,18 @@ void ViewFinderGL::doRender() > >>> case libcamera::formats::SRGGB12_CSI2P: > >>> /* > >>> * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats > >>> - * are stored in GL_RED texture. > >>> - * The texture width is equal to the stride. > >>> + * are stored in GL_LUMINANCE texture. The texture width is > >> > >> I know you're modifying an existing sentence, but should this read either: > >> > >> - are stored in a GL_LUMINANCE texture > >> or > >> - are stored in the GL_LUMINANCE texture > >> > >> depending on if there is only one GL_LUMINANCE texture, or if there > >> might be more and this is specifically allocated. > > > > I'll fix it, using "a GL_LUMINANCE texture". > > > >> (That extra clarification would help me understand those identifiers > >> too... such power from a single word addition). > >> > >> Anyway, aside from / with that: > >> > >> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > >> > >>> + * equal to the stride. > >>> */ > >>> glActiveTexture(GL_TEXTURE0); > >>> configureTexture(*textures_[0]); > >>> glTexImage2D(GL_TEXTURE_2D, > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> stride_, > >>> size_.height(), > >>> 0, > >>> - GL_RED, > >>> + GL_LUMINANCE, > >>> GL_UNSIGNED_BYTE, > >>> data_); > >>> shaderProgram_.setUniformValue(textureUniformY_, 0); > >>>
diff --git a/src/qcam/assets/shader/YUV_2_planes.frag b/src/qcam/assets/shader/YUV_2_planes.frag index 125f1c850a33..254463c05cac 100644 --- a/src/qcam/assets/shader/YUV_2_planes.frag +++ b/src/qcam/assets/shader/YUV_2_planes.frag @@ -26,9 +26,9 @@ void main(void) yuv.x = texture2D(tex_y, textureOut).r - 0.063; #if defined(YUV_PATTERN_UV) yuv.y = texture2D(tex_u, textureOut).r - 0.500; - yuv.z = texture2D(tex_u, textureOut).g - 0.500; + yuv.z = texture2D(tex_u, textureOut).a - 0.500; #elif defined(YUV_PATTERN_VU) - yuv.y = texture2D(tex_u, textureOut).g - 0.500; + yuv.y = texture2D(tex_u, textureOut).a - 0.500; yuv.z = texture2D(tex_u, textureOut).r - 0.500; #else #error Invalid pattern diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index e7c8620c7024..77a6437e56fd 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -481,11 +481,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width(), size_.height(), 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_); shaderProgram_.setUniformValue(textureUniformY_, 0); @@ -495,11 +495,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[1]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RG, + GL_LUMINANCE_ALPHA, size_.width() / horzSubSample_, size_.height() / vertSubSample_, 0, - GL_RG, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data_ + size_.width() * size_.height()); shaderProgram_.setUniformValue(textureUniformU_, 1); @@ -511,11 +511,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width(), size_.height(), 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_); shaderProgram_.setUniformValue(textureUniformY_, 0); @@ -525,11 +525,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[1]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width() / horzSubSample_, size_.height() / vertSubSample_, 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_ + size_.width() * size_.height()); shaderProgram_.setUniformValue(textureUniformU_, 1); @@ -539,11 +539,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[2]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width() / horzSubSample_, size_.height() / vertSubSample_, 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_ + size_.width() * size_.height() * 5 / 4); shaderProgram_.setUniformValue(textureUniformV_, 2); @@ -555,11 +555,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width(), size_.height(), 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_); shaderProgram_.setUniformValue(textureUniformY_, 0); @@ -569,11 +569,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[2]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width() / horzSubSample_, size_.height() / vertSubSample_, 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_ + size_.width() * size_.height()); shaderProgram_.setUniformValue(textureUniformV_, 2); @@ -583,11 +583,11 @@ void ViewFinderGL::doRender() configureTexture(*textures_[1]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, size_.width() / horzSubSample_, size_.height() / vertSubSample_, 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_ + size_.width() * size_.height() * 5 / 4); shaderProgram_.setUniformValue(textureUniformU_, 1); @@ -674,18 +674,18 @@ void ViewFinderGL::doRender() case libcamera::formats::SRGGB12_CSI2P: /* * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats - * are stored in GL_RED texture. - * The texture width is equal to the stride. + * are stored in GL_LUMINANCE texture. The texture width is + * equal to the stride. */ glActiveTexture(GL_TEXTURE0); configureTexture(*textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, - GL_RED, + GL_LUMINANCE, stride_, size_.height(), 0, - GL_RED, + GL_LUMINANCE, GL_UNSIGNED_BYTE, data_); shaderProgram_.setUniformValue(textureUniformY_, 0);
The GL_RG and GL_RED texture formats are not supported in OpenGL ES prior to 3.0. In order to be compatible with OpenGL ES 2.0, use GL_LUMINANCE_ALPHA and GL_LUMINANCE instead. The shader code needs to be updated accordingly for GL_RG, as the second component is now stored in alpha component instead of the green component. Usage of the red component is fine, the luminance value is stored in the red, green and blue components. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- Tested with vivid, using NV12, YV420, YVU420 and SGRBG8, which should cover all code paths. --- src/qcam/assets/shader/YUV_2_planes.frag | 4 +-- src/qcam/viewfinder_gl.cpp | 40 ++++++++++++------------ 2 files changed, 22 insertions(+), 22 deletions(-)