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