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
74using namespace gralloc;
75using namespace qdutils;
76using namespace android;
77
78ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
79ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
80
81static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
82static 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. */
90static 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-----------------------//
101MDPCapabilityInfo :: MDPCapabilityInfo() {
102  qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
103  qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
104}
105
106//------------- AdrenoMemInfo-----------------------//
107AdrenoMemInfo::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
144AdrenoMemInfo::~AdrenoMemInfo()
145{
146    if (libadreno_utils) {
147        ::dlclose(libadreno_utils);
148    }
149}
150
151int AdrenoMemInfo::isMacroTilingSupportedByGPU()
152{
153    if ((libadreno_utils)) {
154        if(LINK_adreno_isMacroTilingSupportedByGpu) {
155            return LINK_adreno_isMacroTilingSupportedByGpu();
156        }
157    }
158    return 0;
159}
160
161void 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
182bool 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
217void 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
324void 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
382int 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
393ADRENOPIXELFORMAT 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-----------------------//
425IAllocController* IAllocController::sController = NULL;
426IAllocController* IAllocController::getInstance(void)
427{
428    if(sController == NULL) {
429        sController = new IonController();
430    }
431    return sController;
432}
433
434
435//-------------- IonController-----------------------//
436IonController::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
445void IonController::allocateIonMem()
446{
447   mIonAlloc = new IonAlloc();
448}
449
450int 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
508IMemAlloc* 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
520bool 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
553unsigned 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
683unsigned 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
701unsigned 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
719void 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
733void 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
763void 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
777int 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
873int 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
909void 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
923static 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
936static 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
957bool 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
991static 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
1014static 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
1040static 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
1064static 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
1095int 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