Merge "display: Add support for UBWC in display hal"
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;
 
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 08a4fb9..b63fb3a 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -132,9 +132,10 @@
     if (LIKELY(ctx->mOverlay)) {
         overlay::Overlay& ov = *(ctx->mOverlay);
 
+        int flags = mTileEnabled ?
+            private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
         ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
-                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
-                    mTileEnabled));
+                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
 
         Overlay::PipeSpecs pipeSpecs;
         pipeSpecs.formatClass = Overlay::FORMAT_RGB;
@@ -276,9 +277,10 @@
     bool ret = false;
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     if (LIKELY(ctx->mOverlay)) {
+        int flags = mTileEnabled ?
+            private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
         ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
-                          ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
-                                                mTileEnabled));
+                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
 
         overlay::Overlay& ov = *(ctx->mOverlay);
         ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
@@ -440,10 +442,10 @@
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     overlay::Overlay& ov = *(ctx->mOverlay);
 
+    int flags = mTileEnabled ? private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
     ovutils::Whf info(mAlignedFBWidth,
             mAlignedFBHeight,
-            ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
-                mTileEnabled));
+            ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
 
     ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
     ovutils::setMdpFlags(mdpFlags,
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 7e7b44b..d2962a3 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2701,7 +2701,7 @@
     int transform = layer->transform;
     eTransform orient = static_cast<eTransform>(transform);
     int rotFlags = ROT_FLAGS_NONE;
-    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
 
     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index adb3b9c..8139013 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1793,7 +1793,7 @@
     int dst_w = dst.right - dst.left;
     int dst_h = dst.bottom - dst.top;
     uint32_t color = layer->transform;
-    Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888), 0);
+    Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));
 
     ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
     if (layer->blending == HWC_BLENDING_PREMULT)
@@ -1860,7 +1860,7 @@
     bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED)
                 && metadata->interlaced;
     int transform = layer->transform;
-    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
 
     if(isYuvBuffer(hnd)) {
         if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
@@ -1970,7 +1970,7 @@
     int transform = layer->transform;
     eTransform orient = static_cast<eTransform>(transform);
     int rotFlags = ovutils::ROT_FLAGS_NONE;
-    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
     Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
 
     // Handle R/B swap
@@ -2066,7 +2066,7 @@
     int transform = layer->transform;
     eTransform orient = static_cast<eTransform>(transform);
     int rotFlags = ROT_FLAGS_NONE;
-    uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
     Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
 
     // Handle R/B swap
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index dd030ef..b37eba9 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -141,12 +141,28 @@
     return -1;
 }
 
-// This function returns corresponding tile format
-// MDSS support following RGB tile formats
-//  32 bit formats
-//  16 bit formats
-int getMdpFormat(int format, bool tileEnabled)
+int getMdpFormat(int format, int flags)
 {
+    bool uBwcEnabled = (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED);
+    bool tileEnabled = (flags & private_handle_t::PRIV_FLAGS_TILE_RENDERED);
+
+    // Use UBWC extension, if UBWC is enabled
+    if (uBwcEnabled) {
+        switch (format) {
+            case HAL_PIXEL_FORMAT_RGBA_8888:
+                return MDP_RGBA_8888_UBWC;
+            case HAL_PIXEL_FORMAT_RGB_565:
+                return MDP_RGB_565_UBWC;
+            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+                return MDP_Y_CBCR_H2V2_UBWC;
+            default:
+                ALOGE("%s: Unsupported HAL format = 0x%x", __func__, format);
+                break;
+        }
+    }
+
     if(!tileEnabled) {
         return getMdpFormat(format);
     }
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 54ee0fd..5e3bd1f 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -368,7 +368,7 @@
 };
 
 int getMdpFormat(int format);
-int getMdpFormat(int format, bool tileEnabled);
+int getMdpFormat(int format, int flags);
 int getHALFormat(int mdpFormat);
 void getDecimationFactor(const int& src_w, const int& src_h,
         const int& dst_w, const int& dst_h, uint8_t& horzDeci,