From patchwork Tue Jun 22 13:46:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12685 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 9D25BC321B for ; Tue, 22 Jun 2021 13:47:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5D7DA68932; Tue, 22 Jun 2021 15:47:07 +0200 (CEST) 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="q57uosxk"; dkim-atps=neutral Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5420460292 for ; Tue, 22 Jun 2021 15:47:06 +0200 (CEST) Received: by mail-lf1-x12f.google.com with SMTP id i13so36011980lfc.7 for ; Tue, 22 Jun 2021 06:47:06 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=1pJOzZy0cA+5PFPsdwnYX3JXmgdw7xElcszVRkfrj+Q=; b=q57uosxkI/AlctAjFGfdAaCiUOyAhwus5n4MIcX4wGGgYTh7zPnW8J1sd1u+htw9Dn rEwxi83XKWG6cbxv+997H3ehhX8uFru6yqBQS5Wt9tlbRI8iIS9shSNaXOwUqohZpxID SPglNG0a1YvglhNVj5wvX0o4Q8mBe1Eu/jhG22BxNYZ7H5fx3NpR7IyaPPxWQ4Xis/ej gIoLOYNvesOooLS4pxnfW9qFqoIzqJA6YFEokg+R87MKAT+eQ81m+1pzdv4b9ZdYODWG CPpOOyGhxQSass7tO+xfD12ew4qbx2DHoVVjy7Ut0mWX6yUrbgBI+JodstSveAPz1UKP 2w8g== 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:mime-version:content-transfer-encoding; bh=1pJOzZy0cA+5PFPsdwnYX3JXmgdw7xElcszVRkfrj+Q=; b=hv4HV5vyr56B59RtCBAX9ylkq05apvqHmMe/pxLgUZLZx4eBYnNfa/0Je8F1cXxlgm 2Oq8aYxeNaLP1P5dGBPOwauw4a/27zO57JkXL3QBA+HhQOrCqZ0pKhunH2ovlqVedS88 OR7KRuvPbiRt6XWE/EYYWGm7SEXBl0UZpYbx8SHDqXAXII2iq7jhzKd2kk9LQbz8nvIB o9n9w4zM3l+Z7lCzK4XCVt+6MmnZLog2kQZyaGBpteST0B7jyszs2P22nljxxArAlfSn Ra75+roJu2yLgLg94mbSr7SaB69vLrMUQrrZrofaO0gLwUSrLe2uhb+a4pWC2g/os/YX wJpw== X-Gm-Message-State: AOAM53094xO2faVJQFLf9v7n2uQ+yMHbufGOG1/gE0d4G5299ZMzyrbh r+/myOB0UuDwD/YKUrpLQelitiQk0ePC9A== X-Google-Smtp-Source: ABdhPJx0ZT/JkmN4xkFB18Y++4gMrgG/SW3L/HYBy23hGL+5MCSCVrOAAoVAhUk0a6e4Qo2CDWxUqA== X-Received: by 2002:ac2:5d69:: with SMTP id h9mr2834485lft.603.1624369625748; Tue, 22 Jun 2021 06:47:05 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:05 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:44 +0300 Message-Id: <20210622134652.1279260-2-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 1/9] 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 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 Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- 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 Tue Jun 22 13:46:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12686 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 F37ABC321B for ; Tue, 22 Jun 2021 13:47:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B20BF60294; Tue, 22 Jun 2021 15:47:09 +0200 (CEST) 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="fZE+e+IJ"; dkim-atps=neutral Received: from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com [IPv6:2a00:1450:4864:20::22e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B32BF60292 for ; Tue, 22 Jun 2021 15:47:08 +0200 (CEST) Received: by mail-lj1-x22e.google.com with SMTP id d13so30160639ljg.12 for ; Tue, 22 Jun 2021 06:47:08 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=2Dj5FDx+IVuIqaxo+q0MrvAfTbvMmkcbelmt5p+0kIs=; b=fZE+e+IJCBWaVMHVRqIDUYYTfHCog4SoH4GsKpVwNeUeEzekfD4yIoHV4c29l7BOmn 8U6Xy+BC4nPV9BmjhHCE4CqDLJBA3mi5oK8Uw4hHrTM6pH+C71QXQV8Y/iPYrupQquJ6 6twN4+9TbjJXGlc+/v1w/mT8AzVsm5ojToXJlDqk9U4KznKWkaAZ4fIoJxTU9rOHgibO bduOASUBsviCDWN7NkqWiXGZUBwj6lSDkfUUKgaW/kQ1bWrMyJb2hMtOH3SVvKmu0+HK Foec1QYOV4RftIxvO3vOFS04pNeToy0HZYJui7UePayyqrgiD8yuLxTDSuA9j6diSfVi 3tNA== 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:mime-version:content-transfer-encoding; bh=2Dj5FDx+IVuIqaxo+q0MrvAfTbvMmkcbelmt5p+0kIs=; b=aBiD0SE+Z2iSNJcKIyvTWdK/s2Bs5OSsaR+73gVt2a2C6kcjvMN/pmQutuOV8TA2Yr C7b+mGAHhfhZYXkJa8Yrnm3Z0xruT9iZBqLerVQQ2wZQQl6RJqBaQ2Tt96yDKDNdcn/2 6iqfY/Vr4GRl1vElA1RSnJ0ijPPdFmtTtKvhTcifL2nDrzFc/vdLng0fgi5C8nCYT6LC tAkDmJyU3cZ5XBlOyXYEbgtY+k4jb4PTNuBkHeb3LBQ0vHogQe1ESsO0huZ7GhhPaelL b0fqYbJc07zqj0FynU/eFq7PBWCu4y+gj0pWOJBvmaCzluZhLZxW8aEk5cfqFFpRk3GU qk5w== X-Gm-Message-State: AOAM531bi7+Ahmz0SJGzXzrvioOYWX5yKUQdT0wQR0MkIUlE3MOB7gGm WZFZoXMJcy8U+jBvtGxyyEXVLiM+QCpIVw== X-Google-Smtp-Source: ABdhPJyc39b6KWj7K2CILri5Cr+/nuSgkxVMd/YtL23NSXI7vU1z3aOjjTs2tIdGfERGPxq1NtowlA== X-Received: by 2002:a2e:a315:: with SMTP id l21mr3434735lje.158.1624369628054; Tue, 22 Jun 2021 06:47:08 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:07 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:45 +0300 Message-Id: <20210622134652.1279260-3-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 2/9] 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The shader supports all 4 packed RAW10 variants. Simple bi-linear Bayer interpolation of nearest pixels 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 Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- src/qcam/assets/shader/bayer_1x_packed.frag | 185 ++++++++++++++++++++ src/qcam/assets/shader/shaders.qrc | 1 + src/qcam/viewfinder_gl.cpp | 78 ++++++++- src/qcam/viewfinder_gl.h | 9 + 4 files changed, 271 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..fac8c3b8 --- /dev/null +++ b/src/qcam/assets/shader/bayer_1x_packed.frag @@ -0,0 +1,185 @@ +/* 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 in pixels */ +uniform vec2 tex_size; +uniform vec2 tex_step; +uniform vec2 tex_bayer_first_red; + +uniform sampler2D tex_y; + +void main(void) +{ + vec3 rgb; + + /* + * center_bytes holds the coordinates of the MS byte of the pixel + * being sampled on the [0, stride-1/height-1] range. + * center_pixel holds the coordinates of the pixel being sampled + * on the [0, width/height-1] range. + */ + vec2 center_bytes; + vec2 center_pixel; + + /* + * x- and y-positions of the adjacent pixels on the [0, 1] range. + */ + vec2 xcoords; + vec2 ycoords; + + /* + * The coordinates passed to the shader in textureOut may point + * to a place in between the pixels if the texture format doesn't + * match the image format. In particulr, MIPI packed raw Bayer + * formats don't have a matching texture format. + * In this case align the coordinates to the left nearest pixel + * by hand. + */ + center_pixel = floor(textureOut * tex_size); + center_bytes.y = center_pixel.y; + + /* + * Add a small number (a few mantissa's LSBs) to avoid float + * representation issues. Maybe paranoic. + */ + center_bytes.x = BPP_X * center_pixel.x + 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_bytes.x); + + /* + * The below floor() call ensures that center_bytes.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_bytes.x = floor(center_bytes.x); + center_bytes *= tex_step; + + xcoords = center_bytes.x + vec2(-tex_step.x, tex_step.x); + ycoords = center_bytes.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_pixel.xy + tex_bayer_first_red, 2.0); + bool even_col = alternate.x < 1.0; + bool even_row = 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_bytes one" etc. + * + * In the even row / 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 row / 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 row / 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 row / 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_y, vec2(x, y)).r + + float C = texture2D(tex_y, center_bytes).r; + vec4 patterns = vec4( + fetch(center_bytes.x, ycoords[0]), /* A0: (0,-1) */ + fetch(xcoords[0], center_bytes.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_bytes.x, ycoords[1]), /* A1: (0,1) */ + fetch(xcoords[1], center_bytes.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_row ? + vec3(C, patterns.zw) : + vec3(patterns.x, C, patterns.y)) : + (even_row ? + 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..ffbbc6c5 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) @@ -106,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; } @@ -114,6 +123,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 +215,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 +330,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 +348,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 +591,36 @@ 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 equal to the stride. + */ + glActiveTexture(GL_TEXTURE0); + configureTexture(*textures_[0]); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_RED, + stride_, + size_.height(), + 0, + GL_RED, + GL_UNSIGNED_BYTE, + 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)); + break; + default: break; }; diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h index 1b1faa91..508155b1 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_; + unsigned int stride_; unsigned char *data_; /* Shaders */ @@ -81,6 +82,9 @@ private: /* Textures */ std::array, 3> textures_; + /* Common texture parameters */ + GLuint textureMinMagFilters_; + /* YUV texture parameters */ GLuint textureUniformU_; GLuint textureUniformV_; @@ -89,6 +93,11 @@ private: unsigned int horzSubSample_; unsigned int vertSubSample_; + /* Raw Bayer texture parameters */ + GLuint textureUniformSize_; + GLuint textureUniformBayerFirstRed_; + QPointF firstRed_; + QMutex mutex_; /* Prevent concurrent access to image_ */ }; From patchwork Tue Jun 22 13:46:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12687 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 535E0C321B for ; Tue, 22 Jun 2021 13:47:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1447A68932; Tue, 22 Jun 2021 15:47:13 +0200 (CEST) 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="qTirR6cB"; dkim-atps=neutral Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9FE3560292 for ; Tue, 22 Jun 2021 15:47:11 +0200 (CEST) Received: by mail-lj1-x22d.google.com with SMTP id d13so30160909ljg.12 for ; Tue, 22 Jun 2021 06:47:11 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=226tjDItQWgHgHoqkprwEDWkO92QkxHcaVY0hI7V8f8=; b=qTirR6cBQT4rMqk+DB3gtanit6Gy/2lPGJ3XzMm2hYrH6qveNG1eoT5vuc8lqrLV2/ MQXZGZfe29002uXYgwC8/YvPcNJM4lvEeDp/mitDeeNPWJcX4rm7pQOW2+Rh1qMwJB8h W89wUwNVOEr50heerHwLppAndTchSySSRqnUCPOQUeuJyVNMo0KJH0Z7vh3q1Gzhl5QC bJDFkZAVZx915lpBlsFA0KTIxKTGC6vjaJROf7KVuhJS7X14U8sZggUZBjAiKNEDy7nQ qTQcACdE30l/ms6O/l0V0c+JJNzgnVUKXZQNpCFiWZhPU6wwwAVLmvvMET/9BEKugiuT H/tg== 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:mime-version:content-transfer-encoding; bh=226tjDItQWgHgHoqkprwEDWkO92QkxHcaVY0hI7V8f8=; b=swRPSoel2x2OkIB1WTWMEmiU/bMBW3bIOG861LHorkjmb0TWJdJFZS0Dx4wV0lVbLQ fMQv0WQnT64wfhkjpXkgz0bnuuaf2NaCAYCtscPYppbGr8m2oXYFcLOP3Yn1eGGVsCJu tJUgtBdL51gV7W7ZZ2d3CCT/B4OeIqNplAN5QgTsSqIFz1xWZ9xz0KOkbshTP+e3+7Bd meSkdoRxaiAqqYmtTFFHPiYlEzKgVBStQeyVKsGImmYeCbC6k1aN4PAuQ4zk2u/ciRhF 6JwlogylsFTuSokMzf4t5ZGrnZ7NZbKDs++vLzbu5S6P9GOfcNYP9tT8En1AbfT41aSj axWg== X-Gm-Message-State: AOAM530bgCRF+zMRC6eVy6o1X/4s5+RN2tSQ1KxPbBlHsgftiNfzxFaW JtK4Y3O+TLdc0iEkFaNWl7uVuCGKu8G31g== X-Google-Smtp-Source: ABdhPJwqDzI6taMucLK+yf4hX0wOYf//mQXGce1TplMOQkq9jE58aOx+jV7vHsxJKxhOf8/pfHQ+Rw== X-Received: by 2002:a2e:95d8:: with SMTP id y24mr3312055ljh.368.1624369631099; Tue, 22 Jun 2021 06:47:11 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:10 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:46 +0300 Message-Id: <20210622134652.1279260-4-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 3/9] 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 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 Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- src/qcam/assets/shader/bayer_1x_packed.frag | 43 +++++++++++++++--- src/qcam/viewfinder_gl.cpp | 48 ++++++++++++++++++--- 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/qcam/assets/shader/bayer_1x_packed.frag b/src/qcam/assets/shader/bayer_1x_packed.frag index fac8c3b8..5da9dce5 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 in pixels */ @@ -66,10 +100,7 @@ void main(void) * Add a small number (a few mantissa's LSBs) to avoid float * representation issues. Maybe paranoic. */ - center_bytes.x = BPP_X * center_pixel.x + 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_bytes.x = BPP * center_pixel.x + 0.02; float fract_x = fract(center_bytes.x); @@ -90,14 +121,14 @@ 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_pixel.xy + 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 ffbbc6c5..a6aa2b44 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,8 +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. + * Packed raw Bayer 10-bit and 12-bit formats are stored in + * GL_RED texture. * The texture width is equal to the stride. */ glActiveTexture(GL_TEXTURE0); From patchwork Tue Jun 22 13:46:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12688 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 F3727C321B for ; Tue, 22 Jun 2021 13:47:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B23586893C; Tue, 22 Jun 2021 15:47:15 +0200 (CEST) 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="u+eUkAja"; dkim-atps=neutral Received: from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com [IPv6:2a00:1450:4864:20::22e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8489660292 for ; Tue, 22 Jun 2021 15:47:14 +0200 (CEST) Received: by mail-lj1-x22e.google.com with SMTP id u11so19285704ljh.2 for ; Tue, 22 Jun 2021 06:47:14 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=toJkMwr37AcuRN1/3qMxHgEcqlJJsuiq1b1YEw63lPk=; b=u+eUkAjaJGEFrra6wa6saS9zp9nt8MST9TbwiQ/+0aLj/rtn2iOGojqr+fQ7XiYvoR Rcb4ob/cqq2sYF1FKw3fT3i2q++6o39DISjwc8s0qMaHjYEU/KAhAwEtQG2/wLONCiKr 1mClsdLNA95LIQhLXa2K1PnynaDNa5lk1eNuwX5fqazGLkTVDgV3mIsjsVyG7RHTrDvv 3dSUVTsVP3BvFbnlIIuMJ9jWoBGL1Now2KszliI3fSxC4CzyxoM+RAoVovwE0v0x7nYD 9Uwi4Ca0sbm2ggpJxeO8uNpyVfbrxBjmHDqc3Xc0Krj2QuT441dW2ghhoS/nRcTh/ZtQ dFig== 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:mime-version:content-transfer-encoding; bh=toJkMwr37AcuRN1/3qMxHgEcqlJJsuiq1b1YEw63lPk=; b=NDG0yQjGEZIesW0ejYB39sl8fBKurw8dM/zhtJE65ZEIhbwJ1tbEwDfSdnMSNrxpQn gFmDXw8baAAuinPl4tCxg+1GzohRAwLX8NlTiKhWKkzZ4NRxCwcuUmohkXaG0oNSUXEw ALiMr3uQHzIRh8gZlm4kqh+5SjtVOeLAe5CLFZ3yR8hTTwHEZjbXgCChA5srt11bi2zu FbK5jUc7VJ3phYEQNazeDM2DXyYafOMbwuXW6bQPhp/cPmQLfjCWURazouJyr2hwAnSP beUQSevTxADEUgbZrANkVO07X5kDE9R140kRwoN/fJ9xV6nlFFdKcMbPdUsW2nfp+PDB nlYA== X-Gm-Message-State: AOAM5332vpHpzkucS6k/P//vyO0cfuGS2iL3nVj6e0gdVnyblXnfgpqS L7Jl+1mLEGGAWjbjUeqphZPRfsFV/P/pog== X-Google-Smtp-Source: ABdhPJyCnNOKuamRlJeETEX/D/ZSr7LFdWtaogQdKsBC9gIOvylCG+GTT5MzOX9g9xg9XKICBsDwhA== X-Received: by 2002:a2e:9788:: with SMTP id y8mr3327363lji.100.1624369633926; Tue, 22 Jun 2021 06:47:13 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:13 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:47 +0300 Message-Id: <20210622134652.1279260-5-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 4/9] qcam: viewfinder_gl: Copy the shaders for RAW8 Bayer format from motmot 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, Morgan McGuire Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Morgan McGuire This commit copies the shaders from: https://github.com/motmot/libcamiface/commit/e36d51580510c211afc0430141085eb7a77d811b Signed-off-by: Andrey Konovalov Acked-by: Paul Elder Acked-by: Laurent Pinchart --- src/qcam/assets/shader/bayer_8.frag | 124 ++++++++++++++++++++++++++++ src/qcam/assets/shader/bayer_8.vert | 70 ++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/qcam/assets/shader/bayer_8.frag create mode 100644 src/qcam/assets/shader/bayer_8.vert diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag new file mode 100644 index 00000000..707e76ed --- /dev/null +++ b/src/qcam/assets/shader/bayer_8.frag @@ -0,0 +1,124 @@ +/* +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. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +//Pixel Shader + +/** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/ +uniform sampler2D source; +varying vec4 center; +varying vec4 yCoord; +varying vec4 xCoord; + +void main(void) { + #define fetch(x, y) texture2D(source, vec2(x, y)).r + + float C = texture2D(source, center.xy).r; // ( 0, 0) + const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; + + // Determine which of four types of pixels we are on. + vec2 alternate = mod(floor(center.zw), 2.0); + + vec4 Dvec = vec4( + fetch(xCoord[1], yCoord[1]), // (-1,-1) + fetch(xCoord[1], yCoord[2]), // (-1, 1) + fetch(xCoord[2], yCoord[1]), // ( 1,-1) + fetch(xCoord[2], yCoord[2])); // ( 1, 1) + + vec4 PATTERN = (kC.xyz * C).xyzz; + + // Can also be a dot product with (1,1,1,1) on hardware where that is + // specially optimized. + // Equivalent to: D = Dvec[0] + Dvec[1] + Dvec[2] + Dvec[3]; + Dvec.xy += Dvec.zw; + Dvec.x += Dvec.y; + + vec4 value = vec4( + fetch(center.x, yCoord[0]), // ( 0,-2) + fetch(center.x, yCoord[1]), // ( 0,-1) + fetch(xCoord[0], center.y), // (-1, 0) + fetch(xCoord[1], center.y)); // (-2, 0) + + vec4 temp = vec4( + fetch(center.x, yCoord[3]), // ( 0, 2) + fetch(center.x, yCoord[2]), // ( 0, 1) + fetch(xCoord[3], center.y), // ( 2, 0) + fetch(xCoord[2], center.y)); // ( 1, 0) + + // Even the simplest compilers should be able to constant-fold these to + // avoid the division. + // Note that on scalar processors these constants force computation of some + // identical products twice. + const vec4 kA = vec4(-1.0, -1.5, 0.5, -1.0) / 8.0; + const vec4 kB = vec4( 2.0, 0.0, 0.0, 4.0) / 8.0; + const vec4 kD = vec4( 0.0, 2.0, -1.0, -1.0) / 8.0; + + // Conserve constant registers and take advantage of free swizzle on load + #define kE (kA.xywz) + #define kF (kB.xywz) + + value += temp; + + // There are five filter patterns (identity, cross, checker, + // theta, phi). Precompute the terms from all of them and then + // use swizzles to assign to color channels. + // + // Channel Matches + // x cross (e.g., EE G) + // y checker (e.g., EE B) + // z theta (e.g., EO R) + // w phi (e.g., EO R) + #define A (value[0]) + #define B (value[1]) + #define D (Dvec.x) + #define E (value[2]) + #define F (value[3]) + + // Avoid zero elements. On a scalar processor this saves two MADDs + // and it has no effect on a vector processor. + PATTERN.yzw += (kD.yz * D).xyy; + + PATTERN += (kA.xyz * A).xyzx + (kE.xyw * E).xyxz; + PATTERN.xw += kB.xw * B; + PATTERN.xz += kF.xz * F; + + gl_FragColor.rgb = (alternate.y == 0.0) ? + ((alternate.x == 0.0) ? + vec3(C, PATTERN.xy) : + vec3(PATTERN.z, C, PATTERN.w)) : + ((alternate.x == 0.0) ? + vec3(PATTERN.w, C, PATTERN.z) : + vec3(PATTERN.yx, C)); +} diff --git a/src/qcam/assets/shader/bayer_8.vert b/src/qcam/assets/shader/bayer_8.vert new file mode 100644 index 00000000..3354860f --- /dev/null +++ b/src/qcam/assets/shader/bayer_8.vert @@ -0,0 +1,70 @@ +/* +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. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +//Vertex Shader + + +/** (w,h,1/w,1/h) */ +uniform vec4 sourceSize; + +/** Pixel position of the first red pixel in the */ +/** Bayer pattern. [{0,1}, {0, 1}]*/ +uniform vec2 firstRed; + +/** .xy = Pixel being sampled in the fragment shader on the range [0, 1] + .zw = ...on the range [0, sourceSize], offset by firstRed */ +varying vec4 center; + +/** center.x + (-2/w, -1/w, 1/w, 2/w); These are the x-positions */ +/** of the adjacent pixels.*/ +varying vec4 xCoord; + +/** center.y + (-2/h, -1/h, 1/h, 2/h); These are the y-positions */ +/** of the adjacent pixels.*/ +varying vec4 yCoord; + +void main(void) { + center.xy = gl_MultiTexCoord0.xy; + center.zw = gl_MultiTexCoord0.xy * sourceSize.xy + firstRed; + + vec2 invSize = sourceSize.zw; + xCoord = center.x + vec4(-2.0 * invSize.x, + -invSize.x, invSize.x, 2.0 * invSize.x); + yCoord = center.y + vec4(-2.0 * invSize.y, + -invSize.y, invSize.y, 2.0 * invSize.y); + + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} From patchwork Tue Jun 22 13:46:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12689 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 63D53C321B for ; Tue, 22 Jun 2021 13:47:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B2F260297; Tue, 22 Jun 2021 15:47:19 +0200 (CEST) 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="E2mOZorX"; dkim-atps=neutral Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BD3BA60292 for ; Tue, 22 Jun 2021 15:47:17 +0200 (CEST) Received: by mail-lj1-x229.google.com with SMTP id r16so30230535ljk.9 for ; Tue, 22 Jun 2021 06:47:17 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=vdQ0X2mdhCu8PAxs8sRLJ2Kgy3COxepLag9X7dpUg3E=; b=E2mOZorX2EKfw9vw4b77RuqHoOSY0IGoBXjpze/6wLiVa+QxYcLaksYNiUPT6fp6jZ av8M/6rmK+6jqML7oFxJBXF9VWJ61Avjg9pC1JIzCMtFoG5Nq2tPxYwEjTqqV5sC6es3 2YfsRIA9RE7cWfXc/G4lIhWcSbGdlCvZ0k4XPJ3GZtjwRvtvN0OoOYBqK6aHiE/JjQQ+ 0TylGfkmYZBSUfjnECOswQfXRHOry3luZ+N8/7bkXl29ua6VdAw+zqU0ICQV3b/rNIJP 6TE4SsT+hJWIF3HdBTw018dgR171kymOt4c2dl8hhqHZq6SOkHsSJeV0gTK8bgg67NlV WdHw== 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:mime-version:content-transfer-encoding; bh=vdQ0X2mdhCu8PAxs8sRLJ2Kgy3COxepLag9X7dpUg3E=; b=iQo6+mUeHT3fyJU2HQJRo+1fGk26kSrau7R0gbEHhAvLEw/G2yJ4nKXXU6nwASRk1x fOmvG9zKbBQbQe/YoW3LVHeJFI57m3nlWPtTaKA7JzBgiu35vnWEFw1KqcV6ENTFRCN8 szmRpixrKJ1SAoNadaUntIpDM2NuLV1715QUxwf751ASkzUyT2poyWIpvdulcZsYVS9K UssrqEr3NzmqdO8KJ2BHXiQxVa+agos52FE8/iEoeE0MZmsiowV9/g6TH1pdqJshb5iu HBNnZvOQOXdN/xcyrBIBkD54nDL7TwozDHgXVv+QSb8IPqGUtXQXFWe2TrQ0pVKUIPTx KwsA== X-Gm-Message-State: AOAM5330+msXv0H2Ncy2DxCwVInQEkMsMHG3VTJbE7WRO8mBzUbWgjuG e5IoQedyfU37nk4pCz45iIK/CTaPDIjaVg== X-Google-Smtp-Source: ABdhPJwbMur9MCVoBW8Q8tcErImz7rYXvLdO9Z4T9ml5E6t1NpgM9kJMbnHddBhDyBOUsj1JkaTMQQ== X-Received: by 2002:a2e:bf2a:: with SMTP id c42mr3432718ljr.1.1624369637256; Tue, 22 Jun 2021 06:47:17 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:16 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:48 +0300 Message-Id: <20210622134652.1279260-6-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 5/9] qcam: viewfinder_gl: fix wrong comment in bayer_8.frag 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Fetching into value[2] corresponds to E0, and fetching into value[3] - to F0. The fetch()-es themselves are correct, but the comments were not. Signed-off-by: Andrey Konovalov Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- src/qcam/assets/shader/bayer_8.frag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag index 707e76ed..74a6322f 100644 --- a/src/qcam/assets/shader/bayer_8.frag +++ b/src/qcam/assets/shader/bayer_8.frag @@ -68,8 +68,8 @@ void main(void) { vec4 value = vec4( fetch(center.x, yCoord[0]), // ( 0,-2) fetch(center.x, yCoord[1]), // ( 0,-1) - fetch(xCoord[0], center.y), // (-1, 0) - fetch(xCoord[1], center.y)); // (-2, 0) + fetch(xCoord[0], center.y), // (-2, 0) + fetch(xCoord[1], center.y)); // (-1, 0) vec4 temp = vec4( fetch(center.x, yCoord[3]), // ( 0, 2) From patchwork Tue Jun 22 13:46:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12690 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 BEBC5C321B for ; Tue, 22 Jun 2021 13:47:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7C4346893F; Tue, 22 Jun 2021 15:47:21 +0200 (CEST) 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="jyPp9hSA"; dkim-atps=neutral Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F1E2B68932 for ; Tue, 22 Jun 2021 15:47:19 +0200 (CEST) Received: by mail-lj1-x233.google.com with SMTP id z22so30198584ljh.8 for ; Tue, 22 Jun 2021 06:47:19 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=AD9bhsFZXTGxwv2ObNbhoFmY7s5fGMRNgZRhCRXwJ6w=; b=jyPp9hSARzMsRglYFDOJHvipHrr1y7ptEZ+5soHbtVIs2ZxozKSuZ0K2QRkMZ67kRH 8U957Di8ihezVmnp0LtExT3xrzuwcZnqiBZCQECyHPPcyA+Koa/i0kKHH8lEN37lqqL5 tAQ2dGkZGcKrOhXOsR5+fvteO14UdHHl7seER90TVk5dAxJgIRsr7xexVamRfXsE6whi u2N5Hd6d33+1QFbYRYMpMs6mq7xat0UInSJmwvVS73GCc3ZdbgdZR+/hgUMB9EbccF1r aNmxgNP7Nf36ReEJcntOBjZgCSm98UpkYen3eepr2hH7WhPgBdz7gN65TSxQk8JuY/Qn 2EKQ== 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:mime-version:content-transfer-encoding; bh=AD9bhsFZXTGxwv2ObNbhoFmY7s5fGMRNgZRhCRXwJ6w=; b=FcJy2gC5GnSMhr0QSUqjyWm0q7Xcn9OLg2HDYp+YHadSGtwDp+RHK5r1bF9bRu2C7P MkJ1jZflr9zaQXpazX0VCiWWly9bmZ2tL4vvdilEG6IwIeO7hMCCif1+evoRSsDGM56x SHaqTx8X3SQNEjuGBWzysoqB7z0XIisFgbg5CKRre5UuBXvNpMsrMbVL1uKOq8jL0unt jGlOu+Rp/aS6KFpD8EWp7BFEtXkPFnp3T8rxutSj9C8KXSFjW17xrUr5rtFfZGZLJJD7 cR1fwbYIkqwU/+0HV8gTh9Cx91NnEuov24Rxfclux7HvGFfK20jWpkuDd7ray70ffzJT d00A== X-Gm-Message-State: AOAM533n15lgMfF8z/np3TTEF/zN8ZTEroF4uJeVJKwXRekeEK/lYWdq s6RbDQnb5cxsrgdjkfeSxlRo3N9/I2Kjfg== X-Google-Smtp-Source: ABdhPJw6AOuSnotVAmkJdO48RDB41mvUag0oRpGzzZkcK4Tdj7pbiT5ZIKZ0fY261vhMUZIIyr1O2A== X-Received: by 2002:a2e:7103:: with SMTP id m3mr3313972ljc.300.1624369639453; Tue, 22 Jun 2021 06:47:19 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:18 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:49 +0300 Message-Id: <20210622134652.1279260-7-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 6/9] qcam: viewfinder_gl: use SPDX-License-Identifier in bayer_8.* shaders 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Andrey Konovalov --- src/qcam/assets/shader/bayer_8.frag | 25 +------------------------ src/qcam/assets/shader/bayer_8.vert | 25 +------------------------ 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag index 74a6322f..a7d65e1d 100644 --- a/src/qcam/assets/shader/bayer_8.frag +++ b/src/qcam/assets/shader/bayer_8.frag @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ /* From http://jgt.akpeters.com/papers/McGuire08/ @@ -8,30 +9,6 @@ Morgan McGuire This paper appears in issue Volume 13, Number 4. --------------------------------------------------------- Copyright (c) 2008, Morgan McGuire. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //Pixel Shader diff --git a/src/qcam/assets/shader/bayer_8.vert b/src/qcam/assets/shader/bayer_8.vert index 3354860f..347c15f7 100644 --- a/src/qcam/assets/shader/bayer_8.vert +++ b/src/qcam/assets/shader/bayer_8.vert @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ /* From http://jgt.akpeters.com/papers/McGuire08/ @@ -8,30 +9,6 @@ Morgan McGuire This paper appears in issue Volume 13, Number 4. --------------------------------------------------------- Copyright (c) 2008, Morgan McGuire. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //Vertex Shader From patchwork Tue Jun 22 13:46:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12691 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 1E7E2C321B for ; Tue, 22 Jun 2021 13:47:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D51A660297; Tue, 22 Jun 2021 15:47:23 +0200 (CEST) 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="jyxWbuLj"; dkim-atps=neutral Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B5D8368EA3 for ; Tue, 22 Jun 2021 15:47:21 +0200 (CEST) Received: by mail-lj1-x22f.google.com with SMTP id d25so2155548lji.7 for ; Tue, 22 Jun 2021 06:47:21 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=TUbjnIpWP4fKLUmcH2E4fnC7KvY82GsTBNsUS9Q1Ci8=; b=jyxWbuLjsaLztD6QY8Gau75RzThsmGBscKM37caq55qbluKmw6O1D6Ny/WYz+cfOZ4 eEa0msMSaLNRNxH0qtKE8uk9lraML5mh4GEGejcoLS7HpXXcSvEaO6DUAHJrZEEmEofA il2fLXIqeHqn6iGECHiZNIOOEPpcuzV+VqBWGmjR2alk+iWwKEcFAdFjOmhueWaaFV2z hRAsepc4otrvVMMUqZfmOTnVd2/7yPK8tUjw/CnZ+1/XUyDlZRu4hqwLC6bbSkr5DZ7q G7xxABtq7RG/oLoJDqjCmkBH6TNaWHmmLAPvd/EYsPmMbcq6gtzTzTylFEm5sYHJFZEa QhQA== 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:mime-version:content-transfer-encoding; bh=TUbjnIpWP4fKLUmcH2E4fnC7KvY82GsTBNsUS9Q1Ci8=; b=S8dFzLIc2apteA5dBS5qcRhYUytlNjRcouHd27OHqcBa81f3BWDpZoy4xSZw6uTx+W zYJMnKFNqyiv9TF/NXhbHtlvlkkOittNWejoMIai/rzRA+rw1UPjCqWDBFLYZbYEXyrH Onlx+M1Ii/r23Qf3+twN37aHGAr1hzwYGrrxE0BlGpvo/RwaGI0FccVU1VmKqEsA9c9e ArM3l4AYjWzJeZ61PJJ8vwt9Tj8lk5SymqWD8EHcJ38y+MY3ombnBIxJJasStofM4LYD LZXqHlv9QQxR+zIRZOnWiqt8blJrtC6N1/Ga1l8PB1kHMHe7j4ALqp902kFwXFY6NNRp C63A== X-Gm-Message-State: AOAM530KAqhglNdLc6jWuaLBeo/SSsPNSRt/rcSz3sEWXavqLusxd7Bx dFQR0Ts2eW/69IP0nFJ1MEE7VEzn4bHCyQ== X-Google-Smtp-Source: ABdhPJyRhEiw46BhtJI6raddN8bX31/6Hg0kSN5finJLTQ8Eoe6x26nLVaCLcLvF9MC30E6MVK+o/A== X-Received: by 2002:a2e:bc0b:: with SMTP id b11mr3351501ljf.131.1624369641244; Tue, 22 Jun 2021 06:47:21 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:20 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:50 +0300 Message-Id: <20210622134652.1279260-8-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 7/9] qcam: viewfinder_gl: set the vertex shader file name in selectFormat() 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In preparation to extend the supported formats, make it possible to use different vertex fragment files depending on the format. Make "identity.vert" the default choice. Signed-off-by: Andrey Konovalov Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- src/qcam/viewfinder_gl.cpp | 5 ++++- src/qcam/viewfinder_gl.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index a6aa2b44..6d1d80bd 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -131,6 +131,9 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) /* 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) { @@ -292,7 +295,7 @@ bool ViewFinderGL::createVertexShader() vertexShader_ = std::make_unique(QOpenGLShader::Vertex, this); /* Compile the vertex shader */ - if (!vertexShader_->compileSourceFile(":identity.vert")) { + if (!vertexShader_->compileSourceFile(vertexShaderFile_)) { qWarning() << "[ViewFinderGL]:" << vertexShader_->log(); return false; } diff --git a/src/qcam/viewfinder_gl.h b/src/qcam/viewfinder_gl.h index 508155b1..bce94c87 100644 --- a/src/qcam/viewfinder_gl.h +++ b/src/qcam/viewfinder_gl.h @@ -73,6 +73,7 @@ private: QOpenGLShaderProgram shaderProgram_; std::unique_ptr vertexShader_; std::unique_ptr fragmentShader_; + QString vertexShaderFile_; QString fragmentShaderFile_; QStringList fragmentShaderDefines_; From patchwork Tue Jun 22 13:46:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12692 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 73FE5C321B for ; Tue, 22 Jun 2021 13:47:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 352FE68935; Tue, 22 Jun 2021 15:47:26 +0200 (CEST) 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="exkVNZ1t"; 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 EF49668935 for ; Tue, 22 Jun 2021 15:47:23 +0200 (CEST) Received: by mail-lf1-x135.google.com with SMTP id i18so1611625lfl.8 for ; Tue, 22 Jun 2021 06:47:23 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=qlnX/HoUrihRatFwUcg/TBzcFGRWcRTzmu9xMnsm4KA=; b=exkVNZ1tqSnjz7h82YSFROZ8c7KuuC/zW7aBREa01iYLRFz4ROvGRnu3M7MNuovlsy czRjEpdgebE8mHow5r7YOEFov1uLpH6B1SnY7qKgMaRT48hmslKQpf4OtwOsSxE24hTA WBTCjHCHx4TbmDZcj732NNTuidSX5T4LsZYSi7gfVD2enpPtwX1zuDNlvgibFZkLh/4c rBxPmEXhOnLBXDYFxqeLUJz3vLOFN+5++w5ID9q5h1Tu+U5BGWHZJEr6imQ9YlWGWeuU iT1qKKkKRQfhnH6rsLgNms9J+xN8kdhlZ8zl4gxv/wpPjWtDNAs1QKUPhYyp4gDELJpD IBMw== 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:mime-version:content-transfer-encoding; bh=qlnX/HoUrihRatFwUcg/TBzcFGRWcRTzmu9xMnsm4KA=; b=sR3vVs4/g0dZKVAV6Q+TAXBmL6reusCEZaKAJE0IxEnEcA8WtbEYn1Wdaa4+qdD3YX DlurJoE8rfjizS2djtTZNBQafbvUeBeYKsE4xzwbJJy41T/2lLMDmZkKpVpmkb1apGpy RFDh4t2YE7g8uBrHj7W96tl37H7tnqDIwTzDcVSwfIe+0CoG+ng8uZZlZm0tE2eIWBAL ZH2/JAQIEsSvVn0XqAK8i/SkqkZXJNgjhS7l+s2kzfvdhoGqxlbdqQeGP9b8X7MOPOOr lWMjpZIufPaIDHkKK/kGznKOqyvUIHx3Xpdxrd2D7b39jS1rhGgZolziNVHbKr9Wbk/2 eNIQ== X-Gm-Message-State: AOAM531Go0L0OrsyKcPETS4sYRQsv9TpxDRnnIaqy8SkoS48CAktY2Ga RHxxrXT9v2x8hlfDr1atrlBQ+7RHgQSNEw== X-Google-Smtp-Source: ABdhPJzqaROaj/7t5CZtK/OisI/L8lAiiypJO+kRym6ZZR5l6/P8fkT6hXS9iz8buzQSWfaPcD/CcA== X-Received: by 2002:ac2:5c0b:: with SMTP id r11mr3101850lfp.655.1624369643374; Tue, 22 Jun 2021 06:47:23 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:22 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:51 +0300 Message-Id: <20210622134652.1279260-9-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 8/9] qcam: viewfinder_gl: Add support for RAW8 Bayer 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This integrates the vertex and the fragment shaders by Morgan McGuire into qcam. Signed-off-by: Andrey Konovalov Reviewed-by: Paul Elder Reviewed-by: Laurent Pinchart --- src/qcam/assets/shader/bayer_8.frag | 9 ++++--- src/qcam/assets/shader/bayer_8.vert | 26 ++++++++++-------- src/qcam/assets/shader/shaders.qrc | 2 ++ src/qcam/viewfinder_gl.cpp | 41 +++++++++++++++++++++++++++-- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag index a7d65e1d..4ece44ab 100644 --- a/src/qcam/assets/shader/bayer_8.frag +++ b/src/qcam/assets/shader/bayer_8.frag @@ -9,20 +9,23 @@ Morgan McGuire This paper appears in issue Volume 13, Number 4. --------------------------------------------------------- Copyright (c) 2008, Morgan McGuire. All rights reserved. + +Modified by Linaro Ltd to integrate it into libcamera. +Copyright (C) 2021, Linaro */ //Pixel Shader /** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/ -uniform sampler2D source; +uniform sampler2D tex_y; varying vec4 center; varying vec4 yCoord; varying vec4 xCoord; void main(void) { - #define fetch(x, y) texture2D(source, vec2(x, y)).r + #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r - float C = texture2D(source, center.xy).r; // ( 0, 0) + float C = texture2D(tex_y, center.xy).r; // ( 0, 0) const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; // Determine which of four types of pixels we are on. diff --git a/src/qcam/assets/shader/bayer_8.vert b/src/qcam/assets/shader/bayer_8.vert index 347c15f7..3695a5e9 100644 --- a/src/qcam/assets/shader/bayer_8.vert +++ b/src/qcam/assets/shader/bayer_8.vert @@ -9,17 +9,22 @@ Morgan McGuire This paper appears in issue Volume 13, Number 4. --------------------------------------------------------- Copyright (c) 2008, Morgan McGuire. All rights reserved. + +Modified by Linaro Ltd to integrate it into libcamera. +Copyright (C) 2021, Linaro */ //Vertex Shader +attribute vec4 vertexIn; +attribute vec2 textureIn; -/** (w,h,1/w,1/h) */ -uniform vec4 sourceSize; +uniform vec2 tex_size; /* The texture size in pixels */ +uniform vec2 tex_step; /** Pixel position of the first red pixel in the */ /** Bayer pattern. [{0,1}, {0, 1}]*/ -uniform vec2 firstRed; +uniform vec2 tex_bayer_first_red; /** .xy = Pixel being sampled in the fragment shader on the range [0, 1] .zw = ...on the range [0, sourceSize], offset by firstRed */ @@ -34,14 +39,13 @@ varying vec4 xCoord; varying vec4 yCoord; void main(void) { - center.xy = gl_MultiTexCoord0.xy; - center.zw = gl_MultiTexCoord0.xy * sourceSize.xy + firstRed; + center.xy = textureIn; + center.zw = textureIn * tex_size + tex_bayer_first_red; - vec2 invSize = sourceSize.zw; - xCoord = center.x + vec4(-2.0 * invSize.x, - -invSize.x, invSize.x, 2.0 * invSize.x); - yCoord = center.y + vec4(-2.0 * invSize.y, - -invSize.y, invSize.y, 2.0 * invSize.y); + xCoord = center.x + vec4(-2.0 * tex_step.x, + -tex_step.x, tex_step.x, 2.0 * tex_step.x); + yCoord = center.y + vec4(-2.0 * tex_step.y, + -tex_step.y, tex_step.y, 2.0 * tex_step.y); - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = vertexIn; } diff --git a/src/qcam/assets/shader/shaders.qrc b/src/qcam/assets/shader/shaders.qrc index d76d65c5..96c709f9 100644 --- a/src/qcam/assets/shader/shaders.qrc +++ b/src/qcam/assets/shader/shaders.qrc @@ -6,6 +6,8 @@ YUV_3_planes.frag YUV_packed.frag bayer_1x_packed.frag + bayer_8.frag + bayer_8.vert identity.vert diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index 6d1d80bd..e7c8620c 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 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, @@ -223,6 +228,34 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) 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); @@ -627,6 +660,10 @@ void ViewFinderGL::doRender() shaderProgram_.setUniformValue(textureUniformY_, 0); 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: @@ -636,8 +673,8 @@ void ViewFinderGL::doRender() case libcamera::formats::SGRBG12_CSI2P: case libcamera::formats::SRGGB12_CSI2P: /* - * Packed raw Bayer 10-bit and 12-bit formats are stored in - * GL_RED texture. + * 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. */ glActiveTexture(GL_TEXTURE0); From patchwork Tue Jun 22 13:46:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Konovalov X-Patchwork-Id: 12693 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 0E88EC321B for ; Tue, 22 Jun 2021 13:47:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BE09A68935; Tue, 22 Jun 2021 15:47:29 +0200 (CEST) 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="X3PO4JM2"; 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 BD61060292 for ; Tue, 22 Jun 2021 15:47:28 +0200 (CEST) Received: by mail-lj1-x235.google.com with SMTP id c11so30228354ljd.6 for ; Tue, 22 Jun 2021 06:47:28 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=BAvEJ84VEQWmiF5nH6jedi2+7DTSJ/Dd6CWNQQoblKM=; b=X3PO4JM2ieRIyhbE0kk68dp4O3+0MBEuGA71zGBS9Yo8n832lueq0FH5MtywGgEzXS QK9RQ4Vj+50vwziry/AOSSNTHHdCtG5/GOUWMTgX4EyyicjnCQfWXRPq/hxfFki4jL0F JEHDeRgsMiCQDPw5mc8pSZUPX+3T+XXRwUSE5EZRBlpb3IFjCc+b34SZMnu+7lL81Da1 I8HOYfxZAI7//Umdr4NrA9kfGZD6mKB06tJJf6oBPasVaZ9TGjeSl3X6qK+UOesEHVx4 RMFPeUDzTJyxs3Az8SkZZdsOkqiZi1YsVAv3w31Ao4QuTbgqS4fqHMV+5CIY/LPhD2zp 5KhA== 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:mime-version:content-transfer-encoding; bh=BAvEJ84VEQWmiF5nH6jedi2+7DTSJ/Dd6CWNQQoblKM=; b=QVh/UcpzfWGrB4cZ9WZOQ4eiXSYxmTYXvQa3dR87FErgXpcmZE75nBubbmDjmnnBfb OvQxLxoiUxv6SUXtFxhpk9YoEM159zBIgkNkU1mL07cqVp3fcyey1zrXZ0JJ1m6/ox88 RoP8gBG5NrJFWzbix2GKdpWHUql3OlSqo0UBPzH6lAWOS6FStcG8yfXvW7Jf7cynJXIA EwVUG+GmO3ZcjcEOmwdhpnM3mm2rX9q3NTchyS3CqE52gYoDc/SAU5gsVQnMNRs5RUAh NVVOMAPVrZSblUflFLlkx90ibHmqaleFkfoFaoyaBmQTcQrNFz71DemIw0chUshKMzh5 H3yg== X-Gm-Message-State: AOAM53034YZZy/nFM26ts2sXM3O++SwAXjiiT2RjvIIlj5Pp3yHxwH5H FjnuQZj/xPUt+IZlFMpv5EthQyPDezaA7Q== X-Google-Smtp-Source: ABdhPJxAbZw1aNb+1fAB4omI6YzAS/lzn+PwtJXjFM/ujDT5Si40ivI7P6WXqJTvkod8qhbHO3D28Q== X-Received: by 2002:a2e:a612:: with SMTP id v18mr3389208ljp.358.1624369648247; Tue, 22 Jun 2021 06:47:28 -0700 (PDT) Received: from localhost.localdomain ([85.249.44.185]) by smtp.googlemail.com with ESMTPSA id b19sm163125ljo.37.2021.06.22.06.47.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Jun 2021 06:47:27 -0700 (PDT) From: Andrey Konovalov To: libcamera-devel@lists.libcamera.org, laurent.pinchart@ideasonboard.com Date: Tue, 22 Jun 2021 16:46:52 +0300 Message-Id: <20210622134652.1279260-10-andrey.konovalov@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210622134652.1279260-1-andrey.konovalov@linaro.org> References: <20210622134652.1279260-1-andrey.konovalov@linaro.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v5 9/9] qcam: viewfinder_gl: bayer_8.frag: compute the coordinates manually 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the identity vertex shader, and compute the coordinates in the fragment shader without using the hardware interpolator. 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_8.frag | 38 ++++++++++++++++++++++++++--- src/qcam/viewfinder_gl.cpp | 4 --- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag index 4ece44ab..be23913b 100644 --- a/src/qcam/assets/shader/bayer_8.frag +++ b/src/qcam/assets/shader/bayer_8.frag @@ -10,21 +10,51 @@ This paper appears in issue Volume 13, Number 4. --------------------------------------------------------- Copyright (c) 2008, Morgan McGuire. All rights reserved. -Modified by Linaro Ltd to integrate it into libcamera. + +Modified by Linaro Ltd to integrate it into libcamera, and to +fix the artifacts due to pixel coordinates interpolation. Copyright (C) 2021, Linaro */ //Pixel Shader +varying vec2 textureOut; + +uniform vec2 tex_size; /* The texture size in pixels */ +uniform vec2 tex_step; + +/** Pixel position of the first red pixel in the */ +/** Bayer pattern. [{0,1}, {0, 1}]*/ +uniform vec2 tex_bayer_first_red; + /** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/ uniform sampler2D tex_y; -varying vec4 center; -varying vec4 yCoord; -varying vec4 xCoord; void main(void) { #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r + /** .xy = Pixel being sampled in the fragment shader on the range [0, 1] + .zw = ...on the range [0, sourceSize], offset by firstRed */ + vec4 center; + + /** center.x + (-2/w, -1/w, 1/w, 2/w); These are the x-positions */ + /** of the adjacent pixels.*/ + vec4 xCoord; + + /** center.y + (-2/h, -1/h, 1/h, 2/h); These are the y-positions */ + /** of the adjacent pixels.*/ + vec4 yCoord; + + /* Align the center coordinates to the nearest pixel */ + center.zw = floor(textureOut * tex_size); + center.xy = center.zw * tex_step; + center.zw += tex_bayer_first_red; + + xCoord = center.x + vec4(-2.0 * tex_step.x, + -tex_step.x, tex_step.x, 2.0 * tex_step.x); + yCoord = center.y + vec4(-2.0 * tex_step.y, + -tex_step.y, tex_step.y, 2.0 * tex_step.y); + float C = texture2D(tex_y, center.xy).r; // ( 0, 0) const vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0; diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp index e7c8620c..a5b1bfbe 100644 --- a/src/qcam/viewfinder_gl.cpp +++ b/src/qcam/viewfinder_gl.cpp @@ -231,28 +231,24 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format) 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;