[{"id":30014,"web_url":"https://patchwork.libcamera.org/comment/30014/","msgid":"<171866427474.804094.9779588349295162791@ping.linuxembedded.co.uk>","date":"2024-06-17T22:44:34","subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Robert Mader (2024-06-17 18:41:19)\n> In order to be more compatible with modern hardware and APIs. This\n> notably allows GL implementations to directly import the buffers more\n> often and seems to be required for Wayland.\n> \n> Further more, as we already enforce a 8 byte stride, these formats work\n> better for clients that don't support padding - such as libwebrtc at the\n> time of writing.\n> \n> Tested devices:\n>  - Librem5\n>  - PinePhone\n>  - Thinkpad X13s\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nCI Green:\n - https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1203631\n\nexcept for lint:\n - https://gitlab.freedesktop.org/camera/libcamera/-/jobs/60008198\n\nCould be helpful to add the checkstyle hooks to your local build to see\nthese in advance.\n\nCould very easily be fixed while applying though ... but I'd probably\nwant to see a review/ack tag from someone directly working on the SoftISP\ncode ...\n\n\n> ---\n>  src/libcamera/software_isp/debayer_cpu.cpp | 101 ++++++++++++++-------\n>  src/libcamera/software_isp/debayer_cpu.h   |   1 +\n>  2 files changed, 68 insertions(+), 34 deletions(-)\n> \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index c038eed4..79bb4d87 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -70,10 +70,11 @@ DebayerCpu::~DebayerCpu()\n>   * GBG\n>   * RGR\n>   */\n> -#define BGGR_BGR888(p, n, div)                                                                \\\n> +#define BGGR_BGR888(p, n, div, addAlphaBit)                                                   \\\n>         *dst++ = blue_[curr[x] / (div)];                                                      \\\n>         *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>         *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> +       if (addAlphaBit) *dst++ = 255;                                                        \\\n>         x++;\n>  \n>  /*\n> @@ -81,10 +82,11 @@ DebayerCpu::~DebayerCpu()\n>   * RGR\n>   * GBG\n>   */\n> -#define GRBG_BGR888(p, n, div)                                    \\\n> +#define GRBG_BGR888(p, n, div, addAlphaBit)                       \\\n>         *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>         *dst++ = green_[curr[x] / (div)];                         \\\n>         *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> +       if (addAlphaBit) *dst++ = 255;                            \\\n>         x++;\n>  \n>  /*\n> @@ -92,10 +94,11 @@ DebayerCpu::~DebayerCpu()\n>   * BGB\n>   * GRG\n>   */\n> -#define GBRG_BGR888(p, n, div)                                     \\\n> +#define GBRG_BGR888(p, n, div, addAlphaBit)                        \\\n>         *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>         *dst++ = green_[curr[x] / (div)];                          \\\n>         *dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> +       if (addAlphaBit) *dst++ = 255;                             \\\n>         x++;\n>  \n>  /*\n> @@ -103,10 +106,11 @@ DebayerCpu::~DebayerCpu()\n>   * GRG\n>   * BGB\n>   */\n> -#define RGGB_BGR888(p, n, div)                                                                 \\\n> +#define RGGB_BGR888(p, n, div, addAlphaBit)                                                    \\\n>         *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>         *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>         *dst++ = red_[curr[x] / (div)];                                                        \\\n> +       if (addAlphaBit) *dst++ = 255;                                                         \\\n>         x++;\n>  \n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> @@ -114,8 +118,8 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>         DECLARE_SRC_POINTERS(uint8_t)\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n> -               BGGR_BGR888(1, 1, 1)\n> -               GBRG_BGR888(1, 1, 1)\n> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -124,8 +128,8 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>         DECLARE_SRC_POINTERS(uint8_t)\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n> -               GRBG_BGR888(1, 1, 1)\n> -               RGGB_BGR888(1, 1, 1)\n> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -135,8 +139,8 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n>                 /* divide values by 4 for 10 -> 8 bpp value */\n> -               BGGR_BGR888(1, 1, 4)\n> -               GBRG_BGR888(1, 1, 4)\n> +               BGGR_BGR888(1, 1, 4, addAlphaBit_)\n> +               GBRG_BGR888(1, 1, 4, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -146,8 +150,8 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n>                 /* divide values by 4 for 10 -> 8 bpp value */\n> -               GRBG_BGR888(1, 1, 4)\n> -               RGGB_BGR888(1, 1, 4)\n> +               GRBG_BGR888(1, 1, 4, addAlphaBit_)\n> +               RGGB_BGR888(1, 1, 4, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -157,8 +161,8 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n>                 /* divide values by 16 for 12 -> 8 bpp value */\n> -               BGGR_BGR888(1, 1, 16)\n> -               GBRG_BGR888(1, 1, 16)\n> +               BGGR_BGR888(1, 1, 16, addAlphaBit_)\n> +               GBRG_BGR888(1, 1, 16, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -168,8 +172,8 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < (int)window_.width;) {\n>                 /* divide values by 16 for 12 -> 8 bpp value */\n> -               GRBG_BGR888(1, 1, 16)\n> -               RGGB_BGR888(1, 1, 16)\n> +               GRBG_BGR888(1, 1, 16, addAlphaBit_)\n> +               RGGB_BGR888(1, 1, 16, addAlphaBit_)\n>         }\n>  }\n>  \n> @@ -187,12 +191,12 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>          */\n>         for (int x = 0; x < widthInBytes;) {\n>                 /* First pixel */\n> -               BGGR_BGR888(2, 1, 1)\n> +               BGGR_BGR888(2, 1, 1, addAlphaBit_)\n>                 /* Second pixel BGGR -> GBRG */\n> -               GBRG_BGR888(1, 1, 1)\n> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n>                 /* Same thing for third and fourth pixels */\n> -               BGGR_BGR888(1, 1, 1)\n> -               GBRG_BGR888(1, 2, 1)\n> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n> +               GBRG_BGR888(1, 2, 1, addAlphaBit_)\n>                 /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>                 x++;\n>         }\n> @@ -207,12 +211,12 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < widthInBytes;) {\n>                 /* First pixel */\n> -               GRBG_BGR888(2, 1, 1)\n> +               GRBG_BGR888(2, 1, 1, addAlphaBit_)\n>                 /* Second pixel GRBG -> RGGB */\n> -               RGGB_BGR888(1, 1, 1)\n> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n>                 /* Same thing for third and fourth pixels */\n> -               GRBG_BGR888(1, 1, 1)\n> -               RGGB_BGR888(1, 2, 1)\n> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n> +               RGGB_BGR888(1, 2, 1, addAlphaBit_)\n>                 /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>                 x++;\n>         }\n> @@ -227,12 +231,12 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < widthInBytes;) {\n>                 /* Even pixel */\n> -               GBRG_BGR888(2, 1, 1)\n> +               GBRG_BGR888(2, 1, 1, addAlphaBit_)\n>                 /* Odd pixel GBGR -> BGGR */\n> -               BGGR_BGR888(1, 1, 1)\n> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n>                 /* Same thing for next 2 pixels */\n> -               GBRG_BGR888(1, 1, 1)\n> -               BGGR_BGR888(1, 2, 1)\n> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n> +               BGGR_BGR888(1, 2, 1, addAlphaBit_)\n>                 /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>                 x++;\n>         }\n> @@ -247,12 +251,12 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>         for (int x = 0; x < widthInBytes;) {\n>                 /* Even pixel */\n> -               RGGB_BGR888(2, 1, 1)\n> +               RGGB_BGR888(2, 1, 1, addAlphaBit_)\n>                 /* Odd pixel RGGB -> GRBG */\n> -               GRBG_BGR888(1, 1, 1)\n> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n>                 /* Same thing for next 2 pixels */\n> -               RGGB_BGR888(1, 1, 1)\n> -               GRBG_BGR888(1, 2, 1)\n> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n> +               GRBG_BGR888(1, 2, 1, addAlphaBit_)\n>                 /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>                 x++;\n>         }\n> @@ -280,7 +284,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>                 config.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>                 config.patternSize.width = 2;\n>                 config.patternSize.height = 2;\n> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +               config.outputFormats = std::vector<PixelFormat>({\n> +                       formats::RGB888,\n> +                       formats::XRGB8888,\n> +                       formats::ARGB8888,\n> +                       formats::BGR888,\n> +                       formats::XBGR8888,\n> +                       formats::ABGR8888\n> +               });\n>                 return 0;\n>         }\n>  \n> @@ -290,7 +301,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>                 config.bpp = 10;\n>                 config.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>                 config.patternSize.height = 2;\n> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +               config.outputFormats = std::vector<PixelFormat>({\n> +                       formats::RGB888,\n> +                       formats::XRGB8888,\n> +                       formats::ARGB8888,\n> +                       formats::BGR888,\n> +                       formats::XBGR8888,\n> +                       formats::ABGR8888\n> +               });\n>                 return 0;\n>         }\n>  \n> @@ -306,6 +324,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>                 return 0;\n>         }\n>  \n> +       if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> +           outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> +               config.bpp = 32;\n> +               return 0;\n> +       }\n> +\n>         LOG(Debayer, Info)\n>                 << \"Unsupported output format \" << outputFormat.toString();\n>         return -EINVAL;\n> @@ -344,6 +368,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \n>         xShift_ = 0;\n>         swapRedBlueGains_ = false;\n> +       addAlphaBit_ = false;\n>  \n>         auto invalidFmt = []() -> int {\n>                 LOG(Debayer, Error) << \"Unsupported input output format combination\";\n> @@ -351,8 +376,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>         };\n>  \n>         switch (outputFormat) {\n> +       case formats::XRGB8888:\n> +       case formats::ARGB8888:\n> +         addAlphaBit_ = true;\n> +         [[fallthrough]];\n>         case formats::RGB888:\n>                 break;\n> +       case formats::XBGR8888:\n> +       case formats::ABGR8888:\n> +         addAlphaBit_ = true;\n> +         [[fallthrough]];\n>         case formats::BGR888:\n>                 /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>                 swapRedBlueGains_ = true;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index be7dcdca..4f77600d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -132,6 +132,7 @@ private:\n>         debayerFn debayer1_;\n>         debayerFn debayer2_;\n>         debayerFn debayer3_;\n> +       bool addAlphaBit_;\n>         Rectangle window_;\n>         DebayerInputConfig inputConfig_;\n>         DebayerOutputConfig outputConfig_;\n> -- \n> 2.45.2\n>","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 436A9C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 17 Jun 2024 22:44:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 603B66548B;\n\tTue, 18 Jun 2024 00:44:39 +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 5308C61A20\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 00:44:38 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id ADA84289;\n\tTue, 18 Jun 2024 00:44:20 +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=\"OB0A18eE\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1718664260;\n\tbh=TMXP0+hnTwyJ9V0Fpb6PjlSVWyEC7YRzAOKgfxv1VVY=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=OB0A18eEwtvUEoXd/9zpUpFGbmqfOmG9dMV6De7GJYwwhxfYprInkXzxe9yrd+LEp\n\td5zRKu1shIQPSg9aQAbEAVLZsb+ci+Pwhag1EVD+QJF2qxmJ9SzedA4G4I2y8ihS1J\n\tWSZFG4p7c17zVarcch/nvSniqGLQoXAuh/tdsLRY=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20240617174131.269437-1-robert.mader@collabora.com>","References":"<20240617174131.269437-1-robert.mader@collabora.com>","Subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Robert Mader <robert.mader@collabora.com>","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 17 Jun 2024 23:44:34 +0100","Message-ID":"<171866427474.804094.9779588349295162791@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>"}},{"id":30015,"web_url":"https://patchwork.libcamera.org/comment/30015/","msgid":"<20240617231039.GF17726@pendragon.ideasonboard.com>","date":"2024-06-17T23:10:39","subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Robert,\n\nThank you for the patch.\n\nOn Mon, Jun 17, 2024 at 07:41:19PM +0200, Robert Mader wrote:\n> In order to be more compatible with modern hardware and APIs. This\n> notably allows GL implementations to directly import the buffers more\n> often and seems to be required for Wayland.\n> \n> Further more, as we already enforce a 8 byte stride, these formats work\n> better for clients that don't support padding - such as libwebrtc at the\n> time of writing.\n> \n> Tested devices:\n>  - Librem5\n>  - PinePhone\n>  - Thinkpad X13s\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  src/libcamera/software_isp/debayer_cpu.cpp | 101 ++++++++++++++-------\n>  src/libcamera/software_isp/debayer_cpu.h   |   1 +\n>  2 files changed, 68 insertions(+), 34 deletions(-)\n> \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index c038eed4..79bb4d87 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -70,10 +70,11 @@ DebayerCpu::~DebayerCpu()\n>   * GBG\n>   * RGR\n>   */\n> -#define BGGR_BGR888(p, n, div)                                                                \\\n> +#define BGGR_BGR888(p, n, div, addAlphaBit)                                                   \\\n>  \t*dst++ = blue_[curr[x] / (div)];                                                      \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>  \t*dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> +\tif (addAlphaBit) *dst++ = 255;                                                        \\\n\nA conditional in here will slow everything down very significantly, not\njust for the new 32-bit formats, but for the existing 24-bit formats. I\ndon't expect Milan and Hans to be very happy about it. We need a way to\nget this conditional optimized out at compile time.\n\nFunction templates could help avoiding the duplication of the macros\nwhile guaranteeing compile-time optimization.\n\n>  \tx++;\n>  \n>  /*\n> @@ -81,10 +82,11 @@ DebayerCpu::~DebayerCpu()\n>   * RGR\n>   * GBG\n>   */\n> -#define GRBG_BGR888(p, n, div)                                    \\\n> +#define GRBG_BGR888(p, n, div, addAlphaBit)                       \\\n>  \t*dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>  \t*dst++ = green_[curr[x] / (div)];                         \\\n>  \t*dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> +\tif (addAlphaBit) *dst++ = 255;                            \\\n>  \tx++;\n>  \n>  /*\n> @@ -92,10 +94,11 @@ DebayerCpu::~DebayerCpu()\n>   * BGB\n>   * GRG\n>   */\n> -#define GBRG_BGR888(p, n, div)                                     \\\n> +#define GBRG_BGR888(p, n, div, addAlphaBit)                        \\\n>  \t*dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>  \t*dst++ = green_[curr[x] / (div)];                          \\\n>  \t*dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> +\tif (addAlphaBit) *dst++ = 255;                             \\\n>  \tx++;\n>  \n>  /*\n> @@ -103,10 +106,11 @@ DebayerCpu::~DebayerCpu()\n>   * GRG\n>   * BGB\n>   */\n> -#define RGGB_BGR888(p, n, div)                                                                 \\\n> +#define RGGB_BGR888(p, n, div, addAlphaBit)                                                    \\\n>  \t*dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>  \t*dst++ = red_[curr[x] / (div)];                                                        \\\n> +\tif (addAlphaBit) *dst++ = 255;                                                         \\\n>  \tx++;\n>  \n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> @@ -114,8 +118,8 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n> -\t\tBGGR_BGR888(1, 1, 1)\n> -\t\tGBRG_BGR888(1, 1, 1)\n> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -124,8 +128,8 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n> -\t\tGRBG_BGR888(1, 1, 1)\n> -\t\tRGGB_BGR888(1, 1, 1)\n> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -135,8 +139,8 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n>  \t\t/* divide values by 4 for 10 -> 8 bpp value */\n> -\t\tBGGR_BGR888(1, 1, 4)\n> -\t\tGBRG_BGR888(1, 1, 4)\n> +\t\tBGGR_BGR888(1, 1, 4, addAlphaBit_)\n> +\t\tGBRG_BGR888(1, 1, 4, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -146,8 +150,8 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n>  \t\t/* divide values by 4 for 10 -> 8 bpp value */\n> -\t\tGRBG_BGR888(1, 1, 4)\n> -\t\tRGGB_BGR888(1, 1, 4)\n> +\t\tGRBG_BGR888(1, 1, 4, addAlphaBit_)\n> +\t\tRGGB_BGR888(1, 1, 4, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -157,8 +161,8 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n>  \t\t/* divide values by 16 for 12 -> 8 bpp value */\n> -\t\tBGGR_BGR888(1, 1, 16)\n> -\t\tGBRG_BGR888(1, 1, 16)\n> +\t\tBGGR_BGR888(1, 1, 16, addAlphaBit_)\n> +\t\tGBRG_BGR888(1, 1, 16, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -168,8 +172,8 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < (int)window_.width;) {\n>  \t\t/* divide values by 16 for 12 -> 8 bpp value */\n> -\t\tGRBG_BGR888(1, 1, 16)\n> -\t\tRGGB_BGR888(1, 1, 16)\n> +\t\tGRBG_BGR888(1, 1, 16, addAlphaBit_)\n> +\t\tRGGB_BGR888(1, 1, 16, addAlphaBit_)\n>  \t}\n>  }\n>  \n> @@ -187,12 +191,12 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t */\n>  \tfor (int x = 0; x < widthInBytes;) {\n>  \t\t/* First pixel */\n> -\t\tBGGR_BGR888(2, 1, 1)\n> +\t\tBGGR_BGR888(2, 1, 1, addAlphaBit_)\n>  \t\t/* Second pixel BGGR -> GBRG */\n> -\t\tGBRG_BGR888(1, 1, 1)\n> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n>  \t\t/* Same thing for third and fourth pixels */\n> -\t\tBGGR_BGR888(1, 1, 1)\n> -\t\tGBRG_BGR888(1, 2, 1)\n> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tGBRG_BGR888(1, 2, 1, addAlphaBit_)\n>  \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>  \t\tx++;\n>  \t}\n> @@ -207,12 +211,12 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < widthInBytes;) {\n>  \t\t/* First pixel */\n> -\t\tGRBG_BGR888(2, 1, 1)\n> +\t\tGRBG_BGR888(2, 1, 1, addAlphaBit_)\n>  \t\t/* Second pixel GRBG -> RGGB */\n> -\t\tRGGB_BGR888(1, 1, 1)\n> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n>  \t\t/* Same thing for third and fourth pixels */\n> -\t\tGRBG_BGR888(1, 1, 1)\n> -\t\tRGGB_BGR888(1, 2, 1)\n> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tRGGB_BGR888(1, 2, 1, addAlphaBit_)\n>  \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>  \t\tx++;\n>  \t}\n> @@ -227,12 +231,12 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < widthInBytes;) {\n>  \t\t/* Even pixel */\n> -\t\tGBRG_BGR888(2, 1, 1)\n> +\t\tGBRG_BGR888(2, 1, 1, addAlphaBit_)\n>  \t\t/* Odd pixel GBGR -> BGGR */\n> -\t\tBGGR_BGR888(1, 1, 1)\n> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n>  \t\t/* Same thing for next 2 pixels */\n> -\t\tGBRG_BGR888(1, 1, 1)\n> -\t\tBGGR_BGR888(1, 2, 1)\n> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tBGGR_BGR888(1, 2, 1, addAlphaBit_)\n>  \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>  \t\tx++;\n>  \t}\n> @@ -247,12 +251,12 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \n>  \tfor (int x = 0; x < widthInBytes;) {\n>  \t\t/* Even pixel */\n> -\t\tRGGB_BGR888(2, 1, 1)\n> +\t\tRGGB_BGR888(2, 1, 1, addAlphaBit_)\n>  \t\t/* Odd pixel RGGB -> GRBG */\n> -\t\tGRBG_BGR888(1, 1, 1)\n> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n>  \t\t/* Same thing for next 2 pixels */\n> -\t\tRGGB_BGR888(1, 1, 1)\n> -\t\tGRBG_BGR888(1, 2, 1)\n> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n> +\t\tGRBG_BGR888(1, 2, 1, addAlphaBit_)\n>  \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>  \t\tx++;\n>  \t}\n> @@ -280,7 +284,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \t\tconfig.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>  \t\tconfig.patternSize.width = 2;\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +\t\tconfig.outputFormats = std::vector<PixelFormat>({\n> +\t\t\tformats::RGB888,\n> +\t\t\tformats::XRGB8888,\n> +\t\t\tformats::ARGB8888,\n> +\t\t\tformats::BGR888,\n> +\t\t\tformats::XBGR8888,\n> +\t\t\tformats::ABGR8888\n> +\t\t});\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -290,7 +301,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \t\tconfig.bpp = 10;\n>  \t\tconfig.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +\t\tconfig.outputFormats = std::vector<PixelFormat>({\n> +\t\t\tformats::RGB888,\n> +\t\t\tformats::XRGB8888,\n> +\t\t\tformats::ARGB8888,\n> +\t\t\tformats::BGR888,\n> +\t\t\tformats::XBGR8888,\n> +\t\t\tformats::ABGR8888\n> +\t\t});\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -306,6 +324,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> +\t    outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> +\t\tconfig.bpp = 32;\n> +\t\treturn 0;\n> +\t}\n> +\n>  \tLOG(Debayer, Info)\n>  \t\t<< \"Unsupported output format \" << outputFormat.toString();\n>  \treturn -EINVAL;\n> @@ -344,6 +368,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \n>  \txShift_ = 0;\n>  \tswapRedBlueGains_ = false;\n> +\taddAlphaBit_ = false;\n>  \n>  \tauto invalidFmt = []() -> int {\n>  \t\tLOG(Debayer, Error) << \"Unsupported input output format combination\";\n> @@ -351,8 +376,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t};\n>  \n>  \tswitch (outputFormat) {\n> +\tcase formats::XRGB8888:\n> +\tcase formats::ARGB8888:\n> +\t  addAlphaBit_ = true;\n> +\t  [[fallthrough]];\n>  \tcase formats::RGB888:\n>  \t\tbreak;\n> +\tcase formats::XBGR8888:\n> +\tcase formats::ABGR8888:\n> +\t  addAlphaBit_ = true;\n> +\t  [[fallthrough]];\n>  \tcase formats::BGR888:\n>  \t\t/* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>  \t\tswapRedBlueGains_ = true;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index be7dcdca..4f77600d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -132,6 +132,7 @@ private:\n>  \tdebayerFn debayer1_;\n>  \tdebayerFn debayer2_;\n>  \tdebayerFn debayer3_;\n> +\tbool addAlphaBit_;\n>  \tRectangle window_;\n>  \tDebayerInputConfig inputConfig_;\n>  \tDebayerOutputConfig outputConfig_;","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 06C83C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 17 Jun 2024 23:11:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F01266548B;\n\tTue, 18 Jun 2024 01:11:03 +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 7C7AD61A20\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 01:11:02 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 19322289;\n\tTue, 18 Jun 2024 01:10:44 +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=\"iEHtwoxK\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1718665844;\n\tbh=SigIPn6UtVz8vbTX/oPrdSz+KPwkT0Q3cTNI0NYMRTw=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=iEHtwoxK3jqnzXU2592F2Sq2FXJLRIfKvNcrCXnPt02O0oVJtXrhtmQGp3d+1b7+G\n\tVAaZxKrVH5WDzTyeiPM8+DSmheNrAFWLs+PerlFDpEvu4PFC4quDzVBl8N0F2MjwCm\n\tW05d1m3qLciu+36jJdALTlX4YpY+zg47FR7ps1TY=","Date":"Tue, 18 Jun 2024 02:10:39 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Robert Mader <robert.mader@collabora.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","Message-ID":"<20240617231039.GF17726@pendragon.ideasonboard.com>","References":"<20240617174131.269437-1-robert.mader@collabora.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20240617174131.269437-1-robert.mader@collabora.com>","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>"}},{"id":30023,"web_url":"https://patchwork.libcamera.org/comment/30023/","msgid":"<0617d891-15bb-47e1-a068-a69e7e84418d@collabora.com>","date":"2024-06-18T06:34:30","subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"On 18.06.24 01:10, Laurent Pinchart wrote:\n> Hi Robert,\n>\n> Thank you for the patch.\n>\n> On Mon, Jun 17, 2024 at 07:41:19PM +0200, Robert Mader wrote:\n>> In order to be more compatible with modern hardware and APIs. This\n>> notably allows GL implementations to directly import the buffers more\n>> often and seems to be required for Wayland.\n>>\n>> Further more, as we already enforce a 8 byte stride, these formats work\n>> better for clients that don't support padding - such as libwebrtc at the\n>> time of writing.\n>>\n>> Tested devices:\n>>   - Librem5\n>>   - PinePhone\n>>   - Thinkpad X13s\n>>\n>> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n>> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>> ---\n>>   src/libcamera/software_isp/debayer_cpu.cpp | 101 ++++++++++++++-------\n>>   src/libcamera/software_isp/debayer_cpu.h   |   1 +\n>>   2 files changed, 68 insertions(+), 34 deletions(-)\n>>\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n>> index c038eed4..79bb4d87 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n>> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n>> @@ -70,10 +70,11 @@ DebayerCpu::~DebayerCpu()\n>>    * GBG\n>>    * RGR\n>>    */\n>> -#define BGGR_BGR888(p, n, div)                                                                \\\n>> +#define BGGR_BGR888(p, n, div, addAlphaBit)                                                   \\\n>>   \t*dst++ = blue_[curr[x] / (div)];                                                      \\\n>>   \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>>   \t*dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>> +\tif (addAlphaBit) *dst++ = 255;                                                        \\\n> A conditional in here will slow everything down very significantly, not\n> just for the new 32-bit formats, but for the existing 24-bit formats. I\n> don't expect Milan and Hans to be very happy about it. We need a way to\n> get this conditional optimized out at compile time.\n>\n> Function templates could help avoiding the duplication of the macros\n> while guaranteeing compile-time optimization.\nTried this in v3 now, turned out quite nicely IMO.\n>\n>>   \tx++;\n>>   \n>>   /*\n>> @@ -81,10 +82,11 @@ DebayerCpu::~DebayerCpu()\n>>    * RGR\n>>    * GBG\n>>    */\n>> -#define GRBG_BGR888(p, n, div)                                    \\\n>> +#define GRBG_BGR888(p, n, div, addAlphaBit)                       \\\n>>   \t*dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>>   \t*dst++ = green_[curr[x] / (div)];                         \\\n>>   \t*dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>> +\tif (addAlphaBit) *dst++ = 255;                            \\\n>>   \tx++;\n>>   \n>>   /*\n>> @@ -92,10 +94,11 @@ DebayerCpu::~DebayerCpu()\n>>    * BGB\n>>    * GRG\n>>    */\n>> -#define GBRG_BGR888(p, n, div)                                     \\\n>> +#define GBRG_BGR888(p, n, div, addAlphaBit)                        \\\n>>   \t*dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>>   \t*dst++ = green_[curr[x] / (div)];                          \\\n>>   \t*dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n>> +\tif (addAlphaBit) *dst++ = 255;                             \\\n>>   \tx++;\n>>   \n>>   /*\n>> @@ -103,10 +106,11 @@ DebayerCpu::~DebayerCpu()\n>>    * GRG\n>>    * BGB\n>>    */\n>> -#define RGGB_BGR888(p, n, div)                                                                 \\\n>> +#define RGGB_BGR888(p, n, div, addAlphaBit)                                                    \\\n>>   \t*dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>>   \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>>   \t*dst++ = red_[curr[x] / (div)];                                                        \\\n>> +\tif (addAlphaBit) *dst++ = 255;                                                         \\\n>>   \tx++;\n>>   \n>>   void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>> @@ -114,8 +118,8 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \tDECLARE_SRC_POINTERS(uint8_t)\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>> -\t\tBGGR_BGR888(1, 1, 1)\n>> -\t\tGBRG_BGR888(1, 1, 1)\n>> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -124,8 +128,8 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \tDECLARE_SRC_POINTERS(uint8_t)\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>> -\t\tGRBG_BGR888(1, 1, 1)\n>> -\t\tRGGB_BGR888(1, 1, 1)\n>> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -135,8 +139,8 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>>   \t\t/* divide values by 4 for 10 -> 8 bpp value */\n>> -\t\tBGGR_BGR888(1, 1, 4)\n>> -\t\tGBRG_BGR888(1, 1, 4)\n>> +\t\tBGGR_BGR888(1, 1, 4, addAlphaBit_)\n>> +\t\tGBRG_BGR888(1, 1, 4, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -146,8 +150,8 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>>   \t\t/* divide values by 4 for 10 -> 8 bpp value */\n>> -\t\tGRBG_BGR888(1, 1, 4)\n>> -\t\tRGGB_BGR888(1, 1, 4)\n>> +\t\tGRBG_BGR888(1, 1, 4, addAlphaBit_)\n>> +\t\tRGGB_BGR888(1, 1, 4, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -157,8 +161,8 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>>   \t\t/* divide values by 16 for 12 -> 8 bpp value */\n>> -\t\tBGGR_BGR888(1, 1, 16)\n>> -\t\tGBRG_BGR888(1, 1, 16)\n>> +\t\tBGGR_BGR888(1, 1, 16, addAlphaBit_)\n>> +\t\tGBRG_BGR888(1, 1, 16, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -168,8 +172,8 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < (int)window_.width;) {\n>>   \t\t/* divide values by 16 for 12 -> 8 bpp value */\n>> -\t\tGRBG_BGR888(1, 1, 16)\n>> -\t\tRGGB_BGR888(1, 1, 16)\n>> +\t\tGRBG_BGR888(1, 1, 16, addAlphaBit_)\n>> +\t\tRGGB_BGR888(1, 1, 16, addAlphaBit_)\n>>   \t}\n>>   }\n>>   \n>> @@ -187,12 +191,12 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \t */\n>>   \tfor (int x = 0; x < widthInBytes;) {\n>>   \t\t/* First pixel */\n>> -\t\tBGGR_BGR888(2, 1, 1)\n>> +\t\tBGGR_BGR888(2, 1, 1, addAlphaBit_)\n>>   \t\t/* Second pixel BGGR -> GBRG */\n>> -\t\tGBRG_BGR888(1, 1, 1)\n>> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t\t/* Same thing for third and fourth pixels */\n>> -\t\tBGGR_BGR888(1, 1, 1)\n>> -\t\tGBRG_BGR888(1, 2, 1)\n>> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tGBRG_BGR888(1, 2, 1, addAlphaBit_)\n>>   \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>   \t\tx++;\n>>   \t}\n>> @@ -207,12 +211,12 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < widthInBytes;) {\n>>   \t\t/* First pixel */\n>> -\t\tGRBG_BGR888(2, 1, 1)\n>> +\t\tGRBG_BGR888(2, 1, 1, addAlphaBit_)\n>>   \t\t/* Second pixel GRBG -> RGGB */\n>> -\t\tRGGB_BGR888(1, 1, 1)\n>> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t\t/* Same thing for third and fourth pixels */\n>> -\t\tGRBG_BGR888(1, 1, 1)\n>> -\t\tRGGB_BGR888(1, 2, 1)\n>> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tRGGB_BGR888(1, 2, 1, addAlphaBit_)\n>>   \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>   \t\tx++;\n>>   \t}\n>> @@ -227,12 +231,12 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < widthInBytes;) {\n>>   \t\t/* Even pixel */\n>> -\t\tGBRG_BGR888(2, 1, 1)\n>> +\t\tGBRG_BGR888(2, 1, 1, addAlphaBit_)\n>>   \t\t/* Odd pixel GBGR -> BGGR */\n>> -\t\tBGGR_BGR888(1, 1, 1)\n>> +\t\tBGGR_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t\t/* Same thing for next 2 pixels */\n>> -\t\tGBRG_BGR888(1, 1, 1)\n>> -\t\tBGGR_BGR888(1, 2, 1)\n>> +\t\tGBRG_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tBGGR_BGR888(1, 2, 1, addAlphaBit_)\n>>   \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>   \t\tx++;\n>>   \t}\n>> @@ -247,12 +251,12 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>   \tfor (int x = 0; x < widthInBytes;) {\n>>   \t\t/* Even pixel */\n>> -\t\tRGGB_BGR888(2, 1, 1)\n>> +\t\tRGGB_BGR888(2, 1, 1, addAlphaBit_)\n>>   \t\t/* Odd pixel RGGB -> GRBG */\n>> -\t\tGRBG_BGR888(1, 1, 1)\n>> +\t\tGRBG_BGR888(1, 1, 1, addAlphaBit_)\n>>   \t\t/* Same thing for next 2 pixels */\n>> -\t\tRGGB_BGR888(1, 1, 1)\n>> -\t\tGRBG_BGR888(1, 2, 1)\n>> +\t\tRGGB_BGR888(1, 1, 1, addAlphaBit_)\n>> +\t\tGRBG_BGR888(1, 2, 1, addAlphaBit_)\n>>   \t\t/* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>   \t\tx++;\n>>   \t}\n>> @@ -280,7 +284,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>   \t\tconfig.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>>   \t\tconfig.patternSize.width = 2;\n>>   \t\tconfig.patternSize.height = 2;\n>> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>> +\t\tconfig.outputFormats = std::vector<PixelFormat>({\n>> +\t\t\tformats::RGB888,\n>> +\t\t\tformats::XRGB8888,\n>> +\t\t\tformats::ARGB8888,\n>> +\t\t\tformats::BGR888,\n>> +\t\t\tformats::XBGR8888,\n>> +\t\t\tformats::ABGR8888\n>> +\t\t});\n>>   \t\treturn 0;\n>>   \t}\n>>   \n>> @@ -290,7 +301,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>   \t\tconfig.bpp = 10;\n>>   \t\tconfig.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>>   \t\tconfig.patternSize.height = 2;\n>> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>> +\t\tconfig.outputFormats = std::vector<PixelFormat>({\n>> +\t\t\tformats::RGB888,\n>> +\t\t\tformats::XRGB8888,\n>> +\t\t\tformats::ARGB8888,\n>> +\t\t\tformats::BGR888,\n>> +\t\t\tformats::XBGR8888,\n>> +\t\t\tformats::ABGR8888\n>> +\t\t});\n>>   \t\treturn 0;\n>>   \t}\n>>   \n>> @@ -306,6 +324,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>>   \t\treturn 0;\n>>   \t}\n>>   \n>> +\tif (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n>> +\t    outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n>> +\t\tconfig.bpp = 32;\n>> +\t\treturn 0;\n>> +\t}\n>> +\n>>   \tLOG(Debayer, Info)\n>>   \t\t<< \"Unsupported output format \" << outputFormat.toString();\n>>   \treturn -EINVAL;\n>> @@ -344,6 +368,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>   \n>>   \txShift_ = 0;\n>>   \tswapRedBlueGains_ = false;\n>> +\taddAlphaBit_ = false;\n>>   \n>>   \tauto invalidFmt = []() -> int {\n>>   \t\tLOG(Debayer, Error) << \"Unsupported input output format combination\";\n>> @@ -351,8 +376,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>   \t};\n>>   \n>>   \tswitch (outputFormat) {\n>> +\tcase formats::XRGB8888:\n>> +\tcase formats::ARGB8888:\n>> +\t  addAlphaBit_ = true;\n>> +\t  [[fallthrough]];\n>>   \tcase formats::RGB888:\n>>   \t\tbreak;\n>> +\tcase formats::XBGR8888:\n>> +\tcase formats::ABGR8888:\n>> +\t  addAlphaBit_ = true;\n>> +\t  [[fallthrough]];\n>>   \tcase formats::BGR888:\n>>   \t\t/* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>>   \t\tswapRedBlueGains_ = true;\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n>> index be7dcdca..4f77600d 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.h\n>> +++ b/src/libcamera/software_isp/debayer_cpu.h\n>> @@ -132,6 +132,7 @@ private:\n>>   \tdebayerFn debayer1_;\n>>   \tdebayerFn debayer2_;\n>>   \tdebayerFn debayer3_;\n>> +\tbool addAlphaBit_;\n>>   \tRectangle window_;\n>>   \tDebayerInputConfig inputConfig_;\n>>   \tDebayerOutputConfig outputConfig_;","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 0D9A0BE175\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Jun 2024 06:34:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B0AFE654A4;\n\tTue, 18 Jun 2024 08:34:32 +0200 (CEST)","from madrid.collaboradmins.com (madrid.collaboradmins.com\n\t[IPv6:2a00:1098:ed:100::25])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D38D0619F6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 08:34:31 +0200 (CEST)","from [100.107.172.5] (cola.collaboradmins.com [195.201.22.229])\n\t(using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (4096 bits)\n\tserver-digest SHA256)\n\t(No client certificate requested) (Authenticated sender: rmader)\n\tby madrid.collaboradmins.com (Postfix) with ESMTPSA id 6275E3781F9A; \n\tTue, 18 Jun 2024 06:34:31 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=collabora.com header.i=@collabora.com\n\theader.b=\"29ZRLb9d\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com;\n\ts=mail; t=1718692471;\n\tbh=v473MSJdop4NFcXnmnXZO9uCR3hBflo5PBRokJJVDes=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=29ZRLb9dbCdJV7DzV85Vb2+nh4QBrkw78v+k0PhRXa0aP75iCHU3V0Ft1xf3R9Hq/\n\tK+Xe/dqbRJ4TYWrBKkkvm/XPvNsqmM7qf6B7YjsJaP6+lz+xgnLxXL0mwzGIFdy/Sh\n\tCmkeRYT2iqzLcdKk9to0j4pJQsKGRKVIzxp7iYyMUm4llajkR8fyvNEjL3U6Pj7VQ1\n\tgrVdbm/PB9KESDYYmXibq4RDoUCBB+PyfUp30JM/AoupA9pG7bGGf8yrpwEKYkrckf\n\tKvr2ILeE1hxc15dKLtS5ciqqCnu5lqchOl8yxwq22tBQcXxmG3jm2vEt/n7pM6RP7T\n\t0+JTn/OzWTKtg==","Message-ID":"<0617d891-15bb-47e1-a068-a69e7e84418d@collabora.com>","Date":"Tue, 18 Jun 2024 08:34:30 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","References":"<20240617174131.269437-1-robert.mader@collabora.com>\n\t<20240617231039.GF17726@pendragon.ideasonboard.com>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<20240617231039.GF17726@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","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>"}},{"id":30024,"web_url":"https://patchwork.libcamera.org/comment/30024/","msgid":"<c3ce1346-9b46-4f97-b0d5-887bd462b6b8@collabora.com>","date":"2024-06-18T06:36:05","subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"On 18.06.24 00:44, Kieran Bingham wrote:\n> Quoting Robert Mader (2024-06-17 18:41:19)\n>> In order to be more compatible with modern hardware and APIs. This\n>> notably allows GL implementations to directly import the buffers more\n>> often and seems to be required for Wayland.\n>>\n>> Further more, as we already enforce a 8 byte stride, these formats work\n>> better for clients that don't support padding - such as libwebrtc at the\n>> time of writing.\n>>\n>> Tested devices:\n>>   - Librem5\n>>   - PinePhone\n>>   - Thinkpad X13s\n>>\n>> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n>> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> CI Green:\n>   - https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1203631\n>\n> except for lint:\n>   - https://gitlab.freedesktop.org/camera/libcamera/-/jobs/60008198\n>\n> Could be helpful to add the checkstyle hooks to your local build to see\n> these in advance.\nYeah, my clang-format was a bit odd previously because of other \nprojects. Fixed that now and ran utils/checkstyle.py locally, fixed all \nerrors in v3.\n>\n> Could very easily be fixed while applying though ... but I'd probably\n> want to see a review/ack tag from someone directly working on the SoftISP\n> code ...\n>\n>\n>> ---\n>>   src/libcamera/software_isp/debayer_cpu.cpp | 101 ++++++++++++++-------\n>>   src/libcamera/software_isp/debayer_cpu.h   |   1 +\n>>   2 files changed, 68 insertions(+), 34 deletions(-)\n>>\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n>> index c038eed4..79bb4d87 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n>> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n>> @@ -70,10 +70,11 @@ DebayerCpu::~DebayerCpu()\n>>    * GBG\n>>    * RGR\n>>    */\n>> -#define BGGR_BGR888(p, n, div)                                                                \\\n>> +#define BGGR_BGR888(p, n, div, addAlphaBit)                                                   \\\n>>          *dst++ = blue_[curr[x] / (div)];                                                      \\\n>>          *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>>          *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>> +       if (addAlphaBit) *dst++ = 255;                                                        \\\n>>          x++;\n>>   \n>>   /*\n>> @@ -81,10 +82,11 @@ DebayerCpu::~DebayerCpu()\n>>    * RGR\n>>    * GBG\n>>    */\n>> -#define GRBG_BGR888(p, n, div)                                    \\\n>> +#define GRBG_BGR888(p, n, div, addAlphaBit)                       \\\n>>          *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>>          *dst++ = green_[curr[x] / (div)];                         \\\n>>          *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>> +       if (addAlphaBit) *dst++ = 255;                            \\\n>>          x++;\n>>   \n>>   /*\n>> @@ -92,10 +94,11 @@ DebayerCpu::~DebayerCpu()\n>>    * BGB\n>>    * GRG\n>>    */\n>> -#define GBRG_BGR888(p, n, div)                                     \\\n>> +#define GBRG_BGR888(p, n, div, addAlphaBit)                        \\\n>>          *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>>          *dst++ = green_[curr[x] / (div)];                          \\\n>>          *dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n>> +       if (addAlphaBit) *dst++ = 255;                             \\\n>>          x++;\n>>   \n>>   /*\n>> @@ -103,10 +106,11 @@ DebayerCpu::~DebayerCpu()\n>>    * GRG\n>>    * BGB\n>>    */\n>> -#define RGGB_BGR888(p, n, div)                                                                 \\\n>> +#define RGGB_BGR888(p, n, div, addAlphaBit)                                                    \\\n>>          *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>>          *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>>          *dst++ = red_[curr[x] / (div)];                                                        \\\n>> +       if (addAlphaBit) *dst++ = 255;                                                         \\\n>>          x++;\n>>   \n>>   void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>> @@ -114,8 +118,8 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>          DECLARE_SRC_POINTERS(uint8_t)\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>> -               BGGR_BGR888(1, 1, 1)\n>> -               GBRG_BGR888(1, 1, 1)\n>> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n>> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -124,8 +128,8 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>          DECLARE_SRC_POINTERS(uint8_t)\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>> -               GRBG_BGR888(1, 1, 1)\n>> -               RGGB_BGR888(1, 1, 1)\n>> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n>> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -135,8 +139,8 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>>                  /* divide values by 4 for 10 -> 8 bpp value */\n>> -               BGGR_BGR888(1, 1, 4)\n>> -               GBRG_BGR888(1, 1, 4)\n>> +               BGGR_BGR888(1, 1, 4, addAlphaBit_)\n>> +               GBRG_BGR888(1, 1, 4, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -146,8 +150,8 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>>                  /* divide values by 4 for 10 -> 8 bpp value */\n>> -               GRBG_BGR888(1, 1, 4)\n>> -               RGGB_BGR888(1, 1, 4)\n>> +               GRBG_BGR888(1, 1, 4, addAlphaBit_)\n>> +               RGGB_BGR888(1, 1, 4, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -157,8 +161,8 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>>                  /* divide values by 16 for 12 -> 8 bpp value */\n>> -               BGGR_BGR888(1, 1, 16)\n>> -               GBRG_BGR888(1, 1, 16)\n>> +               BGGR_BGR888(1, 1, 16, addAlphaBit_)\n>> +               GBRG_BGR888(1, 1, 16, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -168,8 +172,8 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < (int)window_.width;) {\n>>                  /* divide values by 16 for 12 -> 8 bpp value */\n>> -               GRBG_BGR888(1, 1, 16)\n>> -               RGGB_BGR888(1, 1, 16)\n>> +               GRBG_BGR888(1, 1, 16, addAlphaBit_)\n>> +               RGGB_BGR888(1, 1, 16, addAlphaBit_)\n>>          }\n>>   }\n>>   \n>> @@ -187,12 +191,12 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>           */\n>>          for (int x = 0; x < widthInBytes;) {\n>>                  /* First pixel */\n>> -               BGGR_BGR888(2, 1, 1)\n>> +               BGGR_BGR888(2, 1, 1, addAlphaBit_)\n>>                  /* Second pixel BGGR -> GBRG */\n>> -               GBRG_BGR888(1, 1, 1)\n>> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n>>                  /* Same thing for third and fourth pixels */\n>> -               BGGR_BGR888(1, 1, 1)\n>> -               GBRG_BGR888(1, 2, 1)\n>> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n>> +               GBRG_BGR888(1, 2, 1, addAlphaBit_)\n>>                  /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>                  x++;\n>>          }\n>> @@ -207,12 +211,12 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < widthInBytes;) {\n>>                  /* First pixel */\n>> -               GRBG_BGR888(2, 1, 1)\n>> +               GRBG_BGR888(2, 1, 1, addAlphaBit_)\n>>                  /* Second pixel GRBG -> RGGB */\n>> -               RGGB_BGR888(1, 1, 1)\n>> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n>>                  /* Same thing for third and fourth pixels */\n>> -               GRBG_BGR888(1, 1, 1)\n>> -               RGGB_BGR888(1, 2, 1)\n>> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n>> +               RGGB_BGR888(1, 2, 1, addAlphaBit_)\n>>                  /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>                  x++;\n>>          }\n>> @@ -227,12 +231,12 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < widthInBytes;) {\n>>                  /* Even pixel */\n>> -               GBRG_BGR888(2, 1, 1)\n>> +               GBRG_BGR888(2, 1, 1, addAlphaBit_)\n>>                  /* Odd pixel GBGR -> BGGR */\n>> -               BGGR_BGR888(1, 1, 1)\n>> +               BGGR_BGR888(1, 1, 1, addAlphaBit_)\n>>                  /* Same thing for next 2 pixels */\n>> -               GBRG_BGR888(1, 1, 1)\n>> -               BGGR_BGR888(1, 2, 1)\n>> +               GBRG_BGR888(1, 1, 1, addAlphaBit_)\n>> +               BGGR_BGR888(1, 2, 1, addAlphaBit_)\n>>                  /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>                  x++;\n>>          }\n>> @@ -247,12 +251,12 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>   \n>>          for (int x = 0; x < widthInBytes;) {\n>>                  /* Even pixel */\n>> -               RGGB_BGR888(2, 1, 1)\n>> +               RGGB_BGR888(2, 1, 1, addAlphaBit_)\n>>                  /* Odd pixel RGGB -> GRBG */\n>> -               GRBG_BGR888(1, 1, 1)\n>> +               GRBG_BGR888(1, 1, 1, addAlphaBit_)\n>>                  /* Same thing for next 2 pixels */\n>> -               RGGB_BGR888(1, 1, 1)\n>> -               GRBG_BGR888(1, 2, 1)\n>> +               RGGB_BGR888(1, 1, 1, addAlphaBit_)\n>> +               GRBG_BGR888(1, 2, 1, addAlphaBit_)\n>>                  /* Skip 5th src byte with 4 x 2 least-significant-bits */\n>>                  x++;\n>>          }\n>> @@ -280,7 +284,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>                  config.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>>                  config.patternSize.width = 2;\n>>                  config.patternSize.height = 2;\n>> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>> +               config.outputFormats = std::vector<PixelFormat>({\n>> +                       formats::RGB888,\n>> +                       formats::XRGB8888,\n>> +                       formats::ARGB8888,\n>> +                       formats::BGR888,\n>> +                       formats::XBGR8888,\n>> +                       formats::ABGR8888\n>> +               });\n>>                  return 0;\n>>          }\n>>   \n>> @@ -290,7 +301,14 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>                  config.bpp = 10;\n>>                  config.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>>                  config.patternSize.height = 2;\n>> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>> +               config.outputFormats = std::vector<PixelFormat>({\n>> +                       formats::RGB888,\n>> +                       formats::XRGB8888,\n>> +                       formats::ARGB8888,\n>> +                       formats::BGR888,\n>> +                       formats::XBGR8888,\n>> +                       formats::ABGR8888\n>> +               });\n>>                  return 0;\n>>          }\n>>   \n>> @@ -306,6 +324,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>>                  return 0;\n>>          }\n>>   \n>> +       if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n>> +           outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n>> +               config.bpp = 32;\n>> +               return 0;\n>> +       }\n>> +\n>>          LOG(Debayer, Info)\n>>                  << \"Unsupported output format \" << outputFormat.toString();\n>>          return -EINVAL;\n>> @@ -344,6 +368,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>   \n>>          xShift_ = 0;\n>>          swapRedBlueGains_ = false;\n>> +       addAlphaBit_ = false;\n>>   \n>>          auto invalidFmt = []() -> int {\n>>                  LOG(Debayer, Error) << \"Unsupported input output format combination\";\n>> @@ -351,8 +376,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>          };\n>>   \n>>          switch (outputFormat) {\n>> +       case formats::XRGB8888:\n>> +       case formats::ARGB8888:\n>> +         addAlphaBit_ = true;\n>> +         [[fallthrough]];\n>>          case formats::RGB888:\n>>                  break;\n>> +       case formats::XBGR8888:\n>> +       case formats::ABGR8888:\n>> +         addAlphaBit_ = true;\n>> +         [[fallthrough]];\n>>          case formats::BGR888:\n>>                  /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>>                  swapRedBlueGains_ = true;\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n>> index be7dcdca..4f77600d 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.h\n>> +++ b/src/libcamera/software_isp/debayer_cpu.h\n>> @@ -132,6 +132,7 @@ private:\n>>          debayerFn debayer1_;\n>>          debayerFn debayer2_;\n>>          debayerFn debayer3_;\n>> +       bool addAlphaBit_;\n>>          Rectangle window_;\n>>          DebayerInputConfig inputConfig_;\n>>          DebayerOutputConfig outputConfig_;\n>> -- \n>> 2.45.2\n>>","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 3F5C1BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Jun 2024 06:36:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E0B6A654A6;\n\tTue, 18 Jun 2024 08:36:07 +0200 (CEST)","from madrid.collaboradmins.com (madrid.collaboradmins.com\n\t[46.235.227.194])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DA45065491\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 08:36:06 +0200 (CEST)","from [100.107.172.5] (cola.collaboradmins.com [195.201.22.229])\n\t(using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (4096 bits)\n\tserver-digest SHA256)\n\t(No client certificate requested) (Authenticated sender: rmader)\n\tby madrid.collaboradmins.com (Postfix) with ESMTPSA id 6DEA03781F9A; \n\tTue, 18 Jun 2024 06:36:06 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=collabora.com header.i=@collabora.com\n\theader.b=\"qf9BUU1T\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com;\n\ts=mail; t=1718692566;\n\tbh=9EaZWBpWV7rVItYrAsWbcdvrlE82a40c8nV2mRr7oVk=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=qf9BUU1Tb0HnTHp6i6MyEH7NGK9bYSuWXT9PlZcEJHge8+pDtz9o8KCMMfDU28vVW\n\tqoVYpwCkY2jhW7+uLsBWKZ0UC1DYlcL019UWM9Y8i7wmDlDXCSV/b3rGGBKq1UxFga\n\toFA2O8u+U2oAQaOfGQ3Ql6JTdDwcMt1PKs6JDArrZJZP2lHFRsjQS3Q96Ib1Nv6xUe\n\tpttLYtwEh3WpLS0rssZZ63QL3ZvVgG8KtPD3bZ59oild7mIDHVx+5TZPRtOBKqiIRO\n\thwc7WXg73CIIrHrRKX+Qvk6LKoIS39VS6HrgRcQqECQEXj9qHQhrRzQWU4Tx6m+R42\n\thZ4KEI7EldMFw==","Message-ID":"<c3ce1346-9b46-4f97-b0d5-887bd462b6b8@collabora.com>","Date":"Tue, 18 Jun 2024 08:36:05 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20240617174131.269437-1-robert.mader@collabora.com>\n\t<171866427474.804094.9779588349295162791@ping.linuxembedded.co.uk>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<171866427474.804094.9779588349295162791@ping.linuxembedded.co.uk>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","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>"}}]