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