summaryrefslogtreecommitdiff
path: root/src/qcam/viewfinder_gl.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-20 00:44:55 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-10-20 13:36:25 +0300
commit84ad104499d9efc0253dae1a60ee070ed375ad95 (patch)
treed10fd53eb79cebb28fa3f72b18b46dddb6382b83 /src/qcam/viewfinder_gl.cpp
parentdaf3f4b59f4ea0ecb42c6a39fe909f071d3a2842 (diff)
Move test applications to src/apps/
The cam and qcam test application share code, currently through a crude hack that references the cam source files directly from the qcam meson.build file. To prepare for the introduction of hosting that code in a static library, move all applications to src/apps/. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/qcam/viewfinder_gl.cpp')
-rw-r--r--src/qcam/viewfinder_gl.cpp835
1 files changed, 0 insertions, 835 deletions
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
deleted file mode 100644
index 38ddad58..00000000
--- a/src/qcam/viewfinder_gl.cpp
+++ /dev/null
@@ -1,835 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Linaro
- *
- * viewfinderGL.cpp - OpenGL Viewfinder for rendering by OpenGL shader
- */
-
-#include "viewfinder_gl.h"
-
-#include <array>
-
-#include <QByteArray>
-#include <QFile>
-#include <QImage>
-#include <QStringList>
-
-#include <libcamera/formats.h>
-
-#include "../cam/image.h"
-
-static const QList<libcamera::PixelFormat> supportedFormats{
- /* YUV - packed (single plane) */
- libcamera::formats::UYVY,
- libcamera::formats::VYUY,
- libcamera::formats::YUYV,
- libcamera::formats::YVYU,
- /* YUV - semi planar (two planes) */
- libcamera::formats::NV12,
- libcamera::formats::NV21,
- libcamera::formats::NV16,
- libcamera::formats::NV61,
- libcamera::formats::NV24,
- libcamera::formats::NV42,
- /* YUV - fully planar (three planes) */
- libcamera::formats::YUV420,
- libcamera::formats::YVU420,
- /* RGB */
- libcamera::formats::ABGR8888,
- libcamera::formats::ARGB8888,
- libcamera::formats::BGRA8888,
- libcamera::formats::RGBA8888,
- libcamera::formats::BGR888,
- libcamera::formats::RGB888,
- /* Raw Bayer 8-bit */
- libcamera::formats::SBGGR8,
- libcamera::formats::SGBRG8,
- libcamera::formats::SGRBG8,
- libcamera::formats::SRGGB8,
- /* Raw Bayer 10-bit packed */
- libcamera::formats::SBGGR10_CSI2P,
- libcamera::formats::SGBRG10_CSI2P,
- libcamera::formats::SGRBG10_CSI2P,
- libcamera::formats::SRGGB10_CSI2P,
- /* Raw Bayer 12-bit packed */
- libcamera::formats::SBGGR12_CSI2P,
- libcamera::formats::SGBRG12_CSI2P,
- libcamera::formats::SGRBG12_CSI2P,
- libcamera::formats::SRGGB12_CSI2P,
-};
-
-ViewFinderGL::ViewFinderGL(QWidget *parent)
- : QOpenGLWidget(parent), buffer_(nullptr),
- colorSpace_(libcamera::ColorSpace::Raw), image_(nullptr),
- vertexBuffer_(QOpenGLBuffer::VertexBuffer)
-{
-}
-
-ViewFinderGL::~ViewFinderGL()
-{
- removeShader();
-}
-
-const QList<libcamera::PixelFormat> &ViewFinderGL::nativeFormats() const
-{
- return supportedFormats;
-}
-
-int ViewFinderGL::setFormat(const libcamera::PixelFormat &format, const QSize &size,
- const libcamera::ColorSpace &colorSpace,
- unsigned int stride)
-{
- if (format != format_ || colorSpace != colorSpace_) {
- /*
- * If the fragment already exists, remove it and create a new
- * one for the new format.
- */
- if (shaderProgram_.isLinked()) {
- shaderProgram_.release();
- shaderProgram_.removeShader(fragmentShader_.get());
- fragmentShader_.reset();
- }
-
- if (!selectFormat(format))
- return -1;
-
- selectColorSpace(colorSpace);
-
- format_ = format;
- colorSpace_ = colorSpace;
- }
-
- size_ = size;
- stride_ = stride;
-
- updateGeometry();
- return 0;
-}
-
-void ViewFinderGL::stop()
-{
- if (buffer_) {
- renderComplete(buffer_);
- buffer_ = nullptr;
- image_ = nullptr;
- }
-}
-
-QImage ViewFinderGL::getCurrentImage()
-{
- QMutexLocker locker(&mutex_);
-
- return grabFramebuffer();
-}
-
-void ViewFinderGL::render(libcamera::FrameBuffer *buffer, Image *image)
-{
- if (buffer_)
- renderComplete(buffer_);
-
- image_ = image;
- update();
- buffer_ = buffer;
-}
-
-bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
-{
- bool ret = true;
-
- /* Set min/mag filters to GL_LINEAR by default. */
- textureMinMagFilters_ = GL_LINEAR;
-
- /* Use identity.vert as the default vertex shader. */
- vertexShaderFile_ = ":identity.vert";
-
- fragmentShaderDefines_.clear();
-
- switch (format) {
- case libcamera::formats::NV12:
- horzSubSample_ = 2;
- vertSubSample_ = 2;
- fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::NV21:
- horzSubSample_ = 2;
- vertSubSample_ = 2;
- fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::NV16:
- horzSubSample_ = 2;
- vertSubSample_ = 1;
- fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::NV61:
- horzSubSample_ = 2;
- vertSubSample_ = 1;
- fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::NV24:
- horzSubSample_ = 1;
- vertSubSample_ = 1;
- fragmentShaderDefines_.append("#define YUV_PATTERN_UV");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::NV42:
- horzSubSample_ = 1;
- vertSubSample_ = 1;
- fragmentShaderDefines_.append("#define YUV_PATTERN_VU");
- fragmentShaderFile_ = ":YUV_2_planes.frag";
- break;
- case libcamera::formats::YUV420:
- horzSubSample_ = 2;
- vertSubSample_ = 2;
- fragmentShaderFile_ = ":YUV_3_planes.frag";
- break;
- case libcamera::formats::YVU420:
- horzSubSample_ = 2;
- vertSubSample_ = 2;
- fragmentShaderFile_ = ":YUV_3_planes.frag";
- break;
- case libcamera::formats::UYVY:
- fragmentShaderDefines_.append("#define YUV_PATTERN_UYVY");
- fragmentShaderFile_ = ":YUV_packed.frag";
- break;
- case libcamera::formats::VYUY:
- fragmentShaderDefines_.append("#define YUV_PATTERN_VYUY");
- fragmentShaderFile_ = ":YUV_packed.frag";
- break;
- case libcamera::formats::YUYV:
- fragmentShaderDefines_.append("#define YUV_PATTERN_YUYV");
- fragmentShaderFile_ = ":YUV_packed.frag";
- break;
- case libcamera::formats::YVYU:
- fragmentShaderDefines_.append("#define YUV_PATTERN_YVYU");
- fragmentShaderFile_ = ":YUV_packed.frag";
- break;
- case libcamera::formats::ABGR8888:
- fragmentShaderDefines_.append("#define RGB_PATTERN rgb");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::ARGB8888:
- fragmentShaderDefines_.append("#define RGB_PATTERN bgr");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::BGRA8888:
- fragmentShaderDefines_.append("#define RGB_PATTERN gba");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::RGBA8888:
- fragmentShaderDefines_.append("#define RGB_PATTERN abg");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::BGR888:
- fragmentShaderDefines_.append("#define RGB_PATTERN rgb");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::RGB888:
- fragmentShaderDefines_.append("#define RGB_PATTERN bgr");
- fragmentShaderFile_ = ":RGB.frag";
- break;
- case libcamera::formats::SBGGR8:
- firstRed_.setX(1.0);
- firstRed_.setY(1.0);
- vertexShaderFile_ = ":bayer_8.vert";
- fragmentShaderFile_ = ":bayer_8.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGBRG8:
- firstRed_.setX(0.0);
- firstRed_.setY(1.0);
- vertexShaderFile_ = ":bayer_8.vert";
- fragmentShaderFile_ = ":bayer_8.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGRBG8:
- firstRed_.setX(1.0);
- firstRed_.setY(0.0);
- vertexShaderFile_ = ":bayer_8.vert";
- fragmentShaderFile_ = ":bayer_8.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SRGGB8:
- firstRed_.setX(0.0);
- firstRed_.setY(0.0);
- vertexShaderFile_ = ":bayer_8.vert";
- fragmentShaderFile_ = ":bayer_8.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SBGGR10_CSI2P:
- firstRed_.setX(1.0);
- firstRed_.setY(1.0);
- fragmentShaderDefines_.append("#define RAW10P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGBRG10_CSI2P:
- firstRed_.setX(0.0);
- firstRed_.setY(1.0);
- fragmentShaderDefines_.append("#define RAW10P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGRBG10_CSI2P:
- firstRed_.setX(1.0);
- firstRed_.setY(0.0);
- fragmentShaderDefines_.append("#define RAW10P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SRGGB10_CSI2P:
- firstRed_.setX(0.0);
- firstRed_.setY(0.0);
- fragmentShaderDefines_.append("#define RAW10P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SBGGR12_CSI2P:
- firstRed_.setX(1.0);
- firstRed_.setY(1.0);
- fragmentShaderDefines_.append("#define RAW12P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGBRG12_CSI2P:
- firstRed_.setX(0.0);
- firstRed_.setY(1.0);
- fragmentShaderDefines_.append("#define RAW12P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SGRBG12_CSI2P:
- firstRed_.setX(1.0);
- firstRed_.setY(0.0);
- fragmentShaderDefines_.append("#define RAW12P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- case libcamera::formats::SRGGB12_CSI2P:
- firstRed_.setX(0.0);
- firstRed_.setY(0.0);
- fragmentShaderDefines_.append("#define RAW12P");
- fragmentShaderFile_ = ":bayer_1x_packed.frag";
- textureMinMagFilters_ = GL_NEAREST;
- break;
- default:
- ret = false;
- qWarning() << "[ViewFinderGL]:"
- << "format not supported.";
- break;
- };
-
- return ret;
-}
-
-void ViewFinderGL::selectColorSpace(const libcamera::ColorSpace &colorSpace)
-{
- std::array<double, 9> yuv2rgb;
-
- /* OpenGL stores arrays in column-major order. */
- switch (colorSpace.ycbcrEncoding) {
- case libcamera::ColorSpace::YcbcrEncoding::None:
- default:
- yuv2rgb = {
- 1.0000, 0.0000, 0.0000,
- 0.0000, 1.0000, 0.0000,
- 0.0000, 0.0000, 1.0000,
- };
- break;
-
- case libcamera::ColorSpace::YcbcrEncoding::Rec601:
- yuv2rgb = {
- 1.0000, 1.0000, 1.0000,
- 0.0000, -0.3441, 1.7720,
- 1.4020, -0.7141, 0.0000,
- };
- break;
-
- case libcamera::ColorSpace::YcbcrEncoding::Rec709:
- yuv2rgb = {
- 1.0000, 1.0000, 1.0000,
- 0.0000, -0.1873, 1.8856,
- 1.5748, -0.4681, 0.0000,
- };
- break;
-
- case libcamera::ColorSpace::YcbcrEncoding::Rec2020:
- yuv2rgb = {
- 1.0000, 1.0000, 1.0000,
- 0.0000, -0.1646, 1.8814,
- 1.4746, -0.5714, 0.0000,
- };
- break;
- }
-
- double offset;
-
- switch (colorSpace.range) {
- case libcamera::ColorSpace::Range::Full:
- default:
- offset = 0.0;
- break;
-
- case libcamera::ColorSpace::Range::Limited:
- offset = 16.0;
-
- for (unsigned int i = 0; i < 3; ++i)
- yuv2rgb[i] *= 255.0 / 219.0;
- for (unsigned int i = 4; i < 9; ++i)
- yuv2rgb[i] *= 255.0 / 224.0;
- break;
- }
-
- QStringList matrix;
-
- for (double coeff : yuv2rgb)
- matrix.append(QString::number(coeff, 'f'));
-
- fragmentShaderDefines_.append("#define YUV2RGB_MATRIX " + matrix.join(", "));
- fragmentShaderDefines_.append(QString("#define YUV2RGB_Y_OFFSET %1")
- .arg(offset, 0, 'f', 1));
-}
-
-bool ViewFinderGL::createVertexShader()
-{
- /* Create Vertex Shader */
- vertexShader_ = std::make_unique<QOpenGLShader>(QOpenGLShader::Vertex, this);
-
- /* Compile the vertex shader */
- if (!vertexShader_->compileSourceFile(vertexShaderFile_)) {
- qWarning() << "[ViewFinderGL]:" << vertexShader_->log();
- return false;
- }
-
- shaderProgram_.addShader(vertexShader_.get());
- return true;
-}
-
-bool ViewFinderGL::createFragmentShader()
-{
- int attributeVertex;
- int attributeTexture;
-
- /*
- * Create the fragment shader, compile it, and add it to the shader
- * program. The #define macros stored in fragmentShaderDefines_, if
- * any, are prepended to the source code.
- */
- fragmentShader_ = std::make_unique<QOpenGLShader>(QOpenGLShader::Fragment, this);
-
- QFile file(fragmentShaderFile_);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning() << "Shader" << fragmentShaderFile_ << "not found";
- return false;
- }
-
- QString defines = fragmentShaderDefines_.join('\n') + "\n";
- QByteArray src = file.readAll();
- src.prepend(defines.toUtf8());
-
- if (!fragmentShader_->compileSourceCode(src)) {
- qWarning() << "[ViewFinderGL]:" << fragmentShader_->log();
- return false;
- }
-
- shaderProgram_.addShader(fragmentShader_.get());
-
- /* Link shader pipeline */
- if (!shaderProgram_.link()) {
- qWarning() << "[ViewFinderGL]:" << shaderProgram_.log();
- close();
- }
-
- /* Bind shader pipeline for use */
- if (!shaderProgram_.bind()) {
- qWarning() << "[ViewFinderGL]:" << shaderProgram_.log();
- close();
- }
-
- attributeVertex = shaderProgram_.attributeLocation("vertexIn");
- attributeTexture = shaderProgram_.attributeLocation("textureIn");
-
- shaderProgram_.enableAttributeArray(attributeVertex);
- shaderProgram_.setAttributeBuffer(attributeVertex,
- GL_FLOAT,
- 0,
- 2,
- 2 * sizeof(GLfloat));
-
- shaderProgram_.enableAttributeArray(attributeTexture);
- shaderProgram_.setAttributeBuffer(attributeTexture,
- GL_FLOAT,
- 8 * sizeof(GLfloat),
- 2,
- 2 * sizeof(GLfloat));
-
- textureUniformY_ = shaderProgram_.uniformLocation("tex_y");
- textureUniformU_ = shaderProgram_.uniformLocation("tex_u");
- textureUniformV_ = shaderProgram_.uniformLocation("tex_v");
- textureUniformStep_ = shaderProgram_.uniformLocation("tex_step");
- textureUniformSize_ = shaderProgram_.uniformLocation("tex_size");
- textureUniformStrideFactor_ = shaderProgram_.uniformLocation("stride_factor");
- textureUniformBayerFirstRed_ = shaderProgram_.uniformLocation("tex_bayer_first_red");
-
- /* Create the textures. */
- for (std::unique_ptr<QOpenGLTexture> &texture : textures_) {
- if (texture)
- continue;
-
- texture = std::make_unique<QOpenGLTexture>(QOpenGLTexture::Target2D);
- texture->create();
- }
-
- return true;
-}
-
-void ViewFinderGL::configureTexture(QOpenGLTexture &texture)
-{
- glBindTexture(GL_TEXTURE_2D, texture.textureId());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- textureMinMagFilters_);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- textureMinMagFilters_);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-void ViewFinderGL::removeShader()
-{
- if (shaderProgram_.isLinked()) {
- shaderProgram_.release();
- shaderProgram_.removeAllShaders();
- }
-}
-
-void ViewFinderGL::initializeGL()
-{
- initializeOpenGLFunctions();
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
-
- static const GLfloat coordinates[2][4][2]{
- {
- /* Vertex coordinates */
- { -1.0f, -1.0f },
- { -1.0f, +1.0f },
- { +1.0f, +1.0f },
- { +1.0f, -1.0f },
- },
- {
- /* Texture coordinates */
- { 0.0f, 1.0f },
- { 0.0f, 0.0f },
- { 1.0f, 0.0f },
- { 1.0f, 1.0f },
- },
- };
-
- vertexBuffer_.create();
- vertexBuffer_.bind();
- vertexBuffer_.allocate(coordinates, sizeof(coordinates));
-
- /* Create Vertex Shader */
- if (!createVertexShader())
- qWarning() << "[ViewFinderGL]: create vertex shader failed.";
-
- glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
-}
-
-void ViewFinderGL::doRender()
-{
- /* Stride of the first plane, in pixels. */
- unsigned int stridePixels;
-
- switch (format_) {
- case libcamera::formats::NV12:
- case libcamera::formats::NV21:
- case libcamera::formats::NV16:
- case libcamera::formats::NV61:
- case libcamera::formats::NV24:
- case libcamera::formats::NV42:
- /* Activate texture Y */
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_,
- size_.height(),
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- /* Activate texture UV/VU */
- glActiveTexture(GL_TEXTURE1);
- configureTexture(*textures_[1]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE_ALPHA,
- stride_ / horzSubSample_,
- size_.height() / vertSubSample_,
- 0,
- GL_LUMINANCE_ALPHA,
- GL_UNSIGNED_BYTE,
- image_->data(1).data());
- shaderProgram_.setUniformValue(textureUniformU_, 1);
-
- stridePixels = stride_;
- break;
-
- case libcamera::formats::YUV420:
- /* Activate texture Y */
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_,
- size_.height(),
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- /* Activate texture U */
- glActiveTexture(GL_TEXTURE1);
- configureTexture(*textures_[1]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_ / horzSubSample_,
- size_.height() / vertSubSample_,
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(1).data());
- shaderProgram_.setUniformValue(textureUniformU_, 1);
-
- /* Activate texture V */
- glActiveTexture(GL_TEXTURE2);
- configureTexture(*textures_[2]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_ / horzSubSample_,
- size_.height() / vertSubSample_,
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(2).data());
- shaderProgram_.setUniformValue(textureUniformV_, 2);
-
- stridePixels = stride_;
- break;
-
- case libcamera::formats::YVU420:
- /* Activate texture Y */
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_,
- size_.height(),
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- /* Activate texture V */
- glActiveTexture(GL_TEXTURE2);
- configureTexture(*textures_[2]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_ / horzSubSample_,
- size_.height() / vertSubSample_,
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(1).data());
- shaderProgram_.setUniformValue(textureUniformV_, 2);
-
- /* Activate texture U */
- glActiveTexture(GL_TEXTURE1);
- configureTexture(*textures_[1]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_ / horzSubSample_,
- size_.height() / vertSubSample_,
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(2).data());
- shaderProgram_.setUniformValue(textureUniformU_, 1);
-
- stridePixels = stride_;
- break;
-
- case libcamera::formats::UYVY:
- case libcamera::formats::VYUY:
- case libcamera::formats::YUYV:
- case libcamera::formats::YVYU:
- /*
- * Packed YUV formats are stored in a RGBA texture to match the
- * OpenGL texel size with the 4 bytes repeating pattern in YUV.
- * The texture width is thus half of the image_ with.
- */
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- stride_ / 4,
- size_.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- /*
- * The shader needs the step between two texture pixels in the
- * horizontal direction, expressed in texture coordinate units
- * ([0, 1]). There are exactly width - 1 steps between the
- * leftmost and rightmost texels.
- */
- shaderProgram_.setUniformValue(textureUniformStep_,
- 1.0f / (size_.width() / 2 - 1),
- 1.0f /* not used */);
-
- stridePixels = stride_ / 2;
- break;
-
- case libcamera::formats::ABGR8888:
- case libcamera::formats::ARGB8888:
- case libcamera::formats::BGRA8888:
- case libcamera::formats::RGBA8888:
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGBA,
- stride_ / 4,
- size_.height(),
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- stridePixels = stride_ / 4;
- break;
-
- case libcamera::formats::BGR888:
- case libcamera::formats::RGB888:
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_RGB,
- stride_ / 3,
- size_.height(),
- 0,
- GL_RGB,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
-
- stridePixels = stride_ / 3;
- break;
-
- case libcamera::formats::SBGGR8:
- case libcamera::formats::SGBRG8:
- case libcamera::formats::SGRBG8:
- case libcamera::formats::SRGGB8:
- case libcamera::formats::SBGGR10_CSI2P:
- case libcamera::formats::SGBRG10_CSI2P:
- case libcamera::formats::SGRBG10_CSI2P:
- case libcamera::formats::SRGGB10_CSI2P:
- case libcamera::formats::SBGGR12_CSI2P:
- case libcamera::formats::SGBRG12_CSI2P:
- case libcamera::formats::SGRBG12_CSI2P:
- case libcamera::formats::SRGGB12_CSI2P:
- /*
- * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats
- * are stored in a GL_LUMINANCE texture. The texture width is
- * equal to the stride.
- */
- glActiveTexture(GL_TEXTURE0);
- configureTexture(*textures_[0]);
- glTexImage2D(GL_TEXTURE_2D,
- 0,
- GL_LUMINANCE,
- stride_,
- size_.height(),
- 0,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- image_->data(0).data());
- shaderProgram_.setUniformValue(textureUniformY_, 0);
- shaderProgram_.setUniformValue(textureUniformBayerFirstRed_,
- firstRed_);
- shaderProgram_.setUniformValue(textureUniformSize_,
- size_.width(), /* in pixels */
- size_.height());
- shaderProgram_.setUniformValue(textureUniformStep_,
- 1.0f / (stride_ - 1),
- 1.0f / (size_.height() - 1));
-
- /*
- * The stride is already taken into account in the shaders, set
- * the generic stride factor to 1.0.
- */
- stridePixels = size_.width();
- break;
-
- default:
- stridePixels = size_.width();
- break;
- };
-
- /*
- * Compute the stride factor for the vertex shader, to map the
- * horizontal texture coordinate range [0.0, 1.0] to the active portion
- * of the image.
- */
- shaderProgram_.setUniformValue(textureUniformStrideFactor_,
- static_cast<float>(size_.width() - 1) /
- (stridePixels - 1));
-}
-
-void ViewFinderGL::paintGL()
-{
- if (!fragmentShader_)
- if (!createFragmentShader()) {
- qWarning() << "[ViewFinderGL]:"
- << "create fragment shader failed.";
- }
-
- if (image_) {
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- doRender();
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-}
-
-void ViewFinderGL::resizeGL(int w, int h)
-{
- glViewport(0, 0, w, h);
-}
-
-QSize ViewFinderGL::sizeHint() const
-{
- return size_.isValid() ? size_ : QSize(640, 480);
-}