Show a patch.

GET /api/patches/21227/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 21227,
    "url": "https://patchwork.libcamera.org/api/patches/21227/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/21227/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20240910234649.28591-4-laurent.pinchart@ideasonboard.com>",
    "date": "2024-09-10T23:46:49",
    "name": "[3/3] qcam: viewfinder_gl: Render image centered in letterbox",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "065725fc223148059dfe50a8e33e325450934afd",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/21227/mbox/",
    "series": [
        {
            "id": 4578,
            "url": "https://patchwork.libcamera.org/api/series/4578/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4578",
            "date": "2024-09-10T23:46:46",
            "name": "qcam: Fix GL renderer on Qt 6",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/4578/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/21227/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/21227/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 75272C3259\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 10 Sep 2024 23:47:31 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CF0D863501;\n\tWed, 11 Sep 2024 01:47:30 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 547F6634FD\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Sep 2024 01:47:26 +0200 (CEST)",
            "from pendragon.ideasonboard.com\n\t(213-229-8-243.static.upcbusiness.at [213.229.8.243])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 36EDB11D6;\n\tWed, 11 Sep 2024 01:46:09 +0200 (CEST)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"FrmEDzEd\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1726011969;\n\tbh=g48epqajRJ9hCS8P7kBtlFSX96b9dh8PpIeMSWb2c2o=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=FrmEDzEdzfIcZPstYUz4Xhc99D5JyXXjiBqTO78xFOzRwoWeHXjaS7cXVaGjs/LQs\n\tc1sLioQorBSfaCi/+2LYChns+6r0wf3/cCfkeVqXC/COQgDinn6v7lm9+0SHGhfdAg\n\tMx6KmYjxn6g6mrLm6fUly9F+WRn5an3zK2iDc/Go=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Neal Gompa <neal@gompa.dev>",
        "Subject": "[PATCH 3/3] qcam: viewfinder_gl: Render image centered in letterbox",
        "Date": "Wed, 11 Sep 2024 02:46:49 +0300",
        "Message-ID": "<20240910234649.28591-4-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.44.2",
        "In-Reply-To": "<20240910234649.28591-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20240910234649.28591-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Mimic the letterbox behaviour of the Qt viewfinder by rendering the\nimage centered. This is done by adding a projection matrix to the vertex\nshader to scale the rendered rectangle.\n\nAnother option would have been to keep using glViewport() (which would\nhave needed to be moved to paintGL(), as Qt resets the viewport to span\nthe full widget before calling). Hidpi displays would then need special\nhandling of the device pixel ratio, which is done automatically by Qt\nwhen it sets the default viewport. Using a projection matrix avoids this\ncomplication.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/apps/qcam/assets/shader/bayer_8.vert  |  4 ++-\n src/apps/qcam/assets/shader/identity.vert |  3 ++-\n src/apps/qcam/viewfinder_gl.cpp           | 31 +++++++++++++++--------\n src/apps/qcam/viewfinder_gl.h             |  2 +-\n 4 files changed, 26 insertions(+), 14 deletions(-)",
    "diff": "diff --git a/src/apps/qcam/assets/shader/bayer_8.vert b/src/apps/qcam/assets/shader/bayer_8.vert\nindex 3695a5e910c9..fb5109eee3f5 100644\n--- a/src/apps/qcam/assets/shader/bayer_8.vert\n+++ b/src/apps/qcam/assets/shader/bayer_8.vert\n@@ -19,6 +19,8 @@ Copyright (C) 2021, Linaro\n attribute vec4 vertexIn;\n attribute vec2 textureIn;\n \n+uniform mat4 proj_matrix;\n+\n uniform vec2 tex_size;\t/* The texture size in pixels */\n uniform vec2 tex_step;\n \n@@ -47,5 +49,5 @@ void main(void) {\n     yCoord = center.y + vec4(-2.0 * tex_step.y,\n                               -tex_step.y, tex_step.y, 2.0 * tex_step.y);\n \n-    gl_Position = vertexIn;\n+    gl_Position = proj_matrix * vertexIn;\n }\ndiff --git a/src/apps/qcam/assets/shader/identity.vert b/src/apps/qcam/assets/shader/identity.vert\nindex 12c41377cfe7..907e8741fae7 100644\n--- a/src/apps/qcam/assets/shader/identity.vert\n+++ b/src/apps/qcam/assets/shader/identity.vert\n@@ -9,10 +9,11 @@ attribute vec4 vertexIn;\n attribute vec2 textureIn;\n varying vec2 textureOut;\n \n+uniform mat4 proj_matrix;\n uniform float stride_factor;\n \n void main(void)\n {\n-\tgl_Position = vertexIn;\n+\tgl_Position = proj_matrix * vertexIn;\n \ttextureOut = vec2(textureIn.x * stride_factor, textureIn.y);\n }\ndiff --git a/src/apps/qcam/viewfinder_gl.cpp b/src/apps/qcam/viewfinder_gl.cpp\nindex b2096faf859f..f31956ff0504 100644\n--- a/src/apps/qcam/viewfinder_gl.cpp\n+++ b/src/apps/qcam/viewfinder_gl.cpp\n@@ -12,6 +12,7 @@\n #include <QByteArray>\n #include <QFile>\n #include <QImage>\n+#include <QMatrix4x4>\n #include <QStringList>\n \n #include <libcamera/formats.h>\n@@ -464,6 +465,7 @@ bool ViewFinderGL::createFragmentShader()\n \n \tvertexBuffer_.release();\n \n+\tprojMatrixUniform_ = shaderProgram_.uniformLocation(\"proj_matrix\");\n \ttextureUniformY_ = shaderProgram_.uniformLocation(\"tex_y\");\n \ttextureUniformU_ = shaderProgram_.uniformLocation(\"tex_u\");\n \ttextureUniformV_ = shaderProgram_.uniformLocation(\"tex_v\");\n@@ -509,7 +511,7 @@ void ViewFinderGL::initializeGL()\n \tglEnable(GL_TEXTURE_2D);\n \tglDisable(GL_DEPTH_TEST);\n \n-\tstatic const GLfloat coordinates[2][4][2]{\n+\tconst GLfloat coordinates[2][4][2]{\n \t\t{\n \t\t\t/* Vertex coordinates */\n \t\t\t{ -1.0f, -1.0f },\n@@ -801,6 +803,17 @@ void ViewFinderGL::doRender()\n \tshaderProgram_.setUniformValue(textureUniformStrideFactor_,\n \t\t\t\t       static_cast<float>(size_.width() - 1) /\n \t\t\t\t       (stridePixels - 1));\n+\n+\t/*\n+\t * Place the viewfinder in the centre of the widget, preserving the\n+\t * aspect ratio of the image.\n+\t */\n+\tQMatrix4x4 projMatrix;\n+\tQSizeF scaledSize = size_.scaled(size(), Qt::KeepAspectRatio);\n+\tprojMatrix.scale(scaledSize.width() / size().width(),\n+\t\t\t scaledSize.height() / size().height());\n+\n+\tshaderProgram_.setUniformValue(projMatrixUniform_, projMatrix);\n }\n \n void ViewFinderGL::paintGL()\n@@ -818,18 +831,14 @@ void ViewFinderGL::paintGL()\n \t\tclose();\n \t}\n \n-\tif (image_) {\n-\t\tglClearColor(0.0f, 0.0f, 0.0f, 1.0f);\n-\t\tglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n+\tif (!image_)\n+\t\treturn;\n \n-\t\tdoRender();\n-\t\tglDrawArrays(GL_TRIANGLE_FAN, 0, 4);\n-\t}\n-}\n+\tglClearColor(0.0f, 0.0f, 0.0f, 1.0f);\n+\tglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n \n-void ViewFinderGL::resizeGL(int w, int h)\n-{\n-\tglViewport(0, 0, w, h);\n+\tdoRender();\n+\tglDrawArrays(GL_TRIANGLE_FAN, 0, 4);\n }\n \n QSize ViewFinderGL::sizeHint() const\ndiff --git a/src/apps/qcam/viewfinder_gl.h b/src/apps/qcam/viewfinder_gl.h\nindex 23744b411c86..23c657bcfae2 100644\n--- a/src/apps/qcam/viewfinder_gl.h\n+++ b/src/apps/qcam/viewfinder_gl.h\n@@ -51,7 +51,6 @@ Q_SIGNALS:\n protected:\n \tvoid initializeGL() override;\n \tvoid paintGL() override;\n-\tvoid resizeGL(int w, int h) override;\n \tQSize sizeHint() const override;\n \n private:\n@@ -88,6 +87,7 @@ private:\n \n \t/* Common texture parameters */\n \tGLuint textureMinMagFilters_;\n+\tGLuint projMatrixUniform_;\n \n \t/* YUV texture parameters */\n \tGLuint textureUniformU_;\n",
    "prefixes": [
        "3/3"
    ]
}