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