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 "layer_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 28LayerCache* LayerCache::Create(uint32_t id) 29{ 30 LayerCache* layer = new LayerCache(id); 31 DISPLAY_CHK_RETURN(layer == nullptr, nullptr, HDF_LOGE("%{public}s: create layer cache failed", __func__)); 32 33 int32_t ret = layer->Init(); 34 if (ret != HDF_SUCCESS) { 35 delete layer; 36 layer = nullptr; 37 HDF_LOGE("%{public}s: layer cache init failed", __func__); 38 } 39 40 return layer; 41} 42 43LayerCache::LayerCache(uint32_t id) : layerId_(id) 44{ 45} 46 47LayerCache::~LayerCache() 48{ 49} 50 51int32_t LayerCache::Init() 52{ 53 bufferCaches_.reset(new CacheManager<uint32_t, NativeBuffer>()); 54 DISPLAY_CHK_RETURN(bufferCaches_ == nullptr, HDF_FAILURE, 55 HDF_LOGE("%{public}s: create buffer caches failed", __func__)); 56 57 bufferCaches_->SetInitFunc(NativeBufferInit); 58 bufferCaches_->SetCleanUpFunc(NativeBufferCleanUp); 59 return HDF_SUCCESS; 60} 61 62int32_t LayerCache::SetBufferCacheMaxCount(uint32_t cacheCount) 63{ 64 bool ret = bufferCaches_->SetCacheMaxCount(cacheCount); 65 DISPLAY_CHK_RETURN(ret == false, HDF_FAILURE, HDF_LOGE("%{public}s: failed", __func__)); 66 return HDF_SUCCESS; 67} 68 69int32_t LayerCache::SetLayerBuffer(BufferHandle*& buffer, uint32_t seqNo, bool &needFreeBuffer, 70 const std::vector<uint32_t>& deletingList, std::function<int32_t (const BufferHandle&)> realFunc) 71{ 72 if (buffer != nullptr) { 73 HDF_LOGI("%{public}s, seqNo %{public}u, fd %{public}d, size %{public}d", __func__, seqNo, buffer->fd, 74 buffer->size); 75 } 76 for (auto num : deletingList) { 77 (void)bufferCaches_->EraseCache(num); 78 } 79 80 BufferHandle* handle = BufferCacheUtils::NativeBufferCache(bufferCaches_, buffer, seqNo, layerId_, needFreeBuffer); 81 DISPLAY_CHK_RETURN(handle == nullptr, HDF_FAILURE, 82 HDF_LOGE("%{public}s: call NativeBufferCache fail", __func__)); 83 int32_t ret = realFunc(*handle); 84 if (ret != HDF_SUCCESS) { 85 bufferCaches_->EraseCache(seqNo); 86 buffer = nullptr; 87 HDF_LOGE("%{public}s: call realFunc fail", __func__); 88 } 89 90 return HDF_SUCCESS; 91} 92 93int32_t LayerCache::ResetLayerBuffer() 94{ 95 HDF_LOGI("%{public}s", __func__); 96 return Init(); 97} 98 99void LayerCache::NativeBufferInit(sptr<NativeBuffer>& buffer) 100{ 101 if (buffer == nullptr) { 102 HDF_LOGW("NativeBufferInit buffer nullptr!"); 103 return; 104 } 105 int32_t ret = RegisterBuffer(buffer); 106 if (ret != HDF_SUCCESS) { 107 HDF_LOGE("%{public}s: RegisterBuffer failed with %{public}d!", __func__, ret); 108 } 109} 110 111void LayerCache::NativeBufferCleanUp(sptr<NativeBuffer>& buffer) 112{ 113 if (buffer == nullptr) { 114 HDF_LOGW("NativeBufferCleanUp buffer nullptr!"); 115 return; 116 } 117 int32_t ret = FreeMem(buffer); 118 if (ret != HDF_SUCCESS) { 119 HDF_LOGE("%{public}s: FreeMem failed with %{public}d!", __func__, ret); 120 } 121} 122 123sptr<Buffer::V1_1::IMetadata> LayerCache::GetMetaService() 124{ 125 static sptr<Buffer::V1_1::IMetadata> metaService = nullptr; 126 if (metaService == nullptr) { 127 metaService = Buffer::V1_1::IMetadata::Get(true); 128 } 129 return metaService; 130} 131 132sptr<Buffer::V1_2::IMapper> LayerCache::GetMapperService() 133{ 134 static sptr<Buffer::V1_2::IMapper> mapperService = nullptr; 135 if (mapperService == nullptr) { 136 mapperService = Buffer::V1_2::IMapper::Get(true); 137 } 138 return mapperService; 139} 140 141int32_t LayerCache::Mmap(sptr<NativeBuffer>& buffer) 142{ 143 auto mapperService = GetMapperService(); 144 if (mapperService == nullptr) { 145 HDF_LOGE("GetMapperService failed!"); 146 return HDF_FAILURE; 147 } 148 return mapperService->Mmap(buffer); 149} 150 151int32_t LayerCache::Unmap(sptr<NativeBuffer>& buffer) 152{ 153 auto mapperService = GetMapperService(); 154 if (mapperService == nullptr) { 155 HDF_LOGE("GetMapperService failed!"); 156 return HDF_FAILURE; 157 } 158 return mapperService->Unmap(buffer); 159} 160 161int32_t LayerCache::FreeMem(sptr<NativeBuffer>& buffer) 162{ 163 auto mapperService = GetMapperService(); 164 if (mapperService == nullptr) { 165 HDF_LOGE("GetMapperService failed!"); 166 return HDF_FAILURE; 167 } 168 int32_t ret = Unmap(buffer); 169 if (ret != HDF_SUCCESS) { 170 HDF_LOGE("Unmap failed!"); 171 } 172 return mapperService->FreeMem(buffer); 173} 174 175int32_t LayerCache::RegisterBuffer(sptr<NativeBuffer>& buffer) 176{ 177 auto metaService = GetMetaService(); 178 if (metaService == nullptr) { 179 return HDF_FAILURE; 180 } 181 int32_t ret = metaService->RegisterBuffer(buffer); 182 if (ret != HDF_SUCCESS) { 183 HDF_LOGE("Register Buffer failed!"); 184 return ret; 185 } 186 ret = Mmap(buffer); 187 if (ret != HDF_SUCCESS) { 188 HDF_LOGE("Mmap failed!"); 189 } 190 return HDF_SUCCESS; 191} 192 193void LayerCache::Dump() const 194{ 195 bufferCaches_->TravelCaches([this](const int32_t id, const NativeBuffer& buffer)->void { 196 auto info = buffer.Dump(); 197 HDF_LOGE("layerId-%{public}d, buffer[%{public}d]: %{public}s", layerId_, id, info.c_str()); 198 }); 199} 200} // namespace Composer 201} // namespace Display 202} // namespace HDI 203} // namespace OHOS 204