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 #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 63 static 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, 120 (void*)framebufferVaddr, 0, m->framebuffer->shallow_fbdev_fd, 121 (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 142 static 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 */ 154 enum 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 */ 181 static 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 */ 262 static 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 */ 355 static 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 */ 400 static 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 */ 439 static 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 */ 517 static 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 */ 572 static 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 */ 619 static 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 */ 661 static 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 */ 704 static 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 */ 795 static 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 */ 877 static 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 937 static 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 1220 static 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); 1237 } 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 1247 int 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 } 1279