[libcamera-devel] [PATCH 6/9] utils: ipc: Add support for Flags
Paul Elder
paul.elder at ideasonboard.com
Wed Aug 3 13:21:47 CEST 2022
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.
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 != '',
--
2.30.2
More information about the libcamera-devel
mailing list