1 /*
2 * Copyright (c) 2021 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 "gralloc_buffer_allocator.h"
17 #include "buffer_adapter.h"
18 #include "image_buffer.h"
19
20 namespace OHOS::Camera {
GrallocBufferAllocator()21 GrallocBufferAllocator::GrallocBufferAllocator() {}
22
~GrallocBufferAllocator()23 GrallocBufferAllocator::~GrallocBufferAllocator()
24 {
25 int32_t ret = GrallocUninitialize(grallocFuncs_);
26 if (ret != 0) {
27 CAMERA_LOGW("uninitialize gralloc failed, ret:%{public}d", ret);
28 }
29 }
30
Init()31 RetCode GrallocBufferAllocator::Init()
32 {
33 if (grallocFuncs_ != nullptr) {
34 CAMERA_LOGD("init success.");
35 return RC_OK;
36 }
37 if (GrallocInitialize(&grallocFuncs_) != DISPLAY_SUCCESS) {
38 return RC_ERROR;
39 }
40
41 return RC_OK;
42 }
43
AllocBuffer(const uint32_t width,const uint32_t height,const uint64_t cameraUsage,const uint32_t cameraFormat)44 std::shared_ptr<IBuffer> GrallocBufferAllocator::AllocBuffer(const uint32_t width,
45 const uint32_t height,
46 const uint64_t cameraUsage,
47 const uint32_t cameraFormat)
48 {
49 if (grallocFuncs_ == nullptr) {
50 CAMERA_LOGE("grallocFuncs_ is null");
51 return nullptr;
52 }
53
54 if (grallocFuncs_->AllocMem == nullptr) {
55 CAMERA_LOGE("not support alloc buffer");
56 return nullptr;
57 }
58
59 PixelFormat format = BufferAdapter::CameraFormatToPixelFormat(cameraFormat);
60 uint64_t usage = BufferAdapter::CameraUsageToGrallocUsage(cameraUsage);
61 CAMERA_LOGI("buffer info : w[%{public}u], h[%{public}u], u[%{public}" PRIu64 "], f[%{public}u]",
62 width, height, usage, format);
63
64 BufferHandle* handle = nullptr;
65 AllocInfo info = {
66 .width = width,
67 .height = height,
68 .usage = usage,
69 .format = format
70 };
71 int32_t ret = grallocFuncs_->AllocMem(&info, &handle);
72 if (ret != DISPLAY_SUCCESS) {
73 CAMERA_LOGE("Alloc graphic buffer failed, ret = %{public}d", ret);
74 return nullptr;
75 }
76
77 std::shared_ptr<IBuffer> buffer = std::make_shared<ImageBuffer>(sourceType_);
78 if (buffer != nullptr) {
79 GrallocBufferToCameraBuffer(*handle, buffer);
80 CAMERA_LOGD("Alloc graphic buffer success");
81 }
82 return buffer;
83 }
84
FreeBuffer(std::shared_ptr<IBuffer> & buffer)85 RetCode GrallocBufferAllocator::FreeBuffer(std::shared_ptr<IBuffer>& buffer)
86 {
87 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_, RC_ERROR);
88 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_->FreeMem, RC_ERROR);
89 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
90 CHECK_IF_NOT_EQUAL_RETURN_VALUE(buffer->GetSourceType(), sourceType_, RC_ERROR);
91
92 BufferHandle* handle = AllocateBufferHandle(0, 0);
93 CHECK_IF_PTR_NULL_RETURN_VALUE(handle, RC_ERROR);
94
95 CameraBufferToGrallocBuffer(buffer, *handle);
96 grallocFuncs_->FreeMem(handle);
97 buffer->Free();
98
99 if (handle != nullptr) {
100 FreeBufferHandle(handle);
101 }
102 CAMERA_LOGD("Free buffer success.");
103
104 return RC_OK;
105 }
106
MapBuffer(std::shared_ptr<IBuffer> & buffer)107 RetCode GrallocBufferAllocator::MapBuffer(std::shared_ptr<IBuffer>& buffer)
108 {
109 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_, RC_ERROR);
110 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_->Mmap, RC_ERROR);
111 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
112 CHECK_IF_NOT_EQUAL_RETURN_VALUE(buffer->GetSourceType(), sourceType_, RC_ERROR);
113
114 BufferHandle* bufHandle = AllocateBufferHandle(0, 0);
115 CHECK_IF_PTR_NULL_RETURN_VALUE(bufHandle, RC_ERROR);
116
117 CameraBufferToGrallocBuffer(buffer, *bufHandle);
118 void* virAddr = grallocFuncs_->Mmap(bufHandle);
119 if (virAddr == nullptr) {
120 CAMERA_LOGE("Map Buffer failed.");
121 FreeBufferHandle(bufHandle);
122 return RC_ERROR;
123 }
124 buffer->SetVirAddress(virAddr);
125
126 if (bufHandle != nullptr) {
127 FreeBufferHandle(bufHandle);
128 }
129 CAMERA_LOGD("Map buffer success.");
130
131 return RC_OK;
132 }
133
UnmapBuffer(std::shared_ptr<IBuffer> & buffer)134 RetCode GrallocBufferAllocator::UnmapBuffer(std::shared_ptr<IBuffer>& buffer)
135 {
136 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_, RC_ERROR);
137 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_->Unmap, RC_ERROR);
138 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
139 CHECK_IF_NOT_EQUAL_RETURN_VALUE(buffer->GetSourceType(), sourceType_, RC_ERROR);
140
141 BufferHandle* handle = AllocateBufferHandle(0, 0);
142 CHECK_IF_PTR_NULL_RETURN_VALUE(handle, RC_ERROR);
143
144 CameraBufferToGrallocBuffer(buffer, *handle);
145 if (grallocFuncs_->Unmap(handle) != DISPLAY_SUCCESS) {
146 CAMERA_LOGE("Unmap buffer failed.");
147 FreeBufferHandle(handle);
148 return RC_ERROR;
149 }
150 void* virAddr = nullptr;
151 buffer->SetVirAddress(virAddr);
152
153 if (handle != nullptr) {
154 FreeBufferHandle(handle);
155 }
156 CAMERA_LOGD("Unmap buffer success.");
157
158 return RC_OK;
159 }
160
FlushCache(std::shared_ptr<IBuffer> & buffer)161 RetCode GrallocBufferAllocator::FlushCache(std::shared_ptr<IBuffer>& buffer)
162 {
163 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_, RC_ERROR);
164 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_->FlushCache, RC_ERROR);
165 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
166 CHECK_IF_NOT_EQUAL_RETURN_VALUE(buffer->GetSourceType(), sourceType_, RC_ERROR);
167
168 BufferHandle* handle = AllocateBufferHandle(0, 0);
169 CHECK_IF_PTR_NULL_RETURN_VALUE(handle, RC_ERROR);
170
171 CameraBufferToGrallocBuffer(buffer, *handle);
172 if (grallocFuncs_->FlushCache(handle) != DISPLAY_SUCCESS) {
173 CAMERA_LOGE("Flush cache buffer failed.");
174 FreeBufferHandle(handle);
175 return RC_ERROR;
176 }
177
178 if (handle != nullptr) {
179 FreeBufferHandle(handle);
180 }
181 return RC_OK;
182 }
183
InvalidateCache(std::shared_ptr<IBuffer> & buffer)184 RetCode GrallocBufferAllocator::InvalidateCache(std::shared_ptr<IBuffer>& buffer)
185 {
186 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_, RC_ERROR);
187 CHECK_IF_PTR_NULL_RETURN_VALUE(grallocFuncs_->InvalidateCache, RC_ERROR);
188 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
189 CHECK_IF_NOT_EQUAL_RETURN_VALUE(buffer->GetSourceType(), sourceType_, RC_ERROR);
190
191 BufferHandle* invalHandle = AllocateBufferHandle(0, 0);
192 CHECK_IF_PTR_NULL_RETURN_VALUE(invalHandle, RC_ERROR);
193
194 CameraBufferToGrallocBuffer(buffer, *invalHandle);
195 if (grallocFuncs_->InvalidateCache(invalHandle) != DISPLAY_SUCCESS) {
196 CAMERA_LOGE("Invalidate cache buffer failed.");
197 FreeBufferHandle(invalHandle);
198 return RC_ERROR;
199 }
200
201 if (invalHandle != nullptr) {
202 FreeBufferHandle(invalHandle);
203 }
204 return RC_OK;
205 }
206
CameraBufferToGrallocBuffer(const std::shared_ptr<IBuffer> & src,BufferHandle & dest) const207 void GrallocBufferAllocator::CameraBufferToGrallocBuffer(const std::shared_ptr<IBuffer>& src, BufferHandle& dest) const
208 {
209 if (src == nullptr || (&dest) == nullptr) {
210 return;
211 }
212
213 dest.phyAddr = src->GetPhyAddress();
214 dest.fd = src->GetFileDescriptor();
215 dest.stride = static_cast<int32_t>(src->GetStride());
216 dest.width = static_cast<int32_t>(src->GetWidth());
217 dest.height = static_cast<int32_t>(src->GetHeight());
218 dest.format = BufferAdapter::CameraFormatToPixelFormat(src->GetFormat());
219 dest.usage =
220 static_cast<uint64_t>(BufferAdapter::CameraUsageToGrallocUsage(src->GetUsage()));
221 dest.size = static_cast<int32_t>(src->GetSize());
222 dest.virAddr = src->GetVirAddress();
223
224 return;
225 }
226
GrallocBufferToCameraBuffer(const BufferHandle & src,std::shared_ptr<IBuffer> & dest) const227 void GrallocBufferAllocator::GrallocBufferToCameraBuffer(const BufferHandle& src, std::shared_ptr<IBuffer>& dest) const
228 {
229 if ((&src) == nullptr || dest == nullptr) {
230 return;
231 }
232
233 dest->SetPhyAddress(src.phyAddr);
234 dest->SetFileDescriptor(src.fd);
235 dest->SetStride(static_cast<uint32_t>(src.stride));
236 dest->SetWidth(static_cast<uint32_t>(src.width));
237 dest->SetHeight(static_cast<uint32_t>(src.height));
238 dest->SetFormat(BufferAdapter::PixelFormatToCameraFormat(static_cast<PixelFormat>(src.format)));
239 dest->SetUsage(BufferAdapter::GrallocUsageToCameraUsage(src.usage));
240 dest->SetSize(static_cast<uint32_t>(src.size));
241 dest->SetVirAddress(src.virAddr);
242
243 return;
244 }
245
246 REGISTER_BUFFER_ALLOCATOR(GrallocBufferAllocator, CAMERA_BUFFER_SOURCE_TYPE_GRALLOC);
247 } // namespace OHOS::Camera
248