1 /*
2 * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <cutils/log.h>
31 #include <fcntl.h>
32 #include <dlfcn.h>
33 #include "gralloc_priv.h"
34 #include "alloc_controller.h"
35 #include "memalloc.h"
36 #include "ionalloc.h"
37 #include "gr.h"
38 #include "comptype.h"
39 #include "mdp_version.h"
40
41 #ifdef VENUS_COLOR_FORMAT
42 #include <media/msm_media_info.h>
43 #else
44 #define VENUS_Y_STRIDE(args...) 0
45 #define VENUS_Y_SCANLINES(args...) 0
46 #define VENUS_BUFFER_SIZE(args...) 0
47 #endif
48
49 #define ASTC_BLOCK_SIZE 16
50
51 using namespace gralloc;
52 using namespace qdutils;
53
54 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
55
56 static void getUBwcWidthAndHeight(int, int, int, int&, int&);
57 static unsigned int getUBwcSize(int, int, int, const int, const int);
58
59 //Common functions
canFallback(int usage,bool triedSystem)60 static bool canFallback(int usage, bool triedSystem)
61 {
62 // Fallback to system heap when alloc fails unless
63 // 1. Composition type is MDP
64 // 2. Alloc from system heap was already tried
65 // 3. The heap type is requsted explicitly
66 // 4. The heap type is protected
67 // 5. The buffer is meant for external display only
68
69 if(QCCompositionType::getInstance().getCompositionType() &
70 COMPOSITION_TYPE_MDP)
71 return false;
72 if(triedSystem)
73 return false;
74 if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
75 return false;
76 if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
77 return false;
78 //Return true by default
79 return true;
80 }
81
82 /* The default policy is to return cached buffers unless the client explicity
83 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
84 * read or written in software. Any combination with a _RARELY_ flag will be
85 * treated as uncached. */
useUncached(const int & usage)86 static bool useUncached(const int& usage) {
87 if ((usage & GRALLOC_USAGE_PROTECTED) or
88 (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
89 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
90 ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
91 return true;
92
93 return false;
94 }
95
96 //-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo()97 AdrenoMemInfo::AdrenoMemInfo()
98 {
99 LINK_adreno_compute_aligned_width_and_height = NULL;
100 LINK_adreno_compute_padding = NULL;
101 LINK_adreno_isMacroTilingSupportedByGpu = NULL;
102 LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
103 LINK_adreno_isUBWCSupportedByGpu = NULL;
104
105 libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
106 if (libadreno_utils) {
107 *(void **)&LINK_adreno_compute_aligned_width_and_height =
108 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
109 *(void **)&LINK_adreno_compute_padding =
110 ::dlsym(libadreno_utils, "compute_surface_padding");
111 *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
112 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
113 *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
114 ::dlsym(libadreno_utils,
115 "compute_compressedfmt_aligned_width_and_height");
116 *(void **)&LINK_adreno_isUBWCSupportedByGpu =
117 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
118 }
119 }
120
~AdrenoMemInfo()121 AdrenoMemInfo::~AdrenoMemInfo()
122 {
123 if (libadreno_utils) {
124 ::dlclose(libadreno_utils);
125 }
126 }
127
isMacroTilingSupportedByGPU()128 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
129 {
130 if ((libadreno_utils)) {
131 if(LINK_adreno_isMacroTilingSupportedByGpu) {
132 return LINK_adreno_isMacroTilingSupportedByGpu();
133 }
134 }
135 return 0;
136 }
137
138
isUncompressedRgbFormat(int format)139 bool isUncompressedRgbFormat(int format)
140 {
141 bool is_rgb_format = false;
142
143 switch (format)
144 {
145 case HAL_PIXEL_FORMAT_RGBA_8888:
146 case HAL_PIXEL_FORMAT_RGBX_8888:
147 case HAL_PIXEL_FORMAT_RGB_888:
148 case HAL_PIXEL_FORMAT_RGB_565:
149 case HAL_PIXEL_FORMAT_BGRA_8888:
150 case HAL_PIXEL_FORMAT_RGBA_5551:
151 case HAL_PIXEL_FORMAT_RGBA_4444:
152 case HAL_PIXEL_FORMAT_R_8:
153 case HAL_PIXEL_FORMAT_RG_88:
154 case HAL_PIXEL_FORMAT_BGRX_8888: // Intentional fallthrough
155 is_rgb_format = true;
156 break;
157 default:
158 break;
159 }
160
161 return is_rgb_format;
162 }
163
getAlignedWidthAndHeight(int width,int height,int format,int usage,int & aligned_w,int & aligned_h)164 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
165 int usage, int& aligned_w, int& aligned_h)
166 {
167
168 // Currently surface padding is only computed for RGB* surfaces.
169 if (isUncompressedRgbFormat(format) == true) {
170 int tileEnabled = isMacroTileEnabled(format, usage);
171 AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
172 height, format, tileEnabled, aligned_w, aligned_h);
173 return;
174 }
175
176 if (isUBwcEnabled(format, usage)) {
177 getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
178 return;
179 }
180
181 aligned_w = width;
182 aligned_h = height;
183 switch (format)
184 {
185 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
186 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
187 aligned_w = ALIGN(width, 32);
188 break;
189 case HAL_PIXEL_FORMAT_RAW16:
190 aligned_w = ALIGN(width, 16);
191 break;
192 case HAL_PIXEL_FORMAT_RAW10:
193 aligned_w = ALIGN(width * 10 /8, 8);
194 break;
195 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
196 aligned_w = ALIGN(width, 128);
197 break;
198 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
199 case HAL_PIXEL_FORMAT_YV12:
200 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
201 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
202 case HAL_PIXEL_FORMAT_YCbCr_422_I:
203 case HAL_PIXEL_FORMAT_YCrCb_422_I:
204 aligned_w = ALIGN(width, 16);
205 break;
206 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
207 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
208 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
209 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
210 break;
211 case HAL_PIXEL_FORMAT_BLOB:
212 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
213 break;
214 case HAL_PIXEL_FORMAT_NV21_ZSL:
215 aligned_w = ALIGN(width, 64);
216 aligned_h = ALIGN(height, 64);
217 break;
218 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
219 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
220 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
221 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
222 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
223 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
224 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
225 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
226 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
227 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
228 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
229 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
230 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
231 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
232 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
233 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
234 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
235 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
236 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
237 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
238 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
239 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
240 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
241 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
242 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
243 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
244 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
245 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
246 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
247 int bytesPerPixel = 0;
248 int raster_mode = 0; //Adreno unknown raster mode.
249 int padding_threshold = 512; //Threshold for padding
250 //surfaces.
251
252 LINK_adreno_compute_compressedfmt_aligned_width_and_height(
253 width, height, format, 0,raster_mode, padding_threshold,
254 &aligned_w, &aligned_h, &bytesPerPixel);
255 } else {
256 ALOGW("%s: Warning!! Symbols" \
257 " compute_compressedfmt_aligned_width_and_height" \
258 " not found", __FUNCTION__);
259 }
260 break;
261 default: break;
262 }
263 }
264
getGpuAlignedWidthHeight(int width,int height,int format,int tile_enabled,int & aligned_w,int & aligned_h)265 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
266 int tile_enabled, int& aligned_w, int& aligned_h)
267 {
268 aligned_w = ALIGN(width, 32);
269 aligned_h = ALIGN(height, 32);
270
271 // Don't add any additional padding if debug.gralloc.map_fb_memory
272 // is enabled
273 char property[PROPERTY_VALUE_MAX];
274 if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
275 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
276 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
277 return;
278 }
279
280 int bpp = 4;
281 switch(format)
282 {
283 case HAL_PIXEL_FORMAT_RGB_888:
284 bpp = 3;
285 break;
286 case HAL_PIXEL_FORMAT_RGB_565:
287 case HAL_PIXEL_FORMAT_RGBA_5551:
288 case HAL_PIXEL_FORMAT_RGBA_4444:
289 bpp = 2;
290 break;
291 default: break;
292 }
293
294 if (libadreno_utils) {
295 int raster_mode = 0; // Adreno unknown raster mode.
296 int padding_threshold = 512; // Threshold for padding surfaces.
297 // the function below computes aligned width and aligned height
298 // based on linear or macro tile mode selected.
299 if(LINK_adreno_compute_aligned_width_and_height) {
300 LINK_adreno_compute_aligned_width_and_height(width,
301 height, bpp, tile_enabled,
302 raster_mode, padding_threshold,
303 &aligned_w, &aligned_h);
304
305 } else if(LINK_adreno_compute_padding) {
306 int surface_tile_height = 1; // Linear surface
307 aligned_w = LINK_adreno_compute_padding(width, bpp,
308 surface_tile_height, raster_mode,
309 padding_threshold);
310 ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
311 __FUNCTION__);
312 } else {
313 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
314 "compute_aligned_width_and_height not found", __FUNCTION__);
315 }
316 }
317 }
318
isUBWCSupportedByGPU(int format)319 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
320 {
321 if (libadreno_utils) {
322 if (LINK_adreno_isUBWCSupportedByGpu) {
323 ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
324 return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
325 }
326 }
327 return 0;
328 }
329
getGpuPixelFormat(int hal_format)330 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
331 {
332 switch (hal_format) {
333 case HAL_PIXEL_FORMAT_RGBA_8888:
334 return ADRENO_PIXELFORMAT_R8G8B8A8;
335 case HAL_PIXEL_FORMAT_RGB_565:
336 return ADRENO_PIXELFORMAT_B5G6R5;
337 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
338 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
339 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
340 return ADRENO_PIXELFORMAT_NV12;
341 default:
342 ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
343 break;
344 }
345 return ADRENO_PIXELFORMAT_UNKNOWN;
346 }
347
348 //-------------- IAllocController-----------------------//
349 IAllocController* IAllocController::sController = NULL;
getInstance(void)350 IAllocController* IAllocController::getInstance(void)
351 {
352 if(sController == NULL) {
353 sController = new IonController();
354 }
355 return sController;
356 }
357
358
359 //-------------- IonController-----------------------//
IonController()360 IonController::IonController()
361 {
362 allocateIonMem();
363 }
364
allocateIonMem()365 void IonController::allocateIonMem()
366 {
367 mIonAlloc = new IonAlloc();
368 }
369
allocate(alloc_data & data,int usage)370 int IonController::allocate(alloc_data& data, int usage)
371 {
372 int ionFlags = 0;
373 int ret;
374
375 data.uncached = useUncached(usage);
376 data.allocType = 0;
377
378 if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
379 ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
380
381 if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
382 ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
383
384 if(usage & GRALLOC_USAGE_PROTECTED) {
385 ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
386 ionFlags |= ION_SECURE;
387 #ifdef ION_FLAG_ALLOW_NON_CONTIG
388 if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
389 ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
390 }
391 #endif
392 } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
393 //MM Heap is exclusively a secure heap.
394 //If it is used for non secure cases, fallback to IOMMU heap
395 ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
396 cannot be used as an insecure heap!\
397 trying to use IOMMU instead !!");
398 ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
399 }
400
401 if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
402 ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
403
404 if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
405 ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
406
407 if(ionFlags & ION_SECURE)
408 data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
409
410 // if no flags are set, default to
411 // SF + IOMMU heaps, so that bypass can work
412 // we can fall back to system heap if
413 // we run out.
414 if(!ionFlags)
415 ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
416
417 data.flags = ionFlags;
418 ret = mIonAlloc->alloc_buffer(data);
419
420 // Fallback
421 if(ret < 0 && canFallback(usage,
422 (ionFlags & ION_SYSTEM_HEAP_ID)))
423 {
424 ALOGW("Falling back to system heap");
425 data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
426 ret = mIonAlloc->alloc_buffer(data);
427 }
428
429 if(ret >= 0 ) {
430 data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
431 }
432
433 return ret;
434 }
435
getAllocator(int flags)436 IMemAlloc* IonController::getAllocator(int flags)
437 {
438 IMemAlloc* memalloc = NULL;
439 if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
440 memalloc = mIonAlloc;
441 } else {
442 ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
443 }
444
445 return memalloc;
446 }
447
isMacroTileEnabled(int format,int usage)448 bool isMacroTileEnabled(int format, int usage)
449 {
450 bool tileEnabled = false;
451
452 // Check whether GPU & MDSS supports MacroTiling feature
453 if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
454 qdutils::MDPVersion::getInstance().supportsMacroTile())
455 {
456 // check the format
457 switch(format)
458 {
459 case HAL_PIXEL_FORMAT_RGBA_8888:
460 case HAL_PIXEL_FORMAT_RGBX_8888:
461 case HAL_PIXEL_FORMAT_BGRA_8888:
462 case HAL_PIXEL_FORMAT_RGB_565:
463 {
464 tileEnabled = true;
465 // check the usage flags
466 if (usage & (GRALLOC_USAGE_SW_READ_MASK |
467 GRALLOC_USAGE_SW_WRITE_MASK)) {
468 // Application intends to use CPU for rendering
469 tileEnabled = false;
470 }
471 break;
472 }
473 default:
474 break;
475 }
476 }
477 return tileEnabled;
478 }
479
480 // helper function
getSize(int format,int width,int height,int usage,const int alignedw,const int alignedh)481 unsigned int getSize(int format, int width, int height, int usage,
482 const int alignedw, const int alignedh) {
483
484 if (isUBwcEnabled(format, usage)) {
485 return getUBwcSize(width, height, format, alignedw, alignedh);
486 }
487
488 unsigned int size = 0;
489 switch (format) {
490 case HAL_PIXEL_FORMAT_RGBA_8888:
491 case HAL_PIXEL_FORMAT_RGBX_8888:
492 case HAL_PIXEL_FORMAT_BGRA_8888:
493 size = alignedw * alignedh * 4;
494 break;
495 case HAL_PIXEL_FORMAT_RGB_888:
496 size = alignedw * alignedh * 3;
497 break;
498 case HAL_PIXEL_FORMAT_RGB_565:
499 case HAL_PIXEL_FORMAT_RGBA_5551:
500 case HAL_PIXEL_FORMAT_RGBA_4444:
501 case HAL_PIXEL_FORMAT_RAW16:
502 size = alignedw * alignedh * 2;
503 break;
504 case HAL_PIXEL_FORMAT_RAW10:
505 size = ALIGN(alignedw * alignedh, 4096);
506 break;
507 // adreno formats
508 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
509 size = ALIGN(alignedw*alignedh, 4096);
510 size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
511 break;
512 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
513 // The chroma plane is subsampled,
514 // but the pitch in bytes is unchanged
515 // The GPU needs 4K alignment, but the video decoder needs 8K
516 size = ALIGN( alignedw * alignedh, 8192);
517 size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
518 break;
519 case HAL_PIXEL_FORMAT_YV12:
520 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
521 ALOGE("w or h is odd for the YV12 format");
522 return 0;
523 }
524 size = alignedw*alignedh +
525 (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
526 size = ALIGN(size, (unsigned int)4096);
527 break;
528 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
529 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
530 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
531 break;
532 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
533 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
534 case HAL_PIXEL_FORMAT_YCbCr_422_I:
535 case HAL_PIXEL_FORMAT_YCrCb_422_I:
536 if(width & 1) {
537 ALOGE("width is odd for the YUV422_SP format");
538 return 0;
539 }
540 size = ALIGN(alignedw * alignedh * 2, 4096);
541 break;
542 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
543 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
544 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
545 break;
546 case HAL_PIXEL_FORMAT_BLOB:
547 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
548 if(height != 1) {
549 ALOGE("%s: Buffers with RAW_OPAQUE/blob formats \
550 must have height==1 ", __FUNCTION__);
551 return 0;
552 }
553 size = width;
554 break;
555 case HAL_PIXEL_FORMAT_NV21_ZSL:
556 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
557 break;
558 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
559 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
560 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
561 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
562 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
563 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
564 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
565 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
566 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
567 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
568 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
569 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
570 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
571 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
572 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
573 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
574 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
575 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
576 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
577 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
578 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
579 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
580 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
581 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
582 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
583 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
584 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
585 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
586 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
587 break;
588 default:
589 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
590 return 0;
591 }
592 return size;
593 }
594
getBufferSizeAndDimensions(int width,int height,int format,int & alignedw,int & alignedh)595 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
596 int& alignedw, int &alignedh)
597 {
598 unsigned int size;
599
600 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
601 height,
602 format,
603 0,
604 alignedw,
605 alignedh);
606
607 size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
608
609 return size;
610 }
611
612
getBufferSizeAndDimensions(int width,int height,int format,int usage,int & alignedw,int & alignedh)613 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
614 int usage, int& alignedw, int &alignedh)
615 {
616 unsigned int size;
617
618 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
619 height,
620 format,
621 usage,
622 alignedw,
623 alignedh);
624
625 size = getSize(format, width, height, usage, alignedw, alignedh);
626
627 return size;
628 }
629
630
getBufferAttributes(int width,int height,int format,int usage,int & alignedw,int & alignedh,int & tileEnabled,unsigned int & size)631 void getBufferAttributes(int width, int height, int format, int usage,
632 int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
633 {
634 tileEnabled = isMacroTileEnabled(format, usage);
635
636 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
637 height,
638 format,
639 usage,
640 alignedw,
641 alignedh);
642 size = getSize(format, width, height, usage, alignedw, alignedh);
643 }
644
getYUVPlaneInfo(private_handle_t * hnd,struct android_ycbcr * ycbcr)645 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
646 {
647 int err = 0;
648 unsigned int ystride, cstride;
649 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
650
651 // Get the chroma offsets from the handle width/height. We take advantage
652 // of the fact the width _is_ the stride
653 switch (hnd->format) {
654 //Semiplanar
655 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
656 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
657 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
658 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
659 ystride = cstride = hnd->width;
660 ycbcr->y = (void*)hnd->base;
661 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
662 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
663 ycbcr->ystride = ystride;
664 ycbcr->cstride = cstride;
665 ycbcr->chroma_step = 2;
666 break;
667
668 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
669 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
670 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
671 case HAL_PIXEL_FORMAT_NV21_ZSL:
672 case HAL_PIXEL_FORMAT_RAW10:
673 case HAL_PIXEL_FORMAT_RAW16:
674 ystride = cstride = hnd->width;
675 ycbcr->y = (void*)hnd->base;
676 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
677 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
678 ycbcr->ystride = ystride;
679 ycbcr->cstride = cstride;
680 ycbcr->chroma_step = 2;
681 break;
682
683 //Planar
684 case HAL_PIXEL_FORMAT_YV12:
685 ystride = hnd->width;
686 cstride = ALIGN(hnd->width/2, 16);
687 ycbcr->y = (void*)hnd->base;
688 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
689 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
690 cstride * hnd->height/2);
691 ycbcr->ystride = ystride;
692 ycbcr->cstride = cstride;
693 ycbcr->chroma_step = 1;
694
695 break;
696 //Unsupported formats
697 case HAL_PIXEL_FORMAT_YCbCr_422_I:
698 case HAL_PIXEL_FORMAT_YCrCb_422_I:
699 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
700 default:
701 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
702 hnd->format);
703 err = -EINVAL;
704 }
705 return err;
706
707 }
708
709
710
711 // Allocate buffer from width, height and format into a
712 // private_handle_t. It is the responsibility of the caller
713 // to free the buffer using the free_buffer function
alloc_buffer(private_handle_t ** pHnd,int w,int h,int format,int usage)714 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
715 {
716 alloc_data data;
717 int alignedw, alignedh;
718 gralloc::IAllocController* sAlloc =
719 gralloc::IAllocController::getInstance();
720 data.base = 0;
721 data.fd = -1;
722 data.offset = 0;
723 data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
724 alignedh);
725
726 data.align = getpagesize();
727 data.uncached = useUncached(usage);
728 int allocFlags = usage;
729
730 int err = sAlloc->allocate(data, allocFlags);
731 if (0 != err) {
732 ALOGE("%s: allocate failed", __FUNCTION__);
733 return -ENOMEM;
734 }
735
736 private_handle_t* hnd = new private_handle_t(data.fd, data.size,
737 data.allocType, 0, format,
738 alignedw, alignedh);
739 hnd->base = (uint64_t) data.base;
740 hnd->offset = data.offset;
741 hnd->gpuaddr = 0;
742 *pHnd = hnd;
743 return 0;
744 }
745
free_buffer(private_handle_t * hnd)746 void free_buffer(private_handle_t *hnd)
747 {
748 gralloc::IAllocController* sAlloc =
749 gralloc::IAllocController::getInstance();
750 if (hnd && hnd->fd > 0) {
751 IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
752 memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
753 }
754 if(hnd)
755 delete hnd;
756
757 }
758
759 // UBWC helper functions
isUBwcFormat(int format)760 static bool isUBwcFormat(int format)
761 {
762 // Explicitly defined UBWC formats
763 switch(format)
764 {
765 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
766 return true;
767 default:
768 return false;
769 }
770 }
771
isUBwcSupported(int format)772 static bool isUBwcSupported(int format)
773 {
774 // Existing HAL formats with UBWC support
775 switch(format)
776 {
777 case HAL_PIXEL_FORMAT_RGB_565:
778 case HAL_PIXEL_FORMAT_RGBA_8888:
779 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
780 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
781 return true;
782 default:
783 return false;
784 }
785 }
786
isUBwcEnabled(int format,int usage)787 bool isUBwcEnabled(int format, int usage)
788 {
789 if (isUBwcFormat(format) ||
790 ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)))
791 {
792 // Allow UBWC, only if GPU supports it and CPU usage flags are not set
793 if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
794 !(usage & (GRALLOC_USAGE_SW_READ_MASK |
795 GRALLOC_USAGE_SW_WRITE_MASK))) {
796 return true;
797 }
798 }
799 return false;
800 }
801
getUBwcWidthAndHeight(int width,int height,int format,int & aligned_w,int & aligned_h)802 static void getUBwcWidthAndHeight(int width, int height, int format,
803 int& aligned_w, int& aligned_h)
804 {
805 switch (format)
806 {
807 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
808 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
809 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
810 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
811 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
812 break;
813 default:
814 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
815 aligned_w = 0;
816 aligned_h = 0;
817 break;
818 }
819 }
820
getUBwcBlockSize(int bpp,int & block_width,int & block_height)821 static void getUBwcBlockSize(int bpp, int& block_width, int& block_height)
822 {
823 block_width = 0;
824 block_height = 0;
825
826 switch(bpp)
827 {
828 case 2:
829 case 4:
830 block_width = 16;
831 block_height = 4;
832 break;
833 case 8:
834 block_width = 8;
835 block_height = 4;
836 break;
837 case 16:
838 block_width = 4;
839 block_height = 4;
840 break;
841 default:
842 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
843 break;
844 }
845 }
846
getUBwcMetaBufferSize(int width,int height,int bpp)847 static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp)
848 {
849 unsigned int size = 0;
850 int meta_width, meta_height;
851 int block_width, block_height;
852
853 getUBwcBlockSize(bpp, block_width, block_height);
854
855 if (!block_width || !block_height) {
856 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
857 return size;
858 }
859
860 // Align meta buffer height to 16 blocks
861 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
862
863 // Align meta buffer width to 64 blocks
864 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
865
866 // Align meta buffer size to 4K
867 size = ((meta_width * meta_height), 4096);
868 return size;
869 }
870
getUBwcSize(int width,int height,int format,const int alignedw,const int alignedh)871 static unsigned int getUBwcSize(int width, int height, int format,
872 const int alignedw, const int alignedh) {
873
874 unsigned int size = 0;
875 switch (format) {
876 case HAL_PIXEL_FORMAT_RGB_565:
877 size = alignedw * alignedh * 2;
878 size += getUBwcMetaBufferSize(width, height, 2);
879 break;
880 case HAL_PIXEL_FORMAT_RGBA_8888:
881 size = alignedw * alignedh * 4;
882 size += getUBwcMetaBufferSize(width, height, 4);
883 break;
884 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
885 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
886 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
887 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
888 break;
889 default:
890 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
891 break;
892 }
893 return size;
894 }
895