blob: 9a3ff8ca949fcfa48a6298ade8d0cdd1bcfa197e [file] [log] [blame]
John Stultz16100f62017-05-03 11:12:18 -07001/*
2 * Copyright (C) 2010 ARM Limited. All rights reserved.
3 *
4 * Copyright (C) 2008 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <string.h>
20#include <errno.h>
21#include <pthread.h>
22
23#include <cutils/log.h>
24#include <cutils/atomic.h>
25#include <hardware/hardware.h>
26#include <hardware/gralloc.h>
27
28#include <sys/ioctl.h>
29
30#include "alloc_device.h"
31#include "gralloc_priv.h"
32#include "gralloc_helper.h"
33#include "framebuffer_device.h"
34
35#include "alloc_device_allocator_specific.h"
36#include "gralloc_buffer_priv.h"
37
38#include "mali_gralloc_formats.h"
39
40#define AFBC_PIXELS_PER_BLOCK 16
41#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16
42
43#define AFBC_BODY_BUFFER_BYTE_ALIGNMENT 1024
44#define AFBC_NORMAL_WIDTH_ALIGN 16
45#define AFBC_NORMAL_HEIGHT_ALIGN 16
46#define AFBC_WIDEBLK_WIDTH_ALIGN 32
47#define AFBC_WIDEBLK_HEIGHT_ALIGN 16
48// Regarding Tiled Headers AFBC mode, both header and body buffer should aligned to 4KB
49// and in non-wide mode (16x16), the width and height should be both rounded up to 128
50// in wide mode (32x8) the width should be rounded up to 256, the height should be rounded up to 64
51#define AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN 128
52#define AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN 128
53#define AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN 256
54#define AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN 64
55
56// This value is platform specific and should be set according to hardware YUV planes restrictions.
57// Please note that EGL winsys platform config file needs to use the same value when importing buffers.
58#define YUV_MALI_PLANE_ALIGN 128
59
60// Default YUV stride aligment in Android
61#define YUV_ANDROID_PLANE_ALIGN 16
62
63static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int* stride, int* byte_stride)
64{
65 private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
66
67 // allocate the framebuffer
68 if (m->framebuffer == NULL)
69 {
70 // initialize the framebuffer, the framebuffer is mapped once and forever.
71 int err = init_frame_buffer_locked(m);
72 if (err < 0)
73 {
74 return err;
75 }
76 }
77
78 const uint32_t bufferMask = m->bufferMask;
79 const uint32_t numBuffers = m->numBuffers;
80 /* framebufferSize is used for allocating the handle to the framebuffer and refers
81 * to the size of the actual framebuffer.
82 * alignedFramebufferSize is used for allocating a possible internal buffer and
83 * thus need to consider internal alignment requirements. */
84 const size_t framebufferSize = m->finfo.line_length * m->info.yres;
85 const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
86
87 *stride = m->info.xres;
88
89 if (numBuffers == 1)
90 {
91 // If we have only one buffer, we never use page-flipping. Instead,
92 // we return a regular buffer which will be memcpy'ed to the main
93 // screen when post is called.
94 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
95 AWAR( "fallback to single buffering. Virtual Y-res too small %d", m->info.yres );
96 *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
97 return alloc_backend_alloc(dev, alignedFramebufferSize, newUsage, pHandle, 0, 0, 0);
98 }
99
100 if (bufferMask >= ((1LU<<numBuffers)-1))
101 {
102 // We ran out of buffers.
103 return -ENOMEM;
104 }
105
106 uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
107 // find a free slot
108 for (uint32_t i=0 ; i<numBuffers ; i++)
109 {
110 if ((bufferMask & (1LU<<i)) == 0)
111 {
112 m->bufferMask |= (1LU<<i);
113 break;
114 }
115 framebufferVaddr += framebufferSize;
116 }
117
118 // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
119 private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size,
Chia-I Wu5f82a372017-05-08 12:50:36 -0700120 (void*)framebufferVaddr, 0, m->framebuffer->shallow_fbdev_fd,
John Stultz16100f62017-05-03 11:12:18 -0700121 (framebufferVaddr - (uintptr_t)m->framebuffer->base));
122
123 /*
124 * Perform allocator specific actions. If these fail we fall back to a regular buffer
125 * which will be memcpy'ed to the main screen when fb_post is called.
126 */
127 if (alloc_backend_alloc_framebuffer(m, hnd) == -1)
128 {
129 delete hnd;
130 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
131 AERR( "Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd );
132 *byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
133 return alloc_backend_alloc(dev, alignedFramebufferSize, newUsage, pHandle, 0, 0, 0);
134 }
135
136 *pHandle = hnd;
137 *byte_stride = m->finfo.line_length;
138
139 return 0;
140}
141
142static int gralloc_alloc_framebuffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int* stride, int* byte_stride)
143{
144 private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
145 pthread_mutex_lock(&m->lock);
146 int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle, stride, byte_stride);
147 pthread_mutex_unlock(&m->lock);
148 return err;
149}
150
151/*
152 * Type of allocation
153 */
154enum AllocType
155{
156 UNCOMPRESSED = 0,
157 AFBC,
158 /* AFBC_WIDEBLK mode requires buffer to have 32 * 16 pixels alignment */
159 AFBC_WIDEBLK,
160 /* AN AFBC buffer with additional padding to ensure a 64-bte alignment
161 * for each row of blocks in the header */
162 AFBC_PADDED,
163 /* AFBC_TILED_HEADERS_AFBC_BASIC mode requires buffer to have 128*128 pixels alignment(16x16 superblocks) */
164 AFBC_TILED_HEADERS_BASIC,
165 /* AFBC_TILED_HEADERS_AFBC_WIDEBLK mode requires buffer to have 256*64 pixels alignment(32x8 superblocks) */
166 AFBC_TILED_HEADERS_WIDEBLK,
167};
168
169/*
170 * Computes the strides and size for an RGB buffer
171 *
172 * width width of the buffer in pixels
173 * height height of the buffer in pixels
174 * pixel_size size of one pixel in bytes
175 *
176 * pixel_stride (out) stride of the buffer in pixels
177 * byte_stride (out) stride of the buffer in bytes
178 * size (out) size of the buffer in bytes
179 * type (in) if buffer should be allocated for afbc
180 */
181static void get_rgb_stride_and_size(int width, int height, int pixel_size,
182 int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
183{
184 int stride;
185
186 stride = width * pixel_size;
187
188 /* Align the lines to 64 bytes.
189 * It's more efficient to write to 64-byte aligned addresses because it's the burst size on the bus */
190 stride = GRALLOC_ALIGN(stride, 64);
191
192 if (size != NULL)
193 {
194 *size = stride * height;
195 }
196
197 if (byte_stride != NULL)
198 {
199 *byte_stride = stride;
200 }
201
202 if (pixel_stride != NULL)
203 {
204 *pixel_stride = stride / pixel_size;
205 }
206
207 if (type != UNCOMPRESSED)
208 {
209 int w_aligned;
210 int h_aligned = GRALLOC_ALIGN( height, AFBC_NORMAL_HEIGHT_ALIGN );
211 int nblocks;
212 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
213
214 if (type == AFBC_TILED_HEADERS_BASIC)
215 {
216 w_aligned = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN );
217 h_aligned = GRALLOC_ALIGN( height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN );
218 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
219 }
220 else if (type == AFBC_TILED_HEADERS_WIDEBLK)
221 {
222 w_aligned = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN );
223 h_aligned = GRALLOC_ALIGN( height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN );
224 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
225 }
226 else if (type == AFBC_PADDED)
227 {
228 w_aligned = GRALLOC_ALIGN( width, 64 );
229 }
230 else if (type == AFBC_WIDEBLK)
231 {
232 w_aligned = GRALLOC_ALIGN( width, AFBC_WIDEBLK_WIDTH_ALIGN );
233 h_aligned = GRALLOC_ALIGN( height, AFBC_WIDEBLK_HEIGHT_ALIGN );
234 }
235 else
236 {
237 w_aligned = GRALLOC_ALIGN( width, AFBC_NORMAL_WIDTH_ALIGN );
238 }
239
240 nblocks = w_aligned / AFBC_PIXELS_PER_BLOCK * h_aligned / AFBC_PIXELS_PER_BLOCK;
241
242 if ( size != NULL )
243 {
244 *size = w_aligned * h_aligned * pixel_size +
245 GRALLOC_ALIGN( nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment );
246 }
247 }
248}
249
250/*
251 * Computes the strides and size for an AFBC 8BIT YUV 4:2:0 buffer
252 *
253 * width Public known width of the buffer in pixels
254 * height Public known height of the buffer in pixels
255 *
256 * pixel_stride (out) stride of the buffer in pixels
257 * byte_stride (out) stride of the buffer in bytes
258 * size (out) size of the buffer in bytes
259 * type if buffer should be allocated for a certain afbc type
260 * internalHeight (out) The internal height, which may be greater than the public known height.
261 */
262static bool get_afbc_yuv420_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride,
263 size_t* size, AllocType type, int *internalHeight)
264{
265 int yuv420_afbc_luma_stride, yuv420_afbc_chroma_stride;
266 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
267
268 *internalHeight = height;
269
270#if MALI_VIDEO_VERSION != 0
271
272 /* If we have a greater internal height than public we set the internalHeight. This
273 * implies that cropping will be applied of internal dimensions to fit the public one.
274 *
275 * NOTE: This should really only be done when the producer is determined to be VPU decoder.
276 */
277 *internalHeight += AFBC_PIXELS_PER_BLOCK;
278#endif
279
280 /* The actual height used in size calculation must include the possible extra row. But
281 * it must also be AFBC-aligned. Only the extra row-padding should be reported back in
282 * internalHeight. This as only this row needs to be considered when cropping. */
283
284 if (type == UNCOMPRESSED)
285 {
286 AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_8BIT_AFBC!");
287 return false;
288 }
289 else if (type == AFBC_TILED_HEADERS_BASIC)
290 {
291 width = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN );
292 height = GRALLOC_ALIGN( *internalHeight, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN );
293 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
294 }
295 else if (type == AFBC_TILED_HEADERS_WIDEBLK)
296 {
297 width = GRALLOC_ALIGN( width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN );
298 height = GRALLOC_ALIGN( *internalHeight, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN );
299 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
300 }
301 else if (type == AFBC_PADDED)
302 {
303 AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV");
304 return false;
305 }
306 else if (type == AFBC_WIDEBLK)
307 {
308 width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
309 height = GRALLOC_ALIGN( *internalHeight, AFBC_WIDEBLK_HEIGHT_ALIGN );
310 }
311 else
312 {
313 width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
314 height = GRALLOC_ALIGN( *internalHeight, AFBC_NORMAL_HEIGHT_ALIGN );
315 }
316
317 yuv420_afbc_luma_stride = width;
318 yuv420_afbc_chroma_stride = GRALLOC_ALIGN(yuv420_afbc_luma_stride / 2, 16); /* Horizontal downsampling*/
319
320 if (size != NULL)
321 {
322 int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
323 /* Simplification of (height * luma-stride + 2 * (height /2 * chroma_stride) */
324 *size =
325 ( yuv420_afbc_luma_stride + yuv420_afbc_chroma_stride ) * height +
326 GRALLOC_ALIGN( nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment );
327 }
328
329 if (byte_stride != NULL)
330 {
331 *byte_stride = yuv420_afbc_luma_stride;
332 }
333
334 if (pixel_stride != NULL)
335 {
336 *pixel_stride = yuv420_afbc_luma_stride;
337 }
338
339 return true;
340}
341
342/*
343 * Computes the strides and size for an YV12 buffer
344 *
345 * width Public known width of the buffer in pixels
346 * height Public known height of the buffer in pixels
347 *
348 * pixel_stride (out) stride of the buffer in pixels
349 * byte_stride (out) stride of the buffer in bytes
350 * size (out) size of the buffer in bytes
351 * type (in) if buffer should be allocated for a certain afbc type
352 * internalHeight (out) The internal height, which may be greater than the public known height.
353 * stride_alignment (in) stride aligment value in bytes.
354 */
355static bool get_yv12_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size,
356 AllocType type, int* internalHeight, int stride_alignment)
357{
358 int luma_stride;
359
360 if (type != UNCOMPRESSED)
361 {
362 return get_afbc_yuv420_8bit_stride_and_size(width, height, pixel_stride, byte_stride, size, type, internalHeight);
363 }
364
365 /* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels.
366 * Width will be even stride aligned anyway so just adjust height here for size calculation. */
367 height = GRALLOC_ALIGN(height, 2);
368
369 luma_stride = GRALLOC_ALIGN(width, stride_alignment);
370
371 if (size != NULL)
372 {
373 int chroma_stride = GRALLOC_ALIGN(luma_stride / 2, stride_alignment);
374 /* Simplification of ((height * luma_stride ) + 2 * ((height / 2) * chroma_stride)). */
375 *size = height * (luma_stride + chroma_stride);
376 }
377
378 if (byte_stride != NULL)
379 {
380 *byte_stride = luma_stride;
381 }
382
383 if (pixel_stride != NULL)
384 {
385 *pixel_stride = luma_stride;
386 }
387
388 return true;
389}
390/*
391 * Computes the strides and size for an 8 bit YUYV 422 buffer
392 *
393 * width Public known width of the buffer in pixels
394 * height Public known height of the buffer in pixels
395 *
396 * pixel_stride (out) stride of the buffer in pixels
397 * byte_stride (out) stride of the buffer in bytes
398 * size (out) size of the buffer in bytes
399 */
400static bool get_yuv422_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
401{
402 int local_byte_stride, local_pixel_stride;
403
404 /* 4:2:2 formats must have buffers with even width as the clump size is 2x1 pixels.
405 * This is taken care of by the even stride alignment. */
406
407 local_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
408 local_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN); /* 4 bytes per 2 pixels */
409
410 if (size != NULL)
411 {
412 *size = local_byte_stride * height;
413 }
414
415 if (byte_stride != NULL)
416 {
417 *byte_stride = local_byte_stride;
418 }
419
420 if (pixel_stride != NULL)
421 {
422 *pixel_stride = local_pixel_stride;
423 }
424
425 return true;
426}
427
428/*
429 * Computes the strides and size for an AFBC 8BIT YUV 4:2:2 buffer
430 *
431 * width width of the buffer in pixels
432 * height height of the buffer in pixels
433 *
434 * pixel_stride (out) stride of the buffer in pixels
435 * byte_stride (out) stride of the buffer in bytes
436 * size (out) size of the buffer in bytes
437 * type if buffer should be allocated for a certain afbc type
438 */
439static bool get_afbc_yuv422_8bit_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
440{
441 int yuv422_afbc_luma_stride;
442 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
443
444 if (type == UNCOMPRESSED)
445 {
446 AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_8BIT_AFBC!");
447 return false;
448 }
449 else if (type == AFBC_TILED_HEADERS_BASIC)
450 {
451 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
452 height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
453 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
454 }
455 else if (type == AFBC_TILED_HEADERS_WIDEBLK)
456 {
457 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
458 height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
459 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
460 }
461 else if (type == AFBC_PADDED)
462 {
463 AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV");
464 return false;
465 }
466 else if (type == AFBC_WIDEBLK)
467 {
468 width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
469 height = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN);
470 }
471 else
472 {
473 width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
474 height = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN);
475 }
476
477 yuv422_afbc_luma_stride = width;
478
479 if (size != NULL)
480 {
481 int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
482 /* YUV 4:2:2 luma size equals chroma size */
483 *size = yuv422_afbc_luma_stride * height * 2
484 + GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
485 }
486
487 if (byte_stride != NULL)
488 {
489 *byte_stride = yuv422_afbc_luma_stride;
490 }
491
492 if (pixel_stride != NULL)
493 {
494 *pixel_stride = yuv422_afbc_luma_stride;
495 }
496
497 return true;
498}
499
500/*
501 * Calculate strides and sizes for a P010 (Y-UV 4:2:0) or P210 (Y-UV 4:2:2) buffer.
502 *
503 * @param width [in] Buffer width.
504 * @param height [in] Buffer height.
505 * @param vss [in] Vertical sub-sampling factor (2 for P010, 1 for
506 * P210. Anything else is invalid).
507 * @param pixel_stride [out] Pixel stride; number of pixels between
508 * consecutive rows.
509 * @param byte_stride [out] Byte stride; number of bytes between
510 * consecutive rows.
511 * @param size [out] Size of the buffer in bytes. Cumulative sum of
512 * sizes of all planes.
513 *
514 * @return true if the calculation was successful; false otherwise (invalid
515 * parameter)
516 */
517static bool get_yuv_pX10_stride_and_size(int width, int height, int vss, int* pixel_stride, int* byte_stride, size_t* size)
518{
519 int luma_pixel_stride, luma_byte_stride;
520
521 if (vss < 1 || vss > 2)
522 {
523 AERR("Invalid vertical sub-sampling factor: %d, should be 1 or 2", vss);
524 return false;
525 }
526
527 /* 4:2:2 must have even width as the clump size is 2x1 pixels. This will be taken care of by the
528 * even stride alignment */
529 if (vss == 2)
530 {
531 /* 4:2:0 must also have even height as the clump size is 2x2 */
532 height = GRALLOC_ALIGN(height, 2);
533 }
534
535 luma_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
536 luma_byte_stride = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN);
537
538 if (size != NULL)
539 {
540 int chroma_size = GRALLOC_ALIGN(width * 2, YUV_MALI_PLANE_ALIGN) * (height / vss);
541 *size = luma_byte_stride * height + chroma_size;
542 }
543
544 if (byte_stride != NULL)
545 {
546 *byte_stride = luma_byte_stride;
547 }
548
549 if (pixel_stride != NULL)
550 {
551 *pixel_stride = luma_pixel_stride;
552 }
553
554 return true;
555}
556
557/*
558 * Calculate strides and strides for Y210 (10 bit YUYV packed, 4:2:2) format buffer.
559 *
560 * @param width [in] Buffer width.
561 * @param height [in] Buffer height.
562 * @param pixel_stride [out] Pixel stride; number of pixels between
563 * consecutive rows.
564 * @param byte_stride [out] Byte stride; number of bytes between
565 * consecutive rows.
566 * @param size [out] Size of the buffer in bytes. Cumulative sum of
567 * sizes of all planes.
568 *
569 * @return true if the calculation was successful; false otherwise (invalid
570 * parameter)
571 */
572static bool get_yuv_y210_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
573{
574 int y210_byte_stride, y210_pixel_stride;
575
576 /* 4:2:2 formats must have buffers with even width as the clump size is 2x1 pixels.
577 * This is taken care of by the even stride alignment */
578
579 y210_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
580 /* 4x16 bits per 2 pixels */
581 y210_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
582
583 if (size != NULL)
584 {
585 *size = y210_byte_stride * height;
586 }
587
588 if (byte_stride != NULL)
589 {
590 *byte_stride = y210_byte_stride;
591 }
592
593 if (pixel_stride != NULL)
594 {
595 *pixel_stride = y210_pixel_stride;
596 }
597
598 return true;
599}
600
601/*
602 * Calculate strides and strides for Y0L2 (YUYAAYVYAA, 4:2:0) format buffer.
603 *
604 * @param width [in] Buffer width.
605 * @param height [in] Buffer height.
606 * @param pixel_stride [out] Pixel stride; number of pixels between
607 * consecutive rows.
608 * @param byte_stride [out] Byte stride; number of bytes between
609 * consecutive rows.
610 * @param size [out] Size of the buffer in bytes. Cumulative sum of
611 * sizes of all planes.
612 *
613 * @return true if the calculation was successful; false otherwise (invalid
614 * parameter)
615 *
616 * @note Each YUYAAYVYAA clump encodes a 2x2 area of pixels. YU&V are 10 bits. A is 1 bit. total 8 bytes
617 *
618 */
619static bool get_yuv_y0l2_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
620{
621 int y0l2_byte_stride, y0l2_pixel_stride;
622
623 /* 4:2:0 formats must have buffers with even height and width as the clump size is 2x2 pixels.
624 * Width is take care of by the even stride alignment so just adjust height here for size calculation. */
625 height = GRALLOC_ALIGN(height, 2);
626
627 y0l2_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
628 y0l2_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN); /* 2 horiz pixels per 8 byte clump */
629
630 if (size != NULL)
631 {
632 *size = y0l2_byte_stride * height / 2; /* byte stride covers 2 vert pixels */
633 }
634
635 if (byte_stride != NULL)
636 {
637 *byte_stride = y0l2_byte_stride;
638 }
639
640 if (pixel_stride != NULL)
641 {
642 *pixel_stride = y0l2_pixel_stride;
643 }
644 return true;
645}
646/*
647 * Calculate strides and strides for Y410 (AVYU packed, 4:4:4) format buffer.
648 *
649 * @param width [in] Buffer width.
650 * @param height [in] Buffer height.
651 * @param pixel_stride [out] Pixel stride; number of pixels between
652 * consecutive rows.
653 * @param byte_stride [out] Byte stride; number of bytes between
654 * consecutive rows.
655 * @param size [out] Size of the buffer in bytes. Cumulative sum of
656 * sizes of all planes.
657 *
658 * @return true if the calculation was successful; false otherwise (invalid
659 * parameter)
660 */
661static bool get_yuv_y410_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size)
662{
663 int y410_byte_stride, y410_pixel_stride;
664
665 y410_pixel_stride = GRALLOC_ALIGN(width, YUV_MALI_PLANE_ALIGN);
666 y410_byte_stride = GRALLOC_ALIGN(width * 4, YUV_MALI_PLANE_ALIGN);
667
668 if (size != NULL)
669 {
670 /* 4x8bits per pixel */
671 *size = y410_byte_stride * height;
672 }
673
674 if (byte_stride != NULL)
675 {
676 *byte_stride = y410_byte_stride;
677 }
678
679 if (pixel_stride != NULL)
680 {
681 *pixel_stride = y410_pixel_stride;
682 }
683 return true;
684}
685
686/*
687 * Calculate strides and strides for YUV420_10BIT_AFBC (Compressed, 4:2:0) format buffer.
688 *
689 * @param width [in] Buffer width.
690 * @param height [in] Buffer height.
691 * @param pixel_stride [out] Pixel stride; number of pixels between
692 * consecutive rows.
693 * @param byte_stride [out] Byte stride; number of bytes between
694 * consecutive rows.
695 * @param size [out] Size of the buffer in bytes. Cumulative sum of
696 * sizes of all planes.
697 * @param type [in] afbc mode that buffer should be allocated with.
698 *
699 * @param internalHeight [out] Internal buffer height that used by consumer or producer
700 *
701 * @return true if the calculation was successful; false otherwise (invalid
702 * parameter)
703 */
704static bool get_yuv420_10bit_afbc_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type, int* internalHeight)
705{
706 int yuv420_afbc_byte_stride, yuv420_afbc_pixel_stride;
707 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
708
709 if (width & 3)
710 {
711 return false;
712 }
713
714 *internalHeight = height;
715#if MALI_VIDEO_VERSION
716 /* If we have a greater internal height than public we set the internalHeight. This
717 * implies that cropping will be applied of internal dimensions to fit the public one. */
718 *internalHeight += AFBC_PIXELS_PER_BLOCK;
719#endif
720 /* The actual height used in size calculation must include the possible extra row. But
721 * it must also be AFBC-aligned. Only the extra row-padding should be reported back in
722 * internalHeight. This as only this row needs to be considered when cropping. */
723 if (type == UNCOMPRESSED)
724 {
725 AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV420_10BIT_AFBC!");
726 return false;
727 }
728 else if (type == AFBC_TILED_HEADERS_BASIC)
729 {
730 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
731 height = GRALLOC_ALIGN(*internalHeight/2, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
732 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
733 }
734 else if (type == AFBC_TILED_HEADERS_WIDEBLK)
735 {
736 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
737 height = GRALLOC_ALIGN(*internalHeight/2, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
738 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
739 }
740 else if (type == AFBC_PADDED)
741 {
742 AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV");
743 return false;
744 }
745 else if (type == AFBC_WIDEBLK)
746 {
747 width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
748 height = GRALLOC_ALIGN(*internalHeight/2, AFBC_WIDEBLK_HEIGHT_ALIGN);
749 }
750 else
751 {
752 width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
753 height = GRALLOC_ALIGN(*internalHeight/2, AFBC_NORMAL_HEIGHT_ALIGN);
754 }
755
756 yuv420_afbc_pixel_stride = GRALLOC_ALIGN(width, 16);
757 yuv420_afbc_byte_stride = GRALLOC_ALIGN(width * 4, 16); /* 64-bit packed and horizontally downsampled */
758
759 if (size != NULL)
760 {
761 int nblocks = width / AFBC_PIXELS_PER_BLOCK * (*internalHeight) / AFBC_PIXELS_PER_BLOCK;
762 *size = yuv420_afbc_byte_stride * height
763 + GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
764 }
765
766 if (byte_stride != NULL)
767 {
768 *byte_stride = yuv420_afbc_pixel_stride;
769 }
770
771 if (pixel_stride != NULL)
772 {
773 *pixel_stride = yuv420_afbc_pixel_stride;
774 }
775
776 return true;
777}
778
779/*
780 * Calculate strides and strides for YUV422_10BIT_AFBC (Compressed, 4:2:2) format buffer.
781 *
782 * @param width [in] Buffer width.
783 * @param height [in] Buffer height.
784 * @param pixel_stride [out] Pixel stride; number of pixels between
785 * consecutive rows.
786 * @param byte_stride [out] Byte stride; number of bytes between
787 * consecutive rows.
788 * @param size [out] Size of the buffer in bytes. Cumulative sum of
789 * sizes of all planes.
790 * @param type [in] afbc mode that buffer should be allocated with.
791 *
792 * @return true if the calculation was successful; false otherwise (invalid
793 * parameter)
794 */
795static bool get_yuv422_10bit_afbc_stride_and_size(int width, int height, int* pixel_stride, int* byte_stride, size_t* size, AllocType type)
796{
797 int yuv422_afbc_byte_stride, yuv422_afbc_pixel_stride;
798 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
799
800 if (width & 3)
801 {
802 return false;
803 }
804
805 if (type == UNCOMPRESSED)
806 {
807 AERR(" Buffer must be allocated with AFBC mode for internal pixel format YUV422_10BIT_AFBC!");
808 return false;
809 }
810 else if (type == AFBC_TILED_HEADERS_BASIC)
811 {
812 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_BASIC_WIDTH_ALIGN);
813 height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_BASIC_HEIGHT_ALIGN);
814 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
815 }
816 else if (type == AFBC_TILED_HEADERS_WIDEBLK)
817 {
818 width = GRALLOC_ALIGN(width, AFBC_TILED_HEADERS_WIDEBLK_WIDTH_ALIGN);
819 height = GRALLOC_ALIGN(height, AFBC_TILED_HEADERS_WIDEBLK_HEIGHT_ALIGN);
820 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
821 }
822 else if (type == AFBC_PADDED)
823 {
824 AERR("GRALLOC_USAGE_PRIVATE_2 (64byte header row alignment for AFBC) is not supported for YUV");
825 return false;
826 }
827 else if (type == AFBC_WIDEBLK)
828 {
829 width = GRALLOC_ALIGN(width, AFBC_WIDEBLK_WIDTH_ALIGN);
830 height = GRALLOC_ALIGN(height, AFBC_WIDEBLK_HEIGHT_ALIGN);
831 }
832 else
833 {
834 width = GRALLOC_ALIGN(width, AFBC_NORMAL_WIDTH_ALIGN);
835 height = GRALLOC_ALIGN(height, AFBC_NORMAL_HEIGHT_ALIGN);
836 }
837
838 yuv422_afbc_pixel_stride = GRALLOC_ALIGN(width, 16);
839 yuv422_afbc_byte_stride = GRALLOC_ALIGN(width * 2, 16);
840
841 if (size != NULL)
842 {
843 int nblocks = width / AFBC_PIXELS_PER_BLOCK * height / AFBC_PIXELS_PER_BLOCK;
844 /* YUV 4:2:2 chroma size equals to luma size */
845 *size = yuv422_afbc_byte_stride * height * 2
846 + GRALLOC_ALIGN(nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, buffer_byte_alignment);
847 }
848
849 if (byte_stride != NULL)
850 {
851 *byte_stride = yuv422_afbc_byte_stride;
852 }
853
854 if (pixel_stride != NULL)
855 {
856 *pixel_stride = yuv422_afbc_pixel_stride;
857 }
858
859 return true;
860}
861
862/*
863 * Calculate strides and strides for Camera RAW and Blob formats
864 *
865 * @param w [in] Buffer width.
866 * @param h [in] Buffer height.
867 * @param format [in] Requested HAL format
868 * @param out_stride [out] Pixel stride; number of pixels/bytes between
869 * consecutive rows. Format description calls for
870 * either bytes or pixels.
871 * @param size [out] Size of the buffer in bytes. Cumulative sum of
872 * sizes of all planes.
873 *
874 * @return true if the calculation was successful; false otherwise (invalid
875 * parameter)
876 */
877static bool get_camera_formats_stride_and_size(int w, int h, uint64_t format, int *out_stride, size_t *out_size)
878{
879 int stride, size;
880
881 switch (format)
882 {
883 case HAL_PIXEL_FORMAT_RAW16:
884 stride = w; /* Format assumes stride in pixels */
885 stride = GRALLOC_ALIGN(stride, 16); /* Alignment mandated by Android */
886 size = stride * h * 2; /* 2 bytes per pixel */
887 break;
888
889 case HAL_PIXEL_FORMAT_RAW12:
890 if (w % 4 != 0)
891 {
892 ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW12 buffers has to be multiple of 4.");
893 return false;
894 }
895 stride = (w / 2) * 3; /* Stride in bytes; 2 pixels in 3 bytes */
896 size = stride * h;
897 break;
898
899 case HAL_PIXEL_FORMAT_RAW10:
900 if (w % 4 != 0)
901 {
902 ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 4.");
903 return false;
904 }
905 stride = (w / 4) * 5; /* Stride in bytes; 4 pixels in 5 bytes */
906 size = stride * h;
907 break;
908
909 case HAL_PIXEL_FORMAT_BLOB:
910 if (h != 1)
911 {
912 ALOGE("ERROR: Height for HAL_PIXEL_FORMAT_BLOB must be 1.");
913 return false;
914 }
915 stride = 0; /* No 'rows', it's effectively a long one dimensional array */
916 size = w;
917 break;
918
919 default:
920 return false;
921
922 }
923
924 if (out_size != NULL)
925 {
926 *out_size = size;
927 }
928
929 if (out_stride != NULL)
930 {
931 *out_stride = stride;
932 }
933
934 return true;
935}
936
937static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride)
938{
939
940 if (!pHandle || !pStride)
941 {
942 return -EINVAL;
943 }
944
945 size_t size; // Size to be allocated for the buffer
946 int byte_stride; // Stride of the buffer in bytes
947 int pixel_stride; // Stride of the buffer in pixels - as returned in pStride
948 uint64_t internal_format;
949 AllocType type = UNCOMPRESSED;
950 int internalWidth,internalHeight;
951
952#if GRALLOC_FB_SWAP_RED_BLUE == 1
953 /* match the framebuffer format */
954 if (usage & GRALLOC_USAGE_HW_FB)
955 {
956#ifdef GRALLOC_16_BITS
957 format = HAL_PIXEL_FORMAT_RGB_565;
958#else
959 format = HAL_PIXEL_FORMAT_BGRA_8888;
960#endif
961 }
962#endif
963
964 /* Some formats require an internal width and height that may be used by
965 * consumers/producers.
966 */
967 internalWidth = w;
968 internalHeight = h;
969
970 internal_format = mali_gralloc_select_format(format, usage, w*h);
971 if(internal_format == 0)
972 {
973 ALOGE("Unrecognized and/or unsupported format(0x%08X) and usage(0x%08X).",format,usage);
974 return -EINVAL;
975 }
976
977 if (internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
978 {
979 if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
980 {
981 if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
982 {
983 type = AFBC_TILED_HEADERS_WIDEBLK;
984 }
985 else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
986 {
987 type = AFBC_TILED_HEADERS_BASIC;
988 }
989 else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK)
990 {
991 ALOGE("Unsupported format. Splitblk in tiled header configuration.");
992 return -EINVAL;
993 }
994 }
995 else if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
996 {
997 type = AFBC_PADDED;
998 }
999 else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
1000 {
1001 type = AFBC_WIDEBLK;
1002 }
1003 else
1004 {
1005 type = AFBC;
1006 }
1007 }
1008
1009 uint64_t base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
1010 switch (base_format)
1011 {
1012 case HAL_PIXEL_FORMAT_RGBA_8888:
1013 case HAL_PIXEL_FORMAT_RGBX_8888:
1014 case HAL_PIXEL_FORMAT_BGRA_8888:
1015 get_rgb_stride_and_size(w, h, 4, &pixel_stride, &byte_stride, &size, type );
1016 break;
1017 case HAL_PIXEL_FORMAT_RGB_888:
1018 get_rgb_stride_and_size(w, h, 3, &pixel_stride, &byte_stride, &size, type );
1019 break;
1020 case HAL_PIXEL_FORMAT_RGB_565:
1021 get_rgb_stride_and_size(w, h, 2, &pixel_stride, &byte_stride, &size, type );
1022 break;
1023
1024 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1025 case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
1026 case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
1027 case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
1028 {
1029 /* Mali subsystem prefers higher stride alignment values (128 bytes) for YUV, but software components assume
1030 * default of 16. We only need to care about YV12 as it's the only, implicit, HAL YUV format in Android.
1031 */
1032 int yv12_align = YUV_MALI_PLANE_ALIGN;
1033 if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
1034 {
1035 yv12_align = YUV_ANDROID_PLANE_ALIGN;
1036 }
1037
1038 if (!get_yv12_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type,
1039 &internalHeight, yv12_align))
1040 {
1041 return -EINVAL;
1042 }
1043 break;
1044 }
1045 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1046 {
1047 /* YUYV 4:2:2 */
1048 if (type != UNCOMPRESSED || !get_yuv422_8bit_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
1049 {
1050 return -EINVAL;
1051 }
1052 break;
1053 }
1054 case HAL_PIXEL_FORMAT_RAW16:
1055 case HAL_PIXEL_FORMAT_RAW12:
1056 case HAL_PIXEL_FORMAT_RAW10:
1057 case HAL_PIXEL_FORMAT_BLOB:
1058 if (type != UNCOMPRESSED)
1059 {
1060 return -EINVAL;
1061 }
1062 get_camera_formats_stride_and_size(w, h, base_format, &pixel_stride, &size);
1063 byte_stride = pixel_stride; /* For Raw/Blob formats stride is defined to be either in bytes or pixels per format */
1064 break;
1065
1066 case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
1067 /* YUYAAYUVAA 4:2:0 with and without AFBC */
1068 if (type != UNCOMPRESSED)
1069 {
1070 if (!get_yuv420_10bit_afbc_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type, &internalHeight))
1071 {
1072 return -EINVAL;
1073 }
1074 }
1075 else
1076 {
1077 if(!get_yuv_y0l2_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
1078 {
1079 return -EINVAL;
1080 }
1081 }
1082 break;
1083
1084 case MALI_GRALLOC_FORMAT_INTERNAL_P010:
1085 /* Y-UV 4:2:0 */
1086 if (type != UNCOMPRESSED || !get_yuv_pX10_stride_and_size(w, h, 2, &pixel_stride, &byte_stride, &size))
1087 {
1088 return -EINVAL;
1089 }
1090 break;
1091
1092 case MALI_GRALLOC_FORMAT_INTERNAL_P210:
1093 /* Y-UV 4:2:2 */
1094 if (type != UNCOMPRESSED || !get_yuv_pX10_stride_and_size(w, h, 1, &pixel_stride, &byte_stride, &size))
1095 {
1096 return -EINVAL;
1097 }
1098 break;
1099
1100 case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
1101 /* YUYV 4:2:2 with and without AFBC */
1102 if (type != UNCOMPRESSED)
1103 {
1104 if (!get_yuv422_10bit_afbc_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type))
1105 {
1106 return -EINVAL;
1107 }
1108 }
1109 else
1110 {
1111 if(!get_yuv_y210_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
1112 {
1113 return -EINVAL;
1114 }
1115 }
1116 break;
1117
1118 case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
1119 /* AVYU 2-10-10-10 */
1120 if (type != UNCOMPRESSED || !get_yuv_y410_stride_and_size(w, h, &pixel_stride, &byte_stride, &size))
1121 {
1122 return -EINVAL;
1123 }
1124 break;
1125
1126 case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
1127 /* 8BIT AFBC YUV4:2:2 testing usage */
1128
1129 /* We only support compressed for this format right now.
1130 * Below will fail in case format is uncompressed.
1131 */
1132 if (!get_afbc_yuv422_8bit_stride_and_size(w, h, &pixel_stride, &byte_stride, &size, type))
1133 {
1134 return -EINVAL;
1135 }
1136 break;
1137 /*
1138 * Additional custom formats can be added here
1139 * and must fill the variables pixel_stride, byte_stride and size.
1140 */
1141 default:
1142 return -EINVAL;
1143 }
1144
1145 int err;
1146#if DISABLE_FRAMEBUFFER_HAL != 1
1147 if (usage & GRALLOC_USAGE_HW_FB)
1148 {
1149 err = gralloc_alloc_framebuffer(dev, size, usage, pHandle, &pixel_stride, &byte_stride);
1150 }
1151 else
1152#endif
1153 {
1154 err = alloc_backend_alloc(dev, size, usage, pHandle, internal_format, w, h);
1155 }
1156
1157 if (err < 0)
1158 {
1159 return err;
1160 }
1161
1162 private_handle_t *hnd = (private_handle_t *)*pHandle;
1163
1164 err = gralloc_buffer_attr_allocate( hnd );
1165 if( err < 0 )
1166 {
1167 private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
1168
1169 if ( (usage & GRALLOC_USAGE_HW_FB) )
1170 {
1171 /*
1172 * Having the attribute region is not critical for the framebuffer so let it pass.
1173 */
1174 err = 0;
1175 }
1176 else
1177 {
1178 alloc_backend_alloc_free( hnd, m );
1179 return err;
1180 }
1181 }
1182
1183 hnd->req_format = format;
1184 hnd->byte_stride = byte_stride;
1185 hnd->internal_format = internal_format;
1186
1187 int private_usage = usage & MALI_GRALLOC_USAGE_YUV_CONF_MASK;
1188
1189 switch (private_usage)
1190 {
1191 case MALI_GRALLOC_USAGE_YUV_CONF_0:
1192 hnd->yuv_info = MALI_YUV_BT601_NARROW;
1193 break;
1194 case MALI_GRALLOC_USAGE_YUV_CONF_1:
1195 hnd->yuv_info = MALI_YUV_BT601_WIDE;
1196 break;
1197 case MALI_GRALLOC_USAGE_YUV_CONF_2:
1198 hnd->yuv_info = MALI_YUV_BT709_NARROW;
1199 break;
1200 case MALI_GRALLOC_USAGE_YUV_CONF_3:
1201 hnd->yuv_info = MALI_YUV_BT709_WIDE;
1202 break;
1203 }
1204
1205 /* Workaround 10bit YUV only support BT709_WIDE in GPU DDK */
1206 if ((hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK) == MALI_GRALLOC_FORMAT_INTERNAL_Y0L2)
1207 {
1208 hnd->yuv_info = MALI_YUV_BT709_WIDE;
1209 }
1210 hnd->width = w;
1211 hnd->height = h;
1212 hnd->stride = pixel_stride;
1213 hnd->internalWidth = internalWidth;
1214 hnd->internalHeight = internalHeight;
1215
1216 *pStride = pixel_stride;
1217 return 0;
1218}
1219
1220static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle)
1221{
1222 if (private_handle_t::validate(handle) < 0)
1223 {
1224 return -EINVAL;
1225 }
1226
1227 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
1228 private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
1229
1230 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
1231 {
1232 // free this buffer
1233 private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
1234 const size_t bufferSize = m->finfo.line_length * m->info.yres;
1235 int index = ((uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base) / bufferSize;
1236 m->bufferMask &= ~(1 << index);
John Stultz16100f62017-05-03 11:12:18 -07001237 }
1238
1239 gralloc_buffer_attr_free( (private_handle_t *) hnd );
1240 alloc_backend_alloc_free(hnd, m);
1241
1242 delete hnd;
1243
1244 return 0;
1245}
1246
1247int alloc_device_open(hw_module_t const* module, const char* name, hw_device_t** device)
1248{
1249 alloc_device_t *dev;
1250
1251 GRALLOC_UNUSED(name);
1252
1253 dev = new alloc_device_t;
1254 if (NULL == dev)
1255 {
1256 return -1;
1257 }
1258
1259 /* initialize our state here */
1260 memset(dev, 0, sizeof(*dev));
1261
1262 /* initialize the procs */
1263 dev->common.tag = HARDWARE_DEVICE_TAG;
1264 dev->common.version = 0;
1265 dev->common.module = const_cast<hw_module_t*>(module);
1266 dev->common.close = alloc_backend_close;
1267 dev->alloc = alloc_device_alloc;
1268 dev->free = alloc_device_free;
1269
1270 if (0 != alloc_backend_open(dev)) {
1271 delete dev;
1272 return -1;
1273 }
1274
1275 *device = &dev->common;
1276
1277 return 0;
1278}