[{"id":34489,"web_url":"https://patchwork.libcamera.org/comment/34489/","msgid":"<de7ba729-b824-4317-8b8c-4f68d7b7b8c1@linaro.org>","date":"2025-06-16T19:12:55","subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","submitter":{"id":175,"url":"https://patchwork.libcamera.org/api/people/175/","name":"Bryan O'Donoghue","email":"bryan.odonoghue@linaro.org"},"content":"On 11/06/2025 02:32, Bryan O'Donoghue wrote:\n> A helper class to interact with GBM. This will allow us to specify the\n> internal storage format of the CPU when making a texture for the Debayer\n> vertext/fragment shaders and thus ensure we receive an uncompressed and\n> untiled output buffer.\n> \n> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> ---\n>   include/libcamera/internal/gbm.h       |  55 ++++++++++\n>   include/libcamera/internal/meson.build |   1 +\n>   src/libcamera/gbm.cpp                  | 137 +++++++++++++++++++++++++\n>   src/libcamera/meson.build              |  11 ++\n>   4 files changed, 204 insertions(+)\n>   create mode 100644 include/libcamera/internal/gbm.h\n>   create mode 100644 src/libcamera/gbm.cpp\n> \n> diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h\n> new file mode 100644\n> index 00000000..a5486cc9\n> --- /dev/null\n> +++ b/include/libcamera/internal/gbm.h\n> @@ -0,0 +1,55 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * gbm.h - Helper class for managing GBM interactions.\n> + */\n> +\n> +#pragma once\n> +\n> +#include <gbm.h>\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include <libcamera/formats.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DECLARE_CATEGORY(GBM)\n> +\n> +class GBM\n> +{\n> +public:\n> +\tGBM();\n> +\t~GBM();\n> +\n> +\tint initSurface(uint32_t width, uint32_t height);\n> +\tint mapSurface();\n> +\tint getFrameBufferData(uint8_t *data_out, size_t data_len);\n> +\tstruct gbm_device *getDevice() { return gbm_device_; }\n> +\tstruct gbm_surface *getSurface() { return gbm_surface_; }\n> +\tuint32_t getFrameSize() { return framesize_; }\n> +\tuint32_t getStride() { return stride_; }\n> +\tPixelFormat getPixelFormat() { return format_; }\n> +\n> +private:\n> +\tint fd_;\n> +\tstruct gbm_device *gbm_device_;\n> +\tstruct gbm_surface *gbm_surface_;\n> +\n> +\tstruct gbm_bo *gbm_bo_;\n> +\tuint32_t width_;\n> +\tuint32_t height_;\n> +\tuint32_t stride_;\n> +\tuint32_t offset_;\n> +\tuint32_t framesize_;\n> +\tvoid *map_;\n> +\tint bo_fd_;\n> +\n> +\tPixelFormat format_;\n> +};\n> +\n> +} // namespace libcamera\n> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\n> index c0b593bf..4a2919f6 100644\n> --- a/include/libcamera/internal/meson.build\n> +++ b/include/libcamera/internal/meson.build\n> @@ -23,6 +23,7 @@ libcamera_internal_headers = files([\n>       'dma_buf_allocator.h',\n>       'formats.h',\n>       'framebuffer.h',\n> +    'gbm.h',\n>       'ipa_data_serializer.h',\n>       'ipa_manager.h',\n>       'ipa_module.h',\n> diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp\n> new file mode 100644\n> index 00000000..43032093\n> --- /dev/null\n> +++ b/src/libcamera/gbm.cpp\n> @@ -0,0 +1,137 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * egl.cpp - Helper class for managing GBM interactions.\n> + */\n> +\n> +#include \"libcamera/internal/gbm.h\"\n> +\n> +#include <fcntl.h>\n> +#include <sys/ioctl.h>\n> +#include <sys/mman.h>\n> +#include <unistd.h>\n> +\n> +#include <linux/dma-buf.h>\n> +#include <linux/dma-heap.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(GBM)\n> +\n> +GBM::GBM()\n> +{\n> +\tfd_ = 0;\n> +}\n> +\n> +GBM::~GBM()\n> +{\n> +\tif (gbm_surface_)\n> +\t\tgbm_surface_destroy(gbm_surface_);\n> +\n> +\tif (gbm_device_)\n> +\t\tgbm_device_destroy(gbm_device_);\n> +\n> +\tif (fd_ >= 0)\n> +\t\tclose(fd_);\n> +}\n> +\n> +// this should probably go into its own class to deal with the\n> +// allocation and deletion of frambuffers attached to GBM devices/objects\n> +int GBM::initSurface(uint32_t width, uint32_t height)\n> +{\n> +\tconst char *dri_node = \"/dev/dri/renderD128\"; //TODO: get from an env or config setting\n> +\n> +\tfd_ = open(dri_node, O_RDWR | O_CLOEXEC); //TODO: CLOEXEC ?\n> +\tif (fd_ < 0) {\n> +\t\tLOG(GBM, Error) << \"Open \" << dri_node << \" fail \" << fd_;\n> +\t\treturn fd_;\n> +\t}\n> +\n> +\tgbm_device_ = gbm_create_device(fd_);\n> +\tif (!gbm_device_) {\n> +\t\tLOG(GBM, Error) << \"gbm_crate_device fail\";\n> +\t\tgoto fail;\n> +\t}\n> +\n> +\t// GBM_FORMAT_RGBA8888 is not supported mesa::src/gbm/dri/gbm_dri.c::gbm_dri_visuals_table[]\n> +\t// This means we need to choose XRGB8888 or ARGB8888 as the raw buffer format\n> +\tgbm_surface_ = gbm_surface_create(gbm_device_, width, height, GBM_FORMAT_ARGB8888,\n> +\t\t\t\t\t  GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);\nTODO:\n\nPass BPP and select between GBM_FORMAT_ARGB8888 and GBM_FORMAT_RGB8888.\n\nDo this because the surface the shader uses - i.e. the number of pixels \nthe shader writes matters.\n\nOnce BPP is passed into the above, we can also amend the shaders with \nsome kind of passed in environment define to allow differentation between.\n\ngl_FragColor = rgba\n\nand\n\ngl_FragColor = rgb\n\nThus allowing feature parity with CPUISP wrt supported output pixel formats.\n\n---\nbod","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 D9DC3BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Jun 2025 19:12:59 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 92EE668DCF;\n\tMon, 16 Jun 2025 21:12:59 +0200 (CEST)","from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com\n\t[IPv6:2a00:1450:4864:20::32d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A65C568DC0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Jun 2025 21:12:57 +0200 (CEST)","by mail-wm1-x32d.google.com with SMTP id\n\t5b1f17b1804b1-450ce3a2dd5so46770315e9.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Jun 2025 12:12:57 -0700 (PDT)","from [192.168.0.35] (188-141-3-146.dynamic.upc.ie. [188.141.3.146])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-3a568b28240sm11869270f8f.72.2025.06.16.12.12.56\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tMon, 16 Jun 2025 12:12:56 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"UHGL/RfL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=linaro.org; s=google; t=1750101177; x=1750705977;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:to:subject:user-agent:mime-version:date:message-id:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=BrprT1NlF7uzRqRAJUSgmnLYOcP9ulSJQrbIVNUoObg=;\n\tb=UHGL/RfLqqq2QPmE46psTm7MZFwkcX5G74mcr4t4RumzqgMWmHUbMcUMx4h5NbUVKA\n\tOPxwokY2/n/foDJxzOy3DjoM1WSl5XXOS8UJS3h1xLICvxxjyY0aeWBMM9iHlV27mdWq\n\t98gs/5u/QkNq5wOhe8yo5hJIvn9tttjrdZPDjBfX9QtXQBFN5YK70p7v0IJNcgZJIwib\n\thSb8xjv9hVUDwRBRUpy3SiwlZQEcqYsjOaxBt+AjSAyGoTc7XnJwQLscRa3qrCvk41aB\n\tbUeHa2yXT44c39u0tWvlDNv464OkEM7XF/A8pmPhjiMAm5Q2ClGrJjHMDYlO14B1hgCt\n\tod2A==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1750101177; x=1750705977;\n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:to:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=BrprT1NlF7uzRqRAJUSgmnLYOcP9ulSJQrbIVNUoObg=;\n\tb=wVRIPFa+KKq86omfqGZx1IStQQu9k20+Uv7yGF/kYw+de2wj8Q99HATomVRO0DBgmD\n\tMByB0gwKSv7q6cPzgXzzSe7bg/NTKjJGNPktki4DlFX05kWS9xUfV0eL/QxzeCvcBMpm\n\ttzFmRO/4p7FyGEw7+6+FmtUeo7GH+uhUO6LV8ZTjoPsXd5r8YLiQdSdkVN5eFQ8jzi/l\n\tUJsAviVsUdiOQB+3MMfb11uyPypk8DHIG2bkcPVCpbXha6V9h5WDI1G4024bk707rdro\n\tZaSw3WtqSRhN6Vi/34uZHpbH8C3FhyFD+bhYZV6elR3Uebhl1OAhhP+QtLGfB+OizJcS\n\tIW/g==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCUKFQbcWt2zZWa5tBz1+/WW41a7KHx5QelrYmP+zuGEZQgf7ZQYe5K7AQzFVzV+vChaUtd71wjA4Qojn9kJRPc=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yw+5kVkWB+5epccWUxad95DGp9QpnwtMR2/8knddpTwUU4JLlYa\n\t7OVrRKfq6/n8i6NFXDoY6OZdLv8uZU4dtQcdjIDAsQ+eSpKbZjT9WmOMqRLHwnuTQWiC9UsNx5X\n\tT8pNBTvw=","X-Gm-Gg":"ASbGnctPWoMXyFz3jq9VEUX/1Ll2P38218sGYlmJqavBh3Ul0yOLibsIanI3BhvMpNz\n\tQ9kIczzjkI/WeRx6yG6KeQm9pJbl6JRmCCF78Q2cG0kUgSu8JYTszo3ijh90lrZODfT5ZMKo+E2\n\tScnXyZmgFKdeltknhuiKPI0NjzROPldamYP+9oChyEH9jv1mAEerSszT3pwBKlezCVzsmPmhBDJ\n\t6Gk675gJSvPVQBaXh1iLzb5xoAk2QntioZWK5qS+zjz9pu7gZGba9v5c8wiuFRTTk2gKDp6bZdw\n\tJYTIOJNVdl8kBiEyoL8s+hD8bRRtzDlGZyxO84NdhuGkW67MxYs40hrz9Rx+T1F5XchVE4/r9CE\n\teVtcl/QUV4cC/BRV02db4ca8/FO4=","X-Google-Smtp-Source":"AGHT+IGra33eKi9kAKCHDc9emVA5u1C2sucAV7Lf7PQkUZ8uD7KsRgB+d7+G5TDW4oGtchtu3psioA==","X-Received":"by 2002:a05:600c:3587:b0:43c:fda5:41e9 with SMTP id\n\t5b1f17b1804b1-4533cad1aa0mr108035555e9.31.1750101177141; \n\tMon, 16 Jun 2025 12:12:57 -0700 (PDT)","Message-ID":"<de7ba729-b824-4317-8b8c-4f68d7b7b8c1@linaro.org>","Date":"Mon, 16 Jun 2025 20:12:55 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250611013245.133785-1-bryan.odonoghue@linaro.org>\n\t<aQ2RnkSZL-DBinFhly4Cu6gtLg0eVCTsJ-y8UuPRMv0Zk2M59l3gA3ZQGxOd9oUH_twR9YnPiq0r2xdbjvjE4g==@protonmail.internalid>\n\t<20250611013245.133785-22-bryan.odonoghue@linaro.org>","Content-Language":"en-US","From":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>","In-Reply-To":"<20250611013245.133785-22-bryan.odonoghue@linaro.org>","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":34527,"web_url":"https://patchwork.libcamera.org/comment/34527/","msgid":"<858qlqa1t6.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-06-17T14:19:01","subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Bryan,\n\ndue to lack of expertise, I cannot comment on the factual correctness;\nand I don't see any obvious flaw, just commenting on some style issues.\n\nBryan O'Donoghue <bryan.odonoghue@linaro.org> writes:\n\n> A helper class to interact with GBM. This will allow us to specify the\n> internal storage format of the CPU when making a texture for the Debayer\n> vertext/fragment shaders and thus ensure we receive an uncompressed and\n> untiled output buffer.\n>\n> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> ---\n>  include/libcamera/internal/gbm.h       |  55 ++++++++++\n>  include/libcamera/internal/meson.build |   1 +\n>  src/libcamera/gbm.cpp                  | 137 +++++++++++++++++++++++++\n>  src/libcamera/meson.build              |  11 ++\n>  4 files changed, 204 insertions(+)\n>  create mode 100644 include/libcamera/internal/gbm.h\n>  create mode 100644 src/libcamera/gbm.cpp\n>\n> diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h\n> new file mode 100644\n> index 00000000..a5486cc9\n> --- /dev/null\n> +++ b/include/libcamera/internal/gbm.h\n> @@ -0,0 +1,55 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * gbm.h - Helper class for managing GBM interactions.\n\nNo file name and no final dot:\n\n  * Helper class for managing GBM interactions\n\n> + */\n> +\n> +#pragma once\n> +\n> +#include <gbm.h>\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include <libcamera/formats.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DECLARE_CATEGORY(GBM)\n> +\n> +class GBM\n> +{\n> +public:\n> +\tGBM();\n> +\t~GBM();\n> +\n> +\tint initSurface(uint32_t width, uint32_t height);\n> +\tint mapSurface();\n> +\tint getFrameBufferData(uint8_t *data_out, size_t data_len);\n\nlibcamera uses camelCase :-( ; this applies also to the identifiers\nbelow.\n\n> +\tstruct gbm_device *getDevice() { return gbm_device_; }\n> +\tstruct gbm_surface *getSurface() { return gbm_surface_; }\n> +\tuint32_t getFrameSize() { return framesize_; }\n> +\tuint32_t getStride() { return stride_; }\n> +\tPixelFormat getPixelFormat() { return format_; }\n> +\n> +private:\n> +\tint fd_;\n> +\tstruct gbm_device *gbm_device_;\n> +\tstruct gbm_surface *gbm_surface_;\n> +\n> +\tstruct gbm_bo *gbm_bo_;\n> +\tuint32_t width_;\n> +\tuint32_t height_;\n> +\tuint32_t stride_;\n> +\tuint32_t offset_;\n> +\tuint32_t framesize_;\n> +\tvoid *map_;\n> +\tint bo_fd_;\n> +\n> +\tPixelFormat format_;\n> +};\n> +\n> +} // namespace libcamera\n\nShould be\n\n  } /* namespace libcamera */\n\n> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\n> index c0b593bf..4a2919f6 100644\n> --- a/include/libcamera/internal/meson.build\n> +++ b/include/libcamera/internal/meson.build\n> @@ -23,6 +23,7 @@ libcamera_internal_headers = files([\n>      'dma_buf_allocator.h',\n>      'formats.h',\n>      'framebuffer.h',\n> +    'gbm.h',\n>      'ipa_data_serializer.h',\n>      'ipa_manager.h',\n>      'ipa_module.h',\n> diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp\n> new file mode 100644\n> index 00000000..43032093\n> --- /dev/null\n> +++ b/src/libcamera/gbm.cpp\n> @@ -0,0 +1,137 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * egl.cpp - Helper class for managing GBM interactions.\n\nNo file name and no final dot.\n\n> + */\n> +\n> +#include \"libcamera/internal/gbm.h\"\n> +\n> +#include <fcntl.h>\n> +#include <sys/ioctl.h>\n> +#include <sys/mman.h>\n> +#include <unistd.h>\n> +\n> +#include <linux/dma-buf.h>\n> +#include <linux/dma-heap.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(GBM)\n> +\n> +GBM::GBM()\n> +{\n> +\tfd_ = 0;\n> +}\n> +\n> +GBM::~GBM()\n> +{\n> +\tif (gbm_surface_)\n> +\t\tgbm_surface_destroy(gbm_surface_);\n> +\n> +\tif (gbm_device_)\n> +\t\tgbm_device_destroy(gbm_device_);\n> +\n> +\tif (fd_ >= 0)\n> +\t\tclose(fd_);\n> +}\n> +\n> +// this should probably go into its own class to deal with the\n> +// allocation and deletion of frambuffers attached to GBM devices/objects\n> +int GBM::initSurface(uint32_t width, uint32_t height)\n> +{\n> +\tconst char *dri_node = \"/dev/dri/renderD128\"; //TODO: get from an env or config setting\n> +\n> +\tfd_ = open(dri_node, O_RDWR | O_CLOEXEC); //TODO: CLOEXEC ?\n> +\tif (fd_ < 0) {\n> +\t\tLOG(GBM, Error) << \"Open \" << dri_node << \" fail \" << fd_;\n> +\t\treturn fd_;\n> +\t}\n> +\n> +\tgbm_device_ = gbm_create_device(fd_);\n> +\tif (!gbm_device_) {\n> +\t\tLOG(GBM, Error) << \"gbm_crate_device fail\";\n\ns/crate/create/\n\n> +\t\tgoto fail;\n> +\t}\n> +\n> +\t// GBM_FORMAT_RGBA8888 is not supported mesa::src/gbm/dri/gbm_dri.c::gbm_dri_visuals_table[]\n> +\t// This means we need to choose XRGB8888 or ARGB8888 as the raw buffer format\n\n/* ... */ comment style.\n\n> +\tgbm_surface_ = gbm_surface_create(gbm_device_, width, height, GBM_FORMAT_ARGB8888,\n> +\t\t\t\t\t  GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);\n> +\tif (!gbm_surface_) {\n> +\t\tLOG(GBM, Error) << \"Unable to create linear gbm surface\";\n> +\t\tgoto fail;\n> +\t}\n> +\n> +\tformat_ = libcamera::formats::ARGB8888;\n> +\n> +\treturn 0;\n> +fail:\n> +\treturn -ENODEV;\n> +}\n> +\n> +int GBM::mapSurface()\n> +{\n> +\tgbm_bo_ = gbm_surface_lock_front_buffer(gbm_surface_);\n> +\tif (!gbm_bo_) {\n> +\t\tLOG(GBM, Error) << \"GBM input buffer object create fail\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n> +\n> +\tbo_fd_ = gbm_bo_get_fd(gbm_bo_);\n> +\n> +\tif (!bo_fd_) {\n> +\t\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n> +\t\tLOG(GBM, Error) << \"Unable to get fd for bo: \" << bo_fd_;\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\tstride_ = gbm_bo_get_stride(gbm_bo_);\n> +\twidth_ = gbm_bo_get_width(gbm_bo_);\n> +\theight_ = gbm_bo_get_height(gbm_bo_);\n> +\toffset_ = gbm_bo_get_offset(gbm_bo_, 0);\n> +\tframesize_ = height_ * stride_;\n> +\n> +\tmap_ = mmap(NULL, height_ * stride_, PROT_READ, MAP_SHARED, bo_fd_, 0);\n> +\tif (map_ == MAP_FAILED) {\n> +\t\tLOG(GBM, Error) << \"mmap gbm_bo_ fail\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\tLOG(GBM, Debug) << \" stride \" << stride_\n> +\t\t\t<< \" width \" << width_\n> +\t\t\t<< \" height \" << height_\n> +\t\t\t<< \" offset \" << offset_\n> +\t\t\t<< \" framesize \" << framesize_;\n> +\n> +\treturn 0;\n> +}\n> +\n> +int GBM::getFrameBufferData(uint8_t *data, size_t data_len)\n> +{\n> +\tstruct dma_buf_sync sync;\n> +\n> +\tgbm_surface_lock_front_buffer(gbm_surface_);\n> +\n> +\tsync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_READ;\n> +\tioctl(bo_fd_, DMA_BUF_IOCTL_SYNC, &sync);\n> +\n> +\tif (data_len > framesize_) {\n> +\t\tLOG(GBM, Error) << \"Invalid read size \" << data_len << \" max is \" << framesize_;\n> +\t\treturn -EINVAL;\n> +\t}\n> +\n> +\tmemcpy(data, map_, data_len);\n> +\n> +\tsync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ;\n> +\tioctl(bo_fd_, DMA_BUF_IOCTL_SYNC, &sync);\n\nA comment/todo should be added about the slow stuff on some archs\n(memcpy, ioctl's).\n\n> +\n> +\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n> +\n> +\treturn 0;\n> +}\n> +} //namespace libcamera\n\n  } /* namespace libcamera */\n\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 202db1ef..0d004694 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -67,6 +67,16 @@ libcamera_deps = []\n>  libatomic = cc.find_library('atomic', required : false)\n>  libthreads = dependency('threads')\n>  \n> +libgbm = cc.find_library('gbm', required: false)\n> +gbm_works = cc.check_header('gbm.h', required: false) \n\nAn extra space add the end of the line.\n\n> +\n> +if libgbm.found() and gbm_works\n> +    config_h.set('HAVE_GBM', 1)\n> +    libcamera_internal_sources += files([\n> +        'gbm.cpp',\n> +    ])\n> +endif\n> +\n>  subdir('base')\n>  subdir('converter')\n>  subdir('ipa')\n> @@ -188,6 +198,7 @@ libcamera_deps += [\n>      libcamera_base_private,\n>      libcrypto,\n>      libdl,\n> +    libgbm,\n>      liblttng,\n>      libudev,\n>      libyaml,","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 70DA4C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 17 Jun 2025 14:19:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 442B968DCD;\n\tTue, 17 Jun 2025 16:19:09 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 65ECC68DB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 17 Jun 2025 16:19:07 +0200 (CEST)","from mail-qt1-f198.google.com (mail-qt1-f198.google.com\n\t[209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-503-Rlji3cc-PbaqAI9_IdABNQ-1; Tue, 17 Jun 2025 10:19:05 -0400","by mail-qt1-f198.google.com with SMTP id\n\td75a77b69052e-4a6fb9bbbc9so197679301cf.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 17 Jun 2025 07:19:05 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb ([85.93.96.130])\n\tby smtp.gmail.com with ESMTPSA id\n\td75a77b69052e-4a72a2bf16esm61128361cf.12.2025.06.17.07.19.03\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 17 Jun 2025 07:19:03 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"DoKylLYP\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1750169946;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=iL7DbC5hLDEPb+SUryj32Ru9jKObxxpgcpCHzkRynAk=;\n\tb=DoKylLYPowUJeYKl1xuUuTSEOcGEub7Wj9b8YOTGkJQy8i+mzXkzZiM4BKn4YTnWXpGuRT\n\tHAIQDbm/6PivDawvyQEuxcqsFv+6clFEoWjgt+vand8hLBUsmWpE2KH9TY1PKBpBFdMwj8\n\tYApR0+RsdNLSLsSJTv+XHIr5Gh065X8=","X-MC-Unique":"Rlji3cc-PbaqAI9_IdABNQ-1","X-Mimecast-MFC-AGG-ID":"Rlji3cc-PbaqAI9_IdABNQ_1750169945","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1750169944; x=1750774744;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=iL7DbC5hLDEPb+SUryj32Ru9jKObxxpgcpCHzkRynAk=;\n\tb=IFsjtK7FWDrpO6Zj25ZOJGqA5LlzR1J0pe4ITIsrpqOWdagetLzaTR/wocyaRT/WeM\n\t5qn4gACs2dZMNav0gZrg9lvqHuhM16e6uZ6onG+CW7LJsdJxrTa0vIUvhyoxwJ8BvmaW\n\t6GQFzVWw6pwu2rmA4Yg1RzOVbtTuHomM8NEiz1NM/2ESpF7ekjlGzmTedJbGiShk7UuB\n\tn48erKQcrJhDNAEcd2BnYCwMc/htMkTkhSdmOQ3YRw/q4ebAp/AQ0+0l8B6RBx5wRllu\n\tKWx5ErXpEfvOk/dMUlUbSRTW3ZKk9QCJElabtD8SOYODhhZ4VeAcGm/SNopLTtzq4B62\n\tg4/g==","X-Gm-Message-State":"AOJu0YxROvPEC7FWyS+LiLjZZGC/aiE21KM2xNYBiiTy0StBSQV5KLOq\n\tGIocoND28gkho2RjuO/E975h1DKCb+WrrtO/qgNPwxYcY8lX0OoG9DIBSgIIeWgIer32yVIPU4m\n\tFQT2sFwwMNk/g1VtLZrhUqlZsh6gdUpxCDaPwjm/Wpy8yJ7hpKMMztIB6XeohH9DQYLSQEbV1U4\n\tCjREPSzBrzCPz2ALrfGDRgIXUG82qlODfe7Gr5HwrSPCVj42WwbHDimpKut2A=","X-Gm-Gg":"ASbGnctGS5msJrUQow6+emrdgFO30sbGBSy8q7SJvZfPis4yIMRTEA4KRjnAi/2Q9Nb\n\tZGLZtBWCM53hU1A5qqAaTHOdF3aEVF68LpoUEk7lhJ0sPMCu5Jus4Na8nf+hk4lciCbT2Vg4e38\n\tMEWg1POnAb58XObdamzAOeQ48FVxa6BGyvshPvTPIx8ZZr7laPmLU7HEfG/qgf7t2D1amXBuvRn\n\tKi/ev+vXrzBcp6mn+fJsKYq8hSUjehA9e/AK6cS+Q8ZJxoMPZiW3tGMJPx7jsiuSNcu6R+w5vtE\n\tsJPjlp367DLf8Wr3mFAn+BirzEHKgccGpoVjG26q2Kq3fqg=","X-Received":["by 2002:a05:622a:60a:b0:4a6:ef6a:ace3 with SMTP id\n\td75a77b69052e-4a73c5b0abbmr213841391cf.44.1750169944419; \n\tTue, 17 Jun 2025 07:19:04 -0700 (PDT)","by 2002:a05:622a:60a:b0:4a6:ef6a:ace3 with SMTP id\n\td75a77b69052e-4a73c5b0abbmr213840841cf.44.1750169943828; \n\tTue, 17 Jun 2025 07:19:03 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IG87FRbnZ3+MWEJ5n5sXcGKCHf0tJ2zHHTxZ8YrVOoE214Zn9ii3pET7evR/GvOaYILcUm8bA==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","In-Reply-To":"<20250611013245.133785-22-bryan.odonoghue@linaro.org> (Bryan\n\tO'Donoghue's message of \"Wed, 11 Jun 2025 02:32:31 +0100\")","References":"<20250611013245.133785-1-bryan.odonoghue@linaro.org>\n\t<20250611013245.133785-22-bryan.odonoghue@linaro.org>","Date":"Tue, 17 Jun 2025 16:19:01 +0200","Message-ID":"<858qlqa1t6.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"cbcnvxl5DQ6dEbsSWsVkXodb0qUM-DfvowJMhNZQOi0_1750169945","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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":34541,"web_url":"https://patchwork.libcamera.org/comment/34541/","msgid":"<4348b1cf-025a-45e1-b0e4-e4a59695ebf3@ideasonboard.com>","date":"2025-06-18T11:30:32","subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2025. 06. 11. 3:32 keltezéssel, Bryan O'Donoghue írta:\n> A helper class to interact with GBM. This will allow us to specify the\n> internal storage format of the CPU when making a texture for the Debayer\n> vertext/fragment shaders and thus ensure we receive an uncompressed and\n> untiled output buffer.\n> \n> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> ---\n>   include/libcamera/internal/gbm.h       |  55 ++++++++++\n>   include/libcamera/internal/meson.build |   1 +\n>   src/libcamera/gbm.cpp                  | 137 +++++++++++++++++++++++++\n>   src/libcamera/meson.build              |  11 ++\n>   4 files changed, 204 insertions(+)\n>   create mode 100644 include/libcamera/internal/gbm.h\n>   create mode 100644 src/libcamera/gbm.cpp\n> \n> diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h\n> new file mode 100644\n> index 00000000..a5486cc9\n> --- /dev/null\n> +++ b/include/libcamera/internal/gbm.h\n> @@ -0,0 +1,55 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * gbm.h - Helper class for managing GBM interactions.\n> + */\n> +\n> +#pragma once\n> +\n> +#include <gbm.h>\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include <libcamera/formats.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DECLARE_CATEGORY(GBM)\n> +\n> +class GBM\n> +{\n> +public:\n> +\tGBM();\n> +\t~GBM();\n> +\n> +\tint initSurface(uint32_t width, uint32_t height);\n\n`Size` type from geometry.h ?\n\n\n> +\tint mapSurface();\n> +\tint getFrameBufferData(uint8_t *data_out, size_t data_len);\n> +\tstruct gbm_device *getDevice() { return gbm_device_; }\n> +\tstruct gbm_surface *getSurface() { return gbm_surface_; }\n> +\tuint32_t getFrameSize() { return framesize_; }\n> +\tuint32_t getStride() { return stride_; }\n> +\tPixelFormat getPixelFormat() { return format_; }\n> +\n> +private:\n> +\tint fd_;\n\nUniqueFD fd_;\n\n> +\tstruct gbm_device *gbm_device_;\n> +\tstruct gbm_surface *gbm_surface_;\n> +\n> +\tstruct gbm_bo *gbm_bo_;\n\n   = nullptr; for the three members above.\n\n> +\tuint32_t width_;\n> +\tuint32_t height_;\n> +\tuint32_t stride_;\n> +\tuint32_t offset_;\n> +\tuint32_t framesize_;\n> +\tvoid *map_;\n> +\tint bo_fd_;\n> +\n> +\tPixelFormat format_;\n> +};\n\nCopy ctor/assignment should be deleted; move ctor/assignment should be deleted,\nor implemented if necessary.\n\n\n> +\n> +} // namespace libcamera\n> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\n> index c0b593bf..4a2919f6 100644\n> --- a/include/libcamera/internal/meson.build\n> +++ b/include/libcamera/internal/meson.build\n> @@ -23,6 +23,7 @@ libcamera_internal_headers = files([\n>       'dma_buf_allocator.h',\n>       'formats.h',\n>       'framebuffer.h',\n> +    'gbm.h',\n>       'ipa_data_serializer.h',\n>       'ipa_manager.h',\n>       'ipa_module.h',\n> diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp\n> new file mode 100644\n> index 00000000..43032093\n> --- /dev/null\n> +++ b/src/libcamera/gbm.cpp\n> @@ -0,0 +1,137 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Linaro Ltd.\n> + *\n> + * Authors:\n> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> + *\n> + * egl.cpp - Helper class for managing GBM interactions.\n> + */\n> +\n> +#include \"libcamera/internal/gbm.h\"\n> +\n> +#include <fcntl.h>\n> +#include <sys/ioctl.h>\n> +#include <sys/mman.h>\n> +#include <unistd.h>\n> +\n> +#include <linux/dma-buf.h>\n> +#include <linux/dma-heap.h>\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(GBM)\n> +\n> +GBM::GBM()\n> +{\n> +\tfd_ = 0;\n\nNot needed if `fd_` is `UniqueFD`. Just remove the constructor or ` = default;`.\n\n\n> +}\n> +\n> +GBM::~GBM()\n> +{\n\nShould `map_` be unmapped?\n\n\n> +\tif (gbm_surface_)\n> +\t\tgbm_surface_destroy(gbm_surface_);\n> +\n> +\tif (gbm_device_)\n> +\t\tgbm_device_destroy(gbm_device_);\n> +\n> +\tif (fd_ >= 0)\n> +\t\tclose(fd_);\n> +}\n> +\n> +// this should probably go into its own class to deal with the\n> +// allocation and deletion of frambuffers attached to GBM devices/objects\n> +int GBM::initSurface(uint32_t width, uint32_t height)\n\nMultiple calls leak `gbm_device_` and `gbm_surface_`. Either\nreturn an error/assert if these are already set, or destroy\nthem in case of an error.\n\n\n> +{\n> +\tconst char *dri_node = \"/dev/dri/renderD128\"; //TODO: get from an env or config setting\n> +\n> +\tfd_ = open(dri_node, O_RDWR | O_CLOEXEC); //TODO: CLOEXEC ?\n> +\tif (fd_ < 0) {\n> +\t\tLOG(GBM, Error) << \"Open \" << dri_node << \" fail \" << fd_;\n> +\t\treturn fd_;\n> +\t}\n> +\n> +\tgbm_device_ = gbm_create_device(fd_);\n> +\tif (!gbm_device_) {\n> +\t\tLOG(GBM, Error) << \"gbm_crate_device fail\";\n> +\t\tgoto fail;\n> +\t}\n> +\n> +\t// GBM_FORMAT_RGBA8888 is not supported mesa::src/gbm/dri/gbm_dri.c::gbm_dri_visuals_table[]\n> +\t// This means we need to choose XRGB8888 or ARGB8888 as the raw buffer format\n> +\tgbm_surface_ = gbm_surface_create(gbm_device_, width, height, GBM_FORMAT_ARGB8888,\n> +\t\t\t\t\t  GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);\n> +\tif (!gbm_surface_) {\n> +\t\tLOG(GBM, Error) << \"Unable to create linear gbm surface\";\n> +\t\tgoto fail;\n> +\t}> +\n> +\tformat_ = libcamera::formats::ARGB8888;\n> +\n> +\treturn 0;\n> +fail:\n> +\treturn -ENODEV;\n> +}\n> +\n> +int GBM::mapSurface()\n> +{\n\nASSERT(gbm_surface_); // or similar\n\n\n> +\tgbm_bo_ = gbm_surface_lock_front_buffer(gbm_surface_);\n> +\tif (!gbm_bo_) {\n> +\t\tLOG(GBM, Error) << \"GBM input buffer object create fail\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n> +\n> +\tbo_fd_ = gbm_bo_get_fd(gbm_bo_);\n> +\n> +\tif (!bo_fd_) {\n> +\t\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n\nIs the above call needed? It was already returned to the surface, no?\n\n\n> +\t\tLOG(GBM, Error) << \"Unable to get fd for bo: \" << bo_fd_;\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\tstride_ = gbm_bo_get_stride(gbm_bo_);\n> +\twidth_ = gbm_bo_get_width(gbm_bo_);\n> +\theight_ = gbm_bo_get_height(gbm_bo_);\n> +\toffset_ = gbm_bo_get_offset(gbm_bo_, 0);\n> +\tframesize_ = height_ * stride_;\n> +\n> +\tmap_ = mmap(NULL, height_ * stride_, PROT_READ, MAP_SHARED, bo_fd_, 0);\n\nnullptr\n\n\n> +\tif (map_ == MAP_FAILED) {\n> +\t\tLOG(GBM, Error) << \"mmap gbm_bo_ fail\";\n> +\t\treturn -ENODEV;\n> +\t}\n> +\n> +\tLOG(GBM, Debug) << \" stride \" << stride_\n> +\t\t\t<< \" width \" << width_\n> +\t\t\t<< \" height \" << height_\n> +\t\t\t<< \" offset \" << offset_\n> +\t\t\t<< \" framesize \" << framesize_;\n> +\n> +\treturn 0;\n> +}\n> +\n> +int GBM::getFrameBufferData(uint8_t *data, size_t data_len)\n\n`void *data` ?\n\n\n> +{\n\nASSERT(gbm_surface_); // or similar?\n\n\n> +\tstruct dma_buf_sync sync;\n> +\n> +\tgbm_surface_lock_front_buffer(gbm_surface_);\n> +\n> +\tsync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_READ;\n> +\tioctl(bo_fd_, DMA_BUF_IOCTL_SYNC, &sync);\n> +\n> +\tif (data_len > framesize_) {\n> +\t\tLOG(GBM, Error) << \"Invalid read size \" << data_len << \" max is \" << framesize_;\n> +\t\treturn -EINVAL;\n\nThis does not finish the sync, and keeps the front buffer locked.\nAre those issues? Could this be moved to the top?\n\n\n> +\t}\n> +\n> +\tmemcpy(data, map_, data_len);\n> +\n> +\tsync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ;\n> +\tioctl(bo_fd_, DMA_BUF_IOCTL_SYNC, &sync);\n> +\n> +\tgbm_surface_release_buffer(gbm_surface_, gbm_bo_);\n> +\n> +\treturn 0;\n> +}\n> +} //namespace libcamera\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 202db1ef..0d004694 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -67,6 +67,16 @@ libcamera_deps = []\n>   libatomic = cc.find_library('atomic', required : false)\n>   libthreads = dependency('threads')\n>   \n> +libgbm = cc.find_library('gbm', required: false)\n\ngbm_dep = dependency('gbm', required: false) ?\n\n\n> +gbm_works = cc.check_header('gbm.h', required: false)\n\ngbm_works = cc.check_header(..., dependency: gbm_dep) ?\n\n\nRegards,\nBarnabás Pőcze\n\n> +\n> +if libgbm.found() and gbm_works\n> +    config_h.set('HAVE_GBM', 1)\n> +    libcamera_internal_sources += files([\n> +        'gbm.cpp',\n> +    ])\n> +endif\n> +\n>   subdir('base')\n>   subdir('converter')\n>   subdir('ipa')\n> @@ -188,6 +198,7 @@ libcamera_deps += [\n>       libcamera_base_private,\n>       libcrypto,\n>       libdl,\n> +    libgbm,\n>       liblttng,\n>       libudev,\n>       libyaml,","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 32319C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 Jun 2025 11:30:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 35FCD68DCC;\n\tWed, 18 Jun 2025 13:30:37 +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 344E468DC1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 Jun 2025 13:30:36 +0200 (CEST)","from [192.168.33.16] (185.221.143.107.nat.pool.zt.hu\n\t[185.221.143.107])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 10775593;\n\tWed, 18 Jun 2025 13:30:23 +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=\"alaxQy1l\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1750246223;\n\tbh=Ej04uy2XGvK90m6mrrbJ57SCfE79gxqgHjoTo2/3psI=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=alaxQy1lPTP/OiPYBmyLeXFLk2nEjd9zKcq3xxqYL0DzDrTYxK/KkZWlyXOtI5nxj\n\t45XYPz7j7Qthj3/aDG5fZVz/itsDhI/vNHYziRwapptFbzIiEiZxl0dIsRW6DyTZW9\n\tJUIwUmbDARqhqOYV0CybKHouhS0ROM0F8KMyXSi0=","Message-ID":"<4348b1cf-025a-45e1-b0e4-e4a59695ebf3@ideasonboard.com>","Date":"Wed, 18 Jun 2025 13:30:32 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 21/35] libcamera: software_isp: gbm: Add in a GBM helper\n\tclass for GPU surface access","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250611013245.133785-1-bryan.odonoghue@linaro.org>\n\t<20250611013245.133785-22-bryan.odonoghue@linaro.org>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20250611013245.133785-22-bryan.odonoghue@linaro.org>","Content-Type":"text/plain; charset=UTF-8; format=flowed","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>"}}]