1 /*
2 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <gralloc_priv.h>
31
32 #include <core/buffer_allocator.h>
33 #include <utils/constants.h>
34 #include <utils/debug.h>
35
36 #include "gr_utils.h"
37 #include "hwc_buffer_allocator.h"
38 #include "hwc_debugger.h"
39
40 #define __CLASS__ "HWCBufferAllocator"
41
42 using android::hardware::graphics::common::V1_0::PixelFormat;
43 using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
44 using android::hardware::graphics::mapper::V2_0::Error;
45 using android::hardware::hidl_handle;
46 using android::hardware::hidl_vec;
47
48 namespace sdm {
49
GetGrallocInstance()50 DisplayError HWCBufferAllocator::GetGrallocInstance() {
51 // Lazy initialization of gralloc HALs
52 if (mapper_ != nullptr || allocator_ != nullptr) {
53 return kErrorNone;
54 }
55
56 allocator_ = IAllocator::getService();
57 mapper_ = IMapper::getService();
58
59 if (mapper_ == nullptr || allocator_ == nullptr) {
60 DLOGE("Unable to get mapper or allocator");
61 return kErrorCriticalResource;
62 }
63 return kErrorNone;
64 }
65
AllocateBuffer(BufferInfo * buffer_info)66 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
67 auto err = GetGrallocInstance();
68 if (err != kErrorNone) {
69 return err;
70 }
71 const BufferConfig &buffer_config = buffer_info->buffer_config;
72 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
73 int format;
74 uint64_t alloc_flags = 0;
75 int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
76 if (error != 0) {
77 return kErrorParameters;
78 }
79
80 if (buffer_config.secure) {
81 alloc_flags |= BufferUsage::PROTECTED;
82 }
83
84 if (buffer_config.secure_camera) {
85 alloc_flags |= BufferUsage::CAMERA_OUTPUT;
86 }
87
88 if (!buffer_config.cache) {
89 // Allocate uncached buffers
90 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
91 }
92
93 if (buffer_config.gfx_client) {
94 alloc_flags |= BufferUsage::GPU_TEXTURE;
95 }
96
97 alloc_flags |= BufferUsage::COMPOSER_OVERLAY;
98
99 IMapper::BufferDescriptorInfo descriptor_info;
100 descriptor_info.width = buffer_config.width;
101 descriptor_info.height = buffer_config.height;
102 descriptor_info.layerCount = 1;
103 descriptor_info.format = static_cast<PixelFormat>(format);
104 descriptor_info.usage = alloc_flags;
105 auto descriptor = BufferDescriptor();
106 auto hidl_err = Error::NONE;
107
108 mapper_->createDescriptor(descriptor_info, [&](const auto &_error, const auto &_descriptor) {
109 hidl_err = _error;
110 descriptor = _descriptor;
111 });
112 if (hidl_err != Error::NONE) {
113 DLOGE("Failed to create descriptor");
114 return kErrorMemory;
115 }
116
117 hidl_handle raw_handle = nullptr;
118 private_handle_t *hnd = nullptr;
119
120 allocator_->allocate(descriptor, 1,
121 [&](const auto &_error, const auto &_stride, const auto &_buffers) {
122 hidl_err = _error;
123 raw_handle = _buffers[0];
124 });
125 if (hidl_err != Error::NONE) {
126 DLOGE("Failed to allocate buffer");
127 return kErrorMemory;
128 }
129
130 const native_handle_t *buf = nullptr;
131 mapper_->importBuffer(raw_handle, [&](const auto &_error, const auto &_buffer) {
132 hidl_err = _error;
133 buf = static_cast<const native_handle_t *>(_buffer);
134 });
135
136 if (hidl_err != Error::NONE) {
137 DLOGE("Failed to import buffer into HWC");
138 return kErrorMemory;
139 }
140
141 hnd = (private_handle_t *)buf; // NOLINT
142 alloc_buffer_info->fd = hnd->fd;
143 alloc_buffer_info->stride = UINT32(hnd->width);
144 alloc_buffer_info->aligned_width = UINT32(hnd->width);
145 alloc_buffer_info->aligned_height = UINT32(hnd->height);
146 alloc_buffer_info->size = hnd->size;
147 alloc_buffer_info->id = hnd->id;
148
149 buffer_info->private_data = reinterpret_cast<void *>(hnd);
150 return kErrorNone;
151 }
152
FreeBuffer(BufferInfo * buffer_info)153 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
154 DisplayError err = kErrorNone;
155 auto hnd = reinterpret_cast<void *>(buffer_info->private_data);
156 mapper_->freeBuffer(hnd);
157 AllocatedBufferInfo &alloc_buffer_info = buffer_info->alloc_buffer_info;
158
159 alloc_buffer_info.fd = -1;
160 alloc_buffer_info.stride = 0;
161 alloc_buffer_info.size = 0;
162 buffer_info->private_data = NULL;
163 return err;
164 }
165
GetCustomWidthAndHeight(const private_handle_t * handle,int * width,int * height)166 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
167 int *height) {
168 *width = handle->width;
169 *height = handle->height;
170 gralloc::GetCustomDimensions(const_cast<private_handle_t *>(handle), width, height);
171 }
172
GetAlignedWidthAndHeight(int width,int height,int format,uint32_t alloc_type,int * aligned_width,int * aligned_height)173 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
174 uint32_t alloc_type, int *aligned_width,
175 int *aligned_height) {
176 uint64_t usage = 0;
177 if (alloc_type & GRALLOC_USAGE_HW_FB) {
178 usage |= BufferUsage::COMPOSER_CLIENT_TARGET;
179 }
180 if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
181 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
182 }
183 uint32_t aligned_w = UINT(width);
184 uint32_t aligned_h = UINT(height);
185 gralloc::BufferInfo info(width, height, format, usage);
186 gralloc::GetAlignedWidthAndHeight(info, &aligned_w, &aligned_h);
187 *aligned_width = INT(aligned_w);
188 *aligned_height = INT(aligned_h);
189 }
190
GetBufferSize(BufferInfo * buffer_info)191 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
192 const BufferConfig &buffer_config = buffer_info->buffer_config;
193 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
194
195 int width = INT(buffer_config.width);
196 int height = INT(buffer_config.height);
197 int format;
198
199 if (buffer_config.secure) {
200 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
201 }
202
203 if (!buffer_config.cache) {
204 // Allocate uncached buffers
205 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
206 }
207
208 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
209 return 0;
210 }
211
212 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
213 gralloc::BufferInfo info(width, height, format, alloc_flags);
214 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
215 return buffer_size;
216 }
217
SetBufferInfo(LayerBufferFormat format,int * target,uint64_t * flags)218 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
219 switch (format) {
220 case kFormatRGBA8888:
221 *target = HAL_PIXEL_FORMAT_RGBA_8888;
222 break;
223 case kFormatRGBX8888:
224 *target = HAL_PIXEL_FORMAT_RGBX_8888;
225 break;
226 case kFormatRGB888:
227 *target = HAL_PIXEL_FORMAT_RGB_888;
228 break;
229 case kFormatRGB565:
230 *target = HAL_PIXEL_FORMAT_RGB_565;
231 break;
232 case kFormatBGR565:
233 *target = HAL_PIXEL_FORMAT_BGR_565;
234 break;
235 case kFormatBGR888:
236 *target = HAL_PIXEL_FORMAT_BGR_888;
237 break;
238 case kFormatBGRA8888:
239 *target = HAL_PIXEL_FORMAT_BGRA_8888;
240 break;
241 case kFormatYCrCb420PlanarStride16:
242 *target = HAL_PIXEL_FORMAT_YV12;
243 break;
244 case kFormatYCrCb420SemiPlanar:
245 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
246 break;
247 case kFormatYCbCr420SemiPlanar:
248 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
249 break;
250 case kFormatYCbCr422H2V1Packed:
251 *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
252 break;
253 case kFormatCbYCrY422H2V1Packed:
254 *target = HAL_PIXEL_FORMAT_CbYCrY_422_I;
255 break;
256 case kFormatYCbCr422H2V1SemiPlanar:
257 *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
258 break;
259 case kFormatYCbCr420SemiPlanarVenus:
260 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
261 break;
262 case kFormatYCrCb420SemiPlanarVenus:
263 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
264 break;
265 case kFormatYCbCr420SPVenusUbwc:
266 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
267 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
268 break;
269 case kFormatRGBA5551:
270 *target = HAL_PIXEL_FORMAT_RGBA_5551;
271 break;
272 case kFormatRGBA4444:
273 *target = HAL_PIXEL_FORMAT_RGBA_4444;
274 break;
275 case kFormatRGBA1010102:
276 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
277 break;
278 case kFormatARGB2101010:
279 *target = HAL_PIXEL_FORMAT_ARGB_2101010;
280 break;
281 case kFormatRGBX1010102:
282 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
283 break;
284 case kFormatXRGB2101010:
285 *target = HAL_PIXEL_FORMAT_XRGB_2101010;
286 break;
287 case kFormatBGRA1010102:
288 *target = HAL_PIXEL_FORMAT_BGRA_1010102;
289 break;
290 case kFormatABGR2101010:
291 *target = HAL_PIXEL_FORMAT_ABGR_2101010;
292 break;
293 case kFormatBGRX1010102:
294 *target = HAL_PIXEL_FORMAT_BGRX_1010102;
295 break;
296 case kFormatXBGR2101010:
297 *target = HAL_PIXEL_FORMAT_XBGR_2101010;
298 break;
299 case kFormatYCbCr420P010:
300 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
301 break;
302 case kFormatYCbCr420TP10Ubwc:
303 *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
304 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
305 break;
306 case kFormatYCbCr420P010Ubwc:
307 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
308 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
309 break;
310 case kFormatYCbCr420P010Venus:
311 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
312 break;
313 case kFormatRGBA8888Ubwc:
314 *target = HAL_PIXEL_FORMAT_RGBA_8888;
315 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
316 break;
317 case kFormatRGBX8888Ubwc:
318 *target = HAL_PIXEL_FORMAT_RGBX_8888;
319 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
320 break;
321 case kFormatBGR565Ubwc:
322 *target = HAL_PIXEL_FORMAT_BGR_565;
323 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
324 break;
325 case kFormatRGBA1010102Ubwc:
326 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
327 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
328 break;
329 case kFormatRGBX1010102Ubwc:
330 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
331 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
332 break;
333 default:
334 DLOGE("Unsupported format = 0x%x", format);
335 return -EINVAL;
336 }
337 return 0;
338 }
339
GetAllocatedBufferInfo(const BufferConfig & buffer_config,AllocatedBufferInfo * allocated_buffer_info)340 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
341 const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
342 // TODO(user): This API should pass the buffer_info of the already allocated buffer
343 // The private_data can then be typecast to the private_handle and used directly.
344 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
345
346 int width = INT(buffer_config.width);
347 int height = INT(buffer_config.height);
348 int format;
349
350 if (buffer_config.secure) {
351 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
352 }
353
354 if (!buffer_config.cache) {
355 // Allocate uncached buffers
356 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
357 }
358
359 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
360 return kErrorParameters;
361 }
362
363 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
364 gralloc::BufferInfo info(width, height, format, alloc_flags);
365 GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
366 allocated_buffer_info->stride = UINT32(aligned_width);
367 allocated_buffer_info->aligned_width = UINT32(aligned_width);
368 allocated_buffer_info->aligned_height = UINT32(aligned_height);
369 allocated_buffer_info->size = UINT32(buffer_size);
370
371 return kErrorNone;
372 }
373
GetBufferLayout(const AllocatedBufferInfo & buf_info,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)374 DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
375 uint32_t stride[4], uint32_t offset[4],
376 uint32_t *num_planes) {
377 // TODO(user): Transition APIs to not need a private handle
378 private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
379 int format = HAL_PIXEL_FORMAT_RGBA_8888;
380 uint64_t flags = 0;
381
382 SetBufferInfo(buf_info.format, &format, &flags);
383 // Setup only the required stuff, skip rest
384 hnd.format = format;
385 hnd.width = INT32(buf_info.aligned_width);
386 hnd.height = INT32(buf_info.aligned_height);
387 if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
388 hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
389 }
390
391 int ret = gralloc::GetBufferLayout(&hnd, stride, offset, num_planes);
392 if (ret < 0) {
393 DLOGE("GetBufferLayout failed");
394 return kErrorParameters;
395 }
396
397 return kErrorNone;
398 }
399
MapBuffer(const private_handle_t * handle,int acquire_fence)400 DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
401 auto err = GetGrallocInstance();
402 if (err != kErrorNone) {
403 return err;
404 }
405 void *buffer_ptr = NULL;
406 const IMapper::Rect access_region = {.left = 0, .top = 0, .width = 0, .height = 0};
407
408 NATIVE_HANDLE_DECLARE_STORAGE(acquire_fence_storage, 1, 0);
409 hidl_handle acquire_fence_handle;
410 if (acquire_fence >= 0) {
411 auto h = native_handle_init(acquire_fence_storage, 1, 0);
412 h->data[0] = acquire_fence;
413 acquire_fence_handle = h;
414 }
415
416 auto hnd = const_cast<private_handle_t *>(handle);
417 mapper_->lock(reinterpret_cast<void *>(hnd), (uint64_t)BufferUsage::CPU_READ_OFTEN,
418 access_region, acquire_fence_handle, [&](const auto &_error, const auto &_buffer) {
419 if (_error == Error::NONE) {
420 buffer_ptr = _buffer;
421 }
422 });
423
424 if (!buffer_ptr) {
425 return kErrorUndefined;
426 }
427 return kErrorNone;
428 }
429
UnmapBuffer(const private_handle_t * handle,int * release_fence)430 DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int *release_fence) {
431 DisplayError err = kErrorNone;
432 *release_fence = -1;
433 auto hnd = const_cast<private_handle_t *>(handle);
434 mapper_->unlock(reinterpret_cast<void *>(hnd),
435 [&](const auto &_error, const auto &_release_fence) {
436 if (_error != Error::NONE) {
437 err = kErrorUndefined;
438 }
439 });
440 return err;
441 }
442
443 } // namespace sdm
444