From patchwork Sat Feb 29 16:42:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2943 Return-Path: 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 6E4376278C for ; Sat, 29 Feb 2020 17:43:31 +0100 (CET) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1205D33E for ; Sat, 29 Feb 2020 17:43:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582994611; bh=FbhM2pKsf9zAPJD/WdkQfCaXmIBrLIK1B+8/o/+OiWo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DWHl/Y+AyZWzwQULaMbSlIwXkoCVEhrgRRebolpCDKWsD9SG9JDhidxV6wNaUEWX8 pvkvohK+jMElq0mWymyfKfmAAI9TMpNfGYnO4uSEdr3j1zeP6+4jOK/nqJi/4EfwD1 bupk/qBKA5gMoQpDHpe+Waw8BwZZyPpq5q6F0wPU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sat, 29 Feb 2020 18:42:49 +0200 Message-Id: <20200229164254.23604-27-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> References: <20200229164254.23604-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 26/31] libcamera: control_serializer: Use zero-copy ByteStreamBuffer::read() 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-List-Received-Date: Sat, 29 Feb 2020 16:43:36 -0000 Use the zero-copy variant of ByteStreamBuffer::read() to read packet haders and control entries. This enhance performance of ControlList and ControlInfoMap deserialization. Deserialization of the actual ControlValue is untouched for now and will be optimized later. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/control_serializer.cpp | 74 +++++++++++++++++----------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index dc87b96f384b..6cac70739468 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -364,39 +364,46 @@ ControlRange ControlSerializer::load(ControlType type, template<> ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer &buffer) { - struct ipa_controls_header hdr; - buffer.read(&hdr); + const struct ipa_controls_header *hdr = buffer.read(); + if (!hdr) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (hdr.version != IPA_CONTROLS_FORMAT_VERSION) { + if (hdr->version != IPA_CONTROLS_FORMAT_VERSION) { LOG(Serializer, Error) << "Unsupported controls format version " - << hdr.version; + << hdr->version; return {}; } - ByteStreamBuffer entries = buffer.carveOut(hdr.data_offset - sizeof(hdr)); - ByteStreamBuffer values = buffer.carveOut(hdr.size - hdr.data_offset); + ByteStreamBuffer entries = buffer.carveOut(hdr->data_offset - sizeof(*hdr)); + ByteStreamBuffer values = buffer.carveOut(hdr->size - hdr->data_offset); if (buffer.overflow()) { - LOG(Serializer, Error) << "Serialized packet too small"; + LOG(Serializer, Error) << "Out of data"; return {}; } ControlInfoMap::Map ctrls; - for (unsigned int i = 0; i < hdr.entries; ++i) { - struct ipa_control_range_entry entry; - entries.read(&entry); + for (unsigned int i = 0; i < hdr->entries; ++i) { + const struct ipa_control_range_entry *entry = + entries.read(); + if (!entry) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } /* Create and cache the individual ControlId. */ - ControlType type = static_cast(entry.type); + ControlType type = static_cast(entry->type); /** * \todo Find a way to preserve the control name for debugging * purpose. */ - controlIds_.emplace_back(std::make_unique(entry.id, "", type)); + controlIds_.emplace_back(std::make_unique(entry->id, "", type)); - if (entry.offset != values.offset()) { + if (entry->offset != values.offset()) { LOG(Serializer, Error) << "Bad data, entry offset mismatch (entry " << i << ")"; @@ -412,8 +419,8 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & * Create the ControlInfoMap in the cache, and store the map to handle * association. */ - ControlInfoMap &map = infoMaps_[hdr.handle] = std::move(ctrls); - infoMapHandles_[&map] = hdr.handle; + ControlInfoMap &map = infoMaps_[hdr->handle] = std::move(ctrls); + infoMapHandles_[&map] = hdr->handle; return map; } @@ -430,21 +437,24 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & template<> ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer) { - struct ipa_controls_header hdr; - buffer.read(&hdr); + const struct ipa_controls_header *hdr = buffer.read(); + if (!hdr) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (hdr.version != IPA_CONTROLS_FORMAT_VERSION) { + if (hdr->version != IPA_CONTROLS_FORMAT_VERSION) { LOG(Serializer, Error) << "Unsupported controls format version " - << hdr.version; + << hdr->version; return {}; } - ByteStreamBuffer entries = buffer.carveOut(hdr.data_offset - sizeof(hdr)); - ByteStreamBuffer values = buffer.carveOut(hdr.size - hdr.data_offset); + ByteStreamBuffer entries = buffer.carveOut(hdr->data_offset - sizeof(*hdr)); + ByteStreamBuffer values = buffer.carveOut(hdr->size - hdr->data_offset); if (buffer.overflow()) { - LOG(Serializer, Error) << "Serialized packet too small"; + LOG(Serializer, Error) << "Out of data"; return {}; } @@ -456,10 +466,10 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer * use the global control::control idmap. */ const ControlInfoMap *infoMap; - if (hdr.handle) { + if (hdr->handle) { auto iter = std::find_if(infoMapHandles_.begin(), infoMapHandles_.end(), [&](decltype(infoMapHandles_)::value_type &entry) { - return entry.second == hdr.handle; + return entry.second == hdr->handle; }); if (iter == infoMapHandles_.end()) { LOG(Serializer, Error) @@ -474,19 +484,23 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer ControlList ctrls(infoMap ? infoMap->idmap() : controls::controls); - for (unsigned int i = 0; i < hdr.entries; ++i) { - struct ipa_control_value_entry entry; - entries.read(&entry); + for (unsigned int i = 0; i < hdr->entries; ++i) { + const struct ipa_control_value_entry *entry = + entries.read(); + if (!entry) { + LOG(Serializer, Error) << "Out of data"; + return {}; + } - if (entry.offset != values.offset()) { + if (entry->offset != values.offset()) { LOG(Serializer, Error) << "Bad data, entry offset mismatch (entry " << i << ")"; return {}; } - ControlType type = static_cast(entry.type); - ctrls.set(entry.id, load(type, values)); + ControlType type = static_cast(entry->type); + ctrls.set(entry->id, load(type, values)); } return ctrls;