1 /*
2 * Copyright (c) 2011 - 2016, 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 "qd_utils.h"
39 #include <qdMetaData.h>
40 #include <utils/Singleton.h>
41 #include <utils/Mutex.h>
42
43
44 #ifdef VENUS_COLOR_FORMAT
45 #include <media/msm_media_info.h>
46 #else
47 #define VENUS_Y_STRIDE(args...) 0
48 #define VENUS_Y_SCANLINES(args...) 0
49 #define VENUS_BUFFER_SIZE(args...) 0
50 #endif
51
52 #define ASTC_BLOCK_SIZE 16
53
54 #ifndef ION_FLAG_CP_PIXEL
55 #define ION_FLAG_CP_PIXEL 0
56 #endif
57
58 #ifndef ION_FLAG_ALLOW_NON_CONTIG
59 #define ION_FLAG_ALLOW_NON_CONTIG 0
60 #endif
61
62 #ifdef MASTER_SIDE_CP
63 #define CP_HEAP_ID ION_SECURE_HEAP_ID
64 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
65 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
66 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
67 #else // SLAVE_SIDE_CP
68 #define CP_HEAP_ID ION_CP_MM_HEAP_ID
69 #define SD_HEAP_ID CP_HEAP_ID
70 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
71 #define ION_SD_FLAGS ION_SECURE
72 #endif
73
74 using namespace gralloc;
75 using namespace qdutils;
76 using namespace android;
77
78 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
79 ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
80
81 static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
82 static unsigned int getUBwcSize(int, int, int, const int, const int);
83
84 //Common functions
85
86 /* The default policy is to return cached buffers unless the client explicity
87 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
88 * read or written in software. Any combination with a _RARELY_ flag will be
89 * treated as uncached. */
useUncached(const int & usage)90 static bool useUncached(const int& usage) {
91 if ((usage & GRALLOC_USAGE_PROTECTED) or
92 (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
93 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
94 ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
95 return true;
96
97 return false;
98 }
99
100 //------------- MDPCapabilityInfo-----------------------//
MDPCapabilityInfo()101 MDPCapabilityInfo :: MDPCapabilityInfo() {
102 qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
103 qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
104 }
105
106 //------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo()107 AdrenoMemInfo::AdrenoMemInfo()
108 {
109 LINK_adreno_compute_aligned_width_and_height = NULL;
110 LINK_adreno_compute_padding = NULL;
111 LINK_adreno_isMacroTilingSupportedByGpu = NULL;
112 LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
113 LINK_adreno_isUBWCSupportedByGpu = NULL;
114 LINK_adreno_get_gpu_pixel_alignment = NULL;
115
116 libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
117 if (libadreno_utils) {
118 *(void **)&LINK_adreno_compute_aligned_width_and_height =
119 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
120 *(void **)&LINK_adreno_compute_padding =
121 ::dlsym(libadreno_utils, "compute_surface_padding");
122 *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
123 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
124 *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
125 ::dlsym(libadreno_utils,
126 "compute_compressedfmt_aligned_width_and_height");
127 *(void **)&LINK_adreno_isUBWCSupportedByGpu =
128 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
129 *(void **)&LINK_adreno_get_gpu_pixel_alignment =
130 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
131 }
132
133 // Check if the overriding property debug.gralloc.gfx_ubwc_disable
134 // that disables UBWC allocations for the graphics stack is set
135 gfx_ubwc_disable = 0;
136 char property[PROPERTY_VALUE_MAX];
137 property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
138 if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
139 !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
140 gfx_ubwc_disable = 1;
141 }
142 }
143
~AdrenoMemInfo()144 AdrenoMemInfo::~AdrenoMemInfo()
145 {
146 if (libadreno_utils) {
147 ::dlclose(libadreno_utils);
148 }
149 }
150
isMacroTilingSupportedByGPU()151 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
152 {
153 if ((libadreno_utils)) {
154 if(LINK_adreno_isMacroTilingSupportedByGpu) {
155 return LINK_adreno_isMacroTilingSupportedByGpu();
156 }
157 }
158 return 0;
159 }
160
getAlignedWidthAndHeight(const private_handle_t * hnd,int & aligned_w,int & aligned_h)161 void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
162 int& aligned_h) {
163 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
164 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
165 int w = metadata->bufferDim.sliceWidth;
166 int h = metadata->bufferDim.sliceHeight;
167 int f = hnd->format;
168 int usage = 0;
169
170 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
171 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
172 }
173
174 getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
175 } else {
176 aligned_w = hnd->width;
177 aligned_h = hnd->height;
178 }
179
180 }
181
isUncompressedRgbFormat(int format)182 bool isUncompressedRgbFormat(int format)
183 {
184 bool is_rgb_format = false;
185
186 switch (format)
187 {
188 case HAL_PIXEL_FORMAT_RGBA_8888:
189 case HAL_PIXEL_FORMAT_RGBX_8888:
190 case HAL_PIXEL_FORMAT_RGB_888:
191 case HAL_PIXEL_FORMAT_RGB_565:
192 case HAL_PIXEL_FORMAT_BGR_565:
193 case HAL_PIXEL_FORMAT_BGRA_8888:
194 case HAL_PIXEL_FORMAT_RGBA_FP16:
195 case HAL_PIXEL_FORMAT_RGBA_5551:
196 case HAL_PIXEL_FORMAT_RGBA_4444:
197 case HAL_PIXEL_FORMAT_R_8:
198 case HAL_PIXEL_FORMAT_RG_88:
199 case HAL_PIXEL_FORMAT_BGRX_8888:
200 case HAL_PIXEL_FORMAT_RGBA_1010102:
201 case HAL_PIXEL_FORMAT_ARGB_2101010:
202 case HAL_PIXEL_FORMAT_RGBX_1010102:
203 case HAL_PIXEL_FORMAT_XRGB_2101010:
204 case HAL_PIXEL_FORMAT_BGRA_1010102:
205 case HAL_PIXEL_FORMAT_ABGR_2101010:
206 case HAL_PIXEL_FORMAT_BGRX_1010102:
207 case HAL_PIXEL_FORMAT_XBGR_2101010: // Intentional fallthrough
208 is_rgb_format = true;
209 break;
210 default:
211 break;
212 }
213
214 return is_rgb_format;
215 }
216
getAlignedWidthAndHeight(int width,int height,int format,int usage,int & aligned_w,int & aligned_h)217 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
218 int usage, int& aligned_w, int& aligned_h)
219 {
220 bool ubwc_enabled = isUBwcEnabled(format, usage);
221
222 // Currently surface padding is only computed for RGB* surfaces.
223 if (isUncompressedRgbFormat(format) == true) {
224 int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
225 getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
226 } else if (ubwc_enabled) {
227 getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
228 } else {
229 aligned_w = width;
230 aligned_h = height;
231 int alignment = 32;
232 switch (format)
233 {
234 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
235 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
236 if (LINK_adreno_get_gpu_pixel_alignment) {
237 alignment = LINK_adreno_get_gpu_pixel_alignment();
238 }
239 aligned_w = ALIGN(width, alignment);
240 break;
241 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
242 aligned_w = ALIGN(width, alignment);
243 break;
244 case HAL_PIXEL_FORMAT_RAW16:
245 aligned_w = ALIGN(width, 16);
246 break;
247 case HAL_PIXEL_FORMAT_RAW10:
248 aligned_w = ALIGN(width * 10 / 8, 8);
249 break;
250 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
251 aligned_w = ALIGN(width, 128);
252 break;
253 case HAL_PIXEL_FORMAT_YV12:
254 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
255 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
256 case HAL_PIXEL_FORMAT_YCbCr_422_I:
257 case HAL_PIXEL_FORMAT_YCrCb_422_I:
258 aligned_w = ALIGN(width, 16);
259 break;
260 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
261 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
262 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
263 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
264 break;
265 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
266 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
267 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
268 break;
269 case HAL_PIXEL_FORMAT_BLOB:
270 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
271 break;
272 case HAL_PIXEL_FORMAT_NV21_ZSL:
273 aligned_w = ALIGN(width, 64);
274 aligned_h = ALIGN(height, 64);
275 break;
276 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
277 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
278 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
279 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
280 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
281 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
282 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
283 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
284 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
285 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
286 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
287 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
288 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
289 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
290 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
291 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
292 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
293 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
294 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
295 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
296 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
297 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
298 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
299 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
300 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
301 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
302 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
303 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
304 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
305 int bytesPerPixel = 0;
306 int raster_mode = 0; //Adreno unknown raster mode.
307 int padding_threshold = 512; //Threshold for padding
308 //surfaces.
309
310 LINK_adreno_compute_compressedfmt_aligned_width_and_height(
311 width, height, format, 0,raster_mode, padding_threshold,
312 &aligned_w, &aligned_h, &bytesPerPixel);
313 } else {
314 ALOGW("%s: Warning!! Symbols" \
315 " compute_compressedfmt_aligned_width_and_height" \
316 " not found", __FUNCTION__);
317 }
318 break;
319 default: break;
320 }
321 }
322 }
323
getGpuAlignedWidthHeight(int width,int height,int format,int tile_enabled,int & aligned_w,int & aligned_h)324 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
325 int tile_enabled, int& aligned_w, int& aligned_h)
326 {
327 aligned_w = ALIGN(width, 32);
328 aligned_h = ALIGN(height, 32);
329
330 // Don't add any additional padding if debug.gralloc.map_fb_memory
331 // is enabled
332 char property[PROPERTY_VALUE_MAX];
333 if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
334 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
335 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
336 return;
337 }
338
339 int bpp = 4;
340 switch(format)
341 {
342 case HAL_PIXEL_FORMAT_RGBA_FP16:
343 bpp = 8;
344 break;
345 case HAL_PIXEL_FORMAT_RGB_888:
346 bpp = 3;
347 break;
348 case HAL_PIXEL_FORMAT_RGB_565:
349 case HAL_PIXEL_FORMAT_BGR_565:
350 case HAL_PIXEL_FORMAT_RGBA_5551:
351 case HAL_PIXEL_FORMAT_RGBA_4444:
352 bpp = 2;
353 break;
354 default: break;
355 }
356
357 if (libadreno_utils) {
358 int raster_mode = 0; // Adreno unknown raster mode.
359 int padding_threshold = 512; // Threshold for padding surfaces.
360 // the function below computes aligned width and aligned height
361 // based on linear or macro tile mode selected.
362 if(LINK_adreno_compute_aligned_width_and_height) {
363 LINK_adreno_compute_aligned_width_and_height(width,
364 height, bpp, tile_enabled,
365 raster_mode, padding_threshold,
366 &aligned_w, &aligned_h);
367
368 } else if(LINK_adreno_compute_padding) {
369 int surface_tile_height = 1; // Linear surface
370 aligned_w = LINK_adreno_compute_padding(width, bpp,
371 surface_tile_height, raster_mode,
372 padding_threshold);
373 ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
374 __FUNCTION__);
375 } else {
376 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
377 "compute_aligned_width_and_height not found", __FUNCTION__);
378 }
379 }
380 }
381
isUBWCSupportedByGPU(int format)382 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
383 {
384 if (!gfx_ubwc_disable && libadreno_utils) {
385 if (LINK_adreno_isUBWCSupportedByGpu) {
386 ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
387 return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
388 }
389 }
390 return 0;
391 }
392
getGpuPixelFormat(int hal_format)393 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
394 {
395 switch (hal_format) {
396 case HAL_PIXEL_FORMAT_RGBA_8888:
397 return ADRENO_PIXELFORMAT_R8G8B8A8;
398 case HAL_PIXEL_FORMAT_RGBX_8888:
399 return ADRENO_PIXELFORMAT_R8G8B8X8;
400 case HAL_PIXEL_FORMAT_RGB_565:
401 return ADRENO_PIXELFORMAT_B5G6R5;
402 case HAL_PIXEL_FORMAT_BGR_565:
403 return ADRENO_PIXELFORMAT_R5G6B5;
404 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
405 return ADRENO_PIXELFORMAT_NV12;
406 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
407 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
408 return ADRENO_PIXELFORMAT_NV12_EXT;
409 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
410 return ADRENO_PIXELFORMAT_TP10;
411 case HAL_PIXEL_FORMAT_RGBA_1010102:
412 return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
413 case HAL_PIXEL_FORMAT_RGBX_1010102:
414 return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
415 case HAL_PIXEL_FORMAT_ABGR_2101010:
416 return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
417 default:
418 ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
419 break;
420 }
421 return ADRENO_PIXELFORMAT_UNKNOWN;
422 }
423
424 //-------------- IAllocController-----------------------//
425 IAllocController* IAllocController::sController = NULL;
getInstance(void)426 IAllocController* IAllocController::getInstance(void)
427 {
428 if(sController == NULL) {
429 sController = new IonController();
430 }
431 return sController;
432 }
433
434
435 //-------------- IonController-----------------------//
IonController()436 IonController::IonController()
437 {
438 allocateIonMem();
439
440 char property[PROPERTY_VALUE_MAX];
441 property_get("video.disable.ubwc", property, "0");
442 mDisableUBWCForEncode = atoi(property);
443 }
444
allocateIonMem()445 void IonController::allocateIonMem()
446 {
447 mIonAlloc = new IonAlloc();
448 }
449
allocate(alloc_data & data,int usage)450 int IonController::allocate(alloc_data& data, int usage)
451 {
452 int ionFlags = 0;
453 int ionHeapId = 0;
454 int ret;
455
456 data.uncached = useUncached(usage);
457 data.allocType = 0;
458
459 if(usage & GRALLOC_USAGE_PROTECTED) {
460 if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
461 ionHeapId = ION_HEAP(SD_HEAP_ID);
462 /*
463 * There is currently no flag in ION for Secure Display
464 * VM. Please add it to the define once available.
465 */
466 ionFlags |= ION_SD_FLAGS;
467 } else {
468 ionHeapId = ION_HEAP(CP_HEAP_ID);
469 ionFlags |= ION_CP_FLAGS;
470 }
471 } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
472 //MM Heap is exclusively a secure heap.
473 //If it is used for non secure cases, fallback to IOMMU heap
474 ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
475 cannot be used as an insecure heap!\
476 trying to use system heap instead !!");
477 ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
478 }
479
480 if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
481 ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
482
483 if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
484 ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
485
486 if(ionFlags & ION_SECURE)
487 data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
488
489 // if no ion heap flags are set, default to system heap
490 if(!ionHeapId)
491 ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
492
493 //At this point we should have the right heap set, there is no fallback
494 data.flags = ionFlags;
495 data.heapId = ionHeapId;
496 ret = mIonAlloc->alloc_buffer(data);
497
498 if(ret >= 0 ) {
499 data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
500 } else {
501 ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
502 __FUNCTION__, ionHeapId, ionFlags);
503 }
504
505 return ret;
506 }
507
getAllocator(int flags)508 IMemAlloc* IonController::getAllocator(int flags)
509 {
510 IMemAlloc* memalloc = NULL;
511 if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
512 memalloc = mIonAlloc;
513 } else {
514 ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
515 }
516
517 return memalloc;
518 }
519
isMacroTileEnabled(int format,int usage)520 bool isMacroTileEnabled(int format, int usage)
521 {
522 bool tileEnabled = false;
523 // Check whether GPU & MDSS supports MacroTiling feature
524 if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
525 MDPCapabilityInfo::getInstance().isMacroTilingSupportedByMDP())
526 {
527 // check the format
528 switch(format)
529 {
530 case HAL_PIXEL_FORMAT_RGBA_8888:
531 case HAL_PIXEL_FORMAT_RGBX_8888:
532 case HAL_PIXEL_FORMAT_BGRA_8888:
533 case HAL_PIXEL_FORMAT_RGB_565:
534 case HAL_PIXEL_FORMAT_BGR_565:
535 {
536 tileEnabled = true;
537 // check the usage flags
538 if (usage & (GRALLOC_USAGE_SW_READ_MASK |
539 GRALLOC_USAGE_SW_WRITE_MASK)) {
540 // Application intends to use CPU for rendering
541 tileEnabled = false;
542 }
543 break;
544 }
545 default:
546 break;
547 }
548 }
549 return tileEnabled;
550 }
551
552 // helper function
getSize(int format,int width,int height,int usage,const int alignedw,const int alignedh)553 unsigned int getSize(int format, int width, int height, int usage,
554 const int alignedw, const int alignedh) {
555
556 if (isUBwcEnabled(format, usage)) {
557 return getUBwcSize(width, height, format, alignedw, alignedh);
558 }
559
560 unsigned int size = 0;
561 switch (format) {
562 case HAL_PIXEL_FORMAT_RGBA_FP16:
563 size = alignedw * alignedh * 8;
564 break;
565 case HAL_PIXEL_FORMAT_RGBA_8888:
566 case HAL_PIXEL_FORMAT_RGBX_8888:
567 case HAL_PIXEL_FORMAT_BGRA_8888:
568 case HAL_PIXEL_FORMAT_RGBA_1010102:
569 case HAL_PIXEL_FORMAT_ARGB_2101010:
570 case HAL_PIXEL_FORMAT_RGBX_1010102:
571 case HAL_PIXEL_FORMAT_XRGB_2101010:
572 case HAL_PIXEL_FORMAT_BGRA_1010102:
573 case HAL_PIXEL_FORMAT_ABGR_2101010:
574 case HAL_PIXEL_FORMAT_BGRX_1010102:
575 case HAL_PIXEL_FORMAT_XBGR_2101010:
576 size = alignedw * alignedh * 4;
577 break;
578 case HAL_PIXEL_FORMAT_RGB_888:
579 size = alignedw * alignedh * 3;
580 break;
581 case HAL_PIXEL_FORMAT_RGB_565:
582 case HAL_PIXEL_FORMAT_BGR_565:
583 case HAL_PIXEL_FORMAT_RGBA_5551:
584 case HAL_PIXEL_FORMAT_RGBA_4444:
585 case HAL_PIXEL_FORMAT_RAW16:
586 size = alignedw * alignedh * 2;
587 break;
588 case HAL_PIXEL_FORMAT_RAW10:
589 size = ALIGN(alignedw * alignedh, 4096);
590 break;
591
592 // adreno formats
593 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
594 size = ALIGN(alignedw*alignedh, 4096);
595 size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
596 break;
597 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
598 // The chroma plane is subsampled,
599 // but the pitch in bytes is unchanged
600 // The GPU needs 4K alignment, but the video decoder needs 8K
601 size = ALIGN( alignedw * alignedh, 8192);
602 size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
603 break;
604 case HAL_PIXEL_FORMAT_YV12:
605 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
606 ALOGE("w or h is odd for the YV12 format");
607 return 0;
608 }
609 size = alignedw*alignedh +
610 (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
611 size = ALIGN(size, (unsigned int)4096);
612 break;
613 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
614 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
615 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
616 break;
617 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
618 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
619 case HAL_PIXEL_FORMAT_YCbCr_422_I:
620 case HAL_PIXEL_FORMAT_YCrCb_422_I:
621 if(width & 1) {
622 ALOGE("width is odd for the YUV422_SP format");
623 return 0;
624 }
625 size = ALIGN(alignedw * alignedh * 2, 4096);
626 break;
627 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
628 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
629 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
630 break;
631 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
632 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
633 break;
634 case HAL_PIXEL_FORMAT_BLOB:
635 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
636 if(height != 1) {
637 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
638 must have height==1 ", __FUNCTION__);
639 return 0;
640 }
641 size = width;
642 break;
643 case HAL_PIXEL_FORMAT_NV21_ZSL:
644 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
645 break;
646 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
647 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
648 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
649 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
650 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
651 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
652 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
653 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
654 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
655 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
656 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
657 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
658 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
659 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
660 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
661 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
662 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
663 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
664 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
665 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
666 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
667 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
668 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
669 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
670 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
671 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
672 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
673 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
674 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
675 break;
676 default:
677 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
678 return 0;
679 }
680 return size;
681 }
682
getBufferSizeAndDimensions(int width,int height,int format,int & alignedw,int & alignedh)683 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
684 int& alignedw, int &alignedh)
685 {
686 unsigned int size;
687
688 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
689 height,
690 format,
691 0,
692 alignedw,
693 alignedh);
694
695 size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
696
697 return size;
698 }
699
700
getBufferSizeAndDimensions(int width,int height,int format,int usage,int & alignedw,int & alignedh)701 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
702 int usage, int& alignedw, int &alignedh)
703 {
704 unsigned int size;
705
706 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
707 height,
708 format,
709 usage,
710 alignedw,
711 alignedh);
712
713 size = getSize(format, width, height, usage, alignedw, alignedh);
714
715 return size;
716 }
717
718
getBufferAttributes(int width,int height,int format,int usage,int & alignedw,int & alignedh,int & tiled,unsigned int & size)719 void getBufferAttributes(int width, int height, int format, int usage,
720 int& alignedw, int &alignedh, int& tiled, unsigned int& size)
721 {
722 tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);
723
724 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
725 height,
726 format,
727 usage,
728 alignedw,
729 alignedh);
730 size = getSize(format, width, height, usage, alignedw, alignedh);
731 }
732
getYuvUbwcSPPlaneInfo(uint64_t base,int width,int height,int color_format,struct android_ycbcr * ycbcr)733 void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
734 int color_format, struct android_ycbcr* ycbcr)
735 {
736 // UBWC buffer has these 4 planes in the following sequence:
737 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
738 unsigned int y_meta_stride, y_meta_height, y_meta_size;
739 unsigned int y_stride, y_height, y_size;
740 unsigned int c_meta_stride, c_meta_height, c_meta_size;
741 unsigned int alignment = 4096;
742
743 y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
744 y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
745 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
746
747 y_stride = VENUS_Y_STRIDE(color_format, width);
748 y_height = VENUS_Y_SCANLINES(color_format, height);
749 y_size = ALIGN((y_stride * y_height), alignment);
750
751 c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
752 c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
753 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
754
755 ycbcr->y = (void*)(base + y_meta_size);
756 ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
757 ycbcr->cr = (void*)(base + y_meta_size + y_size +
758 c_meta_size + 1);
759 ycbcr->ystride = y_stride;
760 ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
761 }
762
getYuvSPPlaneInfo(uint64_t base,int width,int height,int bpp,struct android_ycbcr * ycbcr)763 void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
764 struct android_ycbcr* ycbcr)
765 {
766 unsigned int ystride, cstride;
767
768 ystride = cstride = width * bpp;
769 ycbcr->y = (void*)base;
770 ycbcr->cb = (void*)(base + ystride * height);
771 ycbcr->cr = (void*)(base + ystride * height + 1);
772 ycbcr->ystride = ystride;
773 ycbcr->cstride = cstride;
774 ycbcr->chroma_step = 2 * bpp;
775 }
776
getYUVPlaneInfo(private_handle_t * hnd,struct android_ycbcr * ycbcr)777 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
778 {
779 int err = 0;
780 int width = hnd->width;
781 int height = hnd->height;
782 int format = hnd->format;
783
784 unsigned int ystride, cstride;
785
786 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
787 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
788
789 // Check if UBWC buffer has been rendered in linear format.
790 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
791 format = metadata->linearFormat;
792 }
793
794 // Check metadata if the geometry has been updated.
795 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
796 int usage = 0;
797
798 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
799 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
800 }
801
802 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
803 metadata->bufferDim.sliceHeight, format, usage, width, height);
804 }
805
806 // Get the chroma offsets from the handle width/height. We take advantage
807 // of the fact the width _is_ the stride
808 switch (format) {
809 //Semiplanar
810 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
811 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
812 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
813 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
814 getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
815 break;
816
817 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
818 getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
819 break;
820
821 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
822 getYuvUbwcSPPlaneInfo(hnd->base, width, height,
823 COLOR_FMT_NV12_UBWC, ycbcr);
824 ycbcr->chroma_step = 2;
825 break;
826
827 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
828 getYuvUbwcSPPlaneInfo(hnd->base, width, height,
829 COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
830 ycbcr->chroma_step = 3;
831 break;
832
833 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
834 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
835 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
836 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
837 case HAL_PIXEL_FORMAT_NV21_ZSL:
838 case HAL_PIXEL_FORMAT_RAW16:
839 case HAL_PIXEL_FORMAT_RAW10:
840 getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
841 std::swap(ycbcr->cb, ycbcr->cr);
842 break;
843
844 //Planar
845 case HAL_PIXEL_FORMAT_YV12:
846 ystride = width;
847 cstride = ALIGN(width/2, 16);
848 ycbcr->y = (void*)hnd->base;
849 ycbcr->cr = (void*)(hnd->base + ystride * height);
850 ycbcr->cb = (void*)(hnd->base + ystride * height +
851 cstride * height/2);
852 ycbcr->ystride = ystride;
853 ycbcr->cstride = cstride;
854 ycbcr->chroma_step = 1;
855 break;
856 //Unsupported formats
857 case HAL_PIXEL_FORMAT_YCbCr_422_I:
858 case HAL_PIXEL_FORMAT_YCrCb_422_I:
859 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
860 default:
861 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
862 err = -EINVAL;
863 }
864 return err;
865
866 }
867
868
869
870 // Allocate buffer from width, height and format into a
871 // private_handle_t. It is the responsibility of the caller
872 // to free the buffer using the free_buffer function
alloc_buffer(private_handle_t ** pHnd,int w,int h,int format,int usage)873 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
874 {
875 alloc_data data;
876 int alignedw, alignedh;
877 gralloc::IAllocController* sAlloc =
878 gralloc::IAllocController::getInstance();
879 data.base = 0;
880 data.fd = -1;
881 data.offset = 0;
882 data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
883 alignedh);
884
885 data.align = getpagesize();
886 data.uncached = useUncached(usage);
887 int allocFlags = usage;
888
889 int err = sAlloc->allocate(data, allocFlags);
890 if (0 != err) {
891 ALOGE("%s: allocate failed", __FUNCTION__);
892 return -ENOMEM;
893 }
894
895 if(isUBwcEnabled(format, usage)) {
896 data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
897 }
898
899 private_handle_t* hnd = new private_handle_t(data.fd, data.size,
900 data.allocType, 0, format,
901 alignedw, alignedh);
902 hnd->base = (uint64_t) data.base;
903 hnd->offset = data.offset;
904 hnd->gpuaddr = 0;
905 *pHnd = hnd;
906 return 0;
907 }
908
free_buffer(private_handle_t * hnd)909 void free_buffer(private_handle_t *hnd)
910 {
911 gralloc::IAllocController* sAlloc =
912 gralloc::IAllocController::getInstance();
913 if (hnd && hnd->fd > 0) {
914 IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
915 memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
916 }
917 if(hnd)
918 delete hnd;
919
920 }
921
922 // UBWC helper functions
isUBwcFormat(int format)923 static bool isUBwcFormat(int format)
924 {
925 // Explicitly defined UBWC formats
926 switch(format)
927 {
928 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
929 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
930 return true;
931 default:
932 return false;
933 }
934 }
935
isUBwcSupported(int format)936 static bool isUBwcSupported(int format)
937 {
938 if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
939 // Existing HAL formats with UBWC support
940 switch(format)
941 {
942 case HAL_PIXEL_FORMAT_BGR_565:
943 case HAL_PIXEL_FORMAT_RGBA_8888:
944 case HAL_PIXEL_FORMAT_RGBX_8888:
945 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
946 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
947 case HAL_PIXEL_FORMAT_RGBA_1010102:
948 case HAL_PIXEL_FORMAT_RGBX_1010102:
949 return true;
950 default:
951 break;
952 }
953 }
954 return false;
955 }
956
isUBwcEnabled(int format,int usage)957 bool isUBwcEnabled(int format, int usage)
958 {
959 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
960 if (isUBwcFormat(format))
961 return true;
962
963 if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
964 gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
965 return false;
966 }
967
968 // Workaround for bug 30191188/ CR 1047578
969 if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
970 return false;
971 }
972
973 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
974 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
975 // usage flag and MDP supports the format.
976 if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
977 bool enable = true;
978 // Query GPU for UBWC only if buffer is intended to be used by GPU.
979 if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
980 enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
981 }
982 // Allow UBWC, only if CPU usage flags are not set
983 if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
984 GRALLOC_USAGE_SW_WRITE_MASK))) {
985 return true;
986 }
987 }
988 return false;
989 }
990
getYuvUBwcWidthHeight(int width,int height,int format,int & aligned_w,int & aligned_h)991 static void getYuvUBwcWidthHeight(int width, int height, int format,
992 int& aligned_w, int& aligned_h)
993 {
994 switch (format)
995 {
996 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
997 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
998 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
999 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
1000 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
1001 break;
1002 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1003 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width);
1004 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
1005 break;
1006 default:
1007 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
1008 aligned_w = 0;
1009 aligned_h = 0;
1010 break;
1011 }
1012 }
1013
getRgbUBwcBlockSize(int bpp,int & block_width,int & block_height)1014 static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
1015 {
1016 block_width = 0;
1017 block_height = 0;
1018
1019 switch(bpp)
1020 {
1021 case 2:
1022 case 4:
1023 block_width = 16;
1024 block_height = 4;
1025 break;
1026 case 8:
1027 block_width = 8;
1028 block_height = 4;
1029 break;
1030 case 16:
1031 block_width = 4;
1032 block_height = 4;
1033 break;
1034 default:
1035 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
1036 break;
1037 }
1038 }
1039
getRgbUBwcMetaBufferSize(int width,int height,int bpp)1040 static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
1041 {
1042 unsigned int size = 0;
1043 int meta_width, meta_height;
1044 int block_width, block_height;
1045
1046 getRgbUBwcBlockSize(bpp, block_width, block_height);
1047
1048 if (!block_width || !block_height) {
1049 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
1050 return size;
1051 }
1052
1053 // Align meta buffer height to 16 blocks
1054 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
1055
1056 // Align meta buffer width to 64 blocks
1057 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
1058
1059 // Align meta buffer size to 4K
1060 size = ALIGN((meta_width * meta_height), 4096);
1061 return size;
1062 }
1063
getUBwcSize(int width,int height,int format,const int alignedw,const int alignedh)1064 static unsigned int getUBwcSize(int width, int height, int format,
1065 const int alignedw, const int alignedh) {
1066
1067 unsigned int size = 0;
1068 switch (format) {
1069 case HAL_PIXEL_FORMAT_BGR_565:
1070 size = alignedw * alignedh * 2;
1071 size += getRgbUBwcMetaBufferSize(width, height, 2);
1072 break;
1073 case HAL_PIXEL_FORMAT_RGBA_8888:
1074 case HAL_PIXEL_FORMAT_RGBX_8888:
1075 case HAL_PIXEL_FORMAT_RGBA_1010102:
1076 case HAL_PIXEL_FORMAT_RGBX_1010102:
1077 size = alignedw * alignedh * 4;
1078 size += getRgbUBwcMetaBufferSize(width, height, 4);
1079 break;
1080 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1081 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1082 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1083 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
1084 break;
1085 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1086 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
1087 break;
1088 default:
1089 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
1090 break;
1091 }
1092 return size;
1093 }
1094
getRgbDataAddress(private_handle_t * hnd,void ** rgb_data)1095 int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
1096 {
1097 int err = 0;
1098
1099 // This api is for RGB* formats
1100 if (!isUncompressedRgbFormat(hnd->format)) {
1101 return -EINVAL;
1102 }
1103
1104 // linear buffer
1105 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
1106 *rgb_data = (void*)hnd->base;
1107 return err;
1108 }
1109
1110 unsigned int meta_size = 0;
1111 switch (hnd->format) {
1112 case HAL_PIXEL_FORMAT_BGR_565:
1113 meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
1114 break;
1115 case HAL_PIXEL_FORMAT_RGBA_8888:
1116 case HAL_PIXEL_FORMAT_RGBX_8888:
1117 meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
1118 break;
1119 default:
1120 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
1121 err = -EINVAL;
1122 break;
1123 }
1124
1125 *rgb_data = (void*)(hnd->base + meta_size);
1126 return err;
1127 }
1128