1 /*
2 * Copyright (c) 2015-2017, 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 "hwc_buffer_allocator.h"
37 #include "hwc_debugger.h"
38 #include "gr_utils.h"
39 
40 #define __CLASS__ "HWCBufferAllocator"
41 
42 namespace sdm {
43 
Init()44 DisplayError HWCBufferAllocator::Init() {
45   int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
46   if (err != 0) {
47     DLOGE("FATAL: can not get GRALLOC module");
48     return kErrorResources;
49   }
50 
51   err = gralloc1_open(module_, &gralloc_device_);
52   if (err != 0) {
53     DLOGE("FATAL: can not open GRALLOC device");
54     return kErrorResources;
55   }
56 
57   if (gralloc_device_ == nullptr) {
58     DLOGE("FATAL: gralloc device is null");
59     return kErrorResources;
60   }
61 
62   ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
63       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
64   Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
65       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
66   Lock_ = reinterpret_cast<GRALLOC1_PFN_LOCK>(
67       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_LOCK));
68   Unlock_ = reinterpret_cast<GRALLOC1_PFN_UNLOCK>(
69       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_UNLOCK));
70 
71   return kErrorNone;
72 }
73 
Deinit()74 DisplayError HWCBufferAllocator::Deinit() {
75   if (gralloc_device_ != nullptr) {
76     int err = gralloc1_close(gralloc_device_);
77     if (err != 0) {
78       DLOGE("FATAL: can not close GRALLOC device");
79       return kErrorResources;
80     }
81   }
82   return kErrorNone;
83 }
84 
AllocateBuffer(BufferInfo * buffer_info)85 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
86   const BufferConfig &buffer_config = buffer_info->buffer_config;
87   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
88   uint32_t width = buffer_config.width;
89   uint32_t height = buffer_config.height;
90   int format;
91   uint64_t alloc_flags = 0;
92   int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
93   if (error != 0) {
94     return kErrorParameters;
95   }
96 
97   if (buffer_config.secure) {
98     alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
99   }
100 
101   if (buffer_config.secure_camera) {
102     alloc_flags |= GRALLOC1_PRODUCER_USAGE_CAMERA;
103   }
104 
105   if (!buffer_config.cache) {
106     // Allocate uncached buffers
107     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
108   }
109 
110   if (buffer_config.gfx_client) {
111     alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
112   }
113 
114   uint64_t producer_usage = alloc_flags;
115   uint64_t consumer_usage = (alloc_flags | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
116   // CreateBuffer
117   private_handle_t *hnd = nullptr;
118   Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
119            producer_usage, consumer_usage, &hnd);
120 
121   if (hnd) {
122     alloc_buffer_info->fd = hnd->fd;
123     alloc_buffer_info->stride = UINT32(hnd->width);
124     alloc_buffer_info->aligned_width = UINT32(hnd->width);
125     alloc_buffer_info->aligned_height = UINT32(hnd->height);
126     alloc_buffer_info->size = hnd->size;
127   } else {
128     DLOGE("Failed to allocate memory");
129     return kErrorMemory;
130   }
131 
132   buffer_info->private_data = reinterpret_cast<void *>(hnd);
133   return kErrorNone;
134 }
135 
FreeBuffer(BufferInfo * buffer_info)136 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
137   DisplayError err = kErrorNone;
138   buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
139   ReleaseBuffer_(gralloc_device_, hnd);
140   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
141 
142   alloc_buffer_info->fd = -1;
143   alloc_buffer_info->stride = 0;
144   alloc_buffer_info->size = 0;
145   buffer_info->private_data = NULL;
146   return err;
147 }
148 
GetCustomWidthAndHeight(const private_handle_t * handle,int * width,int * height)149 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
150                                                  int *height) {
151   Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle,
152            width, height);
153 }
154 
GetAlignedWidthAndHeight(int width,int height,int format,uint32_t alloc_type,int * aligned_width,int * aligned_height)155 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
156                                                   uint32_t alloc_type, int *aligned_width,
157                                                   int *aligned_height) {
158   int tile_enabled;
159   gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
160   gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
161   if (alloc_type & GRALLOC_USAGE_HW_FB) {
162     consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
163   }
164   if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
165     producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
166   }
167 
168   Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
169            producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
170 }
171 
GetBufferSize(BufferInfo * buffer_info)172 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
173   const BufferConfig &buffer_config = buffer_info->buffer_config;
174   uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
175 
176   int width = INT(buffer_config.width);
177   int height = INT(buffer_config.height);
178   int format;
179 
180   if (buffer_config.secure) {
181     alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
182   }
183 
184   if (!buffer_config.cache) {
185     // Allocate uncached buffers
186     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
187   }
188 
189   if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
190     return 0;
191   }
192 
193   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
194   gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
195   gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
196   // TODO(user): Currently both flags are treated similarly in gralloc
197   producer_usage = gralloc1_producer_usage_t(alloc_flags);
198   consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
199   gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
200   GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
201   return buffer_size;
202 }
203 
SetBufferInfo(LayerBufferFormat format,int * target,uint64_t * flags)204 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, uint64_t *flags) {
205   switch (format) {
206     case kFormatRGBA8888:
207       *target = HAL_PIXEL_FORMAT_RGBA_8888;
208       break;
209     case kFormatRGBX8888:
210       *target = HAL_PIXEL_FORMAT_RGBX_8888;
211       break;
212     case kFormatRGB888:
213       *target = HAL_PIXEL_FORMAT_RGB_888;
214       break;
215     case kFormatRGB565:
216       *target = HAL_PIXEL_FORMAT_RGB_565;
217       break;
218     case kFormatBGR565:
219       *target = HAL_PIXEL_FORMAT_BGR_565;
220       break;
221     case kFormatBGR888:
222       *target = HAL_PIXEL_FORMAT_BGR_888;
223       break;
224     case kFormatBGRA8888:
225       *target = HAL_PIXEL_FORMAT_BGRA_8888;
226       break;
227     case kFormatYCrCb420PlanarStride16:
228       *target = HAL_PIXEL_FORMAT_YV12;
229       break;
230     case kFormatYCrCb420SemiPlanar:
231       *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
232       break;
233     case kFormatYCbCr420SemiPlanar:
234       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
235       break;
236     case kFormatYCbCr422H2V1Packed:
237       *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
238       break;
239     case kFormatCbYCrY422H2V1Packed:
240       *target = HAL_PIXEL_FORMAT_CbYCrY_422_I;
241       break;
242     case kFormatYCbCr422H2V1SemiPlanar:
243       *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
244       break;
245     case kFormatYCbCr420SemiPlanarVenus:
246       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
247       break;
248     case kFormatYCrCb420SemiPlanarVenus:
249       *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
250       break;
251     case kFormatYCbCr420SPVenusUbwc:
252       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
253       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
254       break;
255     case kFormatRGBA5551:
256       *target = HAL_PIXEL_FORMAT_RGBA_5551;
257       break;
258     case kFormatRGBA4444:
259       *target = HAL_PIXEL_FORMAT_RGBA_4444;
260       break;
261     case kFormatRGBA1010102:
262       *target = HAL_PIXEL_FORMAT_RGBA_1010102;
263       break;
264     case kFormatARGB2101010:
265       *target = HAL_PIXEL_FORMAT_ARGB_2101010;
266       break;
267     case kFormatRGBX1010102:
268       *target = HAL_PIXEL_FORMAT_RGBX_1010102;
269       break;
270     case kFormatXRGB2101010:
271       *target = HAL_PIXEL_FORMAT_XRGB_2101010;
272       break;
273     case kFormatBGRA1010102:
274       *target = HAL_PIXEL_FORMAT_BGRA_1010102;
275       break;
276     case kFormatABGR2101010:
277       *target = HAL_PIXEL_FORMAT_ABGR_2101010;
278       break;
279     case kFormatBGRX1010102:
280       *target = HAL_PIXEL_FORMAT_BGRX_1010102;
281       break;
282     case kFormatXBGR2101010:
283       *target = HAL_PIXEL_FORMAT_XBGR_2101010;
284       break;
285     case kFormatYCbCr420P010:
286       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
287       break;
288     case kFormatYCbCr420TP10Ubwc:
289       *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
290       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
291       break;
292     case kFormatYCbCr420P010Ubwc:
293       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
294       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
295       break;
296     case kFormatRGBA8888Ubwc:
297       *target = HAL_PIXEL_FORMAT_RGBA_8888;
298       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
299       break;
300     case kFormatRGBX8888Ubwc:
301       *target = HAL_PIXEL_FORMAT_RGBX_8888;
302       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
303       break;
304     case kFormatBGR565Ubwc:
305       *target = HAL_PIXEL_FORMAT_BGR_565;
306       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
307       break;
308     case kFormatRGBA1010102Ubwc:
309       *target = HAL_PIXEL_FORMAT_RGBA_1010102;
310       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
311       break;
312     case kFormatRGBX1010102Ubwc:
313       *target = HAL_PIXEL_FORMAT_RGBX_1010102;
314       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
315       break;
316     default:
317       DLOGE("Unsupported format = 0x%x", format);
318       return -EINVAL;
319   }
320   return 0;
321 }
322 
GetAllocatedBufferInfo(const BufferConfig & buffer_config,AllocatedBufferInfo * allocated_buffer_info)323 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
324     const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
325   // TODO(user): This API should pass the buffer_info of the already allocated buffer
326   // The private_data can then be typecast to the private_handle and used directly.
327   uint64_t alloc_flags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
328 
329   int width = INT(buffer_config.width);
330   int height = INT(buffer_config.height);
331   int format;
332 
333   if (buffer_config.secure) {
334     alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
335   }
336 
337   if (!buffer_config.cache) {
338     // Allocate uncached buffers
339     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
340   }
341 
342   if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
343     return kErrorParameters;
344   }
345 
346   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
347   gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
348   gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
349   // TODO(user): Currently both flags are treated similarly in gralloc
350   producer_usage = gralloc1_producer_usage_t(alloc_flags);
351   consumer_usage = gralloc1_consumer_usage_t(alloc_flags);
352   gralloc1::BufferInfo info(width, height, format, producer_usage, consumer_usage);
353   GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
354   allocated_buffer_info->stride = UINT32(aligned_width);
355   allocated_buffer_info->aligned_width = UINT32(aligned_width);
356   allocated_buffer_info->aligned_height = UINT32(aligned_height);
357   allocated_buffer_info->size = UINT32(buffer_size);
358 
359   return kErrorNone;
360 }
361 
GetBufferLayout(const AllocatedBufferInfo & buf_info,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)362 DisplayError HWCBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info,
363                                                  uint32_t stride[4], uint32_t offset[4],
364                                                  uint32_t *num_planes) {
365   // TODO(user): Transition APIs to not need a private handle
366   private_handle_t hnd(-1, 0, 0, 0, 0, 0, 0);
367   int format = HAL_PIXEL_FORMAT_RGBA_8888;
368   uint64_t flags = 0;
369 
370   SetBufferInfo(buf_info.format, &format, &flags);
371   // Setup only the required stuff, skip rest
372   hnd.format = format;
373   hnd.width = INT32(buf_info.aligned_width);
374   hnd.height = INT32(buf_info.aligned_height);
375   if (flags & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
376     hnd.flags = private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
377   }
378 
379   int ret = gralloc1::GetBufferLayout(&hnd, stride, offset, num_planes);
380   if (ret < 0) {
381     DLOGE("GetBufferLayout failed");
382     return kErrorParameters;
383   }
384 
385   return kErrorNone;
386 }
387 
MapBuffer(const private_handle_t * handle,int acquire_fence)388 DisplayError HWCBufferAllocator::MapBuffer(const private_handle_t *handle, int acquire_fence) {
389   void* buffer_ptr = NULL;
390   const gralloc1_rect_t accessRegion = {
391         .left = 0,
392         .top = 0,
393         .width = 0,
394         .height = 0
395   };
396   Lock_(gralloc_device_, handle, GRALLOC1_PRODUCER_USAGE_CPU_READ, GRALLOC1_CONSUMER_USAGE_NONE,
397         &accessRegion, &buffer_ptr, acquire_fence);
398   if (!buffer_ptr) {
399     return kErrorUndefined;
400   }
401 
402   return kErrorNone;
403 }
404 
UnmapBuffer(const private_handle_t * handle,int * release_fence)405 DisplayError HWCBufferAllocator::UnmapBuffer(const private_handle_t *handle, int* release_fence) {
406   return (DisplayError)(Unlock_(gralloc_device_, handle, release_fence));
407 }
408 
409 }  // namespace sdm
410