From patchwork Wed Jan 13 13:08:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 10852 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 83109BD80C for ; Wed, 13 Jan 2021 13:08:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4ADCC680DB; Wed, 13 Jan 2021 14:08:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="OEJYQuTp"; dkim-atps=neutral Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0BE3C6054E for ; Wed, 13 Jan 2021 14:08:53 +0100 (CET) Received: by mail-lj1-x235.google.com with SMTP id u11so2425064ljo.13 for ; Wed, 13 Jan 2021 05:08:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=olzp5+f2p8vLdXof0aF2IDvl6Y/vw19jdOA72WR6mWo=; b=OEJYQuTp2GKc0FdKoPLu3wTSzulGLN6ZwhCGcaK1I4j+EnHehdHkYVl76S8mGqWeIu lurLj5u6J9vrlTMV69fWFWLzqMze9QHvd0xmIVJd70rwVLQouR6TCadAJ8x71aXsaVNU /BEeHnd8p5A1bavz/O/FQlCU7Mb4abzfiNoGuUwcAOCplB1SdKt+lw+K73w+wy5iqzb0 nluhMV3w2kICTyIg1eC2+bYM+w4XOyJqFrQ6O9CoJdFOF0XpmKEZ+oO0Bg13qAdnYDPu +CkiqHiDHvXYfss0ucD5OP6jRPYZBz4GOc+ffiGY4lwWvOtS47awuw9OBs4Y8I6oP1j0 l+qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=olzp5+f2p8vLdXof0aF2IDvl6Y/vw19jdOA72WR6mWo=; b=bbFZWNxcRGVMpd8xXqIapJ5wnTJgWh7gHpMJMrmY7nQM5AMs2tq8gN9F1yR2PAIU0G x/GS6qNFJUL8zHKgBusvFaZUqP07jvEqDbrM7uXYs6HDWC82BSisTgyqWuy8ry5Zwh0n a9ym4nuLN79sjTrzcDWXJTH9W02qfjovDPIR0ip5fTmrW1l58w0TdKigdaZiCE3s4DVS qZZB+IKTMOkTNR7citrFhPa/5fMxvEoLlTIfWyEIPx4zwdW42y5cMNsawCZj06q+szy/ yfd6NXxAPFPVTkr4W2HGDk2Gf041wPHlqm/fUspIOh8TzECaeT+TX2ZqwOywEMda5s99 dLIQ== X-Gm-Message-State: AOAM530bVpllbJR/FtdxlIJr81USja93aWgi1eJYEewcI8QVIKO4RoAS nPXq12y3VWOnEKfWGrOc+zSQL9g4crbqLg== X-Google-Smtp-Source: ABdhPJyw2pOq2YHUOdOnffBEOzr50QW8UUlxFpFBjHQ0pzhxvx7nRDqBsL9ZwRo9JWzhkAEtdan/IQ== X-Received: by 2002:a05:651c:118b:: with SMTP id w11mr895257ljo.402.1610543332045; Wed, 13 Jan 2021 05:08:52 -0800 (PST) Received: from localhost.localdomain ([85.249.43.69]) by smtp.googlemail.com with ESMTPSA id d2sm179477ljg.39.2021.01.13.05.08.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 05:08:51 -0800 (PST) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Wed, 13 Jan 2021 16:08:29 +0300 Message-Id: <20210113130832.15549-2-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210113130832.15549-1-andrey.konovalov@linaro.org> References: <20210113130832.15549-1-andrey.konovalov@linaro.org> Subject: [libcamera-devel] [PATCH 1/4] qcam: viewfinder_gl: change uniform float tex_stepx to vec2 tex_step X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: morgan@casual-effects.com MIME-Version: 1.0 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In preparation to extend the supported formats, extend the tex_stepx uniform to cover the steps between texels in both horizontal and vertical directions. Signed-off-by: Andrey Konovalov --- src/qcam/assets/shader/YUV_packed.frag | 8 ++++---- src/qcam/viewfinder_gl.cpp | 7 ++++--- src/qcam/viewfinder_gl.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/qcam/assets/shader/YUV_packed.frag b/src/qcam/assets/shader/YUV_packed.frag index 224dfafe..d6efd4ce 100644 --- a/src/qcam/assets/shader/YUV_packed.frag +++ b/src/qcam/assets/shader/YUV_packed.frag @@ -12,7 +12,7 @@ precision mediump float; varying vec2 textureOut; uniform sampler2D tex_y; -uniform float tex_stepx; +uniform vec2 tex_step; void main(void) { @@ -49,10 +49,10 @@ void main(void) * a = fract(x) * 2 - 1 if fract(x) >= 0.5 */ vec2 pos = textureOut; - float f_x = fract(pos.x / tex_stepx); + float f_x = fract(pos.x / tex_step.x); - vec4 left = texture2D(tex_y, vec2(pos.x - f_x * tex_stepx, pos.y)); - vec4 right = texture2D(tex_y, vec2(pos.x + (1.0 - f_x) * tex_stepx , pos.y)); + vec4 left = texture2D(tex_y, vec2(pos.x - f_x * tex_step.x, pos.y)); + vec4 right = texture2D(tex_y, vec2(pos.x + (1.0 - f_x) * tex_step.x , pos.y)); #if defined(YUV_PATTERN_UYVY) float y_left = mix(left.g, left.a, f_x * 2.0); diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index 5d9b442e..ff719418 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -289,7 +289,7 @@ bool ViewFinderGL::createFragmentShader() textureUniformY_ = shaderProgram_.uniformLocation("tex_y"); textureUniformU_ = shaderProgram_.uniformLocation("tex_u"); textureUniformV_ = shaderProgram_.uniformLocation("tex_v"); - textureUniformStepX_ = shaderProgram_.uniformLocation("tex_stepx"); + textureUniformStep_ = shaderProgram_.uniformLocation("tex_step"); /* Create the textures. */ for (std::unique_ptr &texture : textures_) { @@ -508,8 +508,9 @@ void ViewFinderGL::doRender() * ([0, 1]). There are exactly width - 1 steps between the * leftmost and rightmost texels. */ - shaderProgram_.setUniformValue(textureUniformStepX_, - 1.0f / (size_.width() / 2 - 1)); + shaderProgram_.setUniformValue(textureUniformStep_, + 1.0f / (size_.width() / 2 - 1), + 1.0f /* not used */); break; case libcamera::formats::ABGR8888: diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h index 150fa4ae..1b1faa91 100644 --- a/src/qcam/viewfinder_gl.h +++ b/src/qcam/viewfinder_gl.h @@ -85,7 +85,7 @@ private: GLuint textureUniformU_; GLuint textureUniformV_; GLuint textureUniformY_; - GLuint textureUniformStepX_; + GLuint textureUniformStep_; unsigned int horzSubSample_; unsigned int vertSubSample_; From patchwork Wed Jan 13 13:08:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 10853 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 1B179BD80C for ; Wed, 13 Jan 2021 13:08:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DD4D8680E1; Wed, 13 Jan 2021 14:08:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="FPpPfBNc"; dkim-atps=neutral Received: from mail-lf1-x129.google.com (mail-lf1-x129.google.com [IPv6:2a00:1450:4864:20::129]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E8616054E for ; Wed, 13 Jan 2021 14:08:56 +0100 (CET) Received: by mail-lf1-x129.google.com with SMTP id m12so2645359lfo.7 for ; Wed, 13 Jan 2021 05:08:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BpmDhIQhpX7hcjrbtD7qJnZrzb7EHJzsq72n+mHUsG4=; b=FPpPfBNcMp640yavsQquihNj95Fn2654plROBHq9a/Y5rlIyKX++hAIsxNY0FHNRGY okPw0KFfllZIc1QaFsY+gUA8XI43pLfHx0NF/fUaXoD0EYshLDNpVs+VUnmEeosDcnIl 5Bnl9A80PyQT4KDYqn2xWdpJXP104Y/2KUfTMukcc4yaaGQ2b/FQa/ys3YkML2WB4mYO gTpHaP575Ge/vjlAHTFJ5is3VuiQ2CTCEBfxuNC2I8cZA9PemL4E57/KVPnonilsnczc Oeu1muA9XwczmxVld6I3MH2RhGcA8srhXYmlmeVavqJYz6Dgb5g+iMU9WQE50uxRombF h3yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BpmDhIQhpX7hcjrbtD7qJnZrzb7EHJzsq72n+mHUsG4=; b=UlEEY1ZXJ/yUS/6qonGG7m4i+ATVd9MIjWV+tXRbG5Qr5QwM/s0IleJfw4tffTSbV2 jgsGh3bptTqFoosB4db2yWyVvhoD9sh9RHOGHR1qzKsCj6CMjrs9VzMS9/guVxPzJqnv FEUcF0nIz4xmd8f8GhuO5ECUtorlQ534d8LMt9EgD8HeL1FOz2HbITO7I3fEIDLSvQQ6 lMnz1TxU/ueJQay8sDulllJrNWExIRYHIdiyRwJWGPgwI6kM+k/lAJtNrpWNjDtYR3iL dZnRw+rqh0KLf6OBhToLns6o1tb6laiDTGL/BrelffbFzH56bcaMsJP3G/u1tikU8COy puOw== X-Gm-Message-State: AOAM532j/8NMYW4XVDv6CIEvQ9LZ9E9LFD0XpgKHcn/fbEr98/Dm6lGP YV4MJg6n/MminCxpmKe4vTCFADQMLawFjQ== X-Google-Smtp-Source: ABdhPJw4mI5WTwQJDhNuknvCzos7lGYgAr9r8NTBCVGVWkBZS/7afBiaKf9l6n2dFk3lr9KhrBVQEw== X-Received: by 2002:a19:4f51:: with SMTP id a17mr915350lfk.522.1610543335067; Wed, 13 Jan 2021 05:08:55 -0800 (PST) Received: from localhost.localdomain ([85.249.43.69]) by smtp.googlemail.com with ESMTPSA id d2sm179477ljg.39.2021.01.13.05.08.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 05:08:54 -0800 (PST) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Wed, 13 Jan 2021 16:08:30 +0300 Message-Id: <20210113130832.15549-3-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210113130832.15549-1-andrey.konovalov@linaro.org> References: <20210113130832.15549-1-andrey.konovalov@linaro.org> Subject: [libcamera-devel] [PATCH 2/4] qcam: viewfinder_gl: Add shader to render packed RAW10 formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: morgan@casual-effects.com MIME-Version: 1.0 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The shader supports all 4 packed RAW10 variants. Simple bi-linear filtering is implemented. The 2 LS bits of the 10-bit colour values are dropped as the RGBA format we convert into has only 8 bits per colour. The texture coordinates passed to the fragment shader are ajusted to point to the nearest pixel in the image. This prevents artifacts when the image is scaled from the frame resolution to the window size. Signed-off-by: Andrey Konovalov --- src/qcam/assets/shader/bayer_1x_packed.frag | 174 ++++++++++++++++++++ src/qcam/assets/shader/shaders.qrc | 1 + src/qcam/viewfinder_gl.cpp | 77 ++++++++- src/qcam/viewfinder_gl.h | 6 + 4 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 src/qcam/assets/shader/bayer_1x_packed.frag diff --git a/src/qcam/assets/shader/bayer_1x_packed.frag b/src/qcam/assets/shader/bayer_1x_packed.frag new file mode 100644 index 00000000..0a87c6db --- /dev/null +++ b/src/qcam/assets/shader/bayer_1x_packed.frag @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Based on the code from http://jgt.akpeters.com/papers/McGuire08/ + * + * Efficient, High-Quality Bayer Demosaic Filtering on GPUs + * + * Morgan McGuire + * + * This paper appears in issue Volume 13, Number 4. + * --------------------------------------------------------- + * Copyright (c) 2008, Morgan McGuire. All rights reserved. + * + * + * Modified by Linaro Ltd for 10/12-bit packed vs 8-bit raw Bayer format, + * and for simpler demosaic algorithm. + * Copyright (C) 2020, Linaro + * + * bayer_1x_packed.frag - Fragment shader code for raw Bayer 10-bit and 12-bit + * packed formats + */ + +#ifdef GL_ES +precision mediump float; +#endif + +varying vec2 textureOut; + +/* the texture size: tex_size.xy is in bytes, tex_size.zw is in pixels */ +uniform vec4 tex_size; +uniform vec2 tex_step; +uniform vec2 tex_bayer_first_red; + +uniform sampler2D tex_raw; + +void main(void) +{ + vec3 rgb; + + /* + * center.xy holds the coordinates of the pixel being sampled + * on the [0, 1] range. + * center.zw holds the coordinates of the pixel being sampled + * on the [0, width/height-1] range. + */ + vec4 center; + /* + * x-positions of the adjacent pixels on the [0, 1] range. + */ + vec2 xcoords; + /* + * y-positions of the adjacent pixels on the [0, 1] range. + */ + vec2 ycoords; + + /* + * The coordinates passed to the shader in textureOut may point + * to a place in between the pixels if the viewfinder window is scaled + * from the original captured frame size. Align them to the nearest + * pixel. + */ + center.zw = floor(textureOut * tex_size.zw); + center.y = center.w; + /* + * Add a small number (a few mantissa's LSBs) to avoid float + * representation issues. Maybe paranoic. + */ + center.x = BPP_X * center.z + 0.02; + + const float threshold_l = 0.127 /* fract(BPP_X) * 0.5 + 0.02 */; + const float threshold_h = 0.625 /* 1.0 - fract(BPP_X) * 1.5 */; + + float fract_x = fract(center.x); + /* + * The below floor() call ensures that center.x points + * at one of the bytes representing the 8 higher bits of + * the pixel value, not at the byte containing the LS bits + * of the group of the pixels. + */ + center.x = floor(center.x); + center.xy *= tex_step; + + xcoords = center.x + vec2(-tex_step.x, tex_step.x); + ycoords = center.y + vec2(-tex_step.y, tex_step.y); + /* + * If xcoords[0] points at the byte containing the LS bits + * of the previous group of the pixels, move xcoords[0] one + * byte back. + */ + xcoords[0] += (fract_x < threshold_l) ? -tex_step.x : 0.0; + /* + * If xcoords[1] points at the byte containing the LS bits + * of the current group of the pixels, move xcoords[1] one + * byte forward. + */ + xcoords[1] += (fract_x > threshold_h) ? tex_step.x : 0.0; + + vec2 alternate = mod(center.zw + tex_bayer_first_red, 2.0); + bool even_col = alternate.x < 1.0; + bool even_raw = alternate.y < 1.0; + + /* + * We need to sample the central pixel and the ones with offset + * of -1 to +1 pixel in both X and Y directions. Let's name these + * pixels as below, where C is the central pixel: + * +----+----+----+----+ + * | \ x| | | | + * |y \ | -1 | 0 | +1 | + * +----+----+----+----+ + * | +1 | D2 | A1 | D3 | + * +----+----+----+----+ + * | 0 | B0 | C | B1 | + * +----+----+----+----+ + * | -1 | D0 | A0 | D1 | + * +----+----+----+----+ + * In the below equations (0,-1).r means "r component of the texel + * shifted by -tex_step.y from the center.xy one" etc. + * In the even raw / even column (EE) case the colour values are: + * R = C = (0,0).r, + * G = (A0 + A1 + B0 + B1) / 4.0 = + * ( (0,-1).r + (0,1).r + (-1,0).r + (1,0).r ) / 4.0, + * B = (D0 + D1 + D2 + D3) / 4.0 = + * ( (-1,-1).r + (1,-1).r + (-1,1).r + (1,1).r ) / 4.0 + * For even raw / odd column (EO): + * R = (B0 + B1) / 2.0 = ( (-1,0).r + (1,0).r ) / 2.0, + * G = C = (0,0).r, + * B = (A0 + A1) / 2.0 = ( (0,-1).r + (0,1).r ) / 2.0 + * For odd raw / even column (OE): + * R = (A0 + A1) / 2.0 = ( (0,-1).r + (0,1).r ) / 2.0, + * G = C = (0,0).r, + * B = (B0 + B1) / 2.0 = ( (-1,0).r + (1,0).r ) / 2.0 + * For odd raw / odd column (OO): + * R = (D0 + D1 + D2 + D3) / 4.0 = + * ( (-1,-1).r + (1,-1).r + (-1,1).r + (1,1).r ) / 4.0, + * G = (A0 + A1 + B0 + B1) / 4.0 = + * ( (0,-1).r + (0,1).r + (-1,0).r + (1,0).r ) / 4.0, + * B = C = (0,0).r + */ + + /* + * Fetch the values and precalculate the terms: + * patterns.x = (A0 + A1) / 2.0 + * patterns.y = (B0 + B1) / 2.0 + * patterns.z = (A0 + A1 + B0 + B1) / 4.0 + * patterns.w = (D0 + D1 + D2 + D3) / 4.0 + */ + #define fetch(x, y) texture2D(tex_raw, vec2(x, y)).r + + float C = texture2D(tex_raw, center.xy).r; + vec4 patterns = vec4( + fetch(center.x, ycoords[0]), /* A0: (0,-1) */ + fetch(xcoords[0], center.y), /* B0: (-1,0) */ + fetch(xcoords[0], ycoords[0]), /* D0: (-1,-1) */ + fetch(xcoords[1], ycoords[0])); /* D1: (1,-1) */ + vec4 temp = vec4( + fetch(center.x, ycoords[1]), /* A1: (0,1) */ + fetch(xcoords[1], center.y), /* B1: (1,0) */ + fetch(xcoords[1], ycoords[1]), /* D3: (1,1) */ + fetch(xcoords[0], ycoords[1])); /* D2: (-1,1) */ + patterns = (patterns + temp) * 0.5; + /* .x = (A0 + A1) / 2.0, .y = (B0 + B1) / 2.0 */ + /* .z = (D0 + D3) / 2.0, .w = (D1 + D2) / 2.0 */ + patterns.w = (patterns.z + patterns.w) * 0.5; + patterns.z = (patterns.x + patterns.y) * 0.5; + + rgb = (even_col) ? + ((even_raw) ? + vec3(C, patterns.zw) : + vec3(patterns.x, C, patterns.y)) : + ((even_raw) ? + vec3(patterns.y, C, patterns.x) : + vec3(patterns.wz, C)); + + gl_FragColor = vec4(rgb, 1.0); +} diff --git a/src/qcam/assets/shader/shaders.qrc b/src/qcam/assets/shader/shaders.qrc index 8a8f9de1..d76d65c5 100644 --- a/src/qcam/assets/shader/shaders.qrc +++ b/src/qcam/assets/shader/shaders.qrc @@ -5,6 +5,7 @@ YUV_2_planes.frag YUV_3_planes.frag YUV_packed.frag + bayer_1x_packed.frag identity.vert diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index ff719418..b324d77f 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -36,6 +36,11 @@ static const QList supportedFormats{ libcamera::formats::RGBA8888, libcamera::formats::BGR888, libcamera::formats::RGB888, + /* Raw Bayer 10-bit packed */ + libcamera::formats::SBGGR10_CSI2P, + libcamera::formats::SGBRG10_CSI2P, + libcamera::formats::SGRBG10_CSI2P, + libcamera::formats::SRGGB10_CSI2P, }; ViewFinderGL::ViewFinderGL(QWidget *parent) @@ -114,6 +119,9 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) { bool ret = true; + /* Set min/mag filters to GL_LINEAR by default. */ + textureMinMagFilters_ = GL_LINEAR; + fragmentShaderDefines_.clear(); switch (format) { @@ -203,6 +211,34 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) fragmentShaderDefines_.append("#define RGB_PATTERN bgr"); fragmentShaderFile_ = ":RGB.frag"; break; + case libcamera::formats::SBGGR10_CSI2P: + firstRed_.setX(1.0); + firstRed_.setY(1.0); + fragmentShaderDefines_.append("#define BPP_X 1.25"); + 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 BPP_X 1.25"); + 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 BPP_X 1.25"); + 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 BPP_X 1.25"); + fragmentShaderFile_ = ":bayer_1x_packed.frag"; + textureMinMagFilters_ = GL_NEAREST; + break; default: ret = false; qWarning() << "[ViewFinderGL]:" @@ -290,6 +326,8 @@ bool ViewFinderGL::createFragmentShader() textureUniformU_ = shaderProgram_.uniformLocation("tex_u"); textureUniformV_ = shaderProgram_.uniformLocation("tex_v"); textureUniformStep_ = shaderProgram_.uniformLocation("tex_step"); + textureUniformSize_ = shaderProgram_.uniformLocation("tex_size"); + textureUniformBayerFirstRed_ = shaderProgram_.uniformLocation("tex_bayer_first_red"); /* Create the textures. */ for (std::unique_ptr &texture : textures_) { @@ -306,8 +344,10 @@ bool ViewFinderGL::createFragmentShader() void ViewFinderGL::configureTexture(QOpenGLTexture &texture) { glBindTexture(GL_TEXTURE_2D, texture.textureId()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + 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); } @@ -547,6 +587,39 @@ void ViewFinderGL::doRender() shaderProgram_.setUniformValue(textureUniformY_, 0); break; + case libcamera::formats::SBGGR10_CSI2P: + case libcamera::formats::SGBRG10_CSI2P: + case libcamera::formats::SGRBG10_CSI2P: + case libcamera::formats::SRGGB10_CSI2P: + /* + * Packed raw Bayer 10-bit formats are stored in GL_RED texture. + * The texture width is 10/8 of the image width. + * TODO: account for padding bytes at the end of the line. + */ + glActiveTexture(GL_TEXTURE0); + configureTexture(*textures_[0]); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RED, + size_.width() * 5 / 4, + size_.height(), + 0, + GL_RED, + GL_UNSIGNED_BYTE, + data_); + shaderProgram_.setUniformValue(textureUniformY_, 0); + shaderProgram_.setUniformValue(textureUniformBayerFirstRed_, + firstRed_); + shaderProgram_.setUniformValue(textureUniformSize_, + size_.width() * 5 / 4, + size_.height(), + size_.width(), + size_.height()); + shaderProgram_.setUniformValue(textureUniformStep_, + 1.0f / (size_.width() * 5 / 4 - 1), + 1.0f / (size_.height() - 1)); + break; + default: break; }; diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h index 1b1faa91..337718e3 100644 --- a/src/qcam/viewfinder_gl.h +++ b/src/qcam/viewfinder_gl.h @@ -81,13 +81,19 @@ private: /* Textures */ std::array, 3> textures_; + /* Common texture parameters */ + GLuint textureMinMagFilters_; /* YUV texture parameters */ GLuint textureUniformU_; GLuint textureUniformV_; GLuint textureUniformY_; + GLuint textureUniformSize_; GLuint textureUniformStep_; unsigned int horzSubSample_; unsigned int vertSubSample_; + /* Raw Bayer texture parameters */ + GLuint textureUniformBayerFirstRed_; + QPointF firstRed_; QMutex mutex_; /* Prevent concurrent access to image_ */ }; From patchwork Wed Jan 13 13:08:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 10854 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 73362BD80C for ; Wed, 13 Jan 2021 13:09:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 41678680D8; Wed, 13 Jan 2021 14:09:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XQT/3gBS"; dkim-atps=neutral Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 659386054E for ; Wed, 13 Jan 2021 14:08:59 +0100 (CET) Received: by mail-lf1-x135.google.com with SMTP id s26so2639248lfc.8 for ; Wed, 13 Jan 2021 05:08:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=veWN98fZcbakbj7dt4jyzAprw0las+6G3CgLk/aoTdY=; b=XQT/3gBSiBbzUppVRAn1Ov1/Us8bjxgmJdoJ16ZYNOGtaS33jzMosINuF88gwfbvRl cGxfRRuHL1VYu/4j3FC+1eBKTqwolaVqxTJMPHgpZ3YqJ/cMYv9RZf8qYx5LUiYT++N9 YUkbyKJSaiM0x6/mM8M3ZjDQ7C5hdjcEyqbl//elCLcCPXQU0+HxZMsTuwAVeqzNTTgT 3VYQfttgpRXdKhvc9JLxZKi/LOTzrblj1jDXqtPtSgJke7GP55WvJuX5XmPcxK+CXneK UWae6TCypiQglb4xPkwrs3ULLjfb+yTDrTPXfDTUaHkTDPFy4kvNQSR6o1Cqn3q9JPGt 9EuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=veWN98fZcbakbj7dt4jyzAprw0las+6G3CgLk/aoTdY=; b=KgbpXL8iyndy32VQykY/bSPKCeqbRrdOgewH1f7wDQ6YdktJ11vDtF9Gg3FyMtc+6l DIUVNZvCuDKAFB2NxXWAwVN2QcTCHapOK242yOFM0DY1jWgpVQ/UVYyu+VueZR5Tgk0+ b265RYQMETrtW533j7x0lH+uoqeaz/dl9hGBCTr0TMD0+jqZWgUpbdVj6x2CwDyMEgwf N9pIu1o+CvTc1QWeuEZw4X6DyV/ANT8wEKblf9sst5zbWq54Gkhv06eOvnC3aajTZVE1 FesUNeAl+ukjRk8/JUhkU1O9y6XXU2zH64Vcy8VZGoCX3iOK/9AkPEdgMOGnB1hLDkBv /BYw== X-Gm-Message-State: AOAM5313rePX+zmxhUD4IOjnBIbuv6im13frooDiQT8KuUYeFO6ROyzE M0B5eW05G4n0N0bKIheu+ePngIjEOc80fw== X-Google-Smtp-Source: ABdhPJxAaKjMxShOg+CM7ho0389jOL9sNIVoNZXi/3yVo+aIcHqWMBL2YqB1rXaVpt3nzhbC33fWmQ== X-Received: by 2002:a19:94f:: with SMTP id 76mr813380lfj.642.1610543338425; Wed, 13 Jan 2021 05:08:58 -0800 (PST) Received: from localhost.localdomain ([85.249.43.69]) by smtp.googlemail.com with ESMTPSA id d2sm179477ljg.39.2021.01.13.05.08.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 05:08:57 -0800 (PST) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Wed, 13 Jan 2021 16:08:31 +0300 Message-Id: <20210113130832.15549-4-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210113130832.15549-1-andrey.konovalov@linaro.org> References: <20210113130832.15549-1-andrey.konovalov@linaro.org> Subject: [libcamera-devel] [PATCH 3/4] qcam: viewfinder_gl: RAW10P: handle the padding bytes properly X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: morgan@casual-effects.com MIME-Version: 1.0 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The texture size must account for the padding bytes which may be present at the end of the lines in the frame. Signed-off-by: Andrey Konovalov --- src/qcam/viewfinder_gl.cpp | 11 +++++++---- src/qcam/viewfinder_gl.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index b324d77f..9db536a6 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -111,6 +111,10 @@ void ViewFinderGL::render(libcamera::FrameBuffer *buffer, MappedBuffer *map) renderComplete(buffer_); data_ = static_cast(map->memory); + /* + * \todo Get the stride from the buffer instead of computing it naively + */ + stride_ = buffer->metadata().planes[0].bytesused / size_.height(); update(); buffer_ = buffer; } @@ -594,14 +598,13 @@ void ViewFinderGL::doRender() /* * Packed raw Bayer 10-bit formats are stored in GL_RED texture. * The texture width is 10/8 of the image width. - * TODO: account for padding bytes at the end of the line. */ glActiveTexture(GL_TEXTURE0); configureTexture(*textures_[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, - size_.width() * 5 / 4, + stride_, size_.height(), 0, GL_RED, @@ -611,12 +614,12 @@ void ViewFinderGL::doRender() shaderProgram_.setUniformValue(textureUniformBayerFirstRed_, firstRed_); shaderProgram_.setUniformValue(textureUniformSize_, - size_.width() * 5 / 4, + stride_, size_.height(), size_.width(), size_.height()); shaderProgram_.setUniformValue(textureUniformStep_, - 1.0f / (size_.width() * 5 / 4 - 1), + 1.0f / (stride_ - 1), 1.0f / (size_.height() - 1)); break; diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h index 337718e3..49f8364a 100644 --- a/src/qcam/viewfinder_gl.h +++ b/src/qcam/viewfinder_gl.h @@ -66,6 +66,7 @@ private: libcamera::FrameBuffer *buffer_; libcamera::PixelFormat format_; QSize size_; + int stride_; unsigned char *data_; /* Shaders */ From patchwork Wed Jan 13 13:08:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 10855 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 00F83BD80C for ; Wed, 13 Jan 2021 13:09:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C1546680E4; Wed, 13 Jan 2021 14:09:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ncc5HYkp"; dkim-atps=neutral Received: from mail-lf1-x129.google.com (mail-lf1-x129.google.com [IPv6:2a00:1450:4864:20::129]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 02BD0680D5 for ; Wed, 13 Jan 2021 14:09:03 +0100 (CET) Received: by mail-lf1-x129.google.com with SMTP id m12so2645886lfo.7 for ; Wed, 13 Jan 2021 05:09:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vfbBToVN87uQ5A/29HWO7lvbJuMk/InA3sQYu3SoI5Q=; b=ncc5HYkp7gXsRsPosvUqip7GDTzJAaSNfCd8EsivnCUai2OuAuPoYVP3SQzzaWFWAs g+bYv4oo2HyUQGpfG9abaRa6WExxMigTUNZSgkVS+0dUL7UywTG1clm7pXYuaeMIjdoT 1zI9bW0dsfK0rBXdLBzcp0AJFqF4X32svaLowqE4vhe9ZQQMngadRbFoqn0lchAVNopN VpP7nBCFxUBmIpWqFIpNKarMFP0Gb1KSoRviM4RywsCIHbZddo7U1RHzwhwpHxyK+OoV yNV2wMRP89Ohj5P1RODCBM1aA9ih6diV7YSDLtLcM2vRFYF/Qz9VMlASVzxZ/Bb8n7n1 xo5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vfbBToVN87uQ5A/29HWO7lvbJuMk/InA3sQYu3SoI5Q=; b=YYTgFqf02G/cav6piGZ8UuSxDFLMmCPMxeMq6O9G3cz7CTz1UB0UvKSEzX2HtXdth/ tKzzq+8R/4rHH15yPq5jOUSRFh2qNMLOZ5GbcwbVVHe4b+rkyNDqXxBSbdSxLsNkM4Of lnY6Dgi+PQn0hYogC/FKn6rxP7WmqMv7GJugy+l+Dyt80QAhXcFRV+5xwPXPnDo5wst6 sTojMi6ZkjRd9T/s3Yx6NxPCx8LPWKYOqlRzYJMdNbMOXNpBY52ZFNQzhywVsQvwpS3+ nluJPJlXyXx3RqKhpSM09ogzw30cXBWpkZCz3BCnckfQf8qlMEgqgVipoUzRbtN/YVrh GkKg== X-Gm-Message-State: AOAM533z4u85GsodfmadUbkMCeedgbecG0TW8RlQZ1Ur5dkndDxTGxU7 wHB44TzHaaImQbN6gp3GDiEyqHmyxldxdw== X-Google-Smtp-Source: ABdhPJwipTBw5QoWpei2ygAvXutG3vNmmIbxjjPX6U+unP02AQl1VHPnCbTDxMJO3GhPOPnMAqh50g== X-Received: by 2002:a05:6512:312b:: with SMTP id p11mr881591lfd.446.1610543341824; Wed, 13 Jan 2021 05:09:01 -0800 (PST) Received: from localhost.localdomain ([85.249.43.69]) by smtp.googlemail.com with ESMTPSA id d2sm179477ljg.39.2021.01.13.05.09.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 05:09:01 -0800 (PST) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Wed, 13 Jan 2021 16:08:32 +0300 Message-Id: <20210113130832.15549-5-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210113130832.15549-1-andrey.konovalov@linaro.org> References: <20210113130832.15549-1-andrey.konovalov@linaro.org> Subject: [libcamera-devel] [PATCH 4/4] qcam: viewfinder_gl: Add support for RAW12 packed formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: morgan@casual-effects.com MIME-Version: 1.0 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" All the four Bayer orders are supported. The 4 LS bits of the 12-bit colour values are dropped as the RGBA format we convert into has only 8 bits per colour. Signed-off-by: Andrey Konovalov --- src/qcam/assets/shader/bayer_1x_packed.frag | 43 ++++++++++++++--- src/qcam/viewfinder_gl.cpp | 53 +++++++++++++++++---- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/qcam/assets/shader/bayer_1x_packed.frag b/src/qcam/assets/shader/bayer_1x_packed.frag index 0a87c6db..d09c6fce 100644 --- a/src/qcam/assets/shader/bayer_1x_packed.frag +++ b/src/qcam/assets/shader/bayer_1x_packed.frag @@ -23,6 +23,40 @@ precision mediump float; #endif +/* + * These constants are used to select the bytes containing the HS part of + * the pixel value: + * BPP - bytes per pixel, + * THRESHOLD_L = fract(BPP) * 0.5 + 0.02 + * THRESHOLD_H = 1.0 - fract(BPP) * 1.5 + 0.02 + * Let X is the x coordinate in the texture measured in bytes (so that the + * range is from 0 to (stride_-1)) aligned on the nearest pixel. + * E.g. for RAW10P: + * -------------+-------------------+-------------------+-- + * pixel No | 0 1 2 3 | 4 5 6 7 | ... + * -------------+-------------------+-------------------+-- + * byte offset | 0 1 2 3 4 | 5 6 7 8 9 | ... + * -------------+-------------------+-------------------+-- + * X | 0.0 1.25 2.5 3.75 | 5.0 6.25 7.5 8.75 | ... + * -------------+-------------------+-------------------+-- + * If fract(X) < THRESHOLD_L then the previous byte contains the LS + * bits of the pixel values and needs to be skipped. + * If fract(X) > THRESHOLD_H then the next byte contains the LS bits + * of the pixel values and needs to be skipped. + */ +#if defined(RAW10P) +#define BPP 1.25 +#define THRESHOLD_L 0.14 +#define THRESHOLD_H 0.64 +#elif defined(RAW12P) +#define BPP 1.5 +#define THRESHOLD_L 0.27 +#define THRESHOLD_H 0.27 +#else +#error Invalid raw format +#endif + + varying vec2 textureOut; /* the texture size: tex_size.xy is in bytes, tex_size.zw is in pixels */ @@ -64,10 +98,7 @@ void main(void) * Add a small number (a few mantissa's LSBs) to avoid float * representation issues. Maybe paranoic. */ - center.x = BPP_X * center.z + 0.02; - - const float threshold_l = 0.127 /* fract(BPP_X) * 0.5 + 0.02 */; - const float threshold_h = 0.625 /* 1.0 - fract(BPP_X) * 1.5 */; + center.x = BPP * center.z + 0.02; float fract_x = fract(center.x); /* @@ -86,13 +117,13 @@ void main(void) * of the previous group of the pixels, move xcoords[0] one * byte back. */ - xcoords[0] += (fract_x < threshold_l) ? -tex_step.x : 0.0; + xcoords[0] += (fract_x < THRESHOLD_L) ? -tex_step.x : 0.0; /* * If xcoords[1] points at the byte containing the LS bits * of the current group of the pixels, move xcoords[1] one * byte forward. */ - xcoords[1] += (fract_x > threshold_h) ? tex_step.x : 0.0; + xcoords[1] += (fract_x > THRESHOLD_H) ? tex_step.x : 0.0; vec2 alternate = mod(center.zw + tex_bayer_first_red, 2.0); bool even_col = alternate.x < 1.0; diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index 9db536a6..13ab31aa 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -41,6 +41,11 @@ static const QList supportedFormats{ 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) @@ -218,28 +223,56 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) case libcamera::formats::SBGGR10_CSI2P: firstRed_.setX(1.0); firstRed_.setY(1.0); - fragmentShaderDefines_.append("#define BPP_X 1.25"); + 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 BPP_X 1.25"); + 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 BPP_X 1.25"); + 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 BPP_X 1.25"); + 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; @@ -595,9 +628,13 @@ void ViewFinderGL::doRender() 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: /* - * Packed raw Bayer 10-bit formats are stored in GL_RED texture. - * The texture width is 10/8 of the image width. + * Packed raw Bayer 10-bit and 12-bit formats are stored in + * GL_RED texture. */ glActiveTexture(GL_TEXTURE0); configureTexture(*textures_[0]); @@ -614,9 +651,9 @@ void ViewFinderGL::doRender() shaderProgram_.setUniformValue(textureUniformBayerFirstRed_, firstRed_); shaderProgram_.setUniformValue(textureUniformSize_, - stride_, + stride_, /* width in bytes */ size_.height(), - size_.width(), + size_.width(), /* in pixels */ size_.height()); shaderProgram_.setUniformValue(textureUniformStep_, 1.0f / (stride_ - 1),