From patchwork Tue Oct 14 11:57:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 24635 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56CFCBF415 for ; Tue, 14 Oct 2025 11:58:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 17F92605F1; Tue, 14 Oct 2025 13:57:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pSsk+MOk"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 62B4C605D6 for ; Tue, 14 Oct 2025 13:57:56 +0200 (CEST) Received: from pb-laptop.local (185.182.214.105.nat.pool.zt.hu [185.182.214.105]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B3A60C73; Tue, 14 Oct 2025 13:56:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1760442977; bh=w2EU3OnA8Uf9goACtx3GkatSbxNruTSnJHxopYrnOUs=; h=From:To:Cc:Subject:Date:From; b=pSsk+MOkai9ncWBIWlUwIsIr0QpxV6cmOgwaZw8RHfEsJhqZwjq6THecOt86Tlfg6 kkHYN7inmH9+9IWza2dprVCjqjGfT0fBmAPJxIlhqRQSSBH0UIt/eZDKiEvHGNq+9Z 3a3XK3S8MOWQ4z5OUJsqxo7iA7ZOR8Ga9wf+oHuQ= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Jacopo Mondi Subject: [RFC PATCH v2 1/2] libcamera: ipa_data_serializer: Add specialization for enums Date: Tue, 14 Oct 2025 13:57:51 +0200 Message-ID: <20251014115752.466522-1-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Instead of handling enums specially in the code generation templates, create a specialization of `IPADataSerializer` that handles enums. Every enum is serialized as a `uint32_t`, with `static_assert` to ensure that every possible value fits. Previously, enums were (de)serialized in `(de)serializer_field()` based on the size of their underlying types. Afer this change, every enum is uniformly handled as a `uint32_t`. Signed-off-by: Barnabás Pőcze Reviewed-by: Paul Elder Reviewed-by: Jacopo Mondi --- changes in v2: * rebase v1: https://patchwork.libcamera.org/patch/23372/ --- .../libcamera/internal/ipa_data_serializer.h | 48 ++++++++++++++++++- .../libcamera_templates/proxy_functions.tmpl | 17 +------ .../libcamera_templates/serializer.tmpl | 14 ------ 3 files changed, 48 insertions(+), 31 deletions(-) -- 2.51.0 diff --git a/include/libcamera/internal/ipa_data_serializer.h b/include/libcamera/internal/ipa_data_serializer.h index b1fefba58..927f5c4c7 100644 --- a/include/libcamera/internal/ipa_data_serializer.h +++ b/include/libcamera/internal/ipa_data_serializer.h @@ -61,7 +61,7 @@ T readPOD(std::vector &vec, size_t pos) } /* namespace */ -template +template class IPADataSerializer { public: @@ -344,6 +344,52 @@ public: } }; +template +class IPADataSerializer>> +{ + using U = uint32_t; + static_assert(sizeof(E) <= sizeof(U)); + +public: + static std::tuple, std::vector> + serialize(const E &data, [[maybe_unused]] ControlSerializer *cs = nullptr) + { + std::vector dataVec; + appendPOD(dataVec, static_cast(data)); + + return { dataVec, {} }; + } + + static E deserialize(std::vector &data, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(data.cbegin(), data.cend()); + } + + static E deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return static_cast(readPOD(dataBegin, 0, dataEnd)); + } + + static E deserialize(std::vector &data, + [[maybe_unused]] std::vector &fds, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(data.cbegin(), data.cend()); + } + + static E deserialize(std::vector::const_iterator dataBegin, + std::vector::const_iterator dataEnd, + [[maybe_unused]] std::vector::const_iterator fdsBegin, + [[maybe_unused]] std::vector::const_iterator fdsEnd, + [[maybe_unused]] ControlSerializer *cs = nullptr) + { + return deserialize(dataBegin, dataEnd); + } +}; + #endif /* __DOXYGEN__ */ } /* namespace libcamera */ diff --git a/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl index 25476990e..01e2567ca 100644 --- a/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl +++ b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl @@ -52,9 +52,6 @@ #} {%- macro serialize_call(params, buf, fds) %} {%- for param in params %} -{%- if param|is_enum %} - static_assert(sizeof({{param|name_full}}) <= 4); -{%- endif %} std::vector {{param.mojom_name}}Buf; {%- if param|has_fd %} std::vector {{param.mojom_name}}Fds; @@ -62,13 +59,7 @@ {%- else %} std::tie({{param.mojom_name}}Buf, std::ignore) = {%- endif %} -{%- if param|is_flags %} IPADataSerializer<{{param|name_full}}>::serialize({{param.mojom_name}} -{%- elif param|is_enum %} - IPADataSerializer::serialize(static_cast({{param.mojom_name}}) -{%- else %} - IPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}} -{% endif -%} {{- ", &controlSerializer_" if param|needs_control_serializer -}} ); {%- endfor %} @@ -107,13 +98,7 @@ #} {%- macro deserialize_param(param, pointer, loop, buf, fds, iter, data_size) -%} {{"*" if pointer}}{{param.mojom_name}} = -{%- if param|is_flags %} IPADataSerializer<{{param|name_full}}>::deserialize( -{%- elif param|is_enum %} -static_cast<{{param|name_full}}>(IPADataSerializer::deserialize( -{%- else %} -IPADataSerializer<{{param|name}}>::deserialize( -{%- endif %} {{buf}}{{- ".cbegin()" if not iter}} + {{param.mojom_name}}Start, {%- if loop.last and not iter %} {{buf}}.cend() @@ -137,7 +122,7 @@ IPADataSerializer<{{param|name}}>::deserialize( {%- if param|needs_control_serializer %} &controlSerializer_ {%- endif -%} -){{")" if param|is_enum and not param|is_flags}}; +); {%- endmacro -%} diff --git a/utils/codegen/ipc/generators/libcamera_templates/serializer.tmpl b/utils/codegen/ipc/generators/libcamera_templates/serializer.tmpl index d07836cc1..e316dd88a 100644 --- a/utils/codegen/ipc/generators/libcamera_templates/serializer.tmpl +++ b/utils/codegen/ipc/generators/libcamera_templates/serializer.tmpl @@ -32,15 +32,7 @@ {%- if field|is_pod or field|is_enum %} std::vector {{field.mojom_name}}; std::tie({{field.mojom_name}}, std::ignore) = - {%- if field|is_pod %} - IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}); - {%- elif field|is_flags %} IPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}}); - {%- elif field|is_enum_scoped %} - IPADataSerializer::serialize(static_cast(data.{{field.mojom_name}})); - {%- elif field|is_enum %} - IPADataSerializer::serialize(data.{{field.mojom_name}}); - {%- endif %} retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end()); {%- elif field|is_fd %} std::vector {{field.mojom_name}}; @@ -98,13 +90,7 @@ {% if field|is_pod or field|is_enum %} {%- set field_size = (field|bit_width|int / 8)|int %} {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}} - {%- if field|is_pod %} - ret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}}); - {%- elif field|is_flags %} ret.{{field.mojom_name}} = IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field_size}}); - {%- else %} - ret.{{field.mojom_name}} = static_cast<{{field|name_full}}>(IPADataSerializer::deserialize(m, m + {{field_size}})); - {%- endif %} {%- if not loop.last %} m += {{field_size}}; dataSize -= {{field_size}};