1 /*
2 * Copyright (C) 2024 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 "effect_memory_manager.h"
17
18 #include "effect_log.h"
19 #include "effect_buffer.h"
20 #include "colorspace_helper.h"
21
22 using namespace OHOS::ColorManager;
23 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
24
25 namespace OHOS {
26 namespace Media {
27 namespace Effect {
Init(const std::shared_ptr<EffectBuffer> & srcEffectBuffer,const std::shared_ptr<EffectBuffer> & dstEffectBuffer)28 ErrorCode EffectMemoryManager::Init(const std::shared_ptr<EffectBuffer> &srcEffectBuffer,
29 const std::shared_ptr<EffectBuffer> &dstEffectBuffer)
30 {
31 AddFilterMemory(srcEffectBuffer, MemDataType::INPUT,
32 dstEffectBuffer == nullptr || srcEffectBuffer->buffer_ == dstEffectBuffer->buffer_);
33 AddFilterMemory(dstEffectBuffer, MemDataType::OUTPUT,
34 dstEffectBuffer != nullptr && srcEffectBuffer->buffer_ != dstEffectBuffer->buffer_);
35 return ErrorCode::SUCCESS;
36 }
37
SetIPType(IPType ipType)38 void EffectMemoryManager::SetIPType(IPType ipType)
39 {
40 runningIPType_ = ipType;
41 }
42
AddFilterMemory(const std::shared_ptr<EffectBuffer> & effectBuffer,MemDataType memDataType,bool isAllowModify)43 void EffectMemoryManager::AddFilterMemory(const std::shared_ptr<EffectBuffer> &effectBuffer, MemDataType memDataType,
44 bool isAllowModify)
45 {
46 // dst effect buffer is null while not set output data.
47 if (effectBuffer == nullptr || effectBuffer->buffer_ == nullptr) {
48 return;
49 }
50
51 std::shared_ptr<Memory> memory = std::make_shared<Memory>();
52 memory->memoryData_ = std::make_shared<MemoryData>();
53 memory->memoryData_->data = effectBuffer->buffer_;
54 memory->memoryData_->memoryInfo.bufferInfo = *effectBuffer->bufferInfo_;
55 memory->memoryData_->memoryInfo.extra = effectBuffer->extraInfo_->surfaceBuffer;
56 memory->memoryData_->memoryInfo.bufferType = effectBuffer->extraInfo_->bufferType;
57 memory->memDataType_ = memDataType;
58 memory->isAllowModify_ = isAllowModify;
59 AddMemory(memory);
60 }
61
UpdateColorSpaceIfNeed(std::shared_ptr<MemoryData> & memoryData)62 void UpdateColorSpaceIfNeed(std::shared_ptr<MemoryData> &memoryData)
63 {
64 const MemoryInfo &memoryInfo = memoryData->memoryInfo;
65 EffectColorSpace colorSpace = memoryInfo.bufferInfo.colorSpace_;
66 if (memoryInfo.bufferType != BufferType::DMA_BUFFER || memoryInfo.extra == nullptr ||
67 !ColorSpaceHelper::IsHdrColorSpace(colorSpace)) {
68 return;
69 }
70
71 EFFECT_LOGI("UpdateColorSpaceIfNeed: UpdateColorSpace colorSpace=%{public}d", colorSpace);
72 auto *sb = static_cast<SurfaceBuffer *>(memoryInfo.extra);
73 ColorSpaceHelper::SetSurfaceBufferMetadataType(sb, CM_HDR_Metadata_Type::CM_IMAGE_HDR_VIVID_SINGLE);
74 ColorSpaceHelper::SetSurfaceBufferColorSpaceType(sb, CM_ColorSpaceType::CM_BT2020_HLG_FULL);
75 }
76
AllocMemoryInner(MemoryInfo & allocMemInfo,BufferType allocBufferType)77 std::shared_ptr<Memory> AllocMemoryInner(MemoryInfo &allocMemInfo, BufferType allocBufferType)
78 {
79 EFFECT_LOGI("Alloc Memory! bufferType=%{public}d", allocBufferType);
80 std::unique_ptr<AbsMemory> absMemory = EffectMemory::CreateMemory(allocBufferType);
81 CHECK_AND_RETURN_RET_LOG(absMemory != nullptr, nullptr,
82 "absMemory is null! bufferType=%{public}d", allocBufferType);
83 std::shared_ptr<MemoryData> memoryData = absMemory->Alloc(allocMemInfo);
84 CHECK_AND_RETURN_RET_LOG(memoryData != nullptr, nullptr,
85 "memoryData is null! bufferType=%{public}d", allocBufferType);
86
87 UpdateColorSpaceIfNeed(memoryData);
88
89 std::shared_ptr<Memory> memory = std::make_shared<Memory>();
90 memory->memoryData_ = memoryData;
91 memory->isAllowModify_ = true;
92
93 return memory;
94 }
95
AllocMemory(void * srcAddr,MemoryInfo & allocMemInfo)96 MemoryData *EffectMemoryManager::AllocMemory(void *srcAddr, MemoryInfo &allocMemInfo)
97 {
98 for (const auto &memory : memorys_) {
99 if (!memory->isAllowModify_ || memory->memoryData_->data == srcAddr) {
100 continue;
101 }
102
103 const MemoryInfo &memInfo = memory->memoryData_->memoryInfo;
104 const BufferInfo &bufferInfo = memInfo.bufferInfo;
105 const BufferInfo &allocBufInfo = allocMemInfo.bufferInfo;
106 if (bufferInfo.width_ == allocBufInfo.width_ && bufferInfo.height_ == allocBufInfo.height_ &&
107 (allocMemInfo.bufferType == BufferType::DEFAULT || allocMemInfo.bufferType == memInfo.bufferType) &&
108 bufferInfo.formatType_ == allocBufInfo.formatType_ && bufferInfo.colorSpace_ == allocBufInfo.colorSpace_) {
109 EFFECT_LOGD("reuse memory. width=%{public}d, height=%{public}d, addr=%{public}p, format=%{public}d, "
110 "bufferType=%{public}d, allocBufType=%{public}d", bufferInfo.width_, bufferInfo.height_,
111 memory->memoryData_->data, bufferInfo.formatType_, memInfo.bufferType, allocMemInfo.bufferType);
112 return memory->memoryData_.get();
113 }
114 }
115
116 BufferType allocBufferType = BufferType::DMA_BUFFER; // default alloc dma buffer
117 if (runningIPType_ == IPType::CPU) {
118 allocBufferType = BufferType::HEAP_MEMORY; // default alloc heap buffer on running with cpu filter
119 }
120 if (allocMemInfo.bufferType != BufferType::DEFAULT) {
121 allocBufferType = allocMemInfo.bufferType;
122 }
123 std::shared_ptr<Memory> memory = AllocMemoryInner(allocMemInfo, allocBufferType);
124 CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr,
125 "AllocMemory fail! bufferType=%{public}d", allocBufferType);
126 AddMemory(memory);
127 EFFECT_LOGD("alloc new memory. memorys size=%{public}zu", memorys_.size());
128 return memory->memoryData_.get();
129 }
130
AddMemory(std::shared_ptr<Memory> & memory)131 void EffectMemoryManager::AddMemory(std::shared_ptr<Memory> &memory)
132 {
133 CHECK_AND_RETURN_LOG(memory != nullptr, "memory is null!");
134 CHECK_AND_RETURN_LOG(memory->memoryData_ != nullptr && memory->memoryData_->data != nullptr,
135 "memory data is null!");
136 if (std::find(memorys_.begin(), memorys_.end(), memory) == memorys_.end()) {
137 memorys_.emplace_back(memory);
138 } else {
139 EFFECT_LOGW("memory is already add! memory=%{public}p", memory.get());
140 }
141 }
142
GetAllocMemoryByAddr(void * addr)143 std::shared_ptr<Memory> EffectMemoryManager::GetAllocMemoryByAddr(void *addr)
144 {
145 for (auto &memory : memorys_) {
146 if (memory->memDataType_ != MemDataType::OTHER) {
147 continue;
148 }
149
150 if (memory->memoryData_->data == addr) {
151 EFFECT_LOGD("addr is find! addr=%{public}p, bufferType=%{public}d",
152 addr, memory->memoryData_->memoryInfo.bufferType);
153 return memory;
154 }
155 }
156 EFFECT_LOGI("addr is not find!");
157 return nullptr;
158 }
159
GetMemoryByAddr(void * addr)160 std::shared_ptr<Memory> EffectMemoryManager::GetMemoryByAddr(void *addr)
161 {
162 auto it = std::find_if(memorys_.begin(), memorys_.end(), [&addr](const auto &item) {
163 return addr == item->memoryData_->data;
164 });
165
166 return it == memorys_.end() ? nullptr : *it;
167 }
168
RemoveMemory(std::shared_ptr<Memory> & memory)169 void EffectMemoryManager::RemoveMemory(std::shared_ptr<Memory> &memory)
170 {
171 auto it = std::find(memorys_.begin(), memorys_.end(), memory);
172 if (it != memorys_.end()) {
173 EFFECT_LOGD("EffectMemoryManager::RemoveMemory success!");
174 memorys_.erase(it);
175 }
176 }
177
ClearMemory()178 void EffectMemoryManager::ClearMemory()
179 {
180 EFFECT_LOGD("EffectMemoryManager::ClearMemory");
181 memorys_.clear();
182 }
183
Deinit()184 void EffectMemoryManager::Deinit()
185 {
186 for (auto it = memorys_.begin(); it != memorys_.end();) {
187 const MemDataType &memDataType_ = (*it)->memDataType_;
188 if (memDataType_ == MemDataType::INPUT || memDataType_ == MemDataType::OUTPUT) {
189 it = memorys_.erase(it);
190 } else {
191 ++it;
192 }
193 }
194 EFFECT_LOGD("EffectMemoryManager: Deinit memorySize=%{public}zu", memorys_.size());
195 }
196 } // namespace Effect
197 } // namespace Media
198 } // namespace OHOS