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