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 
39 #define __CLASS__ "HWCBufferAllocator"
40 namespace sdm {
41 
HWCBufferAllocator()42 HWCBufferAllocator::HWCBufferAllocator() {
43   int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module_);
44   if (err != 0) {
45     DLOGE("FATAL: can not open GRALLOC module");
46   } else {
47     gralloc1_open(module_, &gralloc_device_);
48   }
49   ReleaseBuffer_ = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
50       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_RELEASE));
51   Perform_ = reinterpret_cast<GRALLOC1_PFN_PERFORM>(
52       gralloc_device_->getFunction(gralloc_device_, GRALLOC1_FUNCTION_PERFORM));
53 }
54 
~HWCBufferAllocator()55 HWCBufferAllocator::~HWCBufferAllocator() {
56   if (gralloc_device_ != nullptr) {
57     gralloc1_close(gralloc_device_);
58   }
59 }
60 
AllocateBuffer(BufferInfo * buffer_info)61 DisplayError HWCBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
62   const BufferConfig &buffer_config = buffer_info->buffer_config;
63   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
64   uint32_t width = buffer_config.width;
65   uint32_t height = buffer_config.height;
66   int format;
67   int alloc_flags = 0;
68   int error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
69   if (error != 0) {
70     return kErrorParameters;
71   }
72 
73   if (buffer_config.secure) {
74     alloc_flags |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
75   }
76 
77   if (!buffer_config.cache) {
78     // Allocate uncached buffers
79     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
80   }
81 
82   if (buffer_config.gfx_client) {
83     alloc_flags |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
84   }
85 
86   uint64_t producer_usage = UINT64(alloc_flags);
87   uint64_t consumer_usage = UINT64(alloc_flags);
88 
89   // CreateBuffer
90   private_handle_t *hnd = nullptr;
91   Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER, width, height, format,
92            producer_usage, consumer_usage, &hnd);
93 
94   if (hnd) {
95     alloc_buffer_info->fd = hnd->fd;
96     alloc_buffer_info->stride = UINT32(hnd->width);
97     alloc_buffer_info->size = hnd->size;
98   } else {
99     DLOGE("Failed to allocate memory");
100     return kErrorMemory;
101   }
102 
103   buffer_info->private_data = reinterpret_cast<void *>(hnd);
104   return kErrorNone;
105 }
106 
FreeBuffer(BufferInfo * buffer_info)107 DisplayError HWCBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
108   DisplayError err = kErrorNone;
109   buffer_handle_t hnd = static_cast<private_handle_t *>(buffer_info->private_data);
110   ReleaseBuffer_(gralloc_device_, hnd);
111   AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
112   alloc_buffer_info->fd = -1;
113   alloc_buffer_info->stride = 0;
114   alloc_buffer_info->size = 0;
115   buffer_info->private_data = NULL;
116   return err;
117 }
118 
GetCustomWidthAndHeight(const private_handle_t * handle,int * width,int * height)119 void HWCBufferAllocator::GetCustomWidthAndHeight(const private_handle_t *handle, int *width,
120                                                  int *height) {
121   Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE, handle,
122            width, height);
123 }
124 
GetAlignedWidthAndHeight(int width,int height,int format,uint32_t alloc_type,int * aligned_width,int * aligned_height)125 void HWCBufferAllocator::GetAlignedWidthAndHeight(int width, int height, int format,
126                                                   uint32_t alloc_type, int *aligned_width,
127                                                   int *aligned_height) {
128   int tile_enabled;
129   gralloc1_producer_usage_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
130   gralloc1_consumer_usage_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
131   if (alloc_type & GRALLOC_USAGE_HW_FB) {
132     consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
133   }
134 
135   Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
136            producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
137 }
138 
GetBufferSize(BufferInfo * buffer_info)139 uint32_t HWCBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
140   const BufferConfig &buffer_config = buffer_info->buffer_config;
141   int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
142 
143   int width = INT(buffer_config.width);
144   int height = INT(buffer_config.height);
145   int format;
146 
147   if (buffer_config.secure) {
148     alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
149   }
150 
151   if (!buffer_config.cache) {
152     // Allocate uncached buffers
153     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
154   }
155 
156   if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
157     return 0;
158   }
159 
160   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
161   uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
162   uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
163   // TODO(user): Currently both flags are treated similarly in gralloc
164   producer_usage = UINT64(alloc_flags);
165   consumer_usage = producer_usage;
166   Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
167            format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
168   return buffer_size;
169 }
170 
SetBufferInfo(LayerBufferFormat format,int * target,int * flags)171 int HWCBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target, int *flags) {
172   switch (format) {
173     case kFormatRGBA8888:
174       *target = HAL_PIXEL_FORMAT_RGBA_8888;
175       break;
176     case kFormatRGBX8888:
177       *target = HAL_PIXEL_FORMAT_RGBX_8888;
178       break;
179     case kFormatRGB888:
180       *target = HAL_PIXEL_FORMAT_RGB_888;
181       break;
182     case kFormatRGB565:
183       *target = HAL_PIXEL_FORMAT_RGB_565;
184       break;
185     case kFormatBGR565:
186       *target = HAL_PIXEL_FORMAT_BGR_565;
187       break;
188     case kFormatBGRA8888:
189       *target = HAL_PIXEL_FORMAT_BGRA_8888;
190       break;
191     case kFormatYCrCb420PlanarStride16:
192       *target = HAL_PIXEL_FORMAT_YV12;
193       break;
194     case kFormatYCrCb420SemiPlanar:
195       *target = HAL_PIXEL_FORMAT_YCrCb_420_SP;
196       break;
197     case kFormatYCbCr420SemiPlanar:
198       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP;
199       break;
200     case kFormatYCbCr422H2V1Packed:
201       *target = HAL_PIXEL_FORMAT_YCbCr_422_I;
202       break;
203     case kFormatYCbCr422H2V1SemiPlanar:
204       *target = HAL_PIXEL_FORMAT_YCbCr_422_SP;
205       break;
206     case kFormatYCbCr420SemiPlanarVenus:
207       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
208       break;
209     case kFormatYCrCb420SemiPlanarVenus:
210       *target = HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS;
211       break;
212     case kFormatYCbCr420SPVenusUbwc:
213       *target = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
214       break;
215     case kFormatRGBA5551:
216       *target = HAL_PIXEL_FORMAT_RGBA_5551;
217       break;
218     case kFormatRGBA4444:
219       *target = HAL_PIXEL_FORMAT_RGBA_4444;
220       break;
221     case kFormatRGBA1010102:
222       *target = HAL_PIXEL_FORMAT_RGBA_1010102;
223       break;
224     case kFormatARGB2101010:
225       *target = HAL_PIXEL_FORMAT_ARGB_2101010;
226       break;
227     case kFormatRGBX1010102:
228       *target = HAL_PIXEL_FORMAT_RGBX_1010102;
229       break;
230     case kFormatXRGB2101010:
231       *target = HAL_PIXEL_FORMAT_XRGB_2101010;
232       break;
233     case kFormatBGRA1010102:
234       *target = HAL_PIXEL_FORMAT_BGRA_1010102;
235       break;
236     case kFormatABGR2101010:
237       *target = HAL_PIXEL_FORMAT_ABGR_2101010;
238       break;
239     case kFormatBGRX1010102:
240       *target = HAL_PIXEL_FORMAT_BGRX_1010102;
241       break;
242     case kFormatXBGR2101010:
243       *target = HAL_PIXEL_FORMAT_XBGR_2101010;
244       break;
245     case kFormatYCbCr420P010:
246       *target = HAL_PIXEL_FORMAT_YCbCr_420_P010;
247       break;
248     case kFormatYCbCr420TP10Ubwc:
249       *target = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
250       break;
251     case kFormatRGBA8888Ubwc:
252       *target = HAL_PIXEL_FORMAT_RGBA_8888;
253       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
254       break;
255     case kFormatRGBX8888Ubwc:
256       *target = HAL_PIXEL_FORMAT_RGBX_8888;
257       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
258       break;
259     case kFormatBGR565Ubwc:
260       *target = HAL_PIXEL_FORMAT_BGR_565;
261       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
262       break;
263     case kFormatRGBA1010102Ubwc:
264       *target = HAL_PIXEL_FORMAT_RGBA_1010102;
265       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
266       break;
267     case kFormatRGBX1010102Ubwc:
268       *target = HAL_PIXEL_FORMAT_RGBX_1010102;
269       *flags |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
270       break;
271     default:
272       DLOGE("Unsupported format = 0x%x", format);
273       return -EINVAL;
274   }
275   return 0;
276 }
277 
GetAllocatedBufferInfo(const BufferConfig & buffer_config,AllocatedBufferInfo * allocated_buffer_info)278 DisplayError HWCBufferAllocator::GetAllocatedBufferInfo(
279     const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
280   // TODO(user): This API should pass the buffer_info of the already allocated buffer
281   // The private_data can then be typecast to the private_handle and used directly.
282   int alloc_flags = INT(GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
283 
284   int width = INT(buffer_config.width);
285   int height = INT(buffer_config.height);
286   int format;
287 
288   if (buffer_config.secure) {
289     alloc_flags |= INT(GRALLOC_USAGE_PROTECTED);
290   }
291 
292   if (!buffer_config.cache) {
293     // Allocate uncached buffers
294     alloc_flags |= GRALLOC_USAGE_PRIVATE_UNCACHED;
295   }
296 
297   if (SetBufferInfo(buffer_config.format, &format, &alloc_flags) < 0) {
298     return kErrorParameters;
299   }
300 
301   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
302   uint64_t producer_usage = GRALLOC1_PRODUCER_USAGE_NONE;
303   uint64_t consumer_usage = GRALLOC1_CONSUMER_USAGE_NONE;
304   // TODO(user): Currently both flags are treated similarly in gralloc
305   producer_usage = UINT64(alloc_flags);
306   consumer_usage = producer_usage;
307   Perform_(gralloc_device_, GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS, width, height,
308            format, producer_usage, consumer_usage, &aligned_width, &aligned_height, &buffer_size);
309   allocated_buffer_info->stride = UINT32(aligned_width);
310   allocated_buffer_info->aligned_width = UINT32(aligned_width);
311   allocated_buffer_info->aligned_height = UINT32(aligned_height);
312   allocated_buffer_info->size = UINT32(buffer_size);
313 
314   return kErrorNone;
315 }
316 
317 }  // namespace sdm
318