1c5e268c6Sopenharmony_ci/* 2c5e268c6Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3c5e268c6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c5e268c6Sopenharmony_ci * you may not use this file except in compliance with the License. 5c5e268c6Sopenharmony_ci * You may obtain a copy of the License at 6c5e268c6Sopenharmony_ci * 7c5e268c6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c5e268c6Sopenharmony_ci * 9c5e268c6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c5e268c6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c5e268c6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c5e268c6Sopenharmony_ci * See the License for the specific language governing permissions and 13c5e268c6Sopenharmony_ci * limitations under the License. 14c5e268c6Sopenharmony_ci */ 15c5e268c6Sopenharmony_ci 16c5e268c6Sopenharmony_ci#ifndef OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H 17c5e268c6Sopenharmony_ci#define OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H 18c5e268c6Sopenharmony_ci 19c5e268c6Sopenharmony_ci#include <functional> 20c5e268c6Sopenharmony_ci#include <memory> 21c5e268c6Sopenharmony_ci#include <unordered_map> 22c5e268c6Sopenharmony_ci#include "hdf_log.h" 23c5e268c6Sopenharmony_ci#include "nocopyable.h" 24c5e268c6Sopenharmony_ci#include <mutex> 25c5e268c6Sopenharmony_ci#include "hdf_base.h" 26c5e268c6Sopenharmony_ci#include "hilog/log.h" 27c5e268c6Sopenharmony_ci#include "base/native_buffer.h" 28c5e268c6Sopenharmony_ci 29c5e268c6Sopenharmony_ci#undef LOG_TAG 30c5e268c6Sopenharmony_ci#define LOG_TAG "DISP_CACHE_MGR" 31c5e268c6Sopenharmony_ci#undef LOG_DOMAIN 32c5e268c6Sopenharmony_ci#define LOG_DOMAIN 0xD002515 33c5e268c6Sopenharmony_ci 34c5e268c6Sopenharmony_cinamespace OHOS { 35c5e268c6Sopenharmony_cinamespace HDI { 36c5e268c6Sopenharmony_cinamespace Display { 37c5e268c6Sopenharmony_cinamespace Composer { 38c5e268c6Sopenharmony_ci 39c5e268c6Sopenharmony_citemplate <typename IdType, typename CacheType> 40c5e268c6Sopenharmony_ciclass CacheManager : public NoCopyable { 41c5e268c6Sopenharmony_cipublic: 42c5e268c6Sopenharmony_ci CacheManager() 43c5e268c6Sopenharmony_ci : cacheCountMax_ { 0 }, 44c5e268c6Sopenharmony_ci cleanUpFunc_ { nullptr }, 45c5e268c6Sopenharmony_ci initFunc_ { nullptr } 46c5e268c6Sopenharmony_ci {} 47c5e268c6Sopenharmony_ci 48c5e268c6Sopenharmony_ci virtual ~CacheManager() 49c5e268c6Sopenharmony_ci { 50c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 51c5e268c6Sopenharmony_ci if (cleanUpFunc_) { 52c5e268c6Sopenharmony_ci for (auto& cache : caches_) { 53c5e268c6Sopenharmony_ci cleanUpFunc_(cache.second); 54c5e268c6Sopenharmony_ci } 55c5e268c6Sopenharmony_ci } 56c5e268c6Sopenharmony_ci caches_.clear(); 57c5e268c6Sopenharmony_ci } 58c5e268c6Sopenharmony_ci 59c5e268c6Sopenharmony_ci bool SetCacheMaxCount(uint32_t count) 60c5e268c6Sopenharmony_ci { 61c5e268c6Sopenharmony_ci bool ret = true; 62c5e268c6Sopenharmony_ci uint32_t originalMaxCount = cacheCountMax_; 63c5e268c6Sopenharmony_ci if (count >= cacheCountMax_) { 64c5e268c6Sopenharmony_ci cacheCountMax_ = count; 65c5e268c6Sopenharmony_ci } else if (Size() <= count) { 66c5e268c6Sopenharmony_ci cacheCountMax_ = count; 67c5e268c6Sopenharmony_ci } else { 68c5e268c6Sopenharmony_ci HDF_LOGE("%{public}s error: clientCacheCount can't be set, because cacheCountMax_ > count", __func__); 69c5e268c6Sopenharmony_ci ret = false; 70c5e268c6Sopenharmony_ci } 71c5e268c6Sopenharmony_ci HDF_LOGD("%{public}s: set cache max count from %{public}u to %{public}u", 72c5e268c6Sopenharmony_ci __func__, originalMaxCount, cacheCountMax_); 73c5e268c6Sopenharmony_ci return ret; 74c5e268c6Sopenharmony_ci } 75c5e268c6Sopenharmony_ci 76c5e268c6Sopenharmony_ci uint32_t Size() 77c5e268c6Sopenharmony_ci { 78c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 79c5e268c6Sopenharmony_ci return caches_.size(); 80c5e268c6Sopenharmony_ci } 81c5e268c6Sopenharmony_ci 82c5e268c6Sopenharmony_ci bool InsertCache(IdType id, CacheType* cache) 83c5e268c6Sopenharmony_ci { 84c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 85c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 86c5e268c6Sopenharmony_ci if (cacheItem != caches_.end()) { 87c5e268c6Sopenharmony_ci HDF_LOGI("%{public}s: intend to insert a existing cache, SeqNo=%{public}d", __func__, id); 88c5e268c6Sopenharmony_ci cacheItem->second.reset(cache); 89c5e268c6Sopenharmony_ci } else { 90c5e268c6Sopenharmony_ci if (cacheCountMax_ != 0 && caches_.size() >= cacheCountMax_) { 91c5e268c6Sopenharmony_ci HDF_LOGE("%{public}s: Caches is full, new seqNo:%{public}d can't be inserted", __func__, id); 92c5e268c6Sopenharmony_ci return false; 93c5e268c6Sopenharmony_ci } 94c5e268c6Sopenharmony_ci caches_[id] = std::move(std::unique_ptr<CacheType>(cache)); 95c5e268c6Sopenharmony_ci } 96c5e268c6Sopenharmony_ci if (initFunc_) { 97c5e268c6Sopenharmony_ci initFunc_(caches_[id]); 98c5e268c6Sopenharmony_ci } 99c5e268c6Sopenharmony_ci return true; 100c5e268c6Sopenharmony_ci } 101c5e268c6Sopenharmony_ci 102c5e268c6Sopenharmony_ci bool EraseCache(IdType id) 103c5e268c6Sopenharmony_ci { 104c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 105c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 106c5e268c6Sopenharmony_ci if (cacheItem == caches_.end()) { 107c5e268c6Sopenharmony_ci return false; 108c5e268c6Sopenharmony_ci } 109c5e268c6Sopenharmony_ci 110c5e268c6Sopenharmony_ci if (cleanUpFunc_ && cacheItem->second != nullptr) { 111c5e268c6Sopenharmony_ci cleanUpFunc_(cacheItem->second); 112c5e268c6Sopenharmony_ci } 113c5e268c6Sopenharmony_ci 114c5e268c6Sopenharmony_ci caches_.erase(cacheItem); 115c5e268c6Sopenharmony_ci return true; 116c5e268c6Sopenharmony_ci } 117c5e268c6Sopenharmony_ci 118c5e268c6Sopenharmony_ci CacheType* SearchCache(IdType id) 119c5e268c6Sopenharmony_ci { 120c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 121c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 122c5e268c6Sopenharmony_ci if (cacheItem == caches_.end()) { 123c5e268c6Sopenharmony_ci return nullptr; 124c5e268c6Sopenharmony_ci } 125c5e268c6Sopenharmony_ci 126c5e268c6Sopenharmony_ci return cacheItem->second.get(); 127c5e268c6Sopenharmony_ci } 128c5e268c6Sopenharmony_ci 129c5e268c6Sopenharmony_ci void TravelCaches(std::function<void (IdType id, const CacheType& cache)> func) 130c5e268c6Sopenharmony_ci { 131c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 132c5e268c6Sopenharmony_ci for (auto const& [key, value] : caches_) { 133c5e268c6Sopenharmony_ci func(key, *value.get()); 134c5e268c6Sopenharmony_ci } 135c5e268c6Sopenharmony_ci } 136c5e268c6Sopenharmony_ci 137c5e268c6Sopenharmony_ci void SetCleanUpFunc(void (*func)(std::unique_ptr<CacheType>&)) 138c5e268c6Sopenharmony_ci { 139c5e268c6Sopenharmony_ci cleanUpFunc_ = func; 140c5e268c6Sopenharmony_ci } 141c5e268c6Sopenharmony_ci 142c5e268c6Sopenharmony_ci void SetInitFunc(void (*func)(std::unique_ptr<CacheType>&)) 143c5e268c6Sopenharmony_ci { 144c5e268c6Sopenharmony_ci initFunc_ = func; 145c5e268c6Sopenharmony_ci } 146c5e268c6Sopenharmony_ci 147c5e268c6Sopenharmony_ciprivate: 148c5e268c6Sopenharmony_ci uint32_t cacheCountMax_; 149c5e268c6Sopenharmony_ci std::unordered_map<IdType, std::unique_ptr<CacheType>> caches_; 150c5e268c6Sopenharmony_ci void (*cleanUpFunc_)(std::unique_ptr<CacheType>&); 151c5e268c6Sopenharmony_ci void (*initFunc_)(std::unique_ptr<CacheType>&); 152c5e268c6Sopenharmony_ci std::mutex mutex_; 153c5e268c6Sopenharmony_ci}; 154c5e268c6Sopenharmony_ci 155c5e268c6Sopenharmony_citemplate <typename IdType> 156c5e268c6Sopenharmony_ciclass CacheManager<IdType, Base::NativeBuffer> : public NoCopyable { 157c5e268c6Sopenharmony_cipublic: 158c5e268c6Sopenharmony_ci CacheManager() 159c5e268c6Sopenharmony_ci : cacheCountMax_ { 0 }, 160c5e268c6Sopenharmony_ci cleanUpFunc_ { nullptr }, 161c5e268c6Sopenharmony_ci initFunc_ { nullptr } 162c5e268c6Sopenharmony_ci {} 163c5e268c6Sopenharmony_ci 164c5e268c6Sopenharmony_ci virtual ~CacheManager() 165c5e268c6Sopenharmony_ci { 166c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 167c5e268c6Sopenharmony_ci if (cleanUpFunc_) { 168c5e268c6Sopenharmony_ci for (auto& cache : caches_) { 169c5e268c6Sopenharmony_ci cleanUpFunc_(cache.second); 170c5e268c6Sopenharmony_ci } 171c5e268c6Sopenharmony_ci } 172c5e268c6Sopenharmony_ci caches_.clear(); 173c5e268c6Sopenharmony_ci } 174c5e268c6Sopenharmony_ci 175c5e268c6Sopenharmony_ci bool SetCacheMaxCount(uint32_t count) 176c5e268c6Sopenharmony_ci { 177c5e268c6Sopenharmony_ci bool ret = true; 178c5e268c6Sopenharmony_ci uint32_t originalMaxCount = cacheCountMax_; 179c5e268c6Sopenharmony_ci if (count >= cacheCountMax_) { 180c5e268c6Sopenharmony_ci cacheCountMax_ = count; 181c5e268c6Sopenharmony_ci } else if (Size() <= count) { 182c5e268c6Sopenharmony_ci cacheCountMax_ = count; 183c5e268c6Sopenharmony_ci } else { 184c5e268c6Sopenharmony_ci HDF_LOGE("%{public}s error: clientCacheCount can't be set, because cacheCountMax_ > count", __func__); 185c5e268c6Sopenharmony_ci ret = false; 186c5e268c6Sopenharmony_ci } 187c5e268c6Sopenharmony_ci HDF_LOGI("%{public}s: set cache max count from %{public}u to %{public}u", 188c5e268c6Sopenharmony_ci __func__, originalMaxCount, cacheCountMax_); 189c5e268c6Sopenharmony_ci return ret; 190c5e268c6Sopenharmony_ci } 191c5e268c6Sopenharmony_ci 192c5e268c6Sopenharmony_ci uint32_t Size() 193c5e268c6Sopenharmony_ci { 194c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 195c5e268c6Sopenharmony_ci return caches_.size(); 196c5e268c6Sopenharmony_ci } 197c5e268c6Sopenharmony_ci 198c5e268c6Sopenharmony_ci bool InsertCache(IdType id, Base::NativeBuffer* cache) 199c5e268c6Sopenharmony_ci { 200c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 201c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 202c5e268c6Sopenharmony_ci if (cacheItem != caches_.end()) { 203c5e268c6Sopenharmony_ci HDF_LOGI("%{public}s: intend to insert a existing cache, SeqNo=%{public}d", __func__, id); 204c5e268c6Sopenharmony_ci cacheItem->second = OHOS::sptr<Base::NativeBuffer>(cache); 205c5e268c6Sopenharmony_ci } else { 206c5e268c6Sopenharmony_ci if (cacheCountMax_ != 0 && caches_.size() >= cacheCountMax_) { 207c5e268c6Sopenharmony_ci HDF_LOGE("%{public}s: Caches is full, new seqNo:%{public}d can't be inserted", __func__, id); 208c5e268c6Sopenharmony_ci return false; 209c5e268c6Sopenharmony_ci } 210c5e268c6Sopenharmony_ci caches_[id] = OHOS::sptr<Base::NativeBuffer>(cache); 211c5e268c6Sopenharmony_ci } 212c5e268c6Sopenharmony_ci if (initFunc_) { 213c5e268c6Sopenharmony_ci initFunc_(caches_[id]); 214c5e268c6Sopenharmony_ci } 215c5e268c6Sopenharmony_ci return true; 216c5e268c6Sopenharmony_ci } 217c5e268c6Sopenharmony_ci 218c5e268c6Sopenharmony_ci bool EraseCache(IdType id) 219c5e268c6Sopenharmony_ci { 220c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 221c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 222c5e268c6Sopenharmony_ci if (cacheItem == caches_.end()) { 223c5e268c6Sopenharmony_ci HDF_LOGE("%{public}s: Cache %{public}d is not existing\n", __func__, id); 224c5e268c6Sopenharmony_ci return false; 225c5e268c6Sopenharmony_ci } 226c5e268c6Sopenharmony_ci 227c5e268c6Sopenharmony_ci if (cleanUpFunc_ && cacheItem->second != nullptr) { 228c5e268c6Sopenharmony_ci cleanUpFunc_(cacheItem->second); 229c5e268c6Sopenharmony_ci } 230c5e268c6Sopenharmony_ci 231c5e268c6Sopenharmony_ci caches_.erase(cacheItem); 232c5e268c6Sopenharmony_ci return true; 233c5e268c6Sopenharmony_ci } 234c5e268c6Sopenharmony_ci 235c5e268c6Sopenharmony_ci Base::NativeBuffer* SearchCache(IdType id) 236c5e268c6Sopenharmony_ci { 237c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 238c5e268c6Sopenharmony_ci auto cacheItem = caches_.find(id); 239c5e268c6Sopenharmony_ci if (cacheItem == caches_.end()) { 240c5e268c6Sopenharmony_ci return nullptr; 241c5e268c6Sopenharmony_ci } 242c5e268c6Sopenharmony_ci 243c5e268c6Sopenharmony_ci return cacheItem->second.GetRefPtr(); 244c5e268c6Sopenharmony_ci } 245c5e268c6Sopenharmony_ci 246c5e268c6Sopenharmony_ci void TravelCaches(std::function<void (IdType id, const Base::NativeBuffer& cache)> func) 247c5e268c6Sopenharmony_ci { 248c5e268c6Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 249c5e268c6Sopenharmony_ci for (auto const& [key, value] : caches_) { 250c5e268c6Sopenharmony_ci func(key, *value.GetRefPtr()); 251c5e268c6Sopenharmony_ci } 252c5e268c6Sopenharmony_ci } 253c5e268c6Sopenharmony_ci 254c5e268c6Sopenharmony_ci void SetCleanUpFunc(void (*func)(OHOS::sptr<Base::NativeBuffer>&)) 255c5e268c6Sopenharmony_ci { 256c5e268c6Sopenharmony_ci cleanUpFunc_ = func; 257c5e268c6Sopenharmony_ci } 258c5e268c6Sopenharmony_ci 259c5e268c6Sopenharmony_ci void SetInitFunc(void (*func)(OHOS::sptr<Base::NativeBuffer>&)) 260c5e268c6Sopenharmony_ci { 261c5e268c6Sopenharmony_ci initFunc_ = func; 262c5e268c6Sopenharmony_ci } 263c5e268c6Sopenharmony_ci 264c5e268c6Sopenharmony_ciprivate: 265c5e268c6Sopenharmony_ci uint32_t cacheCountMax_; 266c5e268c6Sopenharmony_ci std::unordered_map<IdType, OHOS::sptr<Base::NativeBuffer>> caches_; 267c5e268c6Sopenharmony_ci void (*cleanUpFunc_)(OHOS::sptr<Base::NativeBuffer>&); 268c5e268c6Sopenharmony_ci void (*initFunc_)(OHOS::sptr<Base::NativeBuffer>&); 269c5e268c6Sopenharmony_ci std::mutex mutex_; 270c5e268c6Sopenharmony_ci}; 271c5e268c6Sopenharmony_ci} // namespace Composer 272c5e268c6Sopenharmony_ci} // namespace Display 273c5e268c6Sopenharmony_ci} // namespace HDI 274c5e268c6Sopenharmony_ci} // namespace OHOS 275c5e268c6Sopenharmony_ci#endif // OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H 276