diff options
Diffstat (limited to 'msm8909/libgralloc/alloc_controller.cpp')
-rw-r--r-- | msm8909/libgralloc/alloc_controller.cpp | 950 |
1 files changed, 749 insertions, 201 deletions
diff --git a/msm8909/libgralloc/alloc_controller.cpp b/msm8909/libgralloc/alloc_controller.cpp index c7ba7c9e..d2a522ed 100644 --- a/msm8909/libgralloc/alloc_controller.cpp +++ b/msm8909/libgralloc/alloc_controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011 - 2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -30,74 +30,92 @@ #include <cutils/log.h> #include <fcntl.h> #include <dlfcn.h> +#include <media/msm_media_info.h> +#include <qdMetaData.h> +#include <utils/Singleton.h> +#include <utils/Mutex.h> +#include <algorithm> + #include "gralloc_priv.h" #include "alloc_controller.h" #include "memalloc.h" #include "ionalloc.h" #include "gr.h" -#include "comptype.h" -#include "mdp_version.h" +#include "qd_utils.h" -#ifdef VENUS_COLOR_FORMAT -#include <media/msm_media_info.h> -#else -#define VENUS_Y_STRIDE(args...) 0 -#define VENUS_Y_SCANLINES(args...) 0 -#define VENUS_BUFFER_SIZE(args...) 0 +#define ASTC_BLOCK_SIZE 16 + +#ifndef ION_FLAG_CP_PIXEL +#define ION_FLAG_CP_PIXEL 0 #endif -#define ASTC_BLOCK_SIZE 16 +#ifndef ION_FLAG_ALLOW_NON_CONTIG +#define ION_FLAG_ALLOW_NON_CONTIG 0 +#endif + +#ifndef ION_FLAG_CP_CAMERA_PREVIEW +#define ION_FLAG_CP_CAMERA_PREVIEW 0 +#endif + +#ifdef MASTER_SIDE_CP +#define CP_HEAP_ID ION_SECURE_HEAP_ID +#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID +#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL) +#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY) +#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA) +#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW) +#else // SLAVE_SIDE_CP +#define CP_HEAP_ID ION_CP_MM_HEAP_ID +#define SD_HEAP_ID CP_HEAP_ID +#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG) +#define ION_SD_FLAGS ION_SECURE +#define ION_SC_FLAGS ION_SECURE +#define ION_SC_PREVIEW_FLAGS ION_SECURE +#endif + +#ifndef COLOR_FMT_P010_UBWC +#define COLOR_FMT_P010_UBWC 9 +#endif using namespace gralloc; using namespace qdutils; +using namespace android; ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo); +ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo); + +static void getYuvUBwcWidthHeight(int, int, int, int&, int&); +static unsigned int getUBwcSize(int, int, int, const int, const int); //Common functions -static bool canFallback(int usage, bool triedSystem) -{ - // Fallback to system heap when alloc fails unless - // 1. Composition type is MDP - // 2. Alloc from system heap was already tried - // 3. The heap type is requsted explicitly - // 4. The heap type is protected - // 5. The buffer is meant for external display only - - if(QCCompositionType::getInstance().getCompositionType() & - COMPOSITION_TYPE_MDP) - return false; - if(triedSystem) - return false; - if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED)) - return false; - if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY)) - return false; - //Return true by default - return true; -} /* The default policy is to return cached buffers unless the client explicity * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely * read or written in software. Any combination with a _RARELY_ flag will be * treated as uncached. */ static bool useUncached(const int& usage) { - if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or - ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == - GRALLOC_USAGE_SW_WRITE_RARELY) or - ((usage & GRALLOC_USAGE_SW_READ_MASK) == - GRALLOC_USAGE_SW_READ_RARELY)) + if ((usage & GRALLOC_USAGE_PROTECTED) or + (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or + ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or + ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)) return true; return false; } -//-------------- AdrenoMemInfo-----------------------// +//------------- MDPCapabilityInfo-----------------------// +MDPCapabilityInfo :: MDPCapabilityInfo() { + qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported); + qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported); +} + +//------------- AdrenoMemInfo-----------------------// AdrenoMemInfo::AdrenoMemInfo() { LINK_adreno_compute_aligned_width_and_height = NULL; LINK_adreno_compute_padding = NULL; - LINK_adreno_isMacroTilingSupportedByGpu = NULL; LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL; + LINK_adreno_isUBWCSupportedByGpu = NULL; LINK_adreno_get_gpu_pixel_alignment = NULL; libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW); @@ -106,14 +124,24 @@ AdrenoMemInfo::AdrenoMemInfo() ::dlsym(libadreno_utils, "compute_aligned_width_and_height"); *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils, "compute_surface_padding"); - *(void **)&LINK_adreno_isMacroTilingSupportedByGpu = - ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu"); *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height = ::dlsym(libadreno_utils, "compute_compressedfmt_aligned_width_and_height"); + *(void **)&LINK_adreno_isUBWCSupportedByGpu = + ::dlsym(libadreno_utils, "isUBWCSupportedByGpu"); *(void **)&LINK_adreno_get_gpu_pixel_alignment = ::dlsym(libadreno_utils, "get_gpu_pixel_alignment"); } + + // Check if the overriding property debug.gralloc.gfx_ubwc_disable + // that disables UBWC allocations for the graphics stack is set + gfx_ubwc_disable = 0; + char property[PROPERTY_VALUE_MAX]; + property_get("debug.gralloc.gfx_ubwc_disable", property, "0"); + if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) || + !(strncmp(property, "true", PROPERTY_VALUE_MAX))) { + gfx_ubwc_disable = 1; + } } AdrenoMemInfo::~AdrenoMemInfo() @@ -123,78 +151,115 @@ AdrenoMemInfo::~AdrenoMemInfo() } } -int AdrenoMemInfo::isMacroTilingSupportedByGPU() -{ - if ((libadreno_utils)) { - if(LINK_adreno_isMacroTilingSupportedByGpu) { - return LINK_adreno_isMacroTilingSupportedByGpu(); +void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, + int& aligned_h) { + MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; + if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { + int w = metadata->bufferDim.sliceWidth; + int h = metadata->bufferDim.sliceHeight; + int f = hnd->format; + int usage = 0; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { + usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; } + + getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h); + } else { + aligned_w = hnd->width; + aligned_h = hnd->height; + } + +} + +void AdrenoMemInfo::getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w, + int& unaligned_h) { + MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; + if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { + unaligned_w = metadata->bufferDim.sliceWidth; + unaligned_h = metadata->bufferDim.sliceHeight; + } else { + unaligned_w = hnd->unaligned_width; + unaligned_h = hnd->unaligned_height; } - return 0; } +bool isUncompressedRgbFormat(int format) +{ + bool is_rgb_format = false; + + switch (format) + { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + case HAL_PIXEL_FORMAT_R_8: + case HAL_PIXEL_FORMAT_RG_88: + case HAL_PIXEL_FORMAT_BGRX_8888: + case HAL_PIXEL_FORMAT_BGR_888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_ARGB_2101010: + case HAL_PIXEL_FORMAT_RGBX_1010102: + case HAL_PIXEL_FORMAT_XRGB_2101010: + case HAL_PIXEL_FORMAT_BGRA_1010102: + case HAL_PIXEL_FORMAT_ABGR_2101010: + case HAL_PIXEL_FORMAT_BGRX_1010102: + case HAL_PIXEL_FORMAT_XBGR_2101010: // Intentional fallthrough + is_rgb_format = true; + break; + default: + break; + } + + return is_rgb_format; +} void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, - int tile_enabled, int& aligned_w, int& aligned_h) + int usage, int& aligned_w, int& aligned_h) { - aligned_w = width; - aligned_h = height; - // Currently surface padding is only computed for RGB* surfaces. - if (format <= HAL_PIXEL_FORMAT_BGRA_8888) { - aligned_w = ALIGN(width, 32); - aligned_h = ALIGN(height, 32); + bool ubwc_enabled = isUBwcEnabled(format, usage); - int bpp = 4; - switch(format) - { - case HAL_PIXEL_FORMAT_RGBA_FP16: - bpp = 8; - break; - case HAL_PIXEL_FORMAT_RGB_888: - bpp = 3; - break; - case HAL_PIXEL_FORMAT_RGB_565: - bpp = 2; - break; - default: break; - } - if (libadreno_utils) { - int raster_mode = 0; // Adreno unknown raster mode. - int padding_threshold = 512; // Threshold for padding surfaces. - // the function below computes aligned width and aligned height - // based on linear or macro tile mode selected. - if(LINK_adreno_compute_aligned_width_and_height) { - LINK_adreno_compute_aligned_width_and_height(width, - height, bpp, tile_enabled, - raster_mode, padding_threshold, - &aligned_w, &aligned_h); - - } else if(LINK_adreno_compute_padding) { - int surface_tile_height = 1; // Linear surface - aligned_w = LINK_adreno_compute_padding(width, bpp, - surface_tile_height, raster_mode, - padding_threshold); - ALOGW("%s: Warning!! Old GFX API is used to calculate stride", - __FUNCTION__); - } else { - ALOGW("%s: Warning!! Symbols compute_surface_padding and " \ - "compute_aligned_width_and_height not found", __FUNCTION__); - } - } + // Currently surface padding is only computed for RGB* surfaces. + if (isUncompressedRgbFormat(format) == true) { + int tileEnabled = ubwc_enabled; + getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h); + } else if (ubwc_enabled) { + getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h); } else { + aligned_w = width; + aligned_h = height; int alignment = 32; switch (format) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YCbCr_420_SP: if (LINK_adreno_get_gpu_pixel_alignment) { - alignment = LINK_adreno_get_gpu_pixel_alignment(); + alignment = LINK_adreno_get_gpu_pixel_alignment(); } aligned_w = ALIGN(width, alignment); break; case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: aligned_w = ALIGN(width, alignment); break; + case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_Y16: + case HAL_PIXEL_FORMAT_Y8: + aligned_w = ALIGN(width, 16); + break; + case HAL_PIXEL_FORMAT_RAW12: + aligned_w = ALIGN(width * 12 / 8, 8); + break; + case HAL_PIXEL_FORMAT_RAW10: + aligned_w = ALIGN(width * 10 / 8, 8); + break; + case HAL_PIXEL_FORMAT_RAW8: + aligned_w = ALIGN(width, 8); + break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: aligned_w = ALIGN(width, 128); break; @@ -203,6 +268,8 @@ void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCbCr_422_I: case HAL_PIXEL_FORMAT_YCrCb_422_I: + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + case HAL_PIXEL_FORMAT_CbYCrY_422_I: aligned_w = ALIGN(width, 16); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: @@ -210,7 +277,12 @@ void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width); + aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height); + break; case HAL_PIXEL_FORMAT_BLOB: + case HAL_PIXEL_FORMAT_RAW_OPAQUE: break; case HAL_PIXEL_FORMAT_NV21_ZSL: aligned_w = ALIGN(width, 64); @@ -253,7 +325,6 @@ void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, LINK_adreno_compute_compressedfmt_aligned_width_and_height( width, height, format, 0,raster_mode, padding_threshold, &aligned_w, &aligned_h, &bytesPerPixel); - } else { ALOGW("%s: Warning!! Symbols" \ " compute_compressedfmt_aligned_width_and_height" \ @@ -265,6 +336,106 @@ void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, } } +void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format, + int tile_enabled, int& aligned_w, int& aligned_h) +{ + aligned_w = ALIGN(width, 32); + aligned_h = ALIGN(height, 32); + + // Don't add any additional padding if debug.gralloc.map_fb_memory + // is enabled + char property[PROPERTY_VALUE_MAX]; + if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && + (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || + (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { + return; + } + + int bpp = 4; + switch(format) + { + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + break; + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + default: break; + } + + if (libadreno_utils) { + int raster_mode = 0; // Adreno unknown raster mode. + int padding_threshold = 512; // Threshold for padding surfaces. + // the function below computes aligned width and aligned height + // based on linear or macro tile mode selected. + if(LINK_adreno_compute_aligned_width_and_height) { + LINK_adreno_compute_aligned_width_and_height(width, + height, bpp, tile_enabled, + raster_mode, padding_threshold, + &aligned_w, &aligned_h); + + } else if(LINK_adreno_compute_padding) { + int surface_tile_height = 1; // Linear surface + aligned_w = LINK_adreno_compute_padding(width, bpp, + surface_tile_height, raster_mode, + padding_threshold); + ALOGW("%s: Warning!! Old GFX API is used to calculate stride", + __FUNCTION__); + } else { + ALOGW("%s: Warning!! Symbols compute_surface_padding and " \ + "compute_aligned_width_and_height not found", __FUNCTION__); + } + } +} + +int AdrenoMemInfo::isUBWCSupportedByGPU(int format) +{ + if (!gfx_ubwc_disable && libadreno_utils) { + if (LINK_adreno_isUBWCSupportedByGpu) { + ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format); + return LINK_adreno_isUBWCSupportedByGpu(gpu_format); + } + } + return 0; +} + +ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format) +{ + switch (hal_format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + return ADRENO_PIXELFORMAT_R8G8B8A8; + case HAL_PIXEL_FORMAT_RGBX_8888: + return ADRENO_PIXELFORMAT_R8G8B8X8; + case HAL_PIXEL_FORMAT_RGB_565: + return ADRENO_PIXELFORMAT_B5G6R5; + case HAL_PIXEL_FORMAT_BGR_565: + return ADRENO_PIXELFORMAT_R5G6B5; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + return ADRENO_PIXELFORMAT_NV12; + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + return ADRENO_PIXELFORMAT_NV12_EXT; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + return ADRENO_PIXELFORMAT_TP10; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + return ADRENO_PIXELFORMAT_P010; + case HAL_PIXEL_FORMAT_RGBA_1010102: + return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM; + case HAL_PIXEL_FORMAT_RGBX_1010102: + return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM; + case HAL_PIXEL_FORMAT_ABGR_2101010: + return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM; + default: + ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format); + break; + } + return ADRENO_PIXELFORMAT_UNKNOWN; +} + //-------------- IAllocController-----------------------// IAllocController* IAllocController::sController = NULL; IAllocController* IAllocController::getInstance(void) @@ -280,6 +451,10 @@ IAllocController* IAllocController::getInstance(void) IonController::IonController() { allocateIonMem(); + + char property[PROPERTY_VALUE_MAX]; + property_get("video.disable.ubwc", property, "0"); + mDisableUBWCForEncode = atoi(property); } void IonController::allocateIonMem() @@ -290,68 +465,59 @@ void IonController::allocateIonMem() int IonController::allocate(alloc_data& data, int usage) { int ionFlags = 0; + int ionHeapId = 0; int ret; data.uncached = useUncached(usage); data.allocType = 0; - if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP) - ionFlags |= ION_HEAP(ION_SF_HEAP_ID); - - if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) - ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID); - - if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP) - ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID); - if(usage & GRALLOC_USAGE_PROTECTED) { - if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) { - ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID); - ionFlags |= ION_SECURE; + if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) { + ionHeapId = ION_HEAP(SD_HEAP_ID); + /* + * There is currently no flag in ION for Secure Display + * VM. Please add it to the define once available. + */ + ionFlags |= ION_SD_FLAGS; + } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) { + ionHeapId = ION_HEAP(SD_HEAP_ID); + ionFlags |= (usage & GRALLOC_USAGE_HW_COMPOSER) ? ION_SC_PREVIEW_FLAGS : ION_SC_FLAGS; } else { - // for targets/OEMs which do not need HW level protection - // do not set ion secure flag & MM heap. Fallback to IOMMU heap. - ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID); + ionHeapId = ION_HEAP(CP_HEAP_ID); + ionFlags |= ION_CP_FLAGS; } } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) { //MM Heap is exclusively a secure heap. //If it is used for non secure cases, fallback to IOMMU heap ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \ cannot be used as an insecure heap!\ - trying to use IOMMU instead !!"); - ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID); + trying to use system heap instead !!"); + ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID); } if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP) - ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID); + ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID); if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) - ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID); + ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID); if(ionFlags & ION_SECURE) data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER; - // if no flags are set, default to - // SF + IOMMU heaps, so that bypass can work - // we can fall back to system heap if - // we run out. - if(!ionFlags) - ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID); + // if no ion heap flags are set, default to system heap + if(!ionHeapId) + ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID); + //At this point we should have the right heap set, there is no fallback data.flags = ionFlags; + data.heapId = ionHeapId; ret = mIonAlloc->alloc_buffer(data); - // Fallback - if(ret < 0 && canFallback(usage, - (ionFlags & ION_SYSTEM_HEAP_ID))) - { - ALOGW("Falling back to system heap"); - data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID); - ret = mIonAlloc->alloc_buffer(data); - } - if(ret >= 0 ) { data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION; + } else { + ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", + __FUNCTION__, ionHeapId, ionFlags); } return ret; @@ -369,61 +535,50 @@ IMemAlloc* IonController::getAllocator(int flags) return memalloc; } -bool isMacroTileEnabled(int format, int usage) -{ - bool tileEnabled = false; +// helper function +unsigned int getSize(int format, int width, int height, int usage, + const int alignedw, const int alignedh) { - // Check whether GPU & MDSS supports MacroTiling feature - if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() && - qdutils::MDPVersion::getInstance().supportsMacroTile()) - { - // check the format - switch(format) - { - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - { - tileEnabled = true; - // check the usage flags - if (usage & (GRALLOC_USAGE_SW_READ_MASK | - GRALLOC_USAGE_SW_WRITE_MASK)) { - // Application intends to use CPU for rendering - tileEnabled = false; - } - break; - } - default: - break; - } + if (isUBwcEnabled(format, usage)) { + return getUBwcSize(width, height, format, alignedw, alignedh); } - return tileEnabled; -} -// helper function -unsigned int getSize(int format, int width, int height, const int alignedw, - const int alignedh) { unsigned int size = 0; - switch (format) { - case HAL_PIXEL_FORMAT_RGBA_FP16: - size = alignedw * alignedh * 8; - break; case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_ARGB_2101010: + case HAL_PIXEL_FORMAT_RGBX_1010102: + case HAL_PIXEL_FORMAT_XRGB_2101010: + case HAL_PIXEL_FORMAT_BGRA_1010102: + case HAL_PIXEL_FORMAT_ABGR_2101010: + case HAL_PIXEL_FORMAT_BGRX_1010102: + case HAL_PIXEL_FORMAT_XBGR_2101010: size = alignedw * alignedh * 4; break; case HAL_PIXEL_FORMAT_RGB_888: size = alignedw * alignedh * 3; break; case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_Y16: size = alignedw * alignedh * 2; break; - + case HAL_PIXEL_FORMAT_RAW12: + size = ALIGN(alignedw * alignedh, 4096); + break; + case HAL_PIXEL_FORMAT_RAW10: + size = ALIGN(alignedw * alignedh, 4096); + break; + case HAL_PIXEL_FORMAT_RAW8: + case HAL_PIXEL_FORMAT_Y8: + size = alignedw * alignedh; + break; // adreno formats case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 size = ALIGN(alignedw*alignedh, 4096); @@ -449,10 +604,14 @@ unsigned int getSize(int format, int width, int height, const int alignedw, case HAL_PIXEL_FORMAT_YCrCb_420_SP: size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096); break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, 4096); + break; case HAL_PIXEL_FORMAT_YCbCr_422_SP: case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCbCr_422_I: case HAL_PIXEL_FORMAT_YCrCb_422_I: + case HAL_PIXEL_FORMAT_CbYCrY_422_I: if(width & 1) { ALOGE("width is odd for the YUV422_SP format"); return 0; @@ -463,7 +622,11 @@ unsigned int getSize(int format, int width, int height, const int alignedw, case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height); + break; case HAL_PIXEL_FORMAT_BLOB: + case HAL_PIXEL_FORMAT_RAW_OPAQUE: if(height != 1) { ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \ must have height==1 ", __FUNCTION__); @@ -519,11 +682,11 @@ unsigned int getBufferSizeAndDimensions(int width, int height, int format, AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height, format, - false, + 0, alignedw, alignedh); - size = getSize(format, width, height, alignedw, alignedh); + size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh); return size; } @@ -533,91 +696,166 @@ unsigned int getBufferSizeAndDimensions(int width, int height, int format, int usage, int& alignedw, int &alignedh) { unsigned int size; - int tileEnabled = isMacroTileEnabled(format, usage); AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height, format, - tileEnabled, + usage, alignedw, alignedh); - size = getSize(format, width, height, alignedw, alignedh); + size = getSize(format, width, height, usage, alignedw, alignedh); return size; } +void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height, + int color_format, struct android_ycbcr* ycbcr) +{ + // UBWC buffer has these 4 planes in the following sequence: + // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane + unsigned int y_meta_stride, y_meta_height, y_meta_size; + unsigned int y_stride, y_height, y_size; + unsigned int c_meta_stride, c_meta_height, c_meta_size; + unsigned int alignment = 4096; + + y_meta_stride = VENUS_Y_META_STRIDE(color_format, width); + y_meta_height = VENUS_Y_META_SCANLINES(color_format, height); + y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment); + + y_stride = VENUS_Y_STRIDE(color_format, width); + y_height = VENUS_Y_SCANLINES(color_format, height); + y_size = ALIGN((y_stride * y_height), alignment); + + c_meta_stride = VENUS_UV_META_STRIDE(color_format, width); + c_meta_height = VENUS_UV_META_SCANLINES(color_format, height); + c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment); + + ycbcr->y = (void*)(base + y_meta_size); + ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size); + ycbcr->cr = (void*)(base + y_meta_size + y_size + + c_meta_size + 1); + ycbcr->ystride = y_stride; + ycbcr->cstride = VENUS_UV_STRIDE(color_format, width); +} -void getBufferAttributes(int width, int height, int format, int usage, - int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size) +void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp, + struct android_ycbcr* ycbcr) { - tileEnabled = isMacroTileEnabled(format, usage); + unsigned int ystride, cstride; - AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, - height, - format, - tileEnabled, - alignedw, - alignedh); - size = getSize(format, width, height, alignedw, alignedh); + ystride = cstride = width * bpp; + ycbcr->y = (void*)base; + ycbcr->cb = (void*)(base + ystride * height); + ycbcr->cr = (void*)(base + ystride * height + 1); + ycbcr->ystride = ystride; + ycbcr->cstride = cstride; + ycbcr->chroma_step = 2 * bpp; } int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr) { int err = 0; + int width = hnd->width; + int height = hnd->height; + int format = hnd->format; + unsigned int ystride, cstride; + memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); + MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; + + // Check if UBWC buffer has been rendered in linear format. + if (metadata && (metadata->operation & LINEAR_FORMAT)) { + format = metadata->linearFormat; + } + + // Check metadata if the geometry has been updated. + if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { + int usage = 0; + + if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { + usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; + } + + AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth, + metadata->bufferDim.sliceHeight, format, usage, width, height); + } // Get the chroma offsets from the handle width/height. We take advantage // of the fact the width _is_ the stride - switch (hnd->format) { + switch (format) { //Semiplanar case HAL_PIXEL_FORMAT_YCbCr_420_SP: case HAL_PIXEL_FORMAT_YCbCr_422_SP: case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS - ystride = cstride = hnd->width; - ycbcr->y = (void*)hnd->base; - ycbcr->cb = (void*)(hnd->base + ystride * hnd->height); - ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1); - ycbcr->ystride = ystride; - ycbcr->cstride = cstride; + getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr); + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + getYuvUbwcSPPlaneInfo(hnd->base, width, height, + COLOR_FMT_NV12_UBWC, ycbcr); ycbcr->chroma_step = 2; break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + getYuvUbwcSPPlaneInfo(hnd->base, width, height, + COLOR_FMT_NV12_BPP10_UBWC, ycbcr); + ycbcr->chroma_step = 3; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + getYuvUbwcSPPlaneInfo(hnd->base, width, height, + COLOR_FMT_P010_UBWC, ycbcr); + ycbcr->chroma_step = 4; + break; case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: case HAL_PIXEL_FORMAT_NV21_ZSL: - ystride = cstride = hnd->width; - ycbcr->y = (void*)hnd->base; - ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); - ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1); - ycbcr->ystride = ystride; - ycbcr->cstride = cstride; - ycbcr->chroma_step = 2; + case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_Y16: + case HAL_PIXEL_FORMAT_RAW12: + case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_RAW8: + case HAL_PIXEL_FORMAT_Y8: + getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); + std::swap(ycbcr->cb, ycbcr->cr); break; //Planar case HAL_PIXEL_FORMAT_YV12: - ystride = hnd->width; - cstride = ALIGN(hnd->width/2, 16); + ystride = width; + cstride = ALIGN(width/2, 16); ycbcr->y = (void*)hnd->base; - ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); - ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + - cstride * hnd->height/2); + ycbcr->cr = (void*)(hnd->base + ystride * height); + ycbcr->cb = (void*)(hnd->base + ystride * height + + cstride * height/2); ycbcr->ystride = ystride; ycbcr->cstride = cstride; ycbcr->chroma_step = 1; - + break; + case HAL_PIXEL_FORMAT_CbYCrY_422_I: + ystride = width * 2; + cstride = 0; + ycbcr->y = (void*)hnd->base; + ycbcr->cr = NULL; + ycbcr->cb = NULL; + ycbcr->ystride = ystride; + ycbcr->cstride = 0; + ycbcr->chroma_step = 0; break; //Unsupported formats case HAL_PIXEL_FORMAT_YCbCr_422_I: case HAL_PIXEL_FORMAT_YCrCb_422_I: case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: default: - ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, - hnd->format); + ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format); err = -EINVAL; } return err; @@ -651,9 +889,13 @@ int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage) return -ENOMEM; } + if(isUBwcEnabled(format, usage)) { + data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; + } + private_handle_t* hnd = new private_handle_t(data.fd, data.size, data.allocType, 0, format, - alignedw, alignedh); + alignedw, alignedh, -1, 0, 0, w, h); hnd->base = (uint64_t) data.base; hnd->offset = data.offset; hnd->gpuaddr = 0; @@ -673,3 +915,309 @@ void free_buffer(private_handle_t *hnd) delete hnd; } + +// UBWC helper functions +static bool isUBwcFormat(int format) +{ + // Explicitly defined UBWC formats + switch(format) + { + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + return true; + default: + return false; + } +} + +static bool isUBwcSupported(int format) +{ + if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) { + // Existing HAL formats with UBWC support + switch(format) + { + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_RGBX_1010102: + return true; + default: + break; + } + } + return false; +} + +bool isUBwcEnabled(int format, int usage) +{ + // Allow UBWC, if client is using an explicitly defined UBWC pixel format. + if (isUBwcFormat(format)) + return true; + + if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && + gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) { + return false; + } + + // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP + // support the format. OR if a non-OpenGL client like Rotator, sets UBWC + // usage flag and MDP supports the format. + if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) { + bool enable = true; + // Query GPU for UBWC only if buffer is intended to be used by GPU. + if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) { + enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format); + } + // Allow UBWC, only if CPU usage flags are not set + if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK | + GRALLOC_USAGE_SW_WRITE_MASK))) { + return true; + } + } + return false; +} + +static void getYuvUBwcWidthHeight(int width, int height, int format, + int& aligned_w, int& aligned_h) +{ + switch (format) + { + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); + aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + // The macro returns the stride which is 4/3 times the width, hence * 3/4 + aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4; + aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + // The macro returns the stride which is 2 times the width, hence / 2 + aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2); + aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height); + break; + default: + ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); + aligned_w = 0; + aligned_h = 0; + break; + } +} + +static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height) +{ + block_width = 0; + block_height = 0; + + switch(bpp) + { + case 2: + case 4: + block_width = 16; + block_height = 4; + break; + case 8: + block_width = 8; + block_height = 4; + break; + case 16: + block_width = 4; + block_height = 4; + break; + default: + ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); + break; + } +} + +static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp) +{ + unsigned int size = 0; + int meta_width, meta_height; + int block_width, block_height; + + getRgbUBwcBlockSize(bpp, block_width, block_height); + + if (!block_width || !block_height) { + ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); + return size; + } + + // Align meta buffer height to 16 blocks + meta_height = ALIGN(((height + block_height - 1) / block_height), 16); + + // Align meta buffer width to 64 blocks + meta_width = ALIGN(((width + block_width - 1) / block_width), 64); + + // Align meta buffer size to 4K + size = ALIGN((meta_width * meta_height), 4096); + return size; +} + +static unsigned int getUBwcSize(int width, int height, int format, + const int alignedw, const int alignedh) { + + unsigned int size = 0; + switch (format) { + case HAL_PIXEL_FORMAT_BGR_565: + size = alignedw * alignedh * 2; + size += getRgbUBwcMetaBufferSize(width, height, 2); + break; + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_RGBX_1010102: + size = alignedw * alignedh * 4; + size += getRgbUBwcMetaBufferSize(width, height, 4); + break; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height); + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height); + break; + default: + ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); + break; + } + return size; +} + +int getRgbDataAddress(private_handle_t* hnd, void** rgb_data) +{ + int err = 0; + + // This api is for RGB* formats + if (!isUncompressedRgbFormat(hnd->format)) { + return -EINVAL; + } + + // linear buffer + if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) { + *rgb_data = (void*)hnd->base; + return err; + } + + // Ubwc buffers + unsigned int meta_size = 0; + switch (hnd->format) { + case HAL_PIXEL_FORMAT_BGR_565: + meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2); + break; + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_RGBX_1010102: + meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4); + break; + default: + ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format); + err = -EINVAL; + break; + } + + *rgb_data = (void*)(hnd->base + meta_size); + return err; +} + +int getBufferLayout(private_handle_t *hnd, uint32_t stride[4], + uint32_t offset[4], uint32_t *num_planes) { + if (!hnd || !stride || !offset || !num_planes) { + return -EINVAL; + } + + struct android_ycbcr yuvInfo = {}; + *num_planes = 1; + stride[0] = 0; + + switch (hnd->format) { + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGR_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + stride[0] = hnd->width * 2; + break; + case HAL_PIXEL_FORMAT_RGB_888: + stride[0] = hnd->width * 3; + break; + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRX_8888: + case HAL_PIXEL_FORMAT_RGBA_1010102: + case HAL_PIXEL_FORMAT_ARGB_2101010: + case HAL_PIXEL_FORMAT_RGBX_1010102: + case HAL_PIXEL_FORMAT_XRGB_2101010: + case HAL_PIXEL_FORMAT_BGRA_1010102: + case HAL_PIXEL_FORMAT_ABGR_2101010: + case HAL_PIXEL_FORMAT_BGRX_1010102: + case HAL_PIXEL_FORMAT_XBGR_2101010: + stride[0] = hnd->width * 4; + break; + } + + // Format is RGB + if (stride[0]) { + return 0; + } + + (*num_planes)++; + int ret = getYUVPlaneInfo(hnd, &yuvInfo); + if (ret < 0) { + ALOGE("%s failed", __FUNCTION__); + return ret; + } + + stride[0] = static_cast<uint32_t>(yuvInfo.ystride); + offset[0] = static_cast<uint32_t>( + reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base); + stride[1] = static_cast<uint32_t>(yuvInfo.cstride); + switch (hnd->format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: + offset[1] = static_cast<uint32_t>( + reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + offset[1] = static_cast<uint32_t>( + reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); + break; + case HAL_PIXEL_FORMAT_YV12: + offset[1] = static_cast<uint32_t>( + reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); + stride[2] = static_cast<uint32_t>(yuvInfo.cstride); + offset[2] = static_cast<uint32_t>( + reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); + (*num_planes)++; + break; + default: + ALOGW("%s: Unsupported format %s", __FUNCTION__, + qdutils::GetHALPixelFormatString(hnd->format)); + ret = -EINVAL; + } + + if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { + std::fill(offset, offset + 4, 0); + } + + return 0; +} |