• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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