summaryrefslogtreecommitdiff
path: root/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-08-08 18:13:00 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-08-15 23:59:08 +0300
commit50c92cc7e2924009ecab3e4004448b01d687707c (patch)
treec22b49816a3c79dae4727780962aa0928df42b52 /utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
parentd3bf27180ef1d91b86b7b87a2378e559eaff5455 (diff)
meson: Move all code generation scripts to utils/codegen/
We have multiple code generation scripts in utils/, mixed with other miscellaneous utilities, as well as a larger code base based on mojom in utils/ipc/. To make code sharing easier between the generator scripts, without creating a mess in the utils/ directory, move all the code generation code to utils/codegen/. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl')
-rw-r--r--utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl202
1 files changed, 202 insertions, 0 deletions
diff --git a/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
new file mode 100644
index 00000000..b5797b14
--- /dev/null
+++ b/utils/codegen/ipc/generators/libcamera_templates/proxy_functions.tmpl
@@ -0,0 +1,202 @@
+{#-
+ # SPDX-License-Identifier: LGPL-2.1-or-later
+ # Copyright (C) 2020, Google Inc.
+-#}
+{#
+ # \brief Generate function prototype
+ #
+ # \param class Class name
+ # \param method mojom Method object
+ # \param suffix Suffix to append to \a method function name
+ # \param need_class_name If true, generate class name with function
+ # \param override If true, generate override tag after the function prototype
+ #}
+{%- macro func_sig(class, method, suffix = "", need_class_name = true, override = false) -%}
+{{method|method_return_value}} {{class + "::" if need_class_name}}{{method.mojom_name}}{{suffix}}(
+{%- for param in method|method_parameters %}
+ {{param}}{{- "," if not loop.last}}
+{%- endfor -%}
+){{" override" if override}}
+{%- endmacro -%}
+
+{#
+ # \brief Generate function body for IPA stop() function for thread
+ #}
+{%- macro stop_thread_body() -%}
+ ASSERT(state_ != ProxyStopping);
+ if (state_ != ProxyRunning)
+ return;
+
+ state_ = ProxyStopping;
+
+ proxy_.invokeMethod(&ThreadProxy::stop, ConnectionTypeBlocking);
+
+ thread_.exit();
+ thread_.wait();
+
+ Thread::current()->dispatchMessages(Message::Type::InvokeMessage);
+
+ state_ = ProxyStopped;
+{%- endmacro -%}
+
+
+{#
+ # \brief Serialize multiple objects into data buffer and fd vector
+ #
+ # Generate code to serialize multiple objects, as specified in \a params
+ # (which are the parameters to some function), into \a buf data buffer and
+ # \a fds fd vector.
+ # This code is meant to be used by the proxy, for serializing prior to IPC calls.
+ #
+ # \todo Avoid intermediate vectors
+ #}
+{%- macro serialize_call(params, buf, fds) %}
+{%- for param in params %}
+{%- if param|is_enum %}
+ static_assert(sizeof({{param|name_full}}) <= 4);
+{%- endif %}
+ std::vector<uint8_t> {{param.mojom_name}}Buf;
+{%- if param|has_fd %}
+ std::vector<SharedFD> {{param.mojom_name}}Fds;
+ std::tie({{param.mojom_name}}Buf, {{param.mojom_name}}Fds) =
+{%- 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<uint32_t>::serialize(static_cast<uint32_t>({{param.mojom_name}})
+{%- else %}
+ IPADataSerializer<{{param|name}}>::serialize({{param.mojom_name}}
+{% endif -%}
+{{- ", &controlSerializer_" if param|needs_control_serializer -}}
+);
+{%- endfor %}
+
+{%- if params|length > 1 %}
+{%- for param in params %}
+ appendPOD<uint32_t>({{buf}}, {{param.mojom_name}}Buf.size());
+{%- if param|has_fd %}
+ appendPOD<uint32_t>({{buf}}, {{param.mojom_name}}Fds.size());
+{%- endif %}
+{%- endfor %}
+{%- endif %}
+
+{%- for param in params %}
+ {{buf}}.insert({{buf}}.end(), {{param.mojom_name}}Buf.begin(), {{param.mojom_name}}Buf.end());
+{%- endfor %}
+
+{%- for param in params %}
+{%- if param|has_fd %}
+ {{fds}}.insert({{fds}}.end(), {{param.mojom_name}}Fds.begin(), {{param.mojom_name}}Fds.end());
+{%- endif %}
+{%- endfor %}
+{%- endmacro -%}
+
+
+{#
+ # \brief Deserialize a single object from data buffer and fd vector
+ #
+ # \param pointer If true, deserialize the object into a dereferenced pointer
+ # \param iter If true, treat \a buf as an iterator instead of a vector
+ # \param data_size Variable that holds the size of the vector referenced by \a buf
+ #
+ # Generate code to deserialize a single object, as specified in \a param,
+ # from \a buf data buffer and \a fds fd vector.
+ # This code is meant to be used by macro deserialize_call.
+ #}
+{%- 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<uint32_t>::deserialize(
+{%- else %}
+IPADataSerializer<{{param|name}}>::deserialize(
+{%- endif %}
+ {{buf}}{{- ".cbegin()" if not iter}} + {{param.mojom_name}}Start,
+{%- if loop.last and not iter %}
+ {{buf}}.cend()
+{%- elif not iter %}
+ {{buf}}.cbegin() + {{param.mojom_name}}Start + {{param.mojom_name}}BufSize
+{%- elif iter and loop.length == 1 %}
+ {{buf}} + {{data_size}}
+{%- else %}
+ {{buf}} + {{param.mojom_name}}Start + {{param.mojom_name}}BufSize
+{%- endif -%}
+{{- "," if param|has_fd}}
+{%- if param|has_fd %}
+ {{fds}}.cbegin() + {{param.mojom_name}}FdStart,
+{%- if loop.last %}
+ {{fds}}.cend()
+{%- else %}
+ {{fds}}.cbegin() + {{param.mojom_name}}FdStart + {{param.mojom_name}}FdsSize
+{%- endif -%}
+{%- endif -%}
+{{- "," if param|needs_control_serializer}}
+{%- if param|needs_control_serializer %}
+ &controlSerializer_
+{%- endif -%}
+){{")" if param|is_enum and not param|is_flags}};
+{%- endmacro -%}
+
+
+{#
+ # \brief Deserialize multiple objects from data buffer and fd vector
+ #
+ # \param pointer If true, deserialize objects into pointers, and adds a null check.
+ # \param declare If true, declare the objects in addition to deserialization.
+ # \param iter if true, treat \a buf as an iterator instead of a vector
+ # \param data_size Variable that holds the size of the vector referenced by \a buf
+ #
+ # Generate code to deserialize multiple objects, as specified in \a params
+ # (which are the parameters to some function), from \a buf data buffer and
+ # \a fds fd vector.
+ # This code is meant to be used by the proxy, for deserializing after IPC calls.
+ #
+ # \todo Avoid intermediate vectors
+ #}
+{%- macro deserialize_call(params, buf, fds, pointer = true, declare = false, iter = false, data_size = '', init_offset = 0) -%}
+{% set ns = namespace(size_offset = init_offset) %}
+{%- if params|length > 1 %}
+{%- for param in params %}
+ [[maybe_unused]] const size_t {{param.mojom_name}}BufSize = readPOD<uint32_t>({{buf}}, {{ns.size_offset}}
+{%- if iter -%}
+, {{buf}} + {{data_size}}
+{%- endif -%}
+);
+ {%- set ns.size_offset = ns.size_offset + 4 %}
+{%- if param|has_fd %}
+ [[maybe_unused]] const size_t {{param.mojom_name}}FdsSize = readPOD<uint32_t>({{buf}}, {{ns.size_offset}}
+{%- if iter -%}
+, {{buf}} + {{data_size}}
+{%- endif -%}
+);
+ {%- set ns.size_offset = ns.size_offset + 4 %}
+{%- endif %}
+{%- endfor %}
+{%- endif %}
+{% for param in params %}
+{%- if loop.first %}
+ const size_t {{param.mojom_name}}Start = {{ns.size_offset}};
+{%- else %}
+ const size_t {{param.mojom_name}}Start = {{loop.previtem.mojom_name}}Start + {{loop.previtem.mojom_name}}BufSize;
+{%- endif %}
+{%- endfor %}
+{% for param in params|with_fds %}
+{%- if loop.first %}
+ const size_t {{param.mojom_name}}FdStart = 0;
+{%- else %}
+ const size_t {{param.mojom_name}}FdStart = {{loop.previtem.mojom_name}}FdStart + {{loop.previtem.mojom_name}}FdsSize;
+{%- endif %}
+{%- endfor %}
+{% for param in params %}
+ {%- if pointer %}
+ if ({{param.mojom_name}}) {
+{{deserialize_param(param, pointer, loop, buf, fds, iter, data_size)|indent(16, True)}}
+ }
+ {%- else %}
+ {{param|name + " " if declare}}{{deserialize_param(param, pointer, loop, buf, fds, iter, data_size)|indent(8)}}
+ {%- endif %}
+{% endfor %}
+{%- endmacro -%}