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#include "device_cache.h"
17c5e268c6Sopenharmony_ci
18c5e268c6Sopenharmony_ci#include "buffer_cache_utils.h"
19c5e268c6Sopenharmony_ci#include "common/include/display_interface_utils.h"
20c5e268c6Sopenharmony_ci#include "hdf_base.h"
21c5e268c6Sopenharmony_ci#include "hdf_log.h"
22c5e268c6Sopenharmony_ci
23c5e268c6Sopenharmony_cinamespace OHOS {
24c5e268c6Sopenharmony_cinamespace HDI {
25c5e268c6Sopenharmony_cinamespace Display {
26c5e268c6Sopenharmony_cinamespace Composer {
27c5e268c6Sopenharmony_ci
28c5e268c6Sopenharmony_ciDeviceCache* DeviceCache::Create(uint32_t id, DeviceType type)
29c5e268c6Sopenharmony_ci{
30c5e268c6Sopenharmony_ci    DeviceCache* device = new DeviceCache(id, type);
31c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(device == nullptr, nullptr, HDF_LOGE("%{public}s: create device cache failed", __func__));
32c5e268c6Sopenharmony_ci
33c5e268c6Sopenharmony_ci    int32_t ret = device->Init();
34c5e268c6Sopenharmony_ci    if (ret != HDF_SUCCESS) {
35c5e268c6Sopenharmony_ci        delete device;
36c5e268c6Sopenharmony_ci        device = nullptr;
37c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: device cache init failed", __func__);
38c5e268c6Sopenharmony_ci    }
39c5e268c6Sopenharmony_ci
40c5e268c6Sopenharmony_ci    return device;
41c5e268c6Sopenharmony_ci}
42c5e268c6Sopenharmony_ci
43c5e268c6Sopenharmony_ciDeviceCache::DeviceCache(uint32_t id, DeviceType type) : deviceId_(id), cacheType_(type)
44c5e268c6Sopenharmony_ci{
45c5e268c6Sopenharmony_ci}
46c5e268c6Sopenharmony_ci
47c5e268c6Sopenharmony_ciDeviceCache::~DeviceCache()
48c5e268c6Sopenharmony_ci{
49c5e268c6Sopenharmony_ci}
50c5e268c6Sopenharmony_ci
51c5e268c6Sopenharmony_ciint32_t DeviceCache::Init()
52c5e268c6Sopenharmony_ci{
53c5e268c6Sopenharmony_ci    layerCaches_.reset(new CacheManager<uint32_t, LayerCache>());
54c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(layerCaches_ == nullptr, HDF_FAILURE,
55c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: create layer caches failed", __func__));
56c5e268c6Sopenharmony_ci
57c5e268c6Sopenharmony_ci    clientBufferCaches_.reset(new CacheManager<uint32_t, NativeBuffer>());
58c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(clientBufferCaches_ == nullptr, HDF_FAILURE,
59c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: create client buffer caches failed", __func__));
60c5e268c6Sopenharmony_ci
61c5e268c6Sopenharmony_ci    clientBufferCaches_->SetInitFunc(LayerCache::NativeBufferInit);
62c5e268c6Sopenharmony_ci    clientBufferCaches_->SetCleanUpFunc(LayerCache::NativeBufferCleanUp);
63c5e268c6Sopenharmony_ci
64c5e268c6Sopenharmony_ci    outputBufferCaches_.reset(new CacheManager<uint32_t, NativeBuffer>());
65c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(outputBufferCaches_ == nullptr, HDF_FAILURE,
66c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: create output buffer caches failed", __func__));
67c5e268c6Sopenharmony_ci
68c5e268c6Sopenharmony_ci    outputBufferCaches_->SetInitFunc(LayerCache::NativeBufferInit);
69c5e268c6Sopenharmony_ci    outputBufferCaches_->SetCleanUpFunc(LayerCache::NativeBufferCleanUp);
70c5e268c6Sopenharmony_ci    return HDF_SUCCESS;
71c5e268c6Sopenharmony_ci}
72c5e268c6Sopenharmony_ci
73c5e268c6Sopenharmony_ciint32_t DeviceCache::SetClientBufferCacheCount(uint32_t bufferCacheCount)
74c5e268c6Sopenharmony_ci{
75c5e268c6Sopenharmony_ci    return clientBufferCaches_->SetCacheMaxCount(bufferCacheCount) ? HDF_SUCCESS : HDF_FAILURE;
76c5e268c6Sopenharmony_ci}
77c5e268c6Sopenharmony_ci
78c5e268c6Sopenharmony_ciLayerCache* DeviceCache::LayerCacheInstance(uint32_t layerId) const
79c5e268c6Sopenharmony_ci{
80c5e268c6Sopenharmony_ci    return layerCaches_->SearchCache(layerId);
81c5e268c6Sopenharmony_ci}
82c5e268c6Sopenharmony_ci
83c5e268c6Sopenharmony_ciint32_t DeviceCache::AddLayerCache(uint32_t id, uint32_t bufferCacheCount)
84c5e268c6Sopenharmony_ci{
85c5e268c6Sopenharmony_ci    LayerCache* layer = LayerCache::Create(id);
86c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(layer == nullptr, HDF_FAILURE, HDF_LOGE("%{public}s: Create cache failed", __func__));
87c5e268c6Sopenharmony_ci
88c5e268c6Sopenharmony_ci    int32_t retResult = layer->SetBufferCacheMaxCount(bufferCacheCount);
89c5e268c6Sopenharmony_ci    if (retResult != HDF_SUCCESS) {
90c5e268c6Sopenharmony_ci        delete layer;
91c5e268c6Sopenharmony_ci        layer = nullptr;
92c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: set buffer cache max count failed", __func__);
93c5e268c6Sopenharmony_ci        return retResult;
94c5e268c6Sopenharmony_ci    }
95c5e268c6Sopenharmony_ci
96c5e268c6Sopenharmony_ci    bool ret = layerCaches_->InsertCache(id, layer);
97c5e268c6Sopenharmony_ci    if (ret != true) {
98c5e268c6Sopenharmony_ci        delete layer;
99c5e268c6Sopenharmony_ci        layer = nullptr;
100c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: insert cache failed", __func__);
101c5e268c6Sopenharmony_ci        return HDF_FAILURE;
102c5e268c6Sopenharmony_ci    }
103c5e268c6Sopenharmony_ci    return HDF_SUCCESS;
104c5e268c6Sopenharmony_ci}
105c5e268c6Sopenharmony_ci
106c5e268c6Sopenharmony_ciint32_t DeviceCache::RemoveLayerCache(uint32_t id)
107c5e268c6Sopenharmony_ci{
108c5e268c6Sopenharmony_ci    bool ret = layerCaches_->EraseCache(id);
109c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(ret != true, HDF_FAILURE, HDF_LOGE("%{public}s: Destroy cache failed", __func__));
110c5e268c6Sopenharmony_ci
111c5e268c6Sopenharmony_ci    return HDF_SUCCESS;
112c5e268c6Sopenharmony_ci}
113c5e268c6Sopenharmony_ci
114c5e268c6Sopenharmony_ciint32_t DeviceCache::ClearClientCache()
115c5e268c6Sopenharmony_ci{
116c5e268c6Sopenharmony_ci    HDF_LOGI("%{public}s", __func__);
117c5e268c6Sopenharmony_ci    clientBufferCaches_.reset(new CacheManager<uint32_t, NativeBuffer>());
118c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(clientBufferCaches_ == nullptr, HDF_FAILURE,
119c5e268c6Sopenharmony_ci                       HDF_LOGE("%{public}s: create client buffer caches failed", __func__));
120c5e268c6Sopenharmony_ci
121c5e268c6Sopenharmony_ci    clientBufferCaches_->SetInitFunc(LayerCache::NativeBufferInit);
122c5e268c6Sopenharmony_ci    clientBufferCaches_->SetCleanUpFunc(LayerCache::NativeBufferCleanUp);
123c5e268c6Sopenharmony_ci    return HDF_SUCCESS;
124c5e268c6Sopenharmony_ci}
125c5e268c6Sopenharmony_ci
126c5e268c6Sopenharmony_ciint32_t DeviceCache::ClearLayerBuffer(uint32_t layerId)
127c5e268c6Sopenharmony_ci{
128c5e268c6Sopenharmony_ci    HDF_LOGI("%{public}s, layerId %{public}u", __func__, layerId);
129c5e268c6Sopenharmony_ci    if (layerCaches_ == nullptr) {
130c5e268c6Sopenharmony_ci        return HDF_FAILURE;
131c5e268c6Sopenharmony_ci    }
132c5e268c6Sopenharmony_ci    LayerCache* layerCache = layerCaches_->SearchCache(layerId);
133c5e268c6Sopenharmony_ci    if (layerCache == nullptr) {
134c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s, layerId %{public}u not found", __func__, layerId);
135c5e268c6Sopenharmony_ci        return HDF_FAILURE;
136c5e268c6Sopenharmony_ci    }
137c5e268c6Sopenharmony_ci
138c5e268c6Sopenharmony_ci    return layerCache->ResetLayerBuffer();
139c5e268c6Sopenharmony_ci}
140c5e268c6Sopenharmony_ci
141c5e268c6Sopenharmony_ciint32_t DeviceCache::SetDisplayClientBuffer(BufferHandle*& buffer, uint32_t seqNo, bool &needFreeBuffer,
142c5e268c6Sopenharmony_ci    std::function<int32_t (const BufferHandle&)> realFunc)
143c5e268c6Sopenharmony_ci{
144c5e268c6Sopenharmony_ci    if (buffer != nullptr) {
145c5e268c6Sopenharmony_ci        HDF_LOGI("%{public}s, seqNo %{public}u, fd %{public}d, size %{public}d", __func__, seqNo, buffer->fd,
146c5e268c6Sopenharmony_ci                 buffer->size);
147c5e268c6Sopenharmony_ci    }
148c5e268c6Sopenharmony_ci    BufferHandle* handle = BufferCacheUtils::NativeBufferCache(clientBufferCaches_, buffer, seqNo, deviceId_,
149c5e268c6Sopenharmony_ci                                                               needFreeBuffer);
150c5e268c6Sopenharmony_ci    DISPLAY_CHK_RETURN(handle == nullptr, HDF_FAILURE,
151c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: call NativeBufferCache fail", __func__));
152c5e268c6Sopenharmony_ci    auto ret = realFunc(*handle);
153c5e268c6Sopenharmony_ci    if (ret != HDF_SUCCESS) {
154c5e268c6Sopenharmony_ci        clientBufferCaches_->EraseCache(seqNo);
155c5e268c6Sopenharmony_ci        buffer = nullptr;
156c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: call realFunc fail", __func__);
157c5e268c6Sopenharmony_ci    }
158c5e268c6Sopenharmony_ci
159c5e268c6Sopenharmony_ci    return ret;
160c5e268c6Sopenharmony_ci}
161c5e268c6Sopenharmony_ci
162c5e268c6Sopenharmony_ciint32_t DeviceCache::SetVirtualDisplayBuffer(BufferHandle*& buffer, uint32_t seqNo, bool &needFreeBuffer,
163c5e268c6Sopenharmony_ci    std::function<int32_t (const BufferHandle&)> realFunc)
164c5e268c6Sopenharmony_ci{
165c5e268c6Sopenharmony_ci    int32_t ret = HDF_FAILURE;
166c5e268c6Sopenharmony_ci    if (CacheType() == DEVICE_TYPE_VIRTUAL) {
167c5e268c6Sopenharmony_ci        BufferHandle* handle = BufferCacheUtils::NativeBufferCache(outputBufferCaches_, buffer, seqNo, deviceId_,
168c5e268c6Sopenharmony_ci                                                                   needFreeBuffer);
169c5e268c6Sopenharmony_ci        DISPLAY_CHK_RETURN(handle == nullptr, HDF_FAILURE,
170c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s: call NativeBufferCache fail", __func__));
171c5e268c6Sopenharmony_ci        ret = realFunc(*handle);
172c5e268c6Sopenharmony_ci        if (ret != HDF_SUCCESS) {
173c5e268c6Sopenharmony_ci            outputBufferCaches_->EraseCache(seqNo);
174c5e268c6Sopenharmony_ci            buffer = nullptr;
175c5e268c6Sopenharmony_ci            HDF_LOGE("%{public}s: call realFunc fail", __func__);
176c5e268c6Sopenharmony_ci        }
177c5e268c6Sopenharmony_ci    } else {
178c5e268c6Sopenharmony_ci        HDF_LOGE("%{public}s: not a virtual display", __func__);
179c5e268c6Sopenharmony_ci    }
180c5e268c6Sopenharmony_ci
181c5e268c6Sopenharmony_ci    return ret;
182c5e268c6Sopenharmony_ci}
183c5e268c6Sopenharmony_ci
184c5e268c6Sopenharmony_ciDeviceCache::DeviceType DeviceCache::CacheType() const
185c5e268c6Sopenharmony_ci{
186c5e268c6Sopenharmony_ci    return cacheType_;
187c5e268c6Sopenharmony_ci}
188c5e268c6Sopenharmony_ci
189c5e268c6Sopenharmony_civoid DeviceCache::Dump() const
190c5e268c6Sopenharmony_ci{
191c5e268c6Sopenharmony_ci    clientBufferCaches_->TravelCaches([this](int32_t id, const NativeBuffer& buffer)->void {
192c5e268c6Sopenharmony_ci        auto info = buffer.Dump();
193c5e268c6Sopenharmony_ci        HDF_LOGE("devId-%{public}d, clientBuffer[%{public}d]: %{public}s", deviceId_, id, info.c_str());
194c5e268c6Sopenharmony_ci    });
195c5e268c6Sopenharmony_ci    outputBufferCaches_->TravelCaches([this](int32_t id, const NativeBuffer& buffer)->void {
196c5e268c6Sopenharmony_ci        auto info = buffer.Dump();
197c5e268c6Sopenharmony_ci        HDF_LOGE("devId-%{public}d, outputBuffer[%{public}d]: %{public}s", deviceId_, id, info.c_str());
198c5e268c6Sopenharmony_ci    });
199c5e268c6Sopenharmony_ci    layerCaches_->TravelCaches([](int32_t id, const LayerCache& cache)->void {
200c5e268c6Sopenharmony_ci        cache.Dump();
201c5e268c6Sopenharmony_ci    });
202c5e268c6Sopenharmony_ci}
203c5e268c6Sopenharmony_ci} // namespace Composer
204c5e268c6Sopenharmony_ci} // namespace Display
205c5e268c6Sopenharmony_ci} // namespace HDI
206c5e268c6Sopenharmony_ci} // namespace OHOS
207