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