Patch Detail
Show a patch.
GET /api/1.1/patches/17214/?format=api
{ "id": 17214, "url": "https://patchwork.libcamera.org/api/1.1/patches/17214/?format=api", "web_url": "https://patchwork.libcamera.org/patch/17214/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20220826165453.135113-1-paul.elder@ideasonboard.com>", "date": "2022-08-26T16:54:53", "name": "[libcamera-devel,v3.1,4/7] utils: ipc: Add support for Flags", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "e0d7b97aa5faf368bca46d96de39412c2e868cb7", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/1.1/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/17214/mbox/", "series": [ { "id": 3439, "url": "https://patchwork.libcamera.org/api/1.1/series/3439/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3439", "date": "2022-08-26T16:54:53", "name": null, "version": 1, "mbox": "https://patchwork.libcamera.org/series/3439/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/17214/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/17214/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 8B0BCC3272\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 26 Aug 2022 16:55:10 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BBE4461FC0;\n\tFri, 26 Aug 2022 18:55:09 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CF96D61FA2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 26 Aug 2022 18:55:07 +0200 (CEST)", "from pyrite.mediacom.info (unknown\n\t[IPv6:2604:2d80:ad8a:9000:1bf9:855b:22de:3645])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E680F2B3;\n\tFri, 26 Aug 2022 18:55:06 +0200 (CEST)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1661532909;\n\tbh=veOn7iDaOLD8SZlBQLblTsSQq33gn/a3psXtcym7ZrA=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=nYV5HBaxlHb6Lnq0ddxTbFxAnd7Q+Tux4tE5T50s0GvuERke3rqC6ROWW9VPSapk6\n\tSvgQk/oOd1hxid6rvGmwdjwmk1QlDZd968iX9MBKjlitugZB/n+CHSa8+kth+/rPmb\n\tSHFCMPSVkKvTCSH7d8jksyp+KqEdlrvwUaiiM3RhVGZ8VDcr7vehGUgaxeCVboRUtc\n\tUd0NYywfmXuMQERdtkWgmm2KJJhU7q8w+81weXsYDx56pMl5eI9wbym7m3d0mKUWkN\n\t9+RI2Rtu9Ng749bTrt2Efgk8g5mPC3fBJY18OrbVByYGiKMIWuRX3RiuOYWf0RGUkS\n\tyAKv7NC0pNLow==", "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1661532907;\n\tbh=veOn7iDaOLD8SZlBQLblTsSQq33gn/a3psXtcym7ZrA=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=vzoXuTU3p4y+JzNX7ejcvVU5aJQ0Dtj1yK7SgMMHuzCdpjAyTBo1mTL9spTOKJbld\n\tFjoxoMnMyXEce+z0PMW2bKWR5vSUSJuarocqyOHF9Kpsq0apesvYWWNcaU6tcO0cPK\n\tiCT0cr+FRRO+8qT3aX0cNqNRBddbDAyK1YABXjbI=" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"vzoXuTU3\"; dkim-atps=neutral", "To": "libcamera-devel@lists.libcamera.org", "Date": "Fri, 26 Aug 2022 11:54:53 -0500", "Message-Id": "<20220826165453.135113-1-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.30.2", "In-Reply-To": "<20220826154419.4099372-5-paul.elder@ideasonboard.com>", "References": "<20220826154419.4099372-5-paul.elder@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v3.1 4/7] utils: ipc: Add support for Flags", "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>", "From": "Paul Elder via libcamera-devel <libcamera-devel@lists.libcamera.org>", "Reply-To": "Paul Elder <paul.elder@ideasonboard.com>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Add Flags<E> as a supported type in the IPA interface.\n\nIt is used in mojom with the [flags] attribute. Any field or parameter\ntype E that is prefixed with the [flags] attribute will direct the code\ngenerator to generate the type name \"Flags<E>\" and appropriate\nserialization/deserialization code for Flags<E> instead of for E.\n\nIt is usable and has been tested in struct members, function input and\noutput parameters, and Signal parameters. This does not add support for\nreturning Flags as direct return values.\n\nAdditionally, the [scopedEnum] attribute can be used on enum\ndefinitions, which will instruct the code generator to convert it to an\nenum class instead of a raw enum.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\n---\nChanges in v3.1:\n- add documentation of [scopedEnum] and [flags] to core.mojom\n - it's not the best place, but better somewhere than nowhere for now\n\nChanges in v3:\n- change flags attribute from [Flags] to [flags]\n- make it so that enum input parameters are passed directly (as opposed\n to const references)\n- to turn enum definitions in mojom to enum classes, use the\n [scopedEnum] attribute (as opposed to the [Flags] attribute in v2)\n - correspondingly, the function in the mojom generator python script\n is separated out from IsFlags() into IsScoped()\n- clean up IsFlags()\n- simplify GetFullNameForElement() for flags\n\nQuestion for reviewers (in v2): Should we use a different attribute name to\nspecify that an enum should be an enum class?\n\nAnswer (in v3): Yes; that attribute name is [scopedEnum]\n\nChanges in v2:\n- Use mojom attribute to specify that a field should be Flags<E>,\n instead of using a magic type name format\n---\n include/libcamera/ipa/core.mojom | 9 ++++++\n include/libcamera/ipa/ipa_interface.h | 1 +\n .../definition_functions.tmpl | 2 +-\n .../libcamera_templates/proxy_functions.tmpl | 10 +++++--\n .../libcamera_templates/serializer.tmpl | 4 +++\n .../generators/mojom_libcamera_generator.py | 29 +++++++++++++++++--\n 6 files changed, 48 insertions(+), 7 deletions(-)", "diff": "diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom\nindex 74f3339e..ef28ff2d 100644\n--- a/include/libcamera/ipa/core.mojom\n+++ b/include/libcamera/ipa/core.mojom\n@@ -33,6 +33,15 @@ module libcamera;\n * available for the type and there's no need to generate one\n * - hasFd - struct fields or empty structs only\n * - Designate that this field or empty struct contains a SharedFD\n+ * - scopedEnum - enum definitions\n+ * - Designate that this enum should be an enum class, as opposed to a pure\n+ * enum\n+ * - flags - struct fields or function parameters that are enums\n+ * - Designate that this enum type E should be Flags<E> in the generated C++\n+ * code\n+ * - For example, if a struct field is defined as `[flags] ErrorFlag f;`\n+ * (where ErrorFlag is defined as an enum elsewhere in mojom), then the\n+ * generated code for this field will be `Flags<ErrorFlag> f`\n *\n * Rules:\n * - If the type is defined in a libcamera C++ header *and* a (de)serializer is\ndiff --git a/include/libcamera/ipa/ipa_interface.h b/include/libcamera/ipa/ipa_interface.h\nindex 50ca0e7b..8afcfe21 100644\n--- a/include/libcamera/ipa/ipa_interface.h\n+++ b/include/libcamera/ipa/ipa_interface.h\n@@ -13,6 +13,7 @@\n #include <map>\n #include <vector>\n \n+#include <libcamera/base/flags.h>\n #include <libcamera/base/signal.h>\n \n #include <libcamera/controls.h>\ndiff --git a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl\nindex 94bb4918..8b8509f3 100644\n--- a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl\n+++ b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl\n@@ -9,7 +9,7 @@\n # \\param enum Enum object whose definition is to be generated\n #}\n {%- macro define_enum(enum) -%}\n-enum {{enum.mojom_name}} {\n+enum{{\" class\" if enum|is_scoped}} {{enum.mojom_name}} {\n {%- for field in enum.fields %}\n \t{{field.mojom_name}} = {{field.numeric_value}},\n {%- endfor %}\ndiff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl\nindex cbcfb64a..2be65d43 100644\n--- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl\n+++ b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl\n@@ -62,7 +62,9 @@\n {%- else %}\n \tstd::tie({{param.mojom_name}}Buf, std::ignore) =\n {%- endif %}\n-{%- if param|is_enum %}\n+{%- if param|is_flags %}\n+\t\tIPADataSerializer<{{param|name_full}}>::serialize({{param.mojom_name}}\n+{%- elif param|is_enum %}\n \t\tIPADataSerializer<uint32_t>::serialize(static_cast<uint32_t>({{param.mojom_name}})\n {%- else %}\n \t\tIPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}}\n@@ -105,7 +107,9 @@\n #}\n {%- macro deserialize_param(param, pointer, loop, buf, fds, iter, data_size) -%}\n {{\"*\" if pointer}}{{param.mojom_name}} =\n-{%- if param|is_enum %}\n+{%- if param|is_flags %}\n+IPADataSerializer<{{param|name_full}}>::deserialize(\n+{%- elif param|is_enum %}\n static_cast<{{param|name_full}}>(IPADataSerializer<uint32_t>::deserialize(\n {%- else %}\n IPADataSerializer<{{param|name}}>::deserialize(\n@@ -133,7 +137,7 @@ IPADataSerializer<{{param|name}}>::deserialize(\n {%- if param|needs_control_serializer %}\n \t&controlSerializer_\n {%- endif -%}\n-){{\")\" if param|is_enum}};\n+){{\")\" if param|is_enum and not param|is_flags}};\n {%- endmacro -%}\n \n \ndiff --git a/utils/ipc/generators/libcamera_templates/serializer.tmpl b/utils/ipc/generators/libcamera_templates/serializer.tmpl\nindex 77bae36f..eec75211 100644\n--- a/utils/ipc/generators/libcamera_templates/serializer.tmpl\n+++ b/utils/ipc/generators/libcamera_templates/serializer.tmpl\n@@ -34,6 +34,8 @@\n \t\tstd::tie({{field.mojom_name}}, std::ignore) =\n \t{%- if field|is_pod %}\n \t\t\tIPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}});\n+\t{%- elif field|is_flags %}\n+\t\t\tIPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}});\n \t{%- elif field|is_enum %}\n \t\t\tIPADataSerializer<uint{{field|bit_width}}_t>::serialize(data.{{field.mojom_name}});\n \t{%- endif %}\n@@ -96,6 +98,8 @@\n \t\t{{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}}\n \t\t{%- if field|is_pod %}\n \t\tret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}});\n+\t\t{%- elif field|is_flags %}\n+\t\tret.{{field.mojom_name}} = IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field_size}});\n \t\t{%- else %}\n \t\tret.{{field.mojom_name}} = static_cast<{{field|name_full}}>(IPADataSerializer<uint{{field|bit_width}}_t>::deserialize(m, m + {{field_size}}));\n \t\t{%- endif %}\ndiff --git a/utils/ipc/generators/mojom_libcamera_generator.py b/utils/ipc/generators/mojom_libcamera_generator.py\nindex 753bfc73..d7fe2031 100644\n--- a/utils/ipc/generators/mojom_libcamera_generator.py\n+++ b/utils/ipc/generators/mojom_libcamera_generator.py\n@@ -74,6 +74,8 @@ def GetDefaultValue(element):\n return element.default\n if type(element.kind) == mojom.Kind:\n return '0'\n+ if IsFlags(element):\n+ return ''\n if mojom.IsEnumKind(element.kind):\n return f'static_cast<{element.kind.mojom_name}>(0)'\n if isinstance(element.kind, mojom.Struct) and \\\n@@ -184,7 +186,7 @@ def MethodParameters(method):\n params = []\n for param in method.parameters:\n params.append('const %s %s%s' % (GetNameForElement(param),\n- '&' if not IsPod(param) else '',\n+ '' if IsPod(param) or (IsEnum(param) and not IsFlags(param)) else '&',\n param.mojom_name))\n for param in MethodParamOutputs(method):\n params.append(f'{GetNameForElement(param)} *{param.mojom_name}')\n@@ -220,9 +222,21 @@ def IsControls(element):\n def IsEnum(element):\n return mojom.IsEnumKind(element.kind)\n \n+def IsScoped(element):\n+ attributes = getattr(element, 'attributes', None)\n+ if not attributes:\n+ return False\n+ return 'scopedEnum' in attributes\n+\n def IsFd(element):\n return mojom.IsStructKind(element.kind) and element.kind.mojom_name == \"SharedFD\"\n \n+def IsFlags(element):\n+ attributes = getattr(element, 'attributes', None)\n+ if not attributes:\n+ return False\n+ return 'flags' in attributes\n+\n def IsMap(element):\n return mojom.IsMapKind(element.kind)\n \n@@ -251,9 +265,11 @@ def ByteWidthFromCppType(t):\n raise Exception('invalid type')\n return str(int(_bit_widths[key]) // 8)\n \n-\n # Get the type name for a given element\n def GetNameForElement(element):\n+ # Flags\n+ if IsFlags(element):\n+ return f'Flags<{GetFullNameForElement(element.kind)}>'\n # structs\n if (mojom.IsEnumKind(element) or\n mojom.IsInterfaceKind(element) or\n@@ -302,7 +318,8 @@ def GetNameForElement(element):\n def GetFullNameForElement(element):\n name = GetNameForElement(element)\n namespace_str = ''\n- if mojom.IsStructKind(element):\n+ if (mojom.IsStructKind(element) or\n+ mojom.IsEnumKind(element)):\n namespace_str = element.module.mojom_namespace.replace('.', '::')\n elif (hasattr(element, 'kind') and\n (mojom.IsStructKind(element.kind) or\n@@ -311,6 +328,10 @@ def GetFullNameForElement(element):\n \n if namespace_str == '':\n return name\n+\n+ if IsFlags(element):\n+ return GetNameForElement(element)\n+\n return f'{namespace_str}::{name}'\n \n def ValidateZeroLength(l, s, cap=True):\n@@ -408,9 +429,11 @@ class Generator(generator.Generator):\n 'is_controls': IsControls,\n 'is_enum': IsEnum,\n 'is_fd': IsFd,\n+ 'is_flags': IsFlags,\n 'is_map': IsMap,\n 'is_plain_struct': IsPlainStruct,\n 'is_pod': IsPod,\n+ 'is_scoped': IsScoped,\n 'is_str': IsStr,\n 'method_input_has_fd': MethodInputHasFd,\n 'method_output_has_fd': MethodOutputHasFd,\n", "prefixes": [ "libcamera-devel", "v3.1", "4/7" ] }