From patchwork Wed Aug 10 00:29:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17062 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 64918C3275 for ; Wed, 10 Aug 2022 00:29:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 33B6D63332; Wed, 10 Aug 2022 02:29:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660091363; bh=kSo2TbnvJTbGucRoEEULwHJAUv/a7vzP3VhgcPh9QIM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=v77kDBkCdbR2/cjBtfYeqkOddVrbSOZpE+jgN8qJ1mV+eo4b0hF5eFz9UUvJw+Kr4 oP8J4eYXJzmzktI1yvf42LLjybwvWbijZJEWweXGdYJjbel/L1jIny4dlS0AkSuOhT JHiO0V1Mj5s88qerdoA5xGcUgWivCNBkLh+piRxb25mP18e4Ai1tKrK0vmKqhxEUUl I0UX70R1RMIvbOYifjTMbNYoQOmWstco3oo2oKEzCAm0ws7vvgh4MFT7n/II+F2jYY u1PiivY9PkwCbiLdN1sQZAoS0iRAyf4TsPrChQRC6io5Xe4E+WjyStxe85B8sqCSNO UZoMBkdFEPVsA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 06A5563326 for ; Wed, 10 Aug 2022 02:29:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="a9737xUu"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 931CB481; Wed, 10 Aug 2022 02:29:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660091359; bh=kSo2TbnvJTbGucRoEEULwHJAUv/a7vzP3VhgcPh9QIM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a9737xUu1a8QYifbPsY5RdhtSqNczAOq3nh9bOCbLNaYLNJnZK8HLeq9eV8rGssLA 0PgFpcNYPW3A2CRbNzrC9NjhVMQf3zp5bfI890nmSkQIuy2BMEBKC6YI+ON0wUskuA n9/ggqLjvnAZCpCdNOQn/+xUNwDO49PvL3K7gERU= To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 03:29:03 +0300 Message-Id: <20220810002906.5406-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> References: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/4] utils: gen-controls: Factor out YAML data handling in classes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The gen-controls.py script handles the data structure produced by the YAML parser manually through the whole code base. Clean this up by encapsulating it in Control and ControlEnum classes to model a control and its enum values respectively, to decouple YAML data handling from generation. No functional change intended. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- utils/gen-controls.py | 156 ++++++++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 50 deletions(-) diff --git a/utils/gen-controls.py b/utils/gen-controls.py index 46ba439439ec..f6a3ae39cc84 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -14,6 +14,90 @@ import sys import yaml +class ControlEnum(object): + def __init__(self, data): + self.__data = data + + @property + def description(self): + """The enum description""" + return self.__data.get('description') + + @property + def name(self): + """The enum name""" + return self.__data.get('name') + + @property + def value(self): + """The enum value""" + return self.__data.get('value') + + +class Control(object): + def __init__(self, name, data): + self.__name = name + self.__data = data + self.__enum = None + + enum_values = data.get('enum') + if enum_values is not None: + self.__enum_values = [ControlEnum(enum) for enum in enum_values] + + @property + def description(self): + """The control description""" + return self.__data.get('description') + + @property + def enum_values(self): + """The enum values, if the control is an enumeration""" + if self.__enum_values is None: + return + for enum in self.__enum_values: + yield enum + + @property + def is_enum(self): + """Is the control an enumeration""" + return self.__data.get('enum') is not None + + @property + def is_draft(self): + """Is the control a draft control""" + return self.__data.get('draft') is not None + + @property + def name(self): + """The control name (CameCase)""" + return self.__name + + @property + def q_name(self): + """The control name, qualified with a namespace""" + ns = 'draft::' if self.is_draft else '' + return ns + self.__name + + @property + def type(self): + typ = self.__data.get('type') + size = self.__data.get('size') + + if typ == 'string': + return 'std::string' + + if size is None: + return typ + + if len(size) > 0: + # fixed-sized Span + span_size = reduce(operator.mul, size) + return f"Span" + else: + # variable-sized Span + return f"Span" + + def snake_case(s): return ''.join([c.isupper() and ('_' + c) or c for c in s]).strip('_') @@ -24,24 +108,6 @@ def format_description(description): return '\n'.join([(line and ' * ' or ' *') + line for line in description]) -def get_ctrl_type(ctrl): - ctrl_type = ctrl['type'] - ctrl_size_arr = ctrl.get('size') - - if ctrl_type == 'string': - return 'std::string' - elif ctrl_size_arr is not None: - if len(ctrl_size_arr) > 0: - # fixed-sized Span - ctrl_span_size = reduce(operator.mul, ctrl_size_arr) - return f"Span" - else: - # variable-sized Span - return f"Span" - else: - return ctrl_type - - def generate_cpp(controls): enum_doc_start_template = string.Template('''/** * \\enum ${name}Enum @@ -67,35 +133,31 @@ ${description} ctrls_map = [] for ctrl in controls: - name, ctrl = ctrl.popitem() - id_name = snake_case(name).upper() - - ctrl_type = get_ctrl_type(ctrl) + id_name = snake_case(ctrl.name).upper() info = { - 'name': name, - 'type': ctrl_type, - 'description': format_description(ctrl['description']), + 'name': ctrl.name, + 'type': ctrl.type, + 'description': format_description(ctrl.description), 'id_name': id_name, } target_doc = ctrls_doc target_def = ctrls_def - if ctrl.get('draft'): + if ctrl.is_draft: target_doc = draft_ctrls_doc target_def = draft_ctrls_def - enum = ctrl.get('enum') - if enum: + if ctrl.is_enum: enum_doc = [] enum_doc.append(enum_doc_start_template.substitute(info)) num_entries = 0 - for entry in enum: + for enum in ctrl.enum_values: value_info = { - 'name': name, - 'value': entry['name'], - 'description': format_description(entry['description']), + 'name': ctrl.name, + 'value': enum.name, + 'description': format_description(enum.description), } enum_doc.append(enum_doc_value_template.substitute(value_info)) num_entries += 1 @@ -110,9 +172,9 @@ ${description} } target_doc.append(enum_values_doc.substitute(values_info)) target_def.append(enum_values_start.substitute(values_info)) - for entry in enum: + for enum in ctrl.enum_values: value_info = { - 'name': entry['name'] + 'name': enum.name } target_def.append(enum_values_values.substitute(value_info)) target_def.append("};") @@ -120,10 +182,7 @@ ${description} target_doc.append(doc_template.substitute(info)) target_def.append(def_template.substitute(info)) - if ctrl.get('draft'): - name = 'draft::' + name - - ctrls_map.append('\t{ ' + id_name + ', &' + name + ' },') + ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.q_name + ' },') return { 'controls_doc': '\n\n'.join(ctrls_doc), @@ -146,31 +205,27 @@ def generate_h(controls): id_value = 1 for ctrl in controls: - name, ctrl = ctrl.popitem() - id_name = snake_case(name).upper() + id_name = snake_case(ctrl.name).upper() ids.append('\t' + id_name + ' = ' + str(id_value) + ',') - ctrl_type = get_ctrl_type(ctrl) - info = { - 'name': name, - 'type': ctrl_type, + 'name': ctrl.name, + 'type': ctrl.type, } target_ctrls = ctrls - if ctrl.get('draft'): + if ctrl.is_draft: target_ctrls = draft_ctrls - enum = ctrl.get('enum') - if enum: + if ctrl.is_enum: target_ctrls.append(enum_template_start.substitute(info)) num_entries = 0 - for entry in enum: + for enum in ctrl.enum_values: value_info = { - 'name': entry['name'], - 'value': entry['value'], + 'name': enum.name, + 'value': enum.value, } target_ctrls.append(enum_value_template.substitute(value_info)) num_entries += 1 @@ -214,6 +269,7 @@ def main(argv): data = open(args.input, 'rb').read() controls = yaml.safe_load(data)['controls'] + controls = [Control(*ctrl.popitem()) for ctrl in controls] if args.template.endswith('.cpp.in'): data = generate_cpp(controls) From patchwork Wed Aug 10 00:29:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17063 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4CF5BC3272 for ; Wed, 10 Aug 2022 00:29:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BAB3F63330; Wed, 10 Aug 2022 02:29:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660091363; bh=3+LLHIx7JHt4B2nWjKpg7cgeXKrzk1gsHhHaKandpAM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Q5+REoEV0F7Vh/Zl09qrdzlqidllvQRmfEXpsrVohsPk6LKZA0J5l1fh9OxghDfFd nMT3IhEsJXwuH7ww9JSzlQyISyWmDPJdW+N0Uj8eClX8q95K7JM/JKbHL+AHtWT51S CopkamxdJkf8IzGU9Rt8O3V+LQCELspz6jwRdToMSlie/YKNe7Vh97x5evTt2hCGxm w1VSuiy1CpB+M4sigYGije1KdrLP486kXGjNi81o3DAWub609Q9qrbrtNsBxmJRItH pQTpfVi702jrPQ/a4Gop4VTRVwTO43YRIpn+BDvSAtiRbRNV2cW9kbDSruhq31hQdE KqxisyWY1P9sA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6A33663326 for ; Wed, 10 Aug 2022 02:29:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZHdr27Ra"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 05A96481; Wed, 10 Aug 2022 02:29:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660091361; bh=3+LLHIx7JHt4B2nWjKpg7cgeXKrzk1gsHhHaKandpAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZHdr27RaK19sH7k3MM/admh5s/HzwN1Ng7w6uv4Vel9IjrWxJ8jVGuBN6XP9brziQ CLfCkw0dA/tjtt9avfUnIB0N53RkfDmPeE0ql3d0ub9qGv8ONzZ/FzrfrrNv6bY7cN cpvej5yIk6I/Wo0fkUX6sR0ArtZVq3+lX7fMtsSc= To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 03:29:04 +0300 Message-Id: <20220810002906.5406-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> References: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] utils: gen-controls: Improve YAML notation for variable-size array controls X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Array controls specify the array size through the YAML 'size' element, which stores a list of values, one per dimension. Variable-size arrays currently use an empty 'size' list, which prevents describing the number of dimensions of the array. Improve this by using the same notation for fixed-size and variable-size array controls. Dimensions that are not fixed are described as a string instead of an integer, such as [n], [n,3] or [w,h]. The strings have currently no special meaning, this may change in the future. Signed-off-by: Laurent Pinchart --- src/libcamera/control_ids.yaml | 2 +- src/libcamera/property_ids.yaml | 4 ++-- utils/gen-controls.py | 31 +++++++++++++++++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml index c93f362463dd..a456e6c0358f 100644 --- a/src/libcamera/control_ids.yaml +++ b/src/libcamera/control_ids.yaml @@ -525,7 +525,7 @@ controls: the window where the focal distance for the objects shown in that part of the image are closest to the camera. - size: [] + size: [n] - AfTrigger: type: int32_t diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index 960e254495b7..cb55e0ed2283 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -497,7 +497,7 @@ controls: - PixelArrayOpticalBlackRectangles: type: Rectangle - size: [] + size: [n] description: | The pixel array region(s) which contain optical black pixels considered valid for calibration purposes. @@ -592,7 +592,7 @@ controls: - PixelArrayActiveAreas: type: Rectangle - size: [] + size: [n] description: | The PixelArrayActiveAreas property defines the (possibly multiple and overlapping) portions of the camera sensor readable pixel matrix diff --git a/utils/gen-controls.py b/utils/gen-controls.py index f6a3ae39cc84..bcfbeb7f9f17 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -39,11 +39,33 @@ class Control(object): self.__name = name self.__data = data self.__enum = None + self.__size = None enum_values = data.get('enum') if enum_values is not None: self.__enum_values = [ControlEnum(enum) for enum in enum_values] + size = self.__data.get('size') + if size is not None: + if len(size) == 0: + raise RuntimeError(f'Control `{self.__name}` size must have at least one dimension') + + # Compute the total number of elemens in the array. If any of the + # array dimension is a string, the array is variable-sized. + num_elems = 1 + for dim in size: + if type(dim) is str: + num_elems = 0 + break + + dim = int(dim) + if dim <= 0: + raise RuntimeError(f'Control `{self.__name}` size must have positive values only') + + num_elems *= dim + + self.__size = num_elems + @property def description(self): """The control description""" @@ -86,15 +108,12 @@ class Control(object): if typ == 'string': return 'std::string' - if size is None: + if self.__size is None: return typ - if len(size) > 0: - # fixed-sized Span - span_size = reduce(operator.mul, size) - return f"Span" + if self.__size: + return f"Span" else: - # variable-sized Span return f"Span" From patchwork Wed Aug 10 00:29:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17064 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7BFA3C3275 for ; Wed, 10 Aug 2022 00:29:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3231063331; Wed, 10 Aug 2022 02:29:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660091365; bh=R2E0Hd9RKLSF/Cq39wA7EfTlovoHLZaj8snJm2/wYeE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=OFjl5PiTUTqmms1as/0ybPm8YVgTV2Ouz7sYgbFFmtVZzpAQTEGAVKKIhErhcGMY7 HiPL9oKf5pH4ESu+xaZ6hDT3wk19i1Iw2dKstsZjUPdPX9mVFykyIvm6r2llmc9PSw aHoRi8vCptC9AbucHZG3izO/95azR2gu3YXCrhoOf5dk8zW+QgMC5hvA0ozRazTYhH t+7tGPJw/a0htaJvh9NNzZko9cPZoUvfklMA5oXXTfBj2o7Tl0U73v1XZzoqRKffwb wpvfxllIXyFKs9JiCblqn3LubjcckJGxMywybP27wJoFT9lFQIMbFqqmiLFGm6Ayrv ESlZAKu7GGzwg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9128C63326 for ; Wed, 10 Aug 2022 02:29:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fEp40fGT"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2AC64481; Wed, 10 Aug 2022 02:29:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660091362; bh=R2E0Hd9RKLSF/Cq39wA7EfTlovoHLZaj8snJm2/wYeE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fEp40fGT57KJBcou0xErEhN4Ps/JA1Gs0OMcGWfwN6nLW1Giw+wh39AKB9dH6ZNVX p3yrozbM4kHmeRMO4n6JlEHjkowqghMMgFteQ7fmZSHCLR+U6PQ8atL9PnoTyQl/oj G2olVeOQ+w41ih7Hbf2pCdWPaB1gz1HiZOipY+Ys= To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 03:29:05 +0300 Message-Id: <20220810002906.5406-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> References: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/4] libcamera: controls: Store array control size in Control class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Baside just identifying a control, the Control class enables usage of the control type for metaprogramming. This is mainly used by the ControlList get() and set() functions to type-check and cast the control value automatically at compilation time. Extend this with a new Size template argument for the Control class that specifies the size of array controls. Use it already in the ControlList::set() overload that takes an std::initializer list to construct the Span with an explicit size, enabling usage of the function for fixed-size array controls. A possible future extension would be to pass the size to the ControlId constructor and store it internally, enabling access to the size at runtime, for instance to perform validity checks. Signed-off-by: Laurent Pinchart --- include/libcamera/controls.h | 20 +++++++++++-------- src/libcamera/controls.cpp | 37 +++++++++++++++++++++++++++--------- utils/gen-controls.py | 24 +++++++++++++++++++++-- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index ebc168fc28b7..dd474a807d68 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -213,6 +214,8 @@ private: class ControlId { public: + static constexpr size_t dynamic_size = std::numeric_limits::max(); + ControlId(unsigned int id, const std::string &name, ControlType type) : id_(id), name_(name), type_(type) { @@ -250,11 +253,12 @@ static inline bool operator!=(const ControlId &lhs, unsigned int rhs) return !(lhs == rhs); } -template +template class Control : public ControlId { public: using type = T; + static constexpr size_t size = Size; Control(unsigned int id, const char *name) : ControlId(id, name, details::control_type>::value) @@ -372,8 +376,8 @@ public: bool contains(unsigned int id) const; - template - std::optional get(const Control &ctrl) const + template + std::optional get(const Control &ctrl) const { const auto entry = controls_.find(ctrl.id()); if (entry == controls_.end()) @@ -383,8 +387,8 @@ public: return val.get(); } - template - void set(const Control &ctrl, const V &value) + template + void set(const Control &ctrl, const V &value) { ControlValue *val = find(ctrl.id()); if (!val) @@ -393,14 +397,14 @@ public: val->set(value); } - template - void set(const Control &ctrl, const std::initializer_list &value) + template + void set(const Control &ctrl, const std::initializer_list &value) { ControlValue *val = find(ctrl.id()); if (!val) return; - val->set(Span>{ value.begin(), value.size() }); + val->set(Span, Size>{ value.begin(), value.size() }); } const ControlValue &get(unsigned int id) const; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index bc3db4f69388..24c836382f10 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -384,6 +384,11 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen * Control class for more information. */ +/** + * \var ControlId::dynamic_size + * \brief Size value for dynamic array controls + */ + /** * \fn ControlId::ControlId(unsigned int id, const std::string &name, ControlType type) * \brief Construct a ControlId instance @@ -431,12 +436,17 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen /** * \class Control * \brief Describe a control and its intrinsic properties + * \tparam T The control data type + * \tparam Size The number of elements (for array controls only) * - * The Control class models a control exposed by an object. Its template type - * name T refers to the control data type, and allows functions that operate on - * control values to be defined as template functions using the same type T for - * the control value. See for instance how the ControlList::get() function - * returns a value corresponding to the type of the requested control. + * The Control class models a control exposed by an object. Its template + * paramter \a T refers to the control data type, and allows functions that + * operate on control values to be defined as template functions using the same + * type T for the control value. See for instance how the ControlList::get() + * function returns a value corresponding to the type of the requested control. + * + * Similarly, for array controls the template parameter \a Size indicates the + * number of elements in the array. * * While this class is the main means to refer to a control, the control * identifying information is stored in the non-template base ControlId class. @@ -469,6 +479,15 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen * \brief The Control template type T */ +/** + * \var Control::size + * \brief The number of elements for array controls + * + * The \a size reports the number of elements stored by an array Control. It is + * equal to 0 for non-array controls, and to ControlId::dynamic_size for + * variable-size controls. + */ + /** * \class ControlInfo * \brief Describe the limits of valid values for a Control @@ -943,7 +962,7 @@ bool ControlList::contains(unsigned int id) const } /** - * \fn ControlList::get(const Control &ctrl) const + * \fn ControlList::get(const Control &ctrl) const * \brief Get the value of control \a ctrl * \param[in] ctrl The control * @@ -956,7 +975,7 @@ bool ControlList::contains(unsigned int id) const */ /** - * \fn ControlList::set(const Control &ctrl, const V &value) + * \fn ControlList::set(const Control &ctrl, const V &value) * \brief Set the control \a ctrl value to \a value * \param[in] ctrl The control * \param[in] value The control value @@ -970,8 +989,8 @@ bool ControlList::contains(unsigned int id) const */ /** - * \fn ControlList::set(const Control &ctrl, const std::initializer_list &value) - * \copydoc ControlList::set(const Control &ctrl, const V &value) + * \fn ControlList::set(const Control &ctrl, const std::initializer_list &value) + * \copydoc ControlList::set(const Control &ctrl, const V &value) */ /** diff --git a/utils/gen-controls.py b/utils/gen-controls.py index bcfbeb7f9f17..a3b9c58beec6 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -100,6 +100,10 @@ class Control(object): ns = 'draft::' if self.is_draft else '' return ns + self.__name + @property + def size(self): + return self.__size + @property def type(self): typ = self.__data.get('type') @@ -137,7 +141,7 @@ ${description}''') * \\var ${name} ${description} */''') - def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");') + def_template = string.Template('extern const Control<${type}${size}> ${name}(${id_name}, "${name}");') enum_values_doc = string.Template('''/** * \\var ${name}Values * \\brief List of all $name supported values @@ -154,9 +158,17 @@ ${description} for ctrl in controls: id_name = snake_case(ctrl.name).upper() + if ctrl.size is None: + size = '' + elif ctrl.size == 0: + size = ', ControlId::dynamic_size' + else: + size = f', {ctrl.size}' + info = { 'name': ctrl.name, 'type': ctrl.type, + 'size': size, 'description': format_description(ctrl.description), 'id_name': id_name, } @@ -216,7 +228,7 @@ def generate_h(controls): enum_template_start = string.Template('''enum ${name}Enum {''') enum_value_template = string.Template('''\t${name} = ${value},''') enum_values_template = string.Template('''extern const std::array ${name}Values;''') - template = string.Template('''extern const Control<${type}> ${name};''') + template = string.Template('''extern const Control<${type}${size}> ${name};''') ctrls = [] draft_ctrls = [] @@ -228,9 +240,17 @@ def generate_h(controls): ids.append('\t' + id_name + ' = ' + str(id_value) + ',') + if ctrl.size is None: + size = '' + elif ctrl.size == 0: + size = ', ControlId::dynamic_size' + else: + size = f', {ctrl.size}' + info = { 'name': ctrl.name, 'type': ctrl.type, + 'size': size, } target_ctrls = ctrls From patchwork Wed Aug 10 00:29:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17065 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 05420C327D for ; Wed, 10 Aug 2022 00:29:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B068E63336; Wed, 10 Aug 2022 02:29:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660091365; bh=vgKidD4dUHJiE6MqADbTQ7+5nNK3eHGDYxq/2y8tFCE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=YlXbE1+ZTVY59rfrMxqS964uOwzkZ6pDaJKdMuuwB2OSyZX04mGRlhlaIY4Tq4Gi9 I9QQF+EVGnxmsEp3aXfnB/DYquN++QZPo2LmV/yKdduc2kWhPtZG1EAZs7UrJKIQvh RxP61Heq/p5QRq656BUNshvr4eRK+/2OxbZWs0RIQzx8l/QDYaQQgwCnLImQL6r3Et bG7bs1dz3YIrD3U8HqSss4mME6vsDwAimspXrPEk3ort+MRPC5rcx3fyt71qzd7OMM RQw0075p47SFBVJJtxXKPoHz+HcVu/cKx7Yv7x1Wj1Dzh6biTc6xhaMxKuBsPjwjCD p1LdHX3ZUW8uQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EB44763334 for ; Wed, 10 Aug 2022 02:29:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="RY3hfScy"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 66FD7481; Wed, 10 Aug 2022 02:29:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660091363; bh=vgKidD4dUHJiE6MqADbTQ7+5nNK3eHGDYxq/2y8tFCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RY3hfScy00EGPq4JFJ2S8S1GuQ8vXsLhXpeU5mKW2S3ygMuYB5JdQAd2EYbDL3Epx ii74LGWXSYcY2olytDN5BOPrG3XB11Tl/fPnG+0968rNbO5UGFnp+PdGcdyIleXSFG e1xaSl0hD5Q02ARp9reCIXq0HfWqr8+CcT8kFywY= To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 03:29:06 +0300 Message-Id: <20220810002906.5406-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> References: <20220810002906.5406-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] ipa: raspberrypi: Remove unneeded Span casts X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Commit 09c1b081baa2 ("libcamera: controls: Generate and use fixed-sized Span types") added explicit Span casts for fixed extent spans that were required due to the ControlList::set() function that takes an std::initializer_list not being able to infer a control size from template arguments. This has now been fixed, so the casts are not needed anymore. Drop them. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Christian Rauch --- src/ipa/raspberrypi/raspberrypi.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 69c73f8c780a..6befdd71433d 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -567,19 +567,18 @@ void IPARPi::reportMetadata() AwbStatus *awbStatus = rpiMetadata_.getLocked("awb.status"); if (awbStatus) { - libcameraMetadata_.set(controls::ColourGains, - Span({ static_cast(awbStatus->gainR), - static_cast(awbStatus->gainB) })); + libcameraMetadata_.set(controls::ColourGains, { static_cast(awbStatus->gainR), + static_cast(awbStatus->gainB) }); libcameraMetadata_.set(controls::ColourTemperature, awbStatus->temperatureK); } BlackLevelStatus *blackLevelStatus = rpiMetadata_.getLocked("black_level.status"); if (blackLevelStatus) libcameraMetadata_.set(controls::SensorBlackLevels, - Span({ static_cast(blackLevelStatus->blackLevelR), - static_cast(blackLevelStatus->blackLevelG), - static_cast(blackLevelStatus->blackLevelG), - static_cast(blackLevelStatus->blackLevelB) })); + { static_cast(blackLevelStatus->blackLevelR), + static_cast(blackLevelStatus->blackLevelG), + static_cast(blackLevelStatus->blackLevelG), + static_cast(blackLevelStatus->blackLevelB) }); FocusStatus *focusStatus = rpiMetadata_.getLocked("focus.status"); if (focusStatus && focusStatus->num == 12) { @@ -884,7 +883,7 @@ void IPARPi::queueRequest(const ControlList &controls) if (gains[0] != 0.0f && gains[1] != 0.0f) /* A gain of 0.0f will switch back to auto mode. */ libcameraMetadata_.set(controls::ColourGains, - Span({ gains[0], gains[1] })); + { gains[0], gains[1] }); break; } @@ -1168,8 +1167,8 @@ void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDur /* Return the validated limits via metadata. */ libcameraMetadata_.set(controls::FrameDurationLimits, - Span({ static_cast(minFrameDuration_.get()), - static_cast(maxFrameDuration_.get()) })); + { static_cast(minFrameDuration_.get()), + static_cast(maxFrameDuration_.get()) }); /* * Calculate the maximum exposure time possible for the AGC to use.