1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "render_data_store_pod.h"
17
18 #include <algorithm>
19 #include <cstdint>
20
21 #include <base/containers/array_view.h>
22 #include <render/namespace.h>
23
24 #include "util/log.h"
25
26 using namespace BASE_NS;
27
RENDER_BEGIN_NAMESPACE()28 RENDER_BEGIN_NAMESPACE()
29 RenderDataStorePod::RenderDataStorePod(const string_view name) : name_(name) {}
30
CreatePod(const string_view tpName,const string_view name,const array_view<const uint8_t> srcData)31 void RenderDataStorePod::CreatePod(
32 const string_view tpName, const string_view name, const array_view<const uint8_t> srcData)
33 {
34 if (srcData.empty()) {
35 PLUGIN_LOG_W("Zero size pod is not created (name: %s)", tpName.data());
36 return;
37 }
38 bool contains = false;
39 {
40 const auto lock = std::lock_guard(mutex_);
41
42 contains = nameToDataOffset_.contains(name);
43 if (!contains) {
44 const size_t prevByteSize = dataStore_.size();
45 const size_t newByteSize = prevByteSize + srcData.size();
46 dataStore_.resize(newByteSize);
47 uint8_t* dst = &dataStore_[prevByteSize];
48 if (!CloneData(dst, dataStore_.size() - prevByteSize, srcData.data(), srcData.size())) {
49 PLUGIN_LOG_E("Copying of RenderDataStorePod Data failed.");
50 }
51
52 auto& typeNameRef = typeNameToPodNames_[tpName];
53 nameToDataOffset_[name] = { static_cast<uint32_t>(prevByteSize), static_cast<uint32_t>(srcData.size()) };
54 typeNameRef.emplace_back(name);
55 }
56 } // end of lock
57
58 // already created, set data
59 if (contains) {
60 PLUGIN_LOG_I("updating already created pod: %s", name.data());
61 Set(name, srcData);
62 }
63 }
64
DestroyPod(const string_view typeName,const string_view name)65 void RenderDataStorePod::DestroyPod(const string_view typeName, const string_view name)
66 {
67 const auto lock = std::lock_guard(mutex_);
68
69 if (const auto iter = nameToDataOffset_.find(name); iter != nameToDataOffset_.end()) {
70 const auto offsetToData = iter->second;
71 PLUGIN_ASSERT(offsetToData.index + offsetToData.byteSize <= static_cast<uint32_t>(dataStore_.size()));
72 const auto first = dataStore_.cbegin() + static_cast<int32_t>(offsetToData.index);
73 const auto last = first + static_cast<int32_t>(offsetToData.byteSize);
74 dataStore_.erase(first, last);
75 nameToDataOffset_.erase(iter);
76 // move the index of pods after the destroyed pod by the size of the pod
77 for (auto& nameToOffset : nameToDataOffset_) {
78 if (nameToOffset.second.index > offsetToData.index) {
79 nameToOffset.second.index -= offsetToData.byteSize;
80 }
81 }
82 if (auto tpIter = typeNameToPodNames_.find(typeName); tpIter != typeNameToPodNames_.end()) {
83 for (auto nameIter = tpIter->second.cbegin(); nameIter != tpIter->second.cend(); ++nameIter) {
84 if (*nameIter == name) {
85 tpIter->second.erase(nameIter);
86 break;
87 }
88 }
89 }
90 } else {
91 PLUGIN_LOG_I("pod not found: %s", name.data());
92 }
93 }
94
Set(const string_view name,const array_view<const uint8_t> srcData)95 void RenderDataStorePod::Set(const string_view name, const array_view<const uint8_t> srcData)
96 {
97 const auto lock = std::lock_guard(mutex_);
98
99 const auto iter = nameToDataOffset_.find(name);
100 if (iter != nameToDataOffset_.cend()) {
101 const uint32_t index = iter->second.index;
102 const uint32_t byteSize = iter->second.byteSize;
103 PLUGIN_ASSERT(index + byteSize <= static_cast<uint32_t>(dataStore_.size()));
104 PLUGIN_ASSERT(srcData.size() <= byteSize);
105
106 const uint32_t maxByteSize = std::min(byteSize, static_cast<uint32_t>(srcData.size()));
107
108 uint8_t* dst = &dataStore_[index];
109 if (!CloneData(dst, dataStore_.size() - index, srcData.data(), maxByteSize)) {
110 PLUGIN_LOG_E("Copying of RenderDataStorePod Data failed.");
111 }
112 } else {
113 PLUGIN_LOG_E("render data store pod: %s not created", name.data());
114 }
115 }
116
Get(const string_view name) const117 array_view<const uint8_t> RenderDataStorePod::Get(const string_view name) const
118 {
119 const auto lock = std::lock_guard(mutex_);
120
121 array_view<const uint8_t> view;
122 const auto iter = nameToDataOffset_.find(name);
123 if (iter != nameToDataOffset_.cend()) {
124 const uint32_t index = iter->second.index;
125 const uint32_t byteSize = iter->second.byteSize;
126 PLUGIN_ASSERT(index + byteSize <= static_cast<uint32_t>(dataStore_.size()));
127
128 const uint8_t* data = &dataStore_[index];
129 view = array_view<const uint8_t>(data, byteSize);
130 }
131 return view;
132 }
133
GetPodNames(const string_view tpName) const134 array_view<const string> RenderDataStorePod::GetPodNames(const string_view tpName) const
135 {
136 const auto lock = std::lock_guard(mutex_);
137
138 const auto iter = typeNameToPodNames_.find(tpName);
139 if (iter != typeNameToPodNames_.cend()) {
140 return array_view<const string>(iter->second.data(), iter->second.size());
141 } else {
142 PLUGIN_LOG_I("render data store pod type (%s), not found", tpName.data());
143 return {};
144 }
145 }
146
147 // for plugin / factory interface
Create(IRenderContext &,char const * name)148 IRenderDataStore* RenderDataStorePod::Create(IRenderContext&, char const* name)
149 {
150 // engine not used
151 return new RenderDataStorePod(name);
152 }
153
Destroy(IRenderDataStore * aInstance)154 void RenderDataStorePod::Destroy(IRenderDataStore* aInstance)
155 {
156 delete static_cast<RenderDataStorePod*>(aInstance);
157 }
158 RENDER_END_NAMESPACE()
159