[libcamera-devel] [PATCH 6/9] utils: ipc: Add support for Flags
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Aug 9 03:59:03 CEST 2022
Hi Paul,
Thank you for the patch.
On Wed, Aug 03, 2022 at 08:21:47PM +0900, Paul Elder via libcamera-devel wrote:
> Add Flags<E> as a supported type in the IPA interface.
>
> It is defined and used in mojom as "Flags_E_t", and the code generator
> will convert it to "Flags<E>". It is usable and has been tested in
> struct members, function input and output parameters, and Signal
> parameters.
Hmmm... mojom can parse the "<...>" syntax to some extend, as it
supports "array<T>" for instance. Would it be possible to extend that
with flags ?
> This does not add support for returning Flags as direct return values.
>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> ---
> .../core_ipa_interface.h.tmpl | 4 +++
> .../definition_functions.tmpl | 13 +++++++
> .../module_ipa_interface.h.tmpl | 4 +++
> .../libcamera_templates/proxy_functions.tmpl | 10 ++++--
> .../libcamera_templates/serializer.tmpl | 4 +++
> .../generators/mojom_libcamera_generator.py | 35 ++++++++++++++++++-
> 6 files changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
> index a565b59a..2fd55119 100644
> --- a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
> @@ -30,6 +30,10 @@ static const {{const.kind|name}} {{const.mojom_name}} = {{const.value}};
> {{funcs.define_enum(enum)}}
> {% endfor %}
>
> +{% for flag in flags %}
> +{{funcs.define_flags(flag)}}
> +{% endfor %}
> +
> {%- for struct in structs_gen_header %}
> {{funcs.define_struct(struct)}}
> {% endfor %}
> diff --git a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl
> index 94bb4918..3dbcfca0 100644
> --- a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl
> @@ -16,6 +16,19 @@ enum {{enum.mojom_name}} {
> };
> {%- endmacro -%}
>
> +{#
> + # \brief Generate Flags definition
> + #
> + # \param flags Enum object from which a Flags definition is to be generated
> + #}
> +{%- macro define_flags(flags) -%}
> +enum class {{flags|flags_name}} {
> +{%- for field in flags.fields %}
> + {{field.mojom_name}} = {{field.numeric_value}},
> +{%- endfor %}
> +};
> +{%- endmacro -%}
> +
> {#
> # \brief Generate struct definition
> #
> diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
> index 415ec283..5e003849 100644
> --- a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
> @@ -48,6 +48,10 @@ enum class {{cmd_event_enum_name}} {
> {{funcs.define_enum(enum)}}
> {% endfor %}
>
> +{% for flag in flags %}
> +{{funcs.define_flags(flag)}}
> +{% endfor %}
> +
> {%- for struct in structs_nonempty %}
> {{funcs.define_struct(struct)}}
> {% endfor %}
> diff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> index dc35620f..c5e24323 100644
> --- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
> @@ -59,7 +59,9 @@
> {%- else %}
> std::tie({{param.mojom_name}}Buf, std::ignore) =
> {%- endif %}
> -{%- if param|is_enum %}
> +{%- if param|is_flags %}
> + IPADataSerializer<{{param|name_full}}>::serialize({{param.mojom_name}}
> +{%- elif param|is_enum %}
> IPADataSerializer<uint32_t>::serialize(static_cast<uint32_t>({{param.mojom_name}})
> {%- else %}
> IPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}}
> @@ -102,7 +104,9 @@
> #}
> {%- macro deserialize_param(param, pointer, loop, buf, fds, iter, data_size) -%}
> {{"*" if pointer}}{{param.mojom_name}} =
> -{%- if param|is_enum %}
> +{%- if param|is_flags %}
> +IPADataSerializer<{{param|name_full}}>::deserialize(
> +{%- elif param|is_enum %}
> static_cast<{{param|name_full}}>(IPADataSerializer<uint32_t>::deserialize(
> {%- else %}
> IPADataSerializer<{{param|name}}>::deserialize(
> @@ -130,7 +134,7 @@ IPADataSerializer<{{param|name}}>::deserialize(
> {%- if param|needs_control_serializer %}
> &controlSerializer_
> {%- endif -%}
> -){{")" if param|is_enum}};
> +){{")" if param|is_enum and not param|is_flags}};
> {%- endmacro -%}
>
>
> diff --git a/utils/ipc/generators/libcamera_templates/serializer.tmpl b/utils/ipc/generators/libcamera_templates/serializer.tmpl
> index 77bae36f..eec75211 100644
> --- a/utils/ipc/generators/libcamera_templates/serializer.tmpl
> +++ b/utils/ipc/generators/libcamera_templates/serializer.tmpl
> @@ -34,6 +34,8 @@
> 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 %}
> IPADataSerializer<uint{{field|bit_width}}_t>::serialize(data.{{field.mojom_name}});
> {%- endif %}
> @@ -96,6 +98,8 @@
> {{- 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<uint{{field|bit_width}}_t>::deserialize(m, m + {{field_size}}));
> {%- endif %}
> diff --git a/utils/ipc/generators/mojom_libcamera_generator.py b/utils/ipc/generators/mojom_libcamera_generator.py
> index 753bfc73..22de6fdd 100644
> --- a/utils/ipc/generators/mojom_libcamera_generator.py
> +++ b/utils/ipc/generators/mojom_libcamera_generator.py
> @@ -47,6 +47,8 @@ _bit_widths = {
> mojom.DOUBLE: '64',
> }
>
> +_flags_re = r'^Flags_(.*)_t$'
> +
> def ModuleName(path):
> return path.split('/')[-1].split('.')[0]
>
> @@ -74,6 +76,8 @@ def GetDefaultValue(element):
> return element.default
> if type(element.kind) == mojom.Kind:
> return '0'
> + if IsFlags(element):
> + return ''
> if mojom.IsEnumKind(element.kind):
> return f'static_cast<{element.kind.mojom_name}>(0)'
> if isinstance(element.kind, mojom.Struct) and \
> @@ -223,6 +227,16 @@ def IsEnum(element):
> def IsFd(element):
> return mojom.IsStructKind(element.kind) and element.kind.mojom_name == "SharedFD"
>
> +def IsFlags(element):
> + if not hasattr(element, 'mojom_name'):
> + return False
> + if re.match(_flags_re, element.mojom_name):
> + return True
> + if hasattr(element, 'kind'):
> + if hasattr(element.kind, 'mojom_name'):
> + return True if re.match(_flags_re, element.kind.mojom_name) else False
> + return False
> +
> def IsMap(element):
> return mojom.IsMapKind(element.kind)
>
> @@ -251,9 +265,20 @@ def ByteWidthFromCppType(t):
> raise Exception('invalid type')
> return str(int(_bit_widths[key]) // 8)
>
> +def FlagsName(element):
> + if hasattr(element, 'mojom_name'):
> + if re.match(_flags_re, element.mojom_name):
> + return re.sub(_flags_re, lambda match: match.group(1), element.mojom_name)
> + if hasattr(element, 'kind'):
> + if hasattr(element.kind, 'mojom_name'):
> + return re.sub(_flags_re, lambda match: match.group(1), element.kind.mojom_name)
> + return None
>
> # Get the type name for a given element
> def GetNameForElement(element):
> + # Flags
> + if IsFlags(element):
> + return f'Flags<{FlagsName(element)}>'
> # structs
> if (mojom.IsEnumKind(element) or
> mojom.IsInterfaceKind(element) or
> @@ -311,6 +336,11 @@ def GetFullNameForElement(element):
>
> if namespace_str == '':
> return name
> +
> + if IsFlags(element):
> + name = re.match(r'^Flags<(.*)>$', name).group(1)
> + return f'Flags<{namespace_str}::{name}>'
> +
> return f'{namespace_str}::{name}'
>
> def ValidateZeroLength(l, s, cap=True):
> @@ -401,6 +431,7 @@ class Generator(generator.Generator):
> 'choose': Choose,
> 'comma_sep': CommaSep,
> 'default_value': GetDefaultValue,
> + 'flags_name': FlagsName,
> 'has_default_fields': HasDefaultFields,
> 'has_fd': HasFd,
> 'is_async': IsAsync,
> @@ -408,6 +439,7 @@ class Generator(generator.Generator):
> 'is_controls': IsControls,
> 'is_enum': IsEnum,
> 'is_fd': IsFd,
> + 'is_flags': IsFlags,
> 'is_map': IsMap,
> 'is_plain_struct': IsPlainStruct,
> 'is_pod': IsPod,
> @@ -433,7 +465,8 @@ class Generator(generator.Generator):
> 'cmd_enum_name': '_%sCmd' % self.module_name,
> 'cmd_event_enum_name': '_%sEventCmd' % self.module_name,
> 'consts': self.module.constants,
> - 'enums': self.module.enums,
> + 'enums': [enum for enum in self.module.enums if not IsFlags(enum)],
> + 'flags': [enum for enum in self.module.enums if IsFlags(enum)],
> 'has_array': len([x for x in self.module.kinds.keys() if x[0] == 'a']) > 0,
> 'has_map': len([x for x in self.module.kinds.keys() if x[0] == 'm']) > 0,
> 'has_namespace': self.module.mojom_namespace != '',
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list