[libcamera-devel] [PATCH v2 2/3] utils: ipc: Make first output parameter direct return if int32

Paul Elder paul.elder at ideasonboard.com
Mon Mar 8 08:48:27 CET 2021


To make it more convenient for synchronous IPA calls to return a status,
convert the first output into a direct return if it is an int32.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Naushir Patuck <naush at raspberrypi.com>

---
Changes in v2:
- cosmetic changes
---
 .../module_ipa_proxy.cpp.tmpl                 |  7 ++-
 .../module_ipa_proxy_worker.cpp.tmpl          |  8 ++--
 .../libcamera_templates/proxy_functions.tmpl  |  4 +-
 .../generators/mojom_libcamera_generator.py   | 45 ++++++++++++-------
 4 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
index 3eb3dced..f75b1206 100644
--- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
+++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
@@ -209,7 +209,12 @@ void {{proxy_name}}::recvMessage(const IPCMessage &data)
 {%- endif %}
 	}
 {% if method|method_return_value != "void" %}
-	return IPADataSerializer<{{method.response_parameters|first|name}}>::deserialize(_ipcOutputBuf.data(), 0);
+	{{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 -%}
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
index ac037fa1..8a57b6cc 100644
--- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl
+++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl
@@ -83,15 +83,14 @@ public:
 			{{param|name}} {{param.mojom_name}};
 {% endfor %}
 {%- if method|method_return_value != "void" %}
-			{{method|method_return_value}} _callRet = ipa_->{{method.mojom_name}}({{method.parameters|params_comma_sep}});
-{%- else %}
+			{{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 -%}
 );
-{%- endif %}
 {% if not method|is_async %}
 			IPCMessage::Header header = { _ipcMessage.header().cmd, _ipcMessage.header().cookie };
 			IPCMessage _response(header);
@@ -100,9 +99,8 @@ public:
 			std::tie(_callRetBuf, std::ignore) =
 				IPADataSerializer<{{method|method_return_value}}>::serialize(_callRet);
 			_response.data().insert(_response.data().end(), _callRetBuf.cbegin(), _callRetBuf.cend());
-{%- else %}
-		{{proxy_funcs.serialize_call(method|method_param_outputs, "_response.data()", "_response.fds()")|indent(16, true)}}
 {%- 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)
diff --git a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
index f2d86b67..c2ac42fc 100644
--- a/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
+++ b/utils/ipc/generators/libcamera_templates/proxy_functions.tmpl
@@ -135,8 +135,8 @@
  #
  # \todo Avoid intermediate vectors
  #}
-{%- macro deserialize_call(params, buf, fds, pointer = true, declare = false, iter = false, data_size = '') -%}
-{% set ns = namespace(size_offset = 0) %}
+{%- 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}}
diff --git a/utils/ipc/generators/mojom_libcamera_generator.py b/utils/ipc/generators/mojom_libcamera_generator.py
index fa0c21a2..db9e28a6 100644
--- a/utils/ipc/generators/mojom_libcamera_generator.py
+++ b/utils/ipc/generators/mojom_libcamera_generator.py
@@ -149,10 +149,16 @@ def MethodParamInputs(method):
     return method.parameters
 
 def MethodParamOutputs(method):
-    if (MethodReturnValue(method) != 'void' or
-        method.response_parameters is None):
+    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
+
+    return method.response_parameters[1:]
 
 def MethodParamsHaveFd(parameters):
     return len([x for x in parameters if HasFd(x)]) > 0
@@ -167,11 +173,8 @@ def MethodParamNames(method):
     params = []
     for param in method.parameters:
         params.append(param.mojom_name)
-    if MethodReturnValue(method) == 'void':
-        if method.response_parameters is None:
-            return params
-        for param in method.response_parameters:
-            params.append(param.mojom_name)
+    for param in MethodParamOutputs(method):
+        params.append(param.mojom_name)
     return params
 
 def MethodParameters(method):
@@ -180,18 +183,17 @@ def MethodParameters(method):
         params.append('const %s %s%s' % (GetNameForElement(param),
                                          '&' if not IsPod(param) else '',
                                          param.mojom_name))
-    if MethodReturnValue(method) == 'void':
-        if method.response_parameters is None:
-            return params
-        for param in method.response_parameters:
-            params.append(f'{GetNameForElement(param)} *{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:
+    if method.response_parameters is None or len(method.response_parameters) == 0:
         return 'void'
-    if len(method.response_parameters) == 1 and IsPod(method.response_parameters[0]):
-        return GetNameForElement(method.response_parameters[0])
+    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):
@@ -237,6 +239,16 @@ def BitWidth(element):
         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):
     # structs
@@ -373,6 +385,7 @@ class Generator(generator.Generator):
         libcamera_filters = {
             'all_types': GetAllTypes,
             'bit_width': BitWidth,
+            'byte_width' : ByteWidthFromCppType,
             'cap': Capitalize,
             'choose': Choose,
             'comma_sep': CommaSep,
-- 
2.27.0



More information about the libcamera-devel mailing list