1 /*
2 * Copyright (C) 2023 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 const uint32_t typeNameVectorIndex = (uint32_t)typeNameRef.size();
54 nameToDataOffset_[name] = { static_cast<uint32_t>(prevByteSize), static_cast<uint32_t>(srcData.size()),
55 typeNameVectorIndex };
56 typeNameRef.emplace_back(name);
57 }
58 } // end of lock
59
60 // already created, set data
61 if (contains) {
62 PLUGIN_LOG_I("updating already created pod: %s", name.data());
63 Set(name, srcData);
64 }
65 }
66
DestroyPod(const string_view typeName,const string_view name)67 void RenderDataStorePod::DestroyPod(const string_view typeName, const string_view name)
68 {
69 const auto lock = std::lock_guard(mutex_);
70
71 if (const auto iter = nameToDataOffset_.find(name); iter == nameToDataOffset_.end()) {
72 const auto& ref = iter->second;
73 PLUGIN_ASSERT(ref.index + ref.byteSize <= (uint32_t)dataStore_.size());
74 const uint32_t typeNameVectorIndex = ref.typeNameVectorIndex;
75 dataStore_.erase(dataStore_.begin() + static_cast<int32_t>(ref.index),
76 dataStore_.end() + static_cast<int32_t>(ref.byteSize));
77 nameToDataOffset_.erase(iter);
78 if (auto tpIter = typeNameToPodNames_.find(typeName); tpIter != typeNameToPodNames_.end()) {
79 PLUGIN_ASSERT(typeNameVectorIndex < (uint32_t)tpIter->second.size());
80 tpIter->second.erase(tpIter->second.begin() + static_cast<int32_t>(typeNameVectorIndex));
81 }
82 } else {
83 PLUGIN_LOG_I("pod not found: %s", name.data());
84 }
85 }
86
Set(const string_view name,const array_view<const uint8_t> srcData)87 void RenderDataStorePod::Set(const string_view name, const array_view<const uint8_t> srcData)
88 {
89 const auto lock = std::lock_guard(mutex_);
90
91 const auto iter = nameToDataOffset_.find(name);
92 if (iter != nameToDataOffset_.cend()) {
93 const uint32_t index = iter->second.index;
94 const uint32_t byteSize = iter->second.byteSize;
95 PLUGIN_ASSERT(index + byteSize <= (uint32_t)dataStore_.size());
96 PLUGIN_ASSERT(srcData.size() <= byteSize);
97
98 const uint32_t maxByteSize = std::min(byteSize, static_cast<uint32_t>(srcData.size()));
99
100 uint8_t* dst = &dataStore_[index];
101 if (!CloneData(dst, dataStore_.size() - index, srcData.data(), maxByteSize)) {
102 PLUGIN_LOG_E("Copying of RenderDataStorePod Data failed.");
103 }
104 } else {
105 PLUGIN_LOG_E("render data store pod: %s not created", name.data());
106 }
107 }
108
Get(const string_view name) const109 array_view<const uint8_t> RenderDataStorePod::Get(const string_view name) const
110 {
111 const auto lock = std::lock_guard(mutex_);
112
113 array_view<const uint8_t> view;
114 const auto iter = nameToDataOffset_.find(name);
115 if (iter != nameToDataOffset_.cend()) {
116 const uint32_t index = iter->second.index;
117 const uint32_t byteSize = iter->second.byteSize;
118 PLUGIN_ASSERT(index + byteSize <= (uint32_t)dataStore_.size());
119
120 const uint8_t* data = &dataStore_[index];
121 view = array_view<const uint8_t>(data, byteSize);
122 }
123 return view;
124 }
125
GetPodNames(const string_view tpName) const126 array_view<const string> RenderDataStorePod::GetPodNames(const string_view tpName) const
127 {
128 const auto lock = std::lock_guard(mutex_);
129
130 const auto iter = typeNameToPodNames_.find(tpName);
131 if (iter != typeNameToPodNames_.cend()) {
132 return array_view<const string>(iter->second.data(), iter->second.size());
133 } else {
134 PLUGIN_LOG_I("render data store pod type (%s), not found", tpName.data());
135 return {};
136 }
137 }
138
139 // for plugin / factory interface
Create(IRenderContext &,char const * name)140 IRenderDataStore* RenderDataStorePod::Create(IRenderContext&, char const* name)
141 {
142 // engine not used
143 return new RenderDataStorePod(name);
144 }
145
Destroy(IRenderDataStore * aInstance)146 void RenderDataStorePod::Destroy(IRenderDataStore* aInstance)
147 {
148 delete static_cast<RenderDataStorePod*>(aInstance);
149 }
150 RENDER_END_NAMESPACE()
151