summaryrefslogtreecommitdiff
path: root/utils/ipc/generators
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/ipc/generators
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/ipc/generators')
-rw-r--r--utils/ipc/generators/__init__.py0
-rw-r--r--utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl37
-rw-r--r--utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl44
-rw-r--r--utils/ipc/generators/libcamera_templates/definition_functions.tmpl56
-rw-r--r--utils/ipc/generators/libcamera_templates/meson.build14
-rw-r--r--utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl84
-rw-r--r--utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl255
-rw-r--r--utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl132
-rw-r--r--utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl246
-rw-r--r--utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl45
-rw-r--r--utils/ipc/generators/libcamera_templates/proxy_functions.tmpl202
-rw-r--r--utils/ipc/generators/libcamera_templates/serializer.tmpl319
-rw-r--r--utils/ipc/generators/meson.build3
-rw-r--r--utils/ipc/generators/mojom_libcamera_generator.py553
14 files changed, 0 insertions, 1990 deletions
diff --git a/utils/ipc/generators/__init__.py b/utils/ipc/generators/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/utils/ipc/generators/__init__.py
+++ /dev/null
diff --git a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
deleted file mode 100644
index 7f2d0810..00000000
--- a/utils/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl
+++ /dev/null
@@ -1,37 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "definition_functions.tmpl" as funcs -%}
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * libcamera core definitions for Image Processing Algorithms
- *
- * This file is auto-generated. Do not edit.
- */
-
-#pragma once
-
-{% if has_map %}#include <map>{% endif %}
-{% if has_array %}#include <vector>{% endif %}
-
-#include <libcamera/ipa/ipa_interface.h>
-
-namespace libcamera {
-
-{# \todo Use const char * instead of std::string for strings #}
-{% for const in consts %}
-static const {{const.kind|name}} {{const.mojom_name}} = {{const.value}};
-{% endfor %}
-
-{% for enum in enums_gen_header %}
-{{funcs.define_enum(enum)}}
-{% endfor %}
-
-{%- for struct in structs_gen_header %}
-{{funcs.define_struct(struct)}}
-{% endfor %}
-
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl b/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl
deleted file mode 100644
index 036518f6..00000000
--- a/utils/ipc/generators/libcamera_templates/core_ipa_serializer.h.tmpl
+++ /dev/null
@@ -1,44 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "serializer.tmpl" as serializer -%}
-
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Data serializer for core libcamera definitions for IPA
- *
- * This file is auto-generated. Do not edit.
- */
-
-#pragma once
-
-#include <tuple>
-#include <vector>
-
-#include <libcamera/ipa/core_ipa_interface.h>
-
-#include "libcamera/internal/control_serializer.h"
-#include "libcamera/internal/ipa_data_serializer.h"
-
-namespace libcamera {
-
-LOG_DECLARE_CATEGORY(IPADataSerializer)
-{% for struct in structs_gen_serializer %}
-template<>
-class IPADataSerializer<{{struct|name}}>
-{
-public:
-{{- serializer.serializer(struct, "")}}
-{%- if struct|has_fd %}
-{{serializer.deserializer_fd(struct, "")}}
-{%- else %}
-{{serializer.deserializer_no_fd(struct, "")}}
-{{serializer.deserializer_fd_simple(struct, "")}}
-{%- endif %}
-};
-{% endfor %}
-
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl b/utils/ipc/generators/libcamera_templates/definition_functions.tmpl
deleted file mode 100644
index 8b8509f3..00000000
--- a/utils/ipc/generators/libcamera_templates/definition_functions.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-
-{#
- # \brief Generate enum definition
- #
- # \param enum Enum object whose definition is to be generated
- #}
-{%- macro define_enum(enum) -%}
-enum{{" class" if enum|is_scoped}} {{enum.mojom_name}} {
-{%- for field in enum.fields %}
- {{field.mojom_name}} = {{field.numeric_value}},
-{%- endfor %}
-};
-{%- endmacro -%}
-
-{#
- # \brief Generate struct definition
- #
- # \param struct Struct object whose definition is to be generated
- #}
-{%- macro define_struct(struct) -%}
-struct {{struct.mojom_name}}
-{
-public:
-#ifndef __DOXYGEN__
- {{struct.mojom_name}}() {%- if struct|has_default_fields %}
- :{% endif %}
-{%- for field in struct.fields|with_default_values -%}
-{{" " if loop.first}}{{field.mojom_name}}({{field|default_value}}){{", " if not loop.last}}
-{%- endfor %}
- {
- }
-
- {{struct.mojom_name}}(
-{%- for field in struct.fields -%}
-{{"const " if not field|is_pod}}{{field|name}} {{"&" if not field|is_pod}}_{{field.mojom_name}}{{", " if not loop.last}}
-{%- endfor -%}
-)
- :
-{%- for field in struct.fields -%}
-{{" " if loop.first}}{{field.mojom_name}}(_{{field.mojom_name}}){{", " if not loop.last}}
-{%- endfor %}
- {
- }
-#endif
-
-{% for field in struct.fields %}
- {{field|name}} {{field.mojom_name}};
-{%- endfor %}
-};
-{%- endmacro -%}
-
-
diff --git a/utils/ipc/generators/libcamera_templates/meson.build b/utils/ipc/generators/libcamera_templates/meson.build
deleted file mode 100644
index 70664eab..00000000
--- a/utils/ipc/generators/libcamera_templates/meson.build
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: CC0-1.0
-
-mojom_template_files = files([
- 'core_ipa_interface.h.tmpl',
- 'core_ipa_serializer.h.tmpl',
- 'definition_functions.tmpl',
- 'module_ipa_interface.h.tmpl',
- 'module_ipa_proxy.cpp.tmpl',
- 'module_ipa_proxy.h.tmpl',
- 'module_ipa_proxy_worker.cpp.tmpl',
- 'module_ipa_serializer.h.tmpl',
- 'proxy_functions.tmpl',
- 'serializer.tmpl',
-])
diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
deleted file mode 100644
index 4d88a3d7..00000000
--- a/utils/ipc/generators/libcamera_templates/module_ipa_interface.h.tmpl
+++ /dev/null
@@ -1,84 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "definition_functions.tmpl" as funcs -%}
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Image Processing Algorithm interface for {{module_name}}
- *
- * This file is auto-generated. Do not edit.
- */
-
-#pragma once
-
-#include <libcamera/ipa/core_ipa_interface.h>
-#include <libcamera/ipa/ipa_interface.h>
-
-{% if has_map %}#include <map>{% endif %}
-{% if has_array %}#include <vector>{% endif %}
-
-namespace libcamera {
-{%- if has_namespace %}
-{% for ns in namespace %}
-namespace {{ns}} {
-{% endfor %}
-{%- endif %}
-
-{% for const in consts %}
-const {{const.kind|name}} {{const.mojom_name}} = {{const.value}};
-{% endfor %}
-
-enum class {{cmd_enum_name}} {
- Exit = 0,
-{%- for method in interface_main.methods %}
- {{method.mojom_name|cap}} = {{loop.index}},
-{%- endfor %}
-};
-
-enum class {{cmd_event_enum_name}} {
-{%- for method in interface_event.methods %}
- {{method.mojom_name|cap}} = {{loop.index}},
-{%- endfor %}
-};
-
-{% for enum in enums %}
-{{funcs.define_enum(enum)}}
-{% endfor %}
-
-{%- for struct in structs_nonempty %}
-{{funcs.define_struct(struct)}}
-{% endfor %}
-
-{#-
-Any consts or #defines should be moved to the mojom file.
-#}
-class {{interface_name}} : public IPAInterface
-{
-public:
-{% for method in interface_main.methods %}
- virtual {{method|method_return_value}} {{method.mojom_name}}(
-{%- for param in method|method_parameters %}
- {{param}}{{- "," if not loop.last}}
-{%- endfor -%}
-) = 0;
-{% endfor %}
-
-{%- for method in interface_event.methods %}
- Signal<
-{%- for param in method.parameters -%}
- {{"const " if not param|is_pod}}{{param|name}}{{" &" if not param|is_pod and not param|is_enum}}
- {{- ", " if not loop.last}}
-{%- endfor -%}
-> {{method.mojom_name}};
-{% endfor -%}
-};
-
-{%- if has_namespace %}
-{% for ns in namespace|reverse %}
-} /* namespace {{ns}} */
-{% endfor %}
-{%- endif %}
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
deleted file mode 100644
index ce3cc5ab..00000000
--- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
+++ /dev/null
@@ -1,255 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "proxy_functions.tmpl" as proxy_funcs -%}
-
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Image Processing Algorithm proxy for {{module_name}}
- *
- * This file is auto-generated. Do not edit.
- */
-
-#include <libcamera/ipa/{{module_name}}_ipa_proxy.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <libcamera/ipa/ipa_module_info.h>
-#include <libcamera/ipa/{{module_name}}_ipa_interface.h>
-#include <libcamera/ipa/{{module_name}}_ipa_serializer.h>
-
-#include <libcamera/base/log.h>
-#include <libcamera/base/thread.h>
-
-#include "libcamera/internal/control_serializer.h"
-#include "libcamera/internal/ipa_data_serializer.h"
-#include "libcamera/internal/ipa_module.h"
-#include "libcamera/internal/ipa_proxy.h"
-#include "libcamera/internal/ipc_pipe.h"
-#include "libcamera/internal/ipc_pipe_unixsocket.h"
-#include "libcamera/internal/ipc_unixsocket.h"
-#include "libcamera/internal/process.h"
-
-namespace libcamera {
-
-LOG_DECLARE_CATEGORY(IPAProxy)
-
-{%- if has_namespace %}
-{% for ns in namespace %}
-namespace {{ns}} {
-{% endfor %}
-{%- endif %}
-
-{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate)
- : IPAProxy(ipam), isolate_(isolate),
- controlSerializer_(ControlSerializer::Role::Proxy), seq_(0)
-{
- LOG(IPAProxy, Debug)
- << "initializing {{module_name}} proxy: loading IPA from "
- << ipam->path();
-
- if (isolate_) {
- const std::string proxyWorkerPath = resolvePath("{{module_name}}_ipa_proxy");
- if (proxyWorkerPath.empty()) {
- LOG(IPAProxy, Error)
- << "Failed to get proxy worker path";
- return;
- }
-
- ipc_ = std::make_unique<IPCPipeUnixSocket>(ipam->path().c_str(),
- proxyWorkerPath.c_str());
- if (!ipc_->isConnected()) {
- LOG(IPAProxy, Error) << "Failed to create IPCPipe";
- return;
- }
-
- ipc_->recv.connect(this, &{{proxy_name}}::recvMessage);
-
- valid_ = true;
- return;
- }
-
- if (!ipam->load())
- return;
-
- IPAInterface *ipai = ipam->createInterface();
- if (!ipai) {
- LOG(IPAProxy, Error)
- << "Failed to create IPA context for " << ipam->path();
- return;
- }
-
- ipa_ = std::unique_ptr<{{interface_name}}>(static_cast<{{interface_name}} *>(ipai));
- proxy_.setIPA(ipa_.get());
-
-{% for method in interface_event.methods %}
- ipa_->{{method.mojom_name}}.connect(this, &{{proxy_name}}::{{method.mojom_name}}Thread);
-{%- endfor %}
-
- valid_ = true;
-}
-
-{{proxy_name}}::~{{proxy_name}}()
-{
- if (isolate_) {
- IPCMessage::Header header =
- { static_cast<uint32_t>({{cmd_enum_name}}::Exit), seq_++ };
- IPCMessage msg(header);
- ipc_->sendAsync(msg);
- }
-}
-
-{% if interface_event.methods|length > 0 %}
-void {{proxy_name}}::recvMessage(const IPCMessage &data)
-{
- size_t dataSize = data.data().size();
- {{cmd_event_enum_name}} _cmd = static_cast<{{cmd_event_enum_name}}>(data.header().cmd);
-
- switch (_cmd) {
-{%- for method in interface_event.methods %}
- case {{cmd_event_enum_name}}::{{method.mojom_name|cap}}: {
- {{method.mojom_name}}IPC(data.data().cbegin(), dataSize, data.fds());
- break;
- }
-{%- endfor %}
- default:
- LOG(IPAProxy, Error) << "Unknown command " << static_cast<uint32_t>(_cmd);
- }
-}
-{%- endif %}
-
-{% for method in interface_main.methods %}
-{{proxy_funcs.func_sig(proxy_name, method)}}
-{
- if (isolate_)
- {{"return " if method|method_return_value != "void"}}{{method.mojom_name}}IPC(
-{%- for param in method|method_param_names -%}
- {{param}}{{- ", " if not loop.last}}
-{%- endfor -%}
-);
- else
- {{"return " if method|method_return_value != "void"}}{{method.mojom_name}}Thread(
-{%- for param in method|method_param_names -%}
- {{param}}{{- ", " if not loop.last}}
-{%- endfor -%}
-);
-}
-
-{{proxy_funcs.func_sig(proxy_name, method, "Thread")}}
-{
-{%- if method.mojom_name == "stop" %}
- {{proxy_funcs.stop_thread_body()}}
-{%- elif method.mojom_name == "init" %}
- {{ method|method_return_value + " _ret = " if method|method_return_value != "void" -}}
- ipa_->{{method.mojom_name}}(
- {%- for param in method|method_param_names -%}
- {{param}}{{- ", " if not loop.last}}
- {%- endfor -%}
-);
-
- proxy_.moveToThread(&thread_);
-
- return {{ "_ret" if method|method_return_value != "void" }};
-{%- elif method.mojom_name == "start" %}
- state_ = ProxyRunning;
- thread_.start();
-
- {{ "return " if method|method_return_value != "void" -}}
- proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking
- {{- ", " if method|method_param_names}}
- {%- for param in method|method_param_names -%}
- {{param}}{{- ", " if not loop.last}}
- {%- endfor -%}
-);
-{%- elif not method|is_async %}
- {{ "return " if method|method_return_value != "void" -}}
- ipa_->{{method.mojom_name}}(
- {%- for param in method|method_param_names -%}
- {{param}}{{- ", " if not loop.last}}
- {%- endfor -%}
-);
-{% elif method|is_async %}
- ASSERT(state_ == ProxyRunning);
- proxy_.invokeMethod(&ThreadProxy::{{method.mojom_name}}, ConnectionTypeQueued
- {%- for param in method|method_param_names -%}
- , {{param}}
- {%- endfor -%}
-);
-{%- endif %}
-}
-
-{{proxy_funcs.func_sig(proxy_name, method, "IPC")}}
-{
-{%- if method.mojom_name == "configure" %}
- controlSerializer_.reset();
-{%- endif %}
-{%- set has_output = true if method|method_param_outputs|length > 0 or method|method_return_value != "void" %}
-{%- set cmd = cmd_enum_name + "::" + method.mojom_name|cap %}
- IPCMessage::Header _header = { static_cast<uint32_t>({{cmd}}), seq_++ };
- IPCMessage _ipcInputBuf(_header);
-{%- if has_output %}
- IPCMessage _ipcOutputBuf;
-{%- endif %}
-
-{{proxy_funcs.serialize_call(method|method_param_inputs, '_ipcInputBuf.data()', '_ipcInputBuf.fds()')}}
-
-{% if method|is_async %}
- int _ret = ipc_->sendAsync(_ipcInputBuf);
-{%- else %}
- int _ret = ipc_->sendSync(_ipcInputBuf
-{{- ", &_ipcOutputBuf" if has_output -}}
-);
-{%- endif %}
- if (_ret < 0) {
- LOG(IPAProxy, Error) << "Failed to call {{method.mojom_name}}";
-{%- if method|method_return_value != "void" %}
- return static_cast<{{method|method_return_value}}>(_ret);
-{%- else %}
- return;
-{%- endif %}
- }
-{% if method|method_return_value != "void" %}
- {{method|method_return_value}} _retValue = IPADataSerializer<{{method|method_return_value}}>::deserialize(_ipcOutputBuf.data(), 0);
-
-{{proxy_funcs.deserialize_call(method|method_param_outputs, '_ipcOutputBuf.data()', '_ipcOutputBuf.fds()', init_offset = method|method_return_value|byte_width|int)}}
-
- return _retValue;
-
-{% elif method|method_param_outputs|length > 0 %}
-{{proxy_funcs.deserialize_call(method|method_param_outputs, '_ipcOutputBuf.data()', '_ipcOutputBuf.fds()')}}
-{% endif -%}
-}
-
-{% endfor %}
-
-{% for method in interface_event.methods %}
-{{proxy_funcs.func_sig(proxy_name, method, "Thread")}}
-{
- ASSERT(state_ != ProxyStopped);
- {{method.mojom_name}}.emit({{method.parameters|params_comma_sep}});
-}
-
-void {{proxy_name}}::{{method.mojom_name}}IPC(
- [[maybe_unused]] std::vector<uint8_t>::const_iterator data,
- [[maybe_unused]] size_t dataSize,
- [[maybe_unused]] const std::vector<SharedFD> &fds)
-{
-{%- for param in method.parameters %}
- {{param|name}} {{param.mojom_name}};
-{%- endfor %}
-{{proxy_funcs.deserialize_call(method.parameters, 'data', 'fds', false, false, true, 'dataSize')}}
- {{method.mojom_name}}.emit({{method.parameters|params_comma_sep}});
-}
-{% endfor %}
-
-{%- if has_namespace %}
-{% for ns in namespace|reverse %}
-} /* namespace {{ns}} */
-{% endfor %}
-{%- endif %}
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
deleted file mode 100644
index e213b18a..00000000
--- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
+++ /dev/null
@@ -1,132 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "proxy_functions.tmpl" as proxy_funcs -%}
-
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Image Processing Algorithm proxy for {{module_name}}
- *
- * This file is auto-generated. Do not edit.
- */
-
-#pragma once
-
-#include <libcamera/ipa/ipa_interface.h>
-#include <libcamera/ipa/{{module_name}}_ipa_interface.h>
-
-#include <libcamera/base/object.h>
-#include <libcamera/base/thread.h>
-
-#include "libcamera/internal/control_serializer.h"
-#include "libcamera/internal/ipa_proxy.h"
-#include "libcamera/internal/ipc_pipe.h"
-#include "libcamera/internal/ipc_pipe_unixsocket.h"
-#include "libcamera/internal/ipc_unixsocket.h"
-
-namespace libcamera {
-{%- if has_namespace %}
-{% for ns in namespace %}
-namespace {{ns}} {
-{% endfor %}
-{%- endif %}
-
-class {{proxy_name}} : public IPAProxy, public {{interface_name}}, public Object
-{
-public:
- {{proxy_name}}(IPAModule *ipam, bool isolate);
- ~{{proxy_name}}();
-
-{% for method in interface_main.methods %}
-{{proxy_funcs.func_sig(proxy_name, method, "", false, true)|indent(8, true)}};
-{% endfor %}
-
-{%- for method in interface_event.methods %}
- Signal<
-{%- for param in method.parameters -%}
- {{"const " if not param|is_pod}}{{param|name}}{{" &" if not param|is_pod and not param|is_enum}}
- {{- ", " if not loop.last}}
-{%- endfor -%}
-> {{method.mojom_name}};
-{% endfor %}
-
-private:
- void recvMessage(const IPCMessage &data);
-
-{% for method in interface_main.methods %}
-{{proxy_funcs.func_sig(proxy_name, method, "Thread", false)|indent(8, true)}};
-{{proxy_funcs.func_sig(proxy_name, method, "IPC", false)|indent(8, true)}};
-{% endfor %}
-{% for method in interface_event.methods %}
-{{proxy_funcs.func_sig(proxy_name, method, "Thread", false)|indent(8, true)}};
- void {{method.mojom_name}}IPC(
- std::vector<uint8_t>::const_iterator data,
- size_t dataSize,
- const std::vector<SharedFD> &fds);
-{% endfor %}
-
- /* Helper class to invoke async functions in another thread. */
- class ThreadProxy : public Object
- {
- public:
- ThreadProxy()
- : ipa_(nullptr)
- {
- }
-
- void setIPA({{interface_name}} *ipa)
- {
- ipa_ = ipa;
- }
-
- void stop()
- {
- ipa_->stop();
- }
-{% for method in interface_main.methods %}
-{%- if method|is_async %}
- {{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(16)}}
- {
- ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}});
- }
-{%- elif method.mojom_name == "start" %}
- {{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(16)}}
- {
-{%- if method|method_return_value != "void" %}
- return ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}});
-{%- else %}
- ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}}
- {{- ", " if method|method_param_outputs|params_comma_sep -}}
- {{- method|method_param_outputs|params_comma_sep}});
-{%- endif %}
- }
-{%- endif %}
-{%- endfor %}
-
- private:
- {{interface_name}} *ipa_;
- };
-
- Thread thread_;
- ThreadProxy proxy_;
- std::unique_ptr<{{interface_name}}> ipa_;
-
- const bool isolate_;
-
- std::unique_ptr<IPCPipeUnixSocket> ipc_;
-
- ControlSerializer controlSerializer_;
-
-{# \todo Move this to IPCPipe #}
- uint32_t seq_;
-};
-
-{%- if has_namespace %}
-{% for ns in namespace|reverse %}
-} /* namespace {{ns}} */
-{% endfor %}
-{%- endif %}
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl
deleted file mode 100644
index 1f990d3f..00000000
--- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl
+++ /dev/null
@@ -1,246 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "proxy_functions.tmpl" as proxy_funcs -%}
-
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Image Processing Algorithm proxy worker for {{module_name}}
- *
- * This file is auto-generated. Do not edit.
- */
-
-{#- \todo Split proxy worker into IPC worker and proxy worker. #}
-
-#include <algorithm>
-#include <iostream>
-#include <sys/types.h>
-#include <tuple>
-#include <unistd.h>
-
-#include <libcamera/ipa/ipa_interface.h>
-#include <libcamera/ipa/{{module_name}}_ipa_interface.h>
-#include <libcamera/ipa/{{module_name}}_ipa_serializer.h>
-#include <libcamera/logging.h>
-
-#include <libcamera/base/event_dispatcher.h>
-#include <libcamera/base/log.h>
-#include <libcamera/base/thread.h>
-#include <libcamera/base/unique_fd.h>
-
-#include "libcamera/internal/camera_sensor.h"
-#include "libcamera/internal/control_serializer.h"
-#include "libcamera/internal/ipa_data_serializer.h"
-#include "libcamera/internal/ipa_module.h"
-#include "libcamera/internal/ipa_proxy.h"
-#include "libcamera/internal/ipc_pipe.h"
-#include "libcamera/internal/ipc_pipe_unixsocket.h"
-#include "libcamera/internal/ipc_unixsocket.h"
-
-using namespace libcamera;
-
-LOG_DEFINE_CATEGORY({{proxy_worker_name}})
-
-{%- if has_namespace %}
-{% for ns in namespace -%}
-using namespace {{ns}};
-{% endfor %}
-{%- endif %}
-
-class {{proxy_worker_name}}
-{
-public:
- {{proxy_worker_name}}()
- : ipa_(nullptr),
- controlSerializer_(ControlSerializer::Role::Worker),
- exit_(false) {}
-
- ~{{proxy_worker_name}}() {}
-
- void readyRead()
- {
- IPCUnixSocket::Payload _message;
- int _retRecv = socket_.receive(&_message);
- if (_retRecv) {
- LOG({{proxy_worker_name}}, Error)
- << "Receive message failed: " << _retRecv;
- return;
- }
-
- IPCMessage _ipcMessage(_message);
-
- {{cmd_enum_name}} _cmd = static_cast<{{cmd_enum_name}}>(_ipcMessage.header().cmd);
-
- switch (_cmd) {
- case {{cmd_enum_name}}::Exit: {
- exit_ = true;
- break;
- }
-
-{% for method in interface_main.methods %}
- case {{cmd_enum_name}}::{{method.mojom_name|cap}}: {
-{%- if method.mojom_name == "configure" %}
- controlSerializer_.reset();
-{%- endif %}
- {{proxy_funcs.deserialize_call(method|method_param_inputs, '_ipcMessage.data()', '_ipcMessage.fds()', false, true)|indent(16, true)}}
-{% for param in method|method_param_outputs %}
- {{param|name}} {{param.mojom_name}};
-{% endfor %}
-{%- if method|method_return_value != "void" %}
- {{method|method_return_value}} _callRet =
-{%- endif -%}
- ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}}
-{{- ", " if method|method_param_outputs|params_comma_sep -}}
-{%- for param in method|method_param_outputs -%}
-&{{param.mojom_name}}{{", " if not loop.last}}
-{%- endfor -%}
-);
-{% if not method|is_async %}
- IPCMessage::Header header = { _ipcMessage.header().cmd, _ipcMessage.header().cookie };
- IPCMessage _response(header);
-{%- if method|method_return_value != "void" %}
- std::vector<uint8_t> _callRetBuf;
- std::tie(_callRetBuf, std::ignore) =
- IPADataSerializer<{{method|method_return_value}}>::serialize(_callRet);
- _response.data().insert(_response.data().end(), _callRetBuf.cbegin(), _callRetBuf.cend());
-{%- endif %}
- {{proxy_funcs.serialize_call(method|method_param_outputs, "_response.data()", "_response.fds()")|indent(16, true)}}
- int _ret = socket_.send(_response.payload());
- if (_ret < 0) {
- LOG({{proxy_worker_name}}, Error)
- << "Reply to {{method.mojom_name}}() failed: " << _ret;
- }
- LOG({{proxy_worker_name}}, Debug) << "Done replying to {{method.mojom_name}}()";
-{%- endif %}
- break;
- }
-{% endfor %}
- default:
- LOG({{proxy_worker_name}}, Error) << "Unknown command " << _ipcMessage.header().cmd;
- }
- }
-
- int init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd)
- {
- if (socket_.bind(std::move(socketfd)) < 0) {
- LOG({{proxy_worker_name}}, Error)
- << "IPC socket binding failed";
- return EXIT_FAILURE;
- }
- socket_.readyRead.connect(this, &{{proxy_worker_name}}::readyRead);
-
- ipa_ = dynamic_cast<{{interface_name}} *>(ipam->createInterface());
- if (!ipa_) {
- LOG({{proxy_worker_name}}, Error)
- << "Failed to create IPA interface instance";
- return EXIT_FAILURE;
- }
-{% for method in interface_event.methods %}
- ipa_->{{method.mojom_name}}.connect(this, &{{proxy_worker_name}}::{{method.mojom_name}});
-{%- endfor %}
- return 0;
- }
-
- void run()
- {
- EventDispatcher *dispatcher = Thread::current()->eventDispatcher();
- while (!exit_)
- dispatcher->processEvents();
- }
-
- void cleanup()
- {
- delete ipa_;
- socket_.close();
- }
-
-private:
-
-{% for method in interface_event.methods %}
-{{proxy_funcs.func_sig(proxy_name, method, "", false)|indent(8, true)}}
- {
- IPCMessage::Header header = {
- static_cast<uint32_t>({{cmd_event_enum_name}}::{{method.mojom_name|cap}}),
- 0
- };
- IPCMessage _message(header);
-
- {{proxy_funcs.serialize_call(method|method_param_inputs, "_message.data()", "_message.fds()")}}
-
- int _ret = socket_.send(_message.payload());
- if (_ret < 0)
- LOG({{proxy_worker_name}}, Error)
- << "Sending event {{method.mojom_name}}() failed: " << _ret;
-
- LOG({{proxy_worker_name}}, Debug) << "{{method.mojom_name}} done";
- }
-{% endfor %}
-
- {{interface_name}} *ipa_;
- IPCUnixSocket socket_;
-
- ControlSerializer controlSerializer_;
-
- bool exit_;
-};
-
-int main(int argc, char **argv)
-{
-{#- \todo Handle enabling debugging more dynamically. #}
- /* Uncomment this for debugging. */
-#if 0
- std::string logPath = "/tmp/libcamera.worker." +
- std::to_string(getpid()) + ".log";
- logSetFile(logPath.c_str());
-#endif
-
- if (argc < 3) {
- LOG({{proxy_worker_name}}, Error)
- << "Tried to start worker with no args: "
- << "expected <path to IPA so> <fd to bind unix socket>";
- return EXIT_FAILURE;
- }
-
- UniqueFD fd(std::stoi(argv[2]));
- LOG({{proxy_worker_name}}, Info)
- << "Starting worker for IPA module " << argv[1]
- << " with IPC fd = " << fd.get();
-
- std::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);
- if (!ipam->isValid() || !ipam->load()) {
- LOG({{proxy_worker_name}}, Error)
- << "IPAModule " << argv[1] << " isn't valid";
- return EXIT_FAILURE;
- }
-
- /*
- * Shutdown of proxy worker can be pre-empted by events like
- * SIGINT/SIGTERM, even before the pipeline handler can request
- * shutdown. Hence, assign a new gid to prevent signals on the
- * application being delivered to the proxy.
- */
- if (setpgid(0, 0) < 0) {
- int err = errno;
- LOG({{proxy_worker_name}}, Warning)
- << "Failed to set new gid: " << strerror(err);
- }
-
- {{proxy_worker_name}} proxyWorker;
- int ret = proxyWorker.init(ipam, std::move(fd));
- if (ret < 0) {
- LOG({{proxy_worker_name}}, Error)
- << "Failed to initialize proxy worker";
- return ret;
- }
-
- LOG({{proxy_worker_name}}, Debug) << "Proxy worker successfully initialized";
-
- proxyWorker.run();
-
- proxyWorker.cleanup();
-
- return 0;
-}
diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl
deleted file mode 100644
index cd5a65a9..00000000
--- a/utils/ipc/generators/libcamera_templates/module_ipa_serializer.h.tmpl
+++ /dev/null
@@ -1,45 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{%- import "serializer.tmpl" as serializer -%}
-
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2020, Google Inc.
- *
- * Image Processing Algorithm data serializer for {{module_name}}
- *
- * This file is auto-generated. Do not edit.
- */
-
-#pragma once
-
-#include <tuple>
-#include <vector>
-
-#include <libcamera/ipa/{{module_name}}_ipa_interface.h>
-#include <libcamera/ipa/core_ipa_serializer.h>
-
-#include "libcamera/internal/control_serializer.h"
-#include "libcamera/internal/ipa_data_serializer.h"
-
-namespace libcamera {
-
-LOG_DECLARE_CATEGORY(IPADataSerializer)
-{% for struct in structs_nonempty %}
-template<>
-class IPADataSerializer<{{struct|name_full}}>
-{
-public:
-{{- serializer.serializer(struct, namespace_str)}}
-{%- if struct|has_fd %}
-{{serializer.deserializer_fd(struct, namespace_str)}}
-{%- else %}
-{{serializer.deserializer_no_fd(struct, namespace_str)}}
-{{serializer.deserializer_fd_simple(struct, namespace_str)}}
-{%- endif %}
-};
-{% endfor %}
-
-} /* namespace libcamera */
diff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
deleted file mode 100644
index b5797b14..00000000
--- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
+++ /dev/null
@@ -1,202 +0,0 @@
-{#-
- # 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 -%}
diff --git a/utils/ipc/generators/libcamera_templates/serializer.tmpl b/utils/ipc/generators/libcamera_templates/serializer.tmpl
deleted file mode 100644
index 323e1293..00000000
--- a/utils/ipc/generators/libcamera_templates/serializer.tmpl
+++ /dev/null
@@ -1,319 +0,0 @@
-{#-
- # SPDX-License-Identifier: LGPL-2.1-or-later
- # Copyright (C) 2020, Google Inc.
--#}
-{#
- # \brief Verify that there is enough bytes to deserialize
- #
- # Generate code that verifies that \a size is not greater than \a dataSize.
- # Otherwise log an error with \a name and \a typename.
- #}
-{%- macro check_data_size(size, dataSize, name, typename) %}
- if ({{dataSize}} < {{size}}) {
- LOG(IPADataSerializer, Error)
- << "Failed to deserialize " << "{{name}}"
- << ": not enough {{typename}}, expected "
- << ({{size}}) << ", got " << ({{dataSize}});
- return ret;
- }
-{%- endmacro %}
-
-
-{#
- # \brief Serialize a field into return vector
- #
- # Generate code to serialize \a field into retData, including size of the
- # field and fds (where appropriate).
- # This code is meant to be used by the IPADataSerializer specialization.
- #
- # \todo Avoid intermediate vectors
- #}
-{%- macro serializer_field(field, namespace, loop) %}
-{%- if field|is_pod or field|is_enum %}
- std::vector<uint8_t> {{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<uint{{field|bit_width}}_t>::serialize(static_cast<uint{{field|bit_width}}_t>(data.{{field.mojom_name}}));
- {%- elif field|is_enum %}
- IPADataSerializer<uint{{field|bit_width}}_t>::serialize(data.{{field.mojom_name}});
- {%- endif %}
- retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
-{%- elif field|is_fd %}
- std::vector<uint8_t> {{field.mojom_name}};
- std::vector<SharedFD> {{field.mojom_name}}Fds;
- std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) =
- IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}});
- retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
- retFds.insert(retFds.end(), {{field.mojom_name}}Fds.begin(), {{field.mojom_name}}Fds.end());
-{%- elif field|is_controls %}
- if (data.{{field.mojom_name}}.size() > 0) {
- std::vector<uint8_t> {{field.mojom_name}};
- std::tie({{field.mojom_name}}, std::ignore) =
- IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}, cs);
- appendPOD<uint32_t>(retData, {{field.mojom_name}}.size());
- retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
- } else {
- appendPOD<uint32_t>(retData, 0);
- }
-{%- elif field|is_plain_struct or field|is_array or field|is_map or field|is_str %}
- std::vector<uint8_t> {{field.mojom_name}};
- {%- if field|has_fd %}
- std::vector<SharedFD> {{field.mojom_name}}Fds;
- std::tie({{field.mojom_name}}, {{field.mojom_name}}Fds) =
- {%- else %}
- std::tie({{field.mojom_name}}, std::ignore) =
- {%- endif %}
- {%- if field|is_array or field|is_map %}
- IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}}, cs);
- {%- elif field|is_str %}
- IPADataSerializer<{{field|name}}>::serialize(data.{{field.mojom_name}});
- {%- else %}
- IPADataSerializer<{{field|name_full}}>::serialize(data.{{field.mojom_name}}, cs);
- {%- endif %}
- appendPOD<uint32_t>(retData, {{field.mojom_name}}.size());
- {%- if field|has_fd %}
- appendPOD<uint32_t>(retData, {{field.mojom_name}}Fds.size());
- {%- endif %}
- retData.insert(retData.end(), {{field.mojom_name}}.begin(), {{field.mojom_name}}.end());
- {%- if field|has_fd %}
- retFds.insert(retFds.end(), {{field.mojom_name}}Fds.begin(), {{field.mojom_name}}Fds.end());
- {%- endif %}
-{%- else %}
- /* Unknown serialization for {{field.mojom_name}}. */
-{%- endif %}
-{%- endmacro %}
-
-
-{#
- # \brief Deserialize a field into return struct
- #
- # Generate code to deserialize \a field into object ret.
- # This code is meant to be used by the IPADataSerializer specialization.
- #}
-{%- macro deserializer_field(field, namespace, loop) %}
-{% 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<uint{{field|bit_width}}_t>::deserialize(m, m + {{field_size}}));
- {%- endif %}
- {%- if not loop.last %}
- m += {{field_size}};
- dataSize -= {{field_size}};
- {%- endif %}
-{% elif field|is_fd %}
- {%- set field_size = 4 %}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}}
- ret.{{field.mojom_name}} = IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field_size}}, n, n + 1, cs);
- {%- if not loop.last %}
- m += {{field_size}};
- dataSize -= {{field_size}};
- n += ret.{{field.mojom_name}}.isValid() ? 1 : 0;
- fdsSize -= ret.{{field.mojom_name}}.isValid() ? 1 : 0;
- {%- endif %}
-{% elif field|is_controls %}
- {%- set field_size = 4 %}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'Size', 'data')}}
- const size_t {{field.mojom_name}}Size = readPOD<uint32_t>(m, 0, dataEnd);
- m += {{field_size}};
- dataSize -= {{field_size}};
- {%- set field_size = field.mojom_name + 'Size' -%}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}}
- if ({{field.mojom_name}}Size > 0)
- ret.{{field.mojom_name}} =
- IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, cs);
- {%- if not loop.last %}
- m += {{field_size}};
- dataSize -= {{field_size}};
- {%- endif %}
-{% elif field|is_plain_struct or field|is_array or field|is_map or field|is_str %}
- {%- set field_size = 4 %}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'Size', 'data')}}
- const size_t {{field.mojom_name}}Size = readPOD<uint32_t>(m, 0, dataEnd);
- m += {{field_size}};
- dataSize -= {{field_size}};
- {%- if field|has_fd %}
- {%- set field_size = 4 %}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name + 'FdsSize', 'data')}}
- const size_t {{field.mojom_name}}FdsSize = readPOD<uint32_t>(m, 0, dataEnd);
- m += {{field_size}};
- dataSize -= {{field_size}};
- {{- check_data_size(field.mojom_name + 'FdsSize', 'fdsSize', field.mojom_name, 'fds')}}
- {%- endif %}
- {%- set field_size = field.mojom_name + 'Size' -%}
- {{- check_data_size(field_size, 'dataSize', field.mojom_name, 'data')}}
- ret.{{field.mojom_name}} =
- {%- if field|is_str %}
- IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size);
- {%- elif field|has_fd and (field|is_array or field|is_map) %}
- IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, n, n + {{field.mojom_name}}FdsSize, cs);
- {%- elif field|has_fd and (not (field|is_array or field|is_map)) %}
- IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field.mojom_name}}Size, n, n + {{field.mojom_name}}FdsSize, cs);
- {%- elif (not field|has_fd) and (field|is_array or field|is_map) %}
- IPADataSerializer<{{field|name}}>::deserialize(m, m + {{field.mojom_name}}Size, cs);
- {%- else %}
- IPADataSerializer<{{field|name_full}}>::deserialize(m, m + {{field.mojom_name}}Size, cs);
- {%- endif %}
- {%- if not loop.last %}
- m += {{field_size}};
- dataSize -= {{field_size}};
- {%- if field|has_fd %}
- n += {{field.mojom_name}}FdsSize;
- fdsSize -= {{field.mojom_name}}FdsSize;
- {%- endif %}
- {%- endif %}
-{% else %}
- /* Unknown deserialization for {{field.mojom_name}}. */
-{%- endif %}
-{%- endmacro %}
-
-
-{#
- # \brief Serialize a struct
- #
- # Generate code for IPADataSerializer specialization, for serializing
- # \a struct.
- #}
-{%- macro serializer(struct, namespace) %}
- static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
- serialize(const {{struct|name_full}} &data,
-{%- if struct|needs_control_serializer %}
- ControlSerializer *cs)
-{%- else %}
- [[maybe_unused]] ControlSerializer *cs = nullptr)
-{%- endif %}
- {
- std::vector<uint8_t> retData;
-{%- if struct|has_fd %}
- std::vector<SharedFD> retFds;
-{%- endif %}
-{%- for field in struct.fields %}
-{{serializer_field(field, namespace, loop)}}
-{%- endfor %}
-{% if struct|has_fd %}
- return {retData, retFds};
-{%- else %}
- return {retData, {}};
-{%- endif %}
- }
-{%- endmacro %}
-
-
-{#
- # \brief Deserialize a struct that has fds
- #
- # Generate code for IPADataSerializer specialization, for deserializing
- # \a struct, in the case that \a struct has file descriptors.
- #}
-{%- macro deserializer_fd(struct, namespace) %}
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t> &data,
- std::vector<SharedFD> &fds,
-{%- if struct|needs_control_serializer %}
- ControlSerializer *cs)
-{%- else %}
- ControlSerializer *cs = nullptr)
-{%- endif %}
- {
- return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs);
- }
-
-{# \todo Don't inline this function #}
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t>::const_iterator dataBegin,
- std::vector<uint8_t>::const_iterator dataEnd,
- std::vector<SharedFD>::const_iterator fdsBegin,
- std::vector<SharedFD>::const_iterator fdsEnd,
-{%- if struct|needs_control_serializer %}
- ControlSerializer *cs)
-{%- else %}
- [[maybe_unused]] ControlSerializer *cs = nullptr)
-{%- endif %}
- {
- {{struct|name_full}} ret;
- std::vector<uint8_t>::const_iterator m = dataBegin;
- std::vector<SharedFD>::const_iterator n = fdsBegin;
-
- size_t dataSize = std::distance(dataBegin, dataEnd);
- [[maybe_unused]] size_t fdsSize = std::distance(fdsBegin, fdsEnd);
-{%- for field in struct.fields -%}
-{{deserializer_field(field, namespace, loop)}}
-{%- endfor %}
- return ret;
- }
-{%- endmacro %}
-
-{#
- # \brief Deserialize a struct that has fds, using non-fd
- #
- # Generate code for IPADataSerializer specialization, for deserializing
- # \a struct, in the case that \a struct has no file descriptors but requires
- # deserializers with file descriptors.
- #}
-{%- macro deserializer_fd_simple(struct, namespace) %}
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t> &data,
- [[maybe_unused]] std::vector<SharedFD> &fds,
- ControlSerializer *cs = nullptr)
- {
- return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), cs);
- }
-
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t>::const_iterator dataBegin,
- std::vector<uint8_t>::const_iterator dataEnd,
- [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
- [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
- ControlSerializer *cs = nullptr)
- {
- return IPADataSerializer<{{struct|name_full}}>::deserialize(dataBegin, dataEnd, cs);
- }
-{%- endmacro %}
-
-
-{#
- # \brief Deserialize a struct that has no fds
- #
- # Generate code for IPADataSerializer specialization, for deserializing
- # \a struct, in the case that \a struct does not have file descriptors.
- #}
-{%- macro deserializer_no_fd(struct, namespace) %}
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t> &data,
-{%- if struct|needs_control_serializer %}
- ControlSerializer *cs)
-{%- else %}
- ControlSerializer *cs = nullptr)
-{%- endif %}
- {
- return IPADataSerializer<{{struct|name_full}}>::deserialize(data.cbegin(), data.cend(), cs);
- }
-
-{# \todo Don't inline this function #}
- static {{struct|name_full}}
- deserialize(std::vector<uint8_t>::const_iterator dataBegin,
- std::vector<uint8_t>::const_iterator dataEnd,
-{%- if struct|needs_control_serializer %}
- ControlSerializer *cs)
-{%- else %}
- [[maybe_unused]] ControlSerializer *cs = nullptr)
-{%- endif %}
- {
- {{struct|name_full}} ret;
- std::vector<uint8_t>::const_iterator m = dataBegin;
-
- size_t dataSize = std::distance(dataBegin, dataEnd);
-{%- for field in struct.fields -%}
-{{deserializer_field(field, namespace, loop)}}
-{%- endfor %}
- return ret;
- }
-{%- endmacro %}
diff --git a/utils/ipc/generators/meson.build b/utils/ipc/generators/meson.build
deleted file mode 100644
index 504f1a46..00000000
--- a/utils/ipc/generators/meson.build
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: CC0-1.0
-
-subdir('libcamera_templates')
diff --git a/utils/ipc/generators/mojom_libcamera_generator.py b/utils/ipc/generators/mojom_libcamera_generator.py
deleted file mode 100644
index b8209e51..00000000
--- a/utils/ipc/generators/mojom_libcamera_generator.py
+++ /dev/null
@@ -1,553 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (C) 2020, Google Inc.
-#
-# Author: Paul Elder <paul.elder@ideasonboard.com>
-#
-# Generates libcamera files from a mojom.Module.
-
-import argparse
-import datetime
-import os
-import re
-
-import mojom.fileutil as fileutil
-import mojom.generate.generator as generator
-import mojom.generate.module as mojom
-from mojom.generate.template_expander import UseJinja
-
-
-GENERATOR_PREFIX = 'libcamera'
-
-_kind_to_cpp_type = {
- mojom.BOOL: 'bool',
- mojom.INT8: 'int8_t',
- mojom.UINT8: 'uint8_t',
- mojom.INT16: 'int16_t',
- mojom.UINT16: 'uint16_t',
- mojom.INT32: 'int32_t',
- mojom.UINT32: 'uint32_t',
- mojom.FLOAT: 'float',
- mojom.INT64: 'int64_t',
- mojom.UINT64: 'uint64_t',
- mojom.DOUBLE: 'double',
-}
-
-_bit_widths = {
- mojom.BOOL: '8',
- mojom.INT8: '8',
- mojom.UINT8: '8',
- mojom.INT16: '16',
- mojom.UINT16: '16',
- mojom.INT32: '32',
- mojom.UINT32: '32',
- mojom.FLOAT: '32',
- mojom.INT64: '64',
- mojom.UINT64: '64',
- mojom.DOUBLE: '64',
-}
-
-def ModuleName(path):
- return path.split('/')[-1].split('.')[0]
-
-def ModuleClassName(module):
- return re.sub(r'^IPA(.*)Interface$', lambda match: match.group(1),
- module.interfaces[0].mojom_name)
-
-def Capitalize(name):
- return name[0].upper() + name[1:]
-
-def ConstantStyle(name):
- return generator.ToUpperSnakeCase(name)
-
-def Choose(cond, t, f):
- return t if cond else f
-
-def CommaSep(l):
- return ', '.join([m for m in l])
-
-def ParamsCommaSep(l):
- return ', '.join([m.mojom_name for m in l])
-
-def GetDefaultValue(element):
- if element.default is not None:
- return element.default
- if type(element.kind) == mojom.ValueKind:
- 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 \
- element.kind.mojom_name == 'SharedFD':
- return '-1'
- return ''
-
-def HasDefaultValue(element):
- return GetDefaultValue(element) != ''
-
-def HasDefaultFields(element):
- return True in [HasDefaultValue(x) for x in element.fields]
-
-def GetAllTypes(element):
- if mojom.IsArrayKind(element):
- return GetAllTypes(element.kind)
- if mojom.IsMapKind(element):
- return GetAllTypes(element.key_kind) + GetAllTypes(element.value_kind)
- if isinstance(element, mojom.Parameter):
- return GetAllTypes(element.kind)
- if mojom.IsEnumKind(element):
- return [element.mojom_name]
- if not mojom.IsStructKind(element):
- return [element.spec]
- if len(element.fields) == 0:
- return [element.mojom_name]
- ret = [GetAllTypes(x.kind) for x in element.fields]
- ret = [x for sublist in ret for x in sublist]
- return list(set(ret))
-
-def GetAllAttrs(element):
- if mojom.IsArrayKind(element):
- return GetAllAttrs(element.kind)
- if mojom.IsMapKind(element):
- return {**GetAllAttrs(element.key_kind), **GetAllAttrs(element.value_kind)}
- if isinstance(element, mojom.Parameter):
- return GetAllAttrs(element.kind)
- if mojom.IsEnumKind(element):
- return element.attributes if element.attributes is not None else {}
- if mojom.IsStructKind(element) and len(element.fields) == 0:
- return element.attributes if element.attributes is not None else {}
- if not mojom.IsStructKind(element):
- if hasattr(element, 'attributes'):
- return element.attributes or {}
- return {}
- attrs = [(x.attributes) for x in element.fields]
- ret = {}
- for d in attrs:
- ret.update(d or {})
- if hasattr(element, 'attributes'):
- ret.update(element.attributes or {})
- return ret
-
-def NeedsControlSerializer(element):
- types = GetAllTypes(element)
- for type in ['ControlList', 'ControlInfoMap']:
- if f'x:{type}' in types:
- raise Exception(f'Unknown type "{type}" in {element.mojom_name}, did you mean "libcamera.{type}"?')
- return "ControlList" in types or "ControlInfoMap" in types
-
-def HasFd(element):
- attrs = GetAllAttrs(element)
- if isinstance(element, mojom.Kind):
- types = GetAllTypes(element)
- else:
- types = GetAllTypes(element.kind)
- return "SharedFD" in types or (attrs is not None and "hasFd" in attrs)
-
-def WithDefaultValues(element):
- return [x for x in element if HasDefaultValue(x)]
-
-def WithFds(element):
- return [x for x in element if HasFd(x)]
-
-def MethodParamInputs(method):
- return method.parameters
-
-def MethodParamOutputs(method):
- if method.response_parameters is None:
- return []
-
- if MethodReturnValue(method) == 'void':
- return method.response_parameters
-
- if len(method.response_parameters) <= 1:
- return []
-
- return method.response_parameters[1:]
-
-def MethodParamsHaveFd(parameters):
- return len([x for x in parameters if HasFd(x)]) > 0
-
-def MethodInputHasFd(method):
- return MethodParamsHaveFd(method.parameters)
-
-def MethodOutputHasFd(method):
- return MethodParamsHaveFd(MethodParamOutputs(method))
-
-def MethodParamNames(method):
- params = []
- for param in method.parameters:
- params.append(param.mojom_name)
- for param in MethodParamOutputs(method):
- params.append(param.mojom_name)
- return params
-
-def MethodParameters(method):
- params = []
- for param in method.parameters:
- params.append('const %s %s%s' % (GetNameForElement(param),
- '' if IsPod(param) or IsEnum(param) else '&',
- param.mojom_name))
- for param in MethodParamOutputs(method):
- params.append(f'{GetNameForElement(param)} *{param.mojom_name}')
- return params
-
-def MethodReturnValue(method):
- if method.response_parameters is None or len(method.response_parameters) == 0:
- return 'void'
- first_output = method.response_parameters[0]
- if ((len(method.response_parameters) == 1 and IsPod(first_output)) or
- first_output.kind == mojom.INT32):
- return GetNameForElement(first_output)
- return 'void'
-
-def IsAsync(method):
- # Events are always async
- if re.match("^IPA.*EventInterface$", method.interface.mojom_name):
- return True
- elif re.match("^IPA.*Interface$", method.interface.mojom_name):
- if method.attributes is None:
- return False
- elif 'async' in method.attributes and method.attributes['async']:
- return True
- return False
-
-def IsArray(element):
- return mojom.IsArrayKind(element.kind)
-
-def IsControls(element):
- return mojom.IsStructKind(element.kind) and (element.kind.mojom_name == "ControlList" or
- element.kind.mojom_name == "ControlInfoMap")
-
-def IsEnum(element):
- return mojom.IsEnumKind(element.kind)
-
-
-# Only works the enum definition, not types
-def IsScoped(element):
- attributes = getattr(element, 'attributes', None)
- if not attributes:
- return False
- return 'scopedEnum' in attributes
-
-
-def IsEnumScoped(element):
- if not IsEnum(element):
- return False
- return IsScoped(element.kind)
-
-def IsFd(element):
- return mojom.IsStructKind(element.kind) and element.kind.mojom_name == "SharedFD"
-
-
-def IsFlags(element):
- attributes = getattr(element, 'attributes', None)
- if not attributes:
- return False
- return 'flags' in attributes
-
-def IsMap(element):
- return mojom.IsMapKind(element.kind)
-
-def IsPlainStruct(element):
- return mojom.IsStructKind(element.kind) and not IsControls(element) and not IsFd(element)
-
-def IsPod(element):
- return element.kind in _kind_to_cpp_type
-
-def IsStr(element):
- return element.kind.spec == 's'
-
-def BitWidth(element):
- if element.kind in _bit_widths:
- return _bit_widths[element.kind]
- if mojom.IsEnumKind(element.kind):
- return '32'
- return ''
-
-def ByteWidthFromCppType(t):
- key = None
- for mojo_type, cpp_type in _kind_to_cpp_type.items():
- if t == cpp_type:
- key = mojo_type
- if key is None:
- raise Exception('invalid type')
- return str(int(_bit_widths[key]) // 8)
-
-# Get the type name for a given element
-def GetNameForElement(element):
- # Flags
- if IsFlags(element):
- return f'Flags<{GetFullNameForElement(element.kind)}>'
- # structs
- if (mojom.IsEnumKind(element) or
- mojom.IsInterfaceKind(element) or
- mojom.IsStructKind(element)):
- return element.mojom_name
- # vectors
- if (mojom.IsArrayKind(element)):
- elem_name = GetFullNameForElement(element.kind)
- return f'std::vector<{elem_name}>'
- # maps
- if (mojom.IsMapKind(element)):
- key_name = GetFullNameForElement(element.key_kind)
- value_name = GetFullNameForElement(element.value_kind)
- return f'std::map<{key_name}, {value_name}>'
- # struct fields and function parameters
- if isinstance(element, (mojom.Field, mojom.Method, mojom.Parameter)):
- # maps and vectors
- if (mojom.IsArrayKind(element.kind) or mojom.IsMapKind(element.kind)):
- return GetNameForElement(element.kind)
- # strings
- if (mojom.IsReferenceKind(element.kind) and element.kind.spec == 's'):
- return 'std::string'
- # PODs
- if element.kind in _kind_to_cpp_type:
- return _kind_to_cpp_type[element.kind]
- # structs and enums
- return element.kind.mojom_name
- # PODs that are members of vectors/maps
- if (hasattr(element, '__hash__') and element in _kind_to_cpp_type):
- return _kind_to_cpp_type[element]
- if (hasattr(element, 'spec')):
- # strings that are members of vectors/maps
- if (element.spec == 's'):
- return 'std::string'
- # structs that aren't defined in mojom that are members of vectors/maps
- if (element.spec[0] == 'x'):
- return element.spec.replace('x:', '').replace('.', '::')
- if (mojom.IsInterfaceRequestKind(element) or
- mojom.IsAssociatedKind(element) or
- mojom.IsPendingRemoteKind(element) or
- mojom.IsPendingReceiverKind(element) or
- mojom.IsUnionKind(element)):
- raise Exception('Unsupported element: %s' % element)
- raise Exception('Unexpected element: %s' % element)
-
-def GetFullNameForElement(element):
- name = GetNameForElement(element)
- namespace_str = ''
- if (mojom.IsStructKind(element) or mojom.IsEnumKind(element)):
- namespace_str = element.module.mojom_namespace.replace('.', '::')
- elif (hasattr(element, 'kind') and
- (mojom.IsStructKind(element.kind) or mojom.IsEnumKind(element.kind))):
- namespace_str = element.kind.module.mojom_namespace.replace('.', '::')
-
- if namespace_str == '':
- return name
-
- if IsFlags(element):
- return GetNameForElement(element)
-
- return f'{namespace_str}::{name}'
-
-def ValidateZeroLength(l, s, cap=True):
- if l is None:
- return
- if len(l) > 0:
- raise Exception(f'{s.capitalize() if cap else s} should be empty')
-
-def ValidateSingleLength(l, s, cap=True):
- if len(l) > 1:
- raise Exception(f'Only one {s} allowed')
- if len(l) < 1:
- raise Exception(f'{s.capitalize() if cap else s} is required')
-
-def GetMainInterface(interfaces):
- intf = [x for x in interfaces
- if re.match("^IPA.*Interface", x.mojom_name) and
- not re.match("^IPA.*EventInterface", x.mojom_name)]
- ValidateSingleLength(intf, 'main interface')
- return None if len(intf) == 0 else intf[0]
-
-def GetEventInterface(interfaces):
- event = [x for x in interfaces if re.match("^IPA.*EventInterface", x.mojom_name)]
- ValidateSingleLength(event, 'event interface')
- return None if len(event) == 0 else event[0]
-
-def ValidateNamespace(namespace):
- if namespace == '':
- raise Exception('Must have a namespace')
-
- if not re.match(r'^ipa\.[0-9A-Za-z_]+', namespace):
- raise Exception('Namespace must be of the form "ipa.{pipeline_name}"')
-
-def ValidateInterfaces(interfaces):
- # Validate presence of main interface
- intf = GetMainInterface(interfaces)
- if intf is None:
- raise Exception('Must have main IPA interface')
-
- # Validate presence of event interface
- event = GetEventInterface(interfaces)
- if intf is None:
- raise Exception('Must have event IPA interface')
-
- # Validate required main interface functions
- f_init = [x for x in intf.methods if x.mojom_name == 'init']
- f_start = [x for x in intf.methods if x.mojom_name == 'start']
- f_stop = [x for x in intf.methods if x.mojom_name == 'stop']
-
- ValidateSingleLength(f_init, 'init()', False)
- ValidateSingleLength(f_start, 'start()', False)
- ValidateSingleLength(f_stop, 'stop()', False)
-
- f_stop = f_stop[0]
-
- # No need to validate init() and start() as they are customizable
-
- # Validate parameters to stop()
- ValidateZeroLength(f_stop.parameters, 'input parameter to stop()')
- ValidateZeroLength(f_stop.parameters, 'output parameter from stop()')
-
- # Validate that event interface has at least one event
- if len(event.methods) < 1:
- raise Exception('Event interface must have at least one event')
-
- # Validate that all async methods don't have return values
- intf_methods_async = [x for x in intf.methods if IsAsync(x)]
- for method in intf_methods_async:
- ValidateZeroLength(method.response_parameters,
- f'{method.mojom_name} response parameters', False)
-
- event_methods_async = [x for x in event.methods if IsAsync(x)]
- for method in event_methods_async:
- ValidateZeroLength(method.response_parameters,
- f'{method.mojom_name} response parameters', False)
-
-class Generator(generator.Generator):
- @staticmethod
- def GetTemplatePrefix():
- return 'libcamera_templates'
-
- def GetFilters(self):
- libcamera_filters = {
- 'all_types': GetAllTypes,
- 'bit_width': BitWidth,
- 'byte_width' : ByteWidthFromCppType,
- 'cap': Capitalize,
- 'choose': Choose,
- 'comma_sep': CommaSep,
- 'default_value': GetDefaultValue,
- 'has_default_fields': HasDefaultFields,
- 'has_fd': HasFd,
- 'is_async': IsAsync,
- 'is_array': IsArray,
- 'is_controls': IsControls,
- 'is_enum': IsEnum,
- 'is_enum_scoped': IsEnumScoped,
- 'is_fd': IsFd,
- 'is_flags': IsFlags,
- 'is_map': IsMap,
- 'is_plain_struct': IsPlainStruct,
- 'is_pod': IsPod,
- 'is_scoped': IsScoped,
- 'is_str': IsStr,
- 'method_input_has_fd': MethodInputHasFd,
- 'method_output_has_fd': MethodOutputHasFd,
- 'method_param_names': MethodParamNames,
- 'method_param_inputs': MethodParamInputs,
- 'method_param_outputs': MethodParamOutputs,
- 'method_parameters': MethodParameters,
- 'method_return_value': MethodReturnValue,
- 'name': GetNameForElement,
- 'name_full': GetFullNameForElement,
- 'needs_control_serializer': NeedsControlSerializer,
- 'params_comma_sep': ParamsCommaSep,
- 'with_default_values': WithDefaultValues,
- 'with_fds': WithFds,
- }
- return libcamera_filters
-
- def _GetJinjaExports(self):
- return {
- 'cmd_enum_name': '_%sCmd' % self.module_name,
- 'cmd_event_enum_name': '_%sEventCmd' % self.module_name,
- 'consts': self.module.constants,
- 'enums': self.module.enums,
- '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 != '',
- 'interface_event': GetEventInterface(self.module.interfaces),
- 'interface_main': GetMainInterface(self.module.interfaces),
- 'interface_name': 'IPA%sInterface' % self.module_name,
- 'module_name': ModuleName(self.module.path),
- 'namespace': self.module.mojom_namespace.split('.'),
- 'namespace_str': self.module.mojom_namespace.replace('.', '::') if
- self.module.mojom_namespace is not None else '',
- 'proxy_name': 'IPAProxy%s' % self.module_name,
- 'proxy_worker_name': 'IPAProxy%sWorker' % self.module_name,
- 'structs_nonempty': [x for x in self.module.structs if len(x.fields) > 0],
- }
-
- def _GetJinjaExportsForCore(self):
- return {
- 'consts': self.module.constants,
- 'enums_gen_header': [x for x in self.module.enums if x.attributes is None or 'skipHeader' not in x.attributes],
- '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,
- 'structs_gen_header': [x for x in self.module.structs if x.attributes is None or 'skipHeader' not in x.attributes],
- 'structs_gen_serializer': [x for x in self.module.structs if x.attributes is None or 'skipSerdes' not in x.attributes],
- }
-
- @UseJinja('core_ipa_interface.h.tmpl')
- def _GenerateCoreHeader(self):
- return self._GetJinjaExportsForCore()
-
- @UseJinja('core_ipa_serializer.h.tmpl')
- def _GenerateCoreSerializer(self):
- return self._GetJinjaExportsForCore()
-
- @UseJinja('module_ipa_interface.h.tmpl')
- def _GenerateDataHeader(self):
- return self._GetJinjaExports()
-
- @UseJinja('module_ipa_serializer.h.tmpl')
- def _GenerateSerializer(self):
- return self._GetJinjaExports()
-
- @UseJinja('module_ipa_proxy.cpp.tmpl')
- def _GenerateProxyCpp(self):
- return self._GetJinjaExports()
-
- @UseJinja('module_ipa_proxy.h.tmpl')
- def _GenerateProxyHeader(self):
- return self._GetJinjaExports()
-
- @UseJinja('module_ipa_proxy_worker.cpp.tmpl')
- def _GenerateProxyWorker(self):
- return self._GetJinjaExports()
-
- def GenerateFiles(self, unparsed_args):
- parser = argparse.ArgumentParser()
- parser.add_argument('--libcamera_generate_core_header', action='store_true')
- parser.add_argument('--libcamera_generate_core_serializer', action='store_true')
- parser.add_argument('--libcamera_generate_header', action='store_true')
- parser.add_argument('--libcamera_generate_serializer', action='store_true')
- parser.add_argument('--libcamera_generate_proxy_cpp', action='store_true')
- parser.add_argument('--libcamera_generate_proxy_h', action='store_true')
- parser.add_argument('--libcamera_generate_proxy_worker', action='store_true')
- parser.add_argument('--libcamera_output_path')
- args = parser.parse_args(unparsed_args)
-
- if not args.libcamera_generate_core_header and \
- not args.libcamera_generate_core_serializer:
- ValidateNamespace(self.module.mojom_namespace)
- ValidateInterfaces(self.module.interfaces)
- self.module_name = ModuleClassName(self.module)
-
- fileutil.EnsureDirectoryExists(os.path.dirname(args.libcamera_output_path))
-
- gen_funcs = [
- [args.libcamera_generate_core_header, self._GenerateCoreHeader],
- [args.libcamera_generate_core_serializer, self._GenerateCoreSerializer],
- [args.libcamera_generate_header, self._GenerateDataHeader],
- [args.libcamera_generate_serializer, self._GenerateSerializer],
- [args.libcamera_generate_proxy_cpp, self._GenerateProxyCpp],
- [args.libcamera_generate_proxy_h, self._GenerateProxyHeader],
- [args.libcamera_generate_proxy_worker, self._GenerateProxyWorker],
- ]
-
- for pair in gen_funcs:
- if pair[0]:
- self.Write(pair[1](), args.libcamera_output_path)