1 /*
2 * Copyright (c) 2015-2019, 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::mapper::V2_0::Error;
43 using MapperV3Error = android::hardware::graphics::mapper::V3_0::Error;
44 using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
45 using MapperV3BufferDescriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
46 using android::hardware::hidl_handle;
47 using android::hardware::hidl_vec;
48
49 namespace sdm {
50
GetGrallocInstance()51 DisplayError HWCBufferAllocator::GetGrallocInstance() {
52 // Lazy initialization of gralloc HALs
53 if (mapper_V3_ != nullptr || mapper_V2_ != nullptr || allocator_V3_ != nullptr ||
54 allocator_V2_ != nullptr) {
55 return kErrorNone;
56 }
57
58 allocator_V3_ = IAllocatorV3::getService();
59 if (allocator_V3_ == nullptr) {
60 allocator_V2_ = IAllocatorV2::getService();
61 if (allocator_V2_ == nullptr) {
62 DLOGE("Unable to get allocator");
63 return kErrorCriticalResource;
64 }
65 }
66
67 mapper_V3_ = IMapperV3::getService();
68 if (mapper_V3_ == nullptr) {
69 mapper_V2_ = IMapperV2::getService();
70 if (mapper_V2_ == nullptr) {
71 DLOGE("Unable to get mapper");
72 return kErrorCriticalResource;
73 }
74 }
75
76 return kErrorNone;
77 }
78
AllocateBuffer(BufferInfo * buffer_info)79 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
80 auto err = GetGrallocInstance();
81 if (err != kErrorNone) {
82 return err;
83 }
84 const BufferConfig &buffer_config = buffer_info->buffer_config;
85 AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
86 int format;
87 uint64_t alloc_flags = 0;
88 int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
89 if (error != 0) {
90 return kErrorParameters;
91 }
92
93 if (buffer_config.secure) {
94 alloc_flags |= BufferUsage::PROTECTED;
95 }
96
97 if (buffer_config.secure_camera) {
98 alloc_flags |= BufferUsage::CAMERA_OUTPUT;
99 }
100
101 if (!buffer_config.cache) {
102 // Allocate uncached buffers
103 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
104 }
105
106 if (buffer_config.gfx_client) {
107 alloc_flags |= BufferUsage::GPU_TEXTURE;
108 }
109
110 alloc_flags |= BufferUsage::COMPOSER_OVERLAY;
111
112 const native_handle_t *buf = nullptr;
113
114 if (mapper_V3_ != nullptr) {
115 IMapperV3::BufferDescriptorInfo descriptor_info;
116 descriptor_info.width = buffer_config.width;
117 descriptor_info.height = buffer_config.height;
118 descriptor_info.layerCount = 1;
119 descriptor_info.format =
120 static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
121 descriptor_info.usage = alloc_flags;
122
123 auto hidl_err = MapperV3Error::NONE;
124
125 auto descriptor = BufferDescriptor();
126 mapper_V3_->createDescriptor(descriptor_info, [&](const auto &_error, const auto &_descriptor) {
127 hidl_err = _error;
128 if (hidl_err != MapperV3Error::NONE) {
129 return;
130 }
131 descriptor = _descriptor;
132 });
133
134 if (hidl_err != MapperV3Error::NONE) {
135 DLOGE("Failed to create descriptor");
136 return kErrorMemory;
137 }
138
139 hidl_handle raw_handle = nullptr;
140
141 allocator_V3_->allocate(descriptor, 1,
142 [&](const auto &_error, const auto &_stride, const auto &_buffers) {
143 hidl_err = _error;
144 if (hidl_err != MapperV3Error::NONE) {
145 return;
146 }
147 raw_handle = _buffers[0];
148 });
149
150 if (hidl_err != MapperV3Error::NONE) {
151 DLOGE("Failed to allocate buffer");
152 return kErrorMemory;
153 }
154
155 mapper_V3_->importBuffer(raw_handle, [&](const auto &_error, const auto &_buffer) {
156 hidl_err = _error;
157 if (hidl_err != MapperV3Error::NONE) {
158 return;
159 }
160 buf = static_cast<const native_handle_t *>(_buffer);
161 });
162
163 if (hidl_err != MapperV3Error::NONE) {
164 DLOGE("Failed to import buffer into HWC");
165 return kErrorMemory;
166 }
167 } else {
168 IMapperV2::BufferDescriptorInfo descriptor_info;
169 descriptor_info.width = buffer_config.width;
170 descriptor_info.height = buffer_config.height;
171 descriptor_info.layerCount = 1;
172 descriptor_info.format =
173 static_cast<android::hardware::graphics::common::V1_0::PixelFormat>(format);
174 descriptor_info.usage = alloc_flags;
175
176 auto hidl_err = Error::NONE;
177
178 auto descriptor = BufferDescriptor();
179 mapper_V2_->createDescriptor(descriptor_info, [&](const auto &_error, const auto &_descriptor) {
180 hidl_err = _error;
181 if (hidl_err != Error::NONE) {
182 return;
183 }
184 descriptor = _descriptor;
185 });
186
187 if (hidl_err != Error::NONE) {
188 DLOGE("Failed to create descriptor");
189 return kErrorMemory;
190 }
191
192 hidl_handle raw_handle = nullptr;
193
194 allocator_V2_->allocate(descriptor, 1,
195 [&](const auto &_error, const auto &_stride, const auto &_buffers) {
196 hidl_err = _error;
197 if (hidl_err != Error::NONE) {
198 return;
199 }
200 raw_handle = _buffers[0];
201 });
202
203 if (hidl_err != Error::NONE) {
204 DLOGE("Failed to allocate buffer");
205 return kErrorMemory;
206 }
207
208 mapper_V2_->importBuffer(raw_handle, [&](const auto &_error, const auto &_buffer) {
209 hidl_err = _error;
210 if (hidl_err != Error::NONE) {
211 return;
212 }
213 buf = static_cast<const native_handle_t *>(_buffer);
214 });
215
216 if (hidl_err != Error::NONE) {
217 DLOGE("Failed to import buffer into HWC");
218 return kErrorMemory;
219 }
220 }
221
222 private_handle_t *hnd = nullptr;
223 hnd = (private_handle_t *)buf; // NOLINT
224 alloc_buffer_info->fd = hnd->fd;
225 alloc_buffer_info->stride = UINT32(hnd->width);
226 alloc_buffer_info->aligned_width = UINT32(hnd->width);
227 alloc_buffer_info->aligned_height = UINT32(hnd->height);
228 alloc_buffer_info->size = hnd->size;
229 alloc_buffer_info->id = hnd->id;
230
231 buffer_info->private_data = reinterpret_cast<void *>(hnd);
232 return kErrorNone;
233 }
234
FreeBuffer(BufferInfo * buffer_info)235 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
236 DisplayError err = kErrorNone;
237 auto hnd = reinterpret_cast<void *>(buffer_info->private_data);
238 if (mapper_V3_ != nullptr) {
239 mapper_V3_->freeBuffer(hnd);
240 } else {
241 mapper_V2_->freeBuffer(hnd);
242 }
243 AllocatedBufferInfo &alloc_buffer_info = buffer_info->alloc_buffer_info;
244
245 alloc_buffer_info.fd = -1;
246 alloc_buffer_info.stride = 0;
247 alloc_buffer_info.size = 0;
248 buffer_info->private_data = NULL;
249 return err;
250 }
251
GetCustomWidthAndHeight(const private_handle_t * handle,int * width,int * height)252 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
253 int *height) {
254 *width = handle->width;
255 *height = handle->height;
256 gralloc::GetCustomDimensions(const_cast<private_handle_t *>(handle), width, height);
257 }
258
GetAlignedWidthAndHeight(int width,int height,int format,uint32_t alloc_type,int * aligned_width,int * aligned_height)259 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
260 uint32_t alloc_type, int *aligned_width,
261 int *aligned_height) {
262 uint64_t usage = 0;
263 if (alloc_type & GRALLOC_USAGE_HW_FB) {
264 usage |= BufferUsage::COMPOSER_CLIENT_TARGET;
265 }
266 if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
267 usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
268 }
269 uint32_t aligned_w = UINT(width);
270 uint32_t aligned_h = UINT(height);
271 gralloc::BufferInfo info(width, height, format, usage);
272 gralloc::GetAlignedWidthAndHeight(info, &aligned_w, &aligned_h);
273 *aligned_width = INT(aligned_w);
274 *aligned_height = INT(aligned_h);
275 }
276
GetBufferSize(BufferInfo * buffer_info)277 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
278 const BufferConfig &buffer_config = buffer_info->buffer_config;
279 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
280
281 int width = INT(buffer_config.width);
282 int height = INT(buffer_config.height);
283 int format;
284
285 if (buffer_config.secure) {
286 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
287 }
288
289 if (!buffer_config.cache) {
290 // Allocate uncached buffers
291 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
292 }
293
294 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
295 return 0;
296 }
297
298 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
299 gralloc::BufferInfo info(width, height, format, alloc_flags);
300 int ret = GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
301 if (ret < 0) {
302 return 0;
303 }
304 return buffer_size;
305 }
306
SetBufferInfo(LayerBufferFormat format,int * target,uint64_t * flags)307 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
308 switch (format) {
309 case kFormatRGBA8888:
310 *target = HAL_PIXEL_FORMAT_RGBA_8888;
311 break;
312 case kFormatRGBX8888:
313 *target = HAL_PIXEL_FORMAT_RGBX_8888;
314 break;
315 case kFormatRGB888:
316 *target = HAL_PIXEL_FORMAT_RGB_888;
317 break;
318 case kFormatRGB565:
319 *target = HAL_PIXEL_FORMAT_RGB_565;
320 break;
321 case kFormatBGR565:
322 *target = HAL_PIXEL_FORMAT_BGR_565;
323 break;
324 case kFormatBGR888:
325 *target = HAL_PIXEL_FORMAT_BGR_888;
326 break;
327 case kFormatBGRA8888:
328 *target = HAL_PIXEL_FORMAT_BGRA_8888;
329 break;
330 case kFormatYCrCb420PlanarStride16:
331 *target = HAL_PIXEL_FORMAT_YV12;
332 break;
333 case kFormatYCrCb420SemiPlanar:
334 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
335 break;
336 case kFormatYCbCr420SemiPlanar:
337 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
338 break;
339 case kFormatYCbCr422H2V1Packed:
340 *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
341 break;
342 case kFormatCbYCrY422H2V1Packed:
343 *target = HAL_PIXEL_FORMAT_CbYCrY_422_I;
344 break;
345 case kFormatYCbCr422H2V1SemiPlanar:
346 *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
347 break;
348 case kFormatYCbCr420SemiPlanarVenus:
349 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
350 break;
351 case kFormatYCrCb420SemiPlanarVenus:
352 *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
353 break;
354 case kFormatYCbCr420SPVenusUbwc:
355 case kFormatYCbCr420SPVenusTile:
356 *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
357 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
358 break;
359 case kFormatRGBA5551:
360 *target = HAL_PIXEL_FORMAT_RGBA_5551;
361 break;
362 case kFormatRGBA4444:
363 *target = HAL_PIXEL_FORMAT_RGBA_4444;
364 break;
365 case kFormatRGBA1010102:
366 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
367 break;
368 case kFormatARGB2101010:
369 *target = HAL_PIXEL_FORMAT_ARGB_2101010;
370 break;
371 case kFormatRGBX1010102:
372 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
373 break;
374 case kFormatXRGB2101010:
375 *target = HAL_PIXEL_FORMAT_XRGB_2101010;
376 break;
377 case kFormatBGRA1010102:
378 *target = HAL_PIXEL_FORMAT_BGRA_1010102;
379 break;
380 case kFormatABGR2101010:
381 *target = HAL_PIXEL_FORMAT_ABGR_2101010;
382 break;
383 case kFormatBGRX1010102:
384 *target = HAL_PIXEL_FORMAT_BGRX_1010102;
385 break;
386 case kFormatXBGR2101010:
387 *target = HAL_PIXEL_FORMAT_XBGR_2101010;
388 break;
389 case kFormatYCbCr420P010:
390 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
391 break;
392 case kFormatYCbCr420TP10Ubwc:
393 case kFormatYCbCr420TP10Tile:
394 *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
395 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
396 break;
397 case kFormatYCbCr420P010Ubwc:
398 case kFormatYCbCr420P010Tile:
399 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
400 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
401 break;
402 case kFormatYCbCr420P010Venus:
403 *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
404 break;
405 case kFormatRGBA8888Ubwc:
406 *target = HAL_PIXEL_FORMAT_RGBA_8888;
407 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
408 break;
409 case kFormatRGBX8888Ubwc:
410 *target = HAL_PIXEL_FORMAT_RGBX_8888;
411 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
412 break;
413 case kFormatBGR565Ubwc:
414 *target = HAL_PIXEL_FORMAT_BGR_565;
415 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
416 break;
417 case kFormatRGBA1010102Ubwc:
418 *target = HAL_PIXEL_FORMAT_RGBA_1010102;
419 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
420 break;
421 case kFormatRGBX1010102Ubwc:
422 *target = HAL_PIXEL_FORMAT_RGBX_1010102;
423 *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
424 break;
425 default:
426 DLOGE("Unsupported format = 0x%x", format);
427 return -EINVAL;
428 }
429 return 0;
430 }
431
GetAllocatedBufferInfo(const BufferConfig & buffer_config,AllocatedBufferInfo * allocated_buffer_info)432 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
433 const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
434 // TODO(user): This API should pass the buffer_info of the already allocated buffer
435 // The private_data can then be typecast to the private_handle and used directly.
436 uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
437
438 int width = INT(buffer_config.width);
439 int height = INT(buffer_config.height);
440 int format;
441
442 if (buffer_config.secure) {
443 alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
444 }
445
446 if (!buffer_config.cache) {
447 // Allocate uncached buffers
448 alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
449 }
450
451 if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
452 return kErrorParameters;
453 }
454
455 uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
456 gralloc::BufferInfo info(width, height, format, alloc_flags);
457 int ret = GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
458 if (ret < 0) {
459 return kErrorParameters;
460 }
461 allocated_buffer_info->stride = UINT32(aligned_width);
462 allocated_buffer_info->aligned_width = UINT32(aligned_width);
463 allocated_buffer_info->aligned_height = UINT32(aligned_height);
464 allocated_buffer_info->size = UINT32(buffer_size);
465
466 return kErrorNone;
467 }
468
GetBufferLayout(const AllocatedBufferInfo & buf_info,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)469 DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
470 uint32_t stride[4], uint32_t offset[4],
471 uint32_t *num_planes) {
472 // TODO(user): Transition APIs to not need a private handle
473 private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
474 int format = HAL_PIXEL_FORMAT_RGBA_8888;
475 uint64_t flags = 0;
476
477 SetBufferInfo(buf_info.format, &format, &flags);
478 // Setup only the required stuff, skip rest
479 hnd.format = format;
480 hnd.width = INT32(buf_info.aligned_width);
481 hnd.height = INT32(buf_info.aligned_height);
482 if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
483 hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
484 }
485
486 int ret = gralloc::GetBufferLayout(&hnd, stride, offset, num_planes);
487 if (ret < 0) {
488 DLOGE("GetBufferLayout failed");
489 return kErrorParameters;
490 }
491
492 return kErrorNone;
493 }
494
MapBuffer(const private_handle_t * handle,int acquire_fence)495 DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
496 auto err = GetGrallocInstance();
497 if (err != kErrorNone) {
498 return err;
499 }
500 NATIVE_HANDLE_DECLARE_STORAGE(acquire_fence_storage, 1, 0);
501 hidl_handle acquire_fence_handle;
502 if (acquire_fence >= 0) {
503 auto h = native_handle_init(acquire_fence_storage, 1, 0);
504 h->data[0] = acquire_fence;
505 acquire_fence_handle = h;
506 }
507
508 auto hnd = const_cast<private_handle_t *>(handle);
509 void *buffer_ptr = NULL;
510 if (mapper_V3_ != nullptr) {
511 const IMapperV3::Rect access_region = {.left = 0, .top = 0, .width = 0, .height = 0};
512 mapper_V3_->lock(
513 reinterpret_cast<void *>(hnd), (uint64_t)BufferUsage::CPU_READ_OFTEN, access_region,
514 acquire_fence_handle,
515 [&](const auto &_error, const auto &_buffer, const auto &_bpp, const auto &_stride) {
516 if (_error == MapperV3Error::NONE) {
517 buffer_ptr = _buffer;
518 }
519 });
520 } else {
521 const IMapperV2::Rect access_region = {.left = 0, .top = 0, .width = 0, .height = 0};
522 mapper_V2_->lock(reinterpret_cast<void *>(hnd), (uint64_t)BufferUsage::CPU_READ_OFTEN,
523 access_region, acquire_fence_handle,
524 [&](const auto &_error, const auto &_buffer) {
525 if (_error == Error::NONE) {
526 buffer_ptr = _buffer;
527 }
528 });
529 }
530 if (!buffer_ptr) {
531 return kErrorUndefined;
532 }
533 return kErrorNone;
534 }
535
UnmapBuffer(const private_handle_t * handle,int * release_fence)536 DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int *release_fence) {
537 DisplayError err = kErrorNone;
538 *release_fence = -1;
539 auto hnd = const_cast<private_handle_t *>(handle);
540 if (mapper_V3_ != nullptr) {
541 mapper_V3_->unlock(reinterpret_cast<void *>(hnd),
542 [&](const auto &_error, const auto &_release_fence) {
543 if (_error != MapperV3Error::NONE) {
544 err = kErrorUndefined;
545 }
546 });
547 } else {
548 mapper_V2_->unlock(reinterpret_cast<void *>(hnd),
549 [&](const auto &_error, const auto &_release_fence) {
550 if (_error != Error::NONE) {
551 err = kErrorUndefined;
552 }
553 });
554 }
555 return err;
556 }
557
558 } // namespace sdm
559