• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
17 #define OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
18 
19 #include <functional>
20 #include <memory>
21 #include <unordered_map>
22 #include "hdf_log.h"
23 #include "nocopyable.h"
24 #include <mutex>
25 #include "hdf_base.h"
26 #include "hilog/log.h"
27 #include "base/native_buffer.h"
28 
29 #undef LOG_TAG
30 #define LOG_TAG "DISP_CACHE_MGR"
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD002515
33 
34 namespace OHOS {
35 namespace HDI {
36 namespace Display {
37 namespace Composer {
38 
39 template <typename IdType, typename CacheType>
40 class CacheManager : public NoCopyable {
41 public:
CacheManager()42     CacheManager()
43         : cacheCountMax_ { 0 },
44           cleanUpFunc_ { nullptr },
45           initFunc_ { nullptr }
46     {}
47 
~CacheManager()48     virtual ~CacheManager()
49     {
50         std::lock_guard<std::mutex> lock(mutex_);
51         if (cleanUpFunc_) {
52             for (auto& cache : caches_) {
53                 cleanUpFunc_(cache.second);
54             }
55         }
56         caches_.clear();
57     }
58 
SetCacheMaxCount(uint32_t count)59     bool SetCacheMaxCount(uint32_t count)
60     {
61         bool ret = true;
62         uint32_t originalMaxCount = cacheCountMax_;
63         if (count >= cacheCountMax_) {
64             cacheCountMax_ = count;
65         } else if (Size() <= count) {
66             cacheCountMax_ = count;
67         } else {
68             HDF_LOGE("%{public}s error: clientCacheCount can't be set, because cacheCountMax_ > count", __func__);
69             ret = false;
70         }
71         HDF_LOGD("%{public}s: set cache max count from %{public}u to %{public}u",
72             __func__, originalMaxCount, cacheCountMax_);
73         return ret;
74     }
75 
Size()76     uint32_t Size()
77     {
78         std::lock_guard<std::mutex> lock(mutex_);
79         return caches_.size();
80     }
81 
InsertCache(IdType id,CacheType * cache)82     bool InsertCache(IdType id, CacheType* cache)
83     {
84         std::lock_guard<std::mutex> lock(mutex_);
85         auto cacheItem = caches_.find(id);
86         if (cacheItem != caches_.end()) {
87             HDF_LOGI("%{public}s: intend to insert a existing cache, SeqNo=%{public}d", __func__, id);
88             if (cleanUpFunc_ && cacheItem->second != nullptr) {
89                 cleanUpFunc_(cacheItem->second);
90             }
91             cacheItem->second.reset(cache);
92         } else {
93             if (cacheCountMax_ != 0 && caches_.size() >= cacheCountMax_) {
94                 HDF_LOGE("%{public}s: Caches is full, new seqNo:%{public}d can't be inserted", __func__, id);
95                 return false;
96             }
97             caches_[id] = std::move(std::unique_ptr<CacheType>(cache));
98         }
99         if (initFunc_) {
100             initFunc_(caches_[id]);
101         }
102         return true;
103     }
104 
EraseCache(IdType id)105     bool EraseCache(IdType id)
106     {
107         std::lock_guard<std::mutex> lock(mutex_);
108         auto cacheItem = caches_.find(id);
109         if (cacheItem == caches_.end()) {
110             return false;
111         }
112 
113         if (cleanUpFunc_ && cacheItem->second != nullptr) {
114             cleanUpFunc_(cacheItem->second);
115         }
116 
117         caches_.erase(cacheItem);
118         return true;
119     }
120 
SearchCache(IdType id)121     CacheType* SearchCache(IdType id)
122     {
123         std::lock_guard<std::mutex> lock(mutex_);
124         auto cacheItem = caches_.find(id);
125         if (cacheItem == caches_.end()) {
126             return nullptr;
127         }
128 
129         return cacheItem->second.get();
130     }
131 
TravelCaches(std::function<void (IdType id,const CacheType & cache)> func)132     void TravelCaches(std::function<void (IdType id, const CacheType& cache)> func)
133     {
134         std::lock_guard<std::mutex> lock(mutex_);
135         for (auto const& [key, value] : caches_) {
136             func(key, *value.get());
137         }
138     }
139 
SetCleanUpFunc(void (* func)(std::unique_ptr<CacheType> &))140     void SetCleanUpFunc(void (*func)(std::unique_ptr<CacheType>&))
141     {
142         cleanUpFunc_ = func;
143     }
144 
SetInitFunc(void (* func)(std::unique_ptr<CacheType> &))145     void SetInitFunc(void (*func)(std::unique_ptr<CacheType>&))
146     {
147         initFunc_ = func;
148     }
149 
150 private:
151     uint32_t cacheCountMax_;
152     std::unordered_map<IdType, std::unique_ptr<CacheType>> caches_;
153     void (*cleanUpFunc_)(std::unique_ptr<CacheType>&);
154     void (*initFunc_)(std::unique_ptr<CacheType>&);
155     std::mutex mutex_;
156 };
157 
158 template <typename IdType>
159 class CacheManager<IdType, Base::NativeBuffer> : public NoCopyable {
160 public:
CacheManager()161     CacheManager()
162         : cacheCountMax_ { 0 },
163           cleanUpFunc_ { nullptr },
164           initFunc_ { nullptr }
165     {}
166 
~CacheManager()167     virtual ~CacheManager()
168     {
169         std::lock_guard<std::mutex> lock(mutex_);
170         if (cleanUpFunc_) {
171             for (auto& cache : caches_) {
172                 cleanUpFunc_(cache.second);
173             }
174         }
175         caches_.clear();
176     }
177 
SetCacheMaxCount(uint32_t count)178     bool SetCacheMaxCount(uint32_t count)
179     {
180         bool ret = true;
181         uint32_t originalMaxCount = cacheCountMax_;
182         if (count >= cacheCountMax_) {
183             cacheCountMax_ = count;
184         } else if (Size() <= count) {
185             cacheCountMax_ = count;
186         } else {
187             HDF_LOGE("%{public}s error: clientCacheCount can't be set, because cacheCountMax_ > count", __func__);
188             ret = false;
189         }
190         HDF_LOGI("%{public}s: set cache max count from %{public}u to %{public}u",
191             __func__, originalMaxCount, cacheCountMax_);
192         return ret;
193     }
194 
Size()195     uint32_t Size()
196     {
197         std::lock_guard<std::mutex> lock(mutex_);
198         return caches_.size();
199     }
200 
InsertCache(IdType id,Base::NativeBuffer * cache)201     bool InsertCache(IdType id, Base::NativeBuffer* cache)
202     {
203         std::lock_guard<std::mutex> lock(mutex_);
204         auto cacheItem = caches_.find(id);
205         if (cacheItem != caches_.end()) {
206             HDF_LOGI("%{public}s: intend to insert a existing cache, SeqNo=%{public}d", __func__, id);
207             if (cleanUpFunc_ && cacheItem->second != nullptr) {
208                 cleanUpFunc_(cacheItem->second);
209             }
210             cacheItem->second = OHOS::sptr<Base::NativeBuffer>(cache);
211         } else {
212             if (cacheCountMax_ != 0 && caches_.size() >= cacheCountMax_) {
213                 HDF_LOGE("%{public}s: Caches is full, new seqNo:%{public}d can't be inserted", __func__, id);
214                 return false;
215             }
216             caches_[id] = OHOS::sptr<Base::NativeBuffer>(cache);
217         }
218         if (initFunc_) {
219             initFunc_(caches_[id]);
220         }
221         return true;
222     }
223 
EraseCache(IdType id)224     bool EraseCache(IdType id)
225     {
226         std::lock_guard<std::mutex> lock(mutex_);
227         auto cacheItem = caches_.find(id);
228         if (cacheItem == caches_.end()) {
229             HDF_LOGE("%{public}s: Cache %{public}d is not existing", __func__, id);
230             return false;
231         }
232 
233         if (cleanUpFunc_ && cacheItem->second != nullptr) {
234             cleanUpFunc_(cacheItem->second);
235         }
236 
237         caches_.erase(cacheItem);
238         return true;
239     }
240 
SearchCache(IdType id)241     Base::NativeBuffer* SearchCache(IdType id)
242     {
243         std::lock_guard<std::mutex> lock(mutex_);
244         auto cacheItem = caches_.find(id);
245         if (cacheItem == caches_.end()) {
246             return nullptr;
247         }
248 
249         return cacheItem->second.GetRefPtr();
250     }
251 
TravelCaches(std::function<void (IdType id,const Base::NativeBuffer & cache)> func)252     void TravelCaches(std::function<void (IdType id, const Base::NativeBuffer& cache)> func)
253     {
254         std::lock_guard<std::mutex> lock(mutex_);
255         for (auto const& [key, value] : caches_) {
256             func(key, *value.GetRefPtr());
257         }
258     }
259 
SetCleanUpFunc(void (* func)(OHOS::sptr<Base::NativeBuffer> &))260     void SetCleanUpFunc(void (*func)(OHOS::sptr<Base::NativeBuffer>&))
261     {
262         cleanUpFunc_ = func;
263     }
264 
SetInitFunc(void (* func)(OHOS::sptr<Base::NativeBuffer> &))265     void SetInitFunc(void (*func)(OHOS::sptr<Base::NativeBuffer>&))
266     {
267         initFunc_ = func;
268     }
269 
270 private:
271     uint32_t cacheCountMax_;
272     std::unordered_map<IdType, OHOS::sptr<Base::NativeBuffer>> caches_;
273     void (*cleanUpFunc_)(OHOS::sptr<Base::NativeBuffer>&);
274     void (*initFunc_)(OHOS::sptr<Base::NativeBuffer>&);
275     std::mutex mutex_;
276 };
277 } // namespace Composer
278 } // namespace Display
279 } // namespace HDI
280 } // namespace OHOS
281 #endif // OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
282