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