display: Add support for UBWC in display hal
1. Add support for UBWC allocation in the Gralloc APIs for aligned
width, aligned height and buffer size. A client can request for UBWC
allocation by sending UBWC specific HAL pixel format or by setting
GRALLOC_USAGE_PRIVATE_ALLOC_UBWC flag in the usage flags.
2. Gralloc allocates UBWC aligned buffer, only if format is supported
by GPU and MDP and no CPU usage flags are set. Otherwise it allocates
linear buffer.
3. If UBWC conditions are met, gralloc sets PRIV_FLAGS_UBWC_ALIGNED
in private handle flags to tell client that allocated buffer has UBWC
alignment. This flag remains unset by default.
4. Add helper functions in gralloc to calculate UBWC meta buffer size
for RGB* formats.
5. Add UBWC HAL pixel format HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC
which has been defined by Video module.
6. Add AdrenoMemInfo api to query, if GPU supports UBWC for a format.
7.MDP driver expects UBWC specific pixel format defined by MDP header.
Change-Id: I5b4344bc90aa498dbdb7bb8100e70ed7728e6ea5
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 596ca77..fe86018 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -53,6 +53,9 @@
ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
+static void getUBwcWidthAndHeight(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)
{
@@ -132,136 +135,159 @@
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_sRGB_X_8888) {
- 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_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__);
- }
- }
- } else {
- switch (format)
- {
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
- aligned_w = ALIGN(width, 32);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- aligned_w = ALIGN(width, 128);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YV12:
- 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:
- aligned_w = ALIGN(width, 16);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
- aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
- break;
- case HAL_PIXEL_FORMAT_BLOB:
- break;
- case HAL_PIXEL_FORMAT_NV21_ZSL:
- aligned_w = ALIGN(width, 64);
- aligned_h = ALIGN(height, 64);
- break;
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
- int bytesPerPixel = 0;
- int raster_mode = 0; //Adreno unknown raster mode.
- int padding_threshold = 512; //Threshold for padding
- //surfaces.
-
- 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" \
- " not found", __FUNCTION__);
- }
- break;
- default: break;
- }
+ int tileEnabled = isMacroTileEnabled(format, usage);
+ AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
+ height, format, tileEnabled, aligned_w, aligned_h);
+ return;
}
+
+ if (isUBwcEnabled(format, usage)) {
+ getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
+ return;
+ }
+
+ aligned_w = width;
+ aligned_h = height;
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ aligned_w = ALIGN(width, 32);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ aligned_w = ALIGN(width, 128);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YV12:
+ 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:
+ aligned_w = ALIGN(width, 16);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
+ break;
+ case HAL_PIXEL_FORMAT_BLOB:
+ break;
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ aligned_w = ALIGN(width, 64);
+ aligned_h = ALIGN(height, 64);
+ break;
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+ int bytesPerPixel = 0;
+ int raster_mode = 0; //Adreno unknown raster mode.
+ int padding_threshold = 512; //Threshold for padding
+ //surfaces.
+
+ 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" \
+ " not found", __FUNCTION__);
+ }
+ break;
+ default: break;
+ }
+}
+
+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_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)
+{
+ // TODO: Convert HAL pixel format to corresponding Adreno format,
+ // then query GPU with Adreno format.
+ return 0;
}
//-------------- IAllocController-----------------------//
@@ -404,10 +430,14 @@
}
// helper function
-unsigned int getSize(int format, int width, int height, const int alignedw,
- const int alignedh) {
- unsigned int size = 0;
+unsigned int getSize(int format, int width, int height, int usage,
+ const int alignedw, const int alignedh) {
+ if (isUBwcEnabled(format, usage)) {
+ return getUBwcSize(width, height, format, alignedw, alignedh);
+ }
+
+ unsigned int size = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
@@ -507,7 +537,7 @@
size = alignedw * alignedh * ASTC_BLOCK_SIZE;
break;
default:
- ALOGE("unrecognized pixel format: 0x%x", format);
+ ALOGE("Unrecognized pixel format: 0x%x", __FUNCTION__, format);
return 0;
}
return size;
@@ -521,11 +551,11 @@
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;
}
@@ -535,16 +565,15 @@
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;
}
@@ -558,10 +587,10 @@
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);
}
int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
@@ -676,3 +705,142 @@
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:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isUBwcSupported(int format)
+{
+ // Existing HAL formats with UBWC support
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool isUBwcEnabled(int format, int usage)
+{
+ if (isUBwcFormat(format) ||
+ ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)))
+ {
+ // Allow UBWC, only if GPU supports it and CPU usage flags are not set
+ if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
+ !(usage & (GRALLOC_USAGE_SW_READ_MASK |
+ GRALLOC_USAGE_SW_WRITE_MASK))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void getUBwcWidthAndHeight(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;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ aligned_w = 0;
+ aligned_h = 0;
+ break;
+ }
+}
+
+static void getUBwcBlockSize(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 getUBwcMetaBufferSize(int width, int height, int bpp)
+{
+ unsigned int size = 0;
+ int meta_width, meta_height;
+ int block_width, block_height;
+
+ getUBwcBlockSize(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 = ((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_RGB_565:
+ size = alignedw * alignedh * 2;
+ size += getUBwcMetaBufferSize(width, height, 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ size = alignedw * alignedh * 4;
+ size += getUBwcMetaBufferSize(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;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ break;
+ }
+ return size;
+}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 5533ffb..9ab9d09 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -149,6 +149,10 @@
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}
+ if (isUBwcEnabled(format, usage)) {
+ flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
}
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 797d57e..492f495 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -71,6 +71,9 @@
void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+// To query if UBWC is enabled, based on format and usage flags
+bool isUBwcEnabled(int format, int usage);
+
/*****************************************************************************/
class Locker {
@@ -106,12 +109,21 @@
~AdrenoMemInfo();
/*
+ * Function to compute aligned width and aligned height based on
+ * width, height, format and usage flags.
+ *
+ * @return aligned width, aligned height
+ */
+ void getAlignedWidthAndHeight(int width, int height, int format,
+ int usage, int& aligned_w, int& aligned_h);
+
+ /*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
- void getAlignedWidthAndHeight(int width, int height, int format,
+ void getGpuAlignedWidthHeight(int width, int height, int format,
int tileEnabled, int& alignedw, int &alignedh);
/*
@@ -122,6 +134,13 @@
*/
int isMacroTilingSupportedByGPU();
+ /*
+ * Function to query whether GPU supports UBWC for given HAL format
+ * @return > 0 : supported
+ * 0 : not supported
+ */
+ int isUBWCSupportedByGPU(int format);
+
private:
// Pointer to the padding library.
void *libadreno_utils;
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index b60eaff..8b134ea 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -41,7 +41,8 @@
* can never be uncached, is not secured*/
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_0,
- /* GRALLOC_USAGE_PRIVATE_1 is unused */
+ /* Non linear, Universal Bandwidth Compression */
+ GRALLOC_USAGE_PRIVATE_ALLOC_UBWC = GRALLOC_USAGE_PRIVATE_1,
/* IOMMU heap comes from manually allocated pages,
* can be cached/uncached, is not secured */
@@ -119,6 +120,9 @@
//format reduces the memory access bandwidth
#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED 0x43574259
+// UBWC aligned Venus format
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06
+
//Khronos ASTC formats
#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
@@ -206,7 +210,9 @@
// Buffer is rendered in Tile Format
PRIV_FLAGS_TILE_RENDERED = 0x02000000,
// Buffer rendered using CPU/SW renderer
- PRIV_FLAGS_CPU_RENDERED = 0x04000000
+ PRIV_FLAGS_CPU_RENDERED = 0x04000000,
+ // Buffer is allocated with UBWC alignment
+ PRIV_FLAGS_UBWC_ALIGNED = 0x08000000
};
// file-descriptors
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 356001e..44f4fb2 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -353,7 +353,7 @@
int *stride = va_arg(args, int *);
int alignedw = 0, alignedh = 0;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- 0, format, false, alignedw, alignedh);
+ 0, format, 0, alignedw, alignedh);
*stride = alignedw;
res = 0;
} break;
@@ -404,8 +404,7 @@
int *tileEnabled = va_arg(args,int *);
*tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- height, format, *tileEnabled, *alignedWidth,
- *alignedHeight);
+ height, format, usage, *alignedWidth, *alignedHeight);
res = 0;
} break;