• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
Ref()31 void RenderDataStorePod::Ref()
32 {
33     refcnt_.fetch_add(1, std::memory_order_relaxed);
34 }
35 
Unref()36 void RenderDataStorePod::Unref()
37 {
38     if (std::atomic_fetch_sub_explicit(&refcnt_, 1, std::memory_order_release) == 1) {
39         std::atomic_thread_fence(std::memory_order_acquire);
40         delete this;
41     }
42 }
43 
GetRefCount()44 int32_t RenderDataStorePod::GetRefCount()
45 {
46     return refcnt_;
47 }
48 
CreatePod(const string_view tpName,const string_view name,const array_view<const uint8_t> srcData)49 void RenderDataStorePod::CreatePod(
50     const string_view tpName, const string_view name, const array_view<const uint8_t> srcData)
51 {
52     if (srcData.empty()) {
53         PLUGIN_LOG_W("Zero size pod is not created (name: %s)", tpName.data());
54         return;
55     }
56     bool contains = false;
57     {
58         const auto lock = std::lock_guard(mutex_);
59 
60         contains = nameToDataOffset_.contains(name);
61         if (!contains) {
62             const size_t prevByteSize = dataStore_.size();
63             const size_t newByteSize = prevByteSize + srcData.size();
64             dataStore_.resize(newByteSize);
65             uint8_t* dst = &dataStore_[prevByteSize];
66             if (!CloneData(dst, dataStore_.size() - prevByteSize, srcData.data(), srcData.size())) {
67                 PLUGIN_LOG_E("Copying of RenderDataStorePod Data failed.");
68             }
69 
70             auto& typeNameRef = typeNameToPodNames_[tpName];
71             nameToDataOffset_[name] = { static_cast<uint32_t>(prevByteSize), static_cast<uint32_t>(srcData.size()) };
72             typeNameRef.emplace_back(name);
73         }
74     } // end of lock
75 
76     // already created, set data
77     if (contains) {
78         PLUGIN_LOG_I("updating already created pod: %s", name.data());
79         Set(name, srcData);
80     }
81 }
82 
DestroyPod(const string_view typeName,const string_view name)83 void RenderDataStorePod::DestroyPod(const string_view typeName, const string_view name)
84 {
85     const auto lock = std::lock_guard(mutex_);
86 
87     if (const auto iter = nameToDataOffset_.find(name); iter != nameToDataOffset_.end()) {
88         const auto offsetToData = iter->second;
89         PLUGIN_ASSERT(offsetToData.index + offsetToData.byteSize <= (uint32_t)dataStore_.size());
90         const auto first = dataStore_.cbegin() + static_cast<int32_t>(offsetToData.index);
91         const auto last = first + static_cast<int32_t>(offsetToData.byteSize);
92         dataStore_.erase(first, last);
93         nameToDataOffset_.erase(iter);
94         // move the index of pods after the destroyed pod by the size of the pod
95         for (auto& nameToOffset : nameToDataOffset_) {
96             if (nameToOffset.second.index > offsetToData.index) {
97                 nameToOffset.second.index -= offsetToData.byteSize;
98             }
99         }
100         if (auto tpIter = typeNameToPodNames_.find(typeName); tpIter != typeNameToPodNames_.end()) {
101             for (auto nameIter = tpIter->second.cbegin(); nameIter != tpIter->second.cend(); ++nameIter) {
102                 if (*nameIter == name) {
103                     tpIter->second.erase(nameIter);
104                     break;
105                 }
106             }
107         }
108     } else {
109         PLUGIN_LOG_I("pod not found: %s", name.data());
110     }
111 }
112 
Set(const string_view name,const array_view<const uint8_t> srcData)113 void RenderDataStorePod::Set(const string_view name, const array_view<const uint8_t> srcData)
114 {
115     const auto lock = std::lock_guard(mutex_);
116 
117     const auto iter = nameToDataOffset_.find(name);
118     if (iter != nameToDataOffset_.cend()) {
119         const uint32_t index = iter->second.index;
120         const uint32_t byteSize = iter->second.byteSize;
121         PLUGIN_ASSERT(index + byteSize <= (uint32_t)dataStore_.size());
122         PLUGIN_ASSERT(srcData.size() <= byteSize);
123 
124         const uint32_t maxByteSize = std::min(byteSize, static_cast<uint32_t>(srcData.size()));
125 
126         uint8_t* dst = &dataStore_[index];
127         if (!CloneData(dst, dataStore_.size() - index, srcData.data(), maxByteSize)) {
128             PLUGIN_LOG_E("Copying of RenderDataStorePod Data failed.");
129         }
130     } else {
131         PLUGIN_LOG_E("render data store pod: %s not created", name.data());
132     }
133 }
134 
Get(const string_view name) const135 array_view<const uint8_t> RenderDataStorePod::Get(const string_view name) const
136 {
137     const auto lock = std::lock_guard(mutex_);
138 
139     array_view<const uint8_t> view;
140     const auto iter = nameToDataOffset_.find(name);
141     if (iter != nameToDataOffset_.cend()) {
142         const uint32_t index = iter->second.index;
143         const uint32_t byteSize = iter->second.byteSize;
144         PLUGIN_ASSERT(index + byteSize <= (uint32_t)dataStore_.size());
145 
146         const uint8_t* data = &dataStore_[index];
147         view = array_view<const uint8_t>(data, byteSize);
148     }
149     return view;
150 }
151 
GetPodNames(const string_view tpName) const152 array_view<const string> RenderDataStorePod::GetPodNames(const string_view tpName) const
153 {
154     const auto lock = std::lock_guard(mutex_);
155 
156     const auto iter = typeNameToPodNames_.find(tpName);
157     if (iter != typeNameToPodNames_.cend()) {
158         return { iter->second.data(), iter->second.size() };
159     } else {
160         PLUGIN_LOG_I("render data store pod type (%s), not found", tpName.data());
161         return {};
162     }
163 }
164 
165 // for plugin / factory interface
Create(IRenderContext &,const char * name)166 refcnt_ptr<IRenderDataStore> RenderDataStorePod::Create(IRenderContext&, const char* name)
167 {
168     return refcnt_ptr<IRenderDataStore>(new RenderDataStorePod(name));
169 }
170 RENDER_END_NAMESPACE()
171