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