Merge "sde: Add support for UBWC in display engine"
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 54b0c83..e062e48 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -545,7 +545,11 @@
       mdp_layer.alpha = layer.plane_alpha;
       mdp_layer.z_order = static_cast<uint16_t>(i);
       mdp_layer.transp_mask = 0xffffffff;
+      mdp_layer.horz_deci = pipe.horizontal_decimation;
+      mdp_layer.vert_deci = pipe.vertical_decimation;
+
       SetBlending(layer.blending, &mdp_layer.blend_op);
+
       SetRect(pipe.src_roi, &mdp_layer.src_rect);
       SetRect(pipe.dst_roi, &mdp_layer.dst_rect);
 
@@ -669,10 +673,10 @@
 }
 
 void HWFrameBuffer::SetRect(const LayerRect &source, mdp_rect *target) {
-  target->x = INT(ceilf(source.left));
-  target->y = INT(ceilf(source.top));
-  target->w = INT(floorf(source.right)) - target->x;
-  target->h = INT(floorf(source.bottom)) - target->y;
+  target->x = UINT32(source.left);
+  target->y = UINT32(source.top);
+  target->w = UINT32(source.right) - target->x;
+  target->h = UINT32(source.bottom) - target->y;
 }
 
 void* HWFrameBuffer::DisplayEventThread(void *context) {
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index f4f33f9..c8611f9 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -93,7 +93,7 @@
 };
 
 struct HWRotateInfo {
-  uint32_t pipe_id;
+  int pipe_id;
   LayerRect src_roi;
   LayerRect dst_roi;
   HWBlockType writeback_id;
@@ -107,12 +107,13 @@
 };
 
 struct HWPipeInfo {
-  uint32_t pipe_id;
+  int pipe_id;
   LayerRect src_roi;
   LayerRect dst_roi;
-  uint8_t decimation;
+  uint8_t horizontal_decimation;
+  uint8_t vertical_decimation;
 
-  HWPipeInfo() : pipe_id(0), decimation(1) { }
+  HWPipeInfo() : pipe_id(0), horizontal_decimation(0), vertical_decimation(0) { }
 
   inline void Reset() { *this = HWPipeInfo(); }
 };
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index d093ab2..1fc1598 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -185,6 +185,8 @@
       return kErrorNotSupported;
 
     struct HWLayerConfig *layer_config = &hw_layers->config[i];
+    HWPipeInfo &left_pipe = layer_config->left_pipe;
+    HWPipeInfo &right_pipe = layer_config->right_pipe;
     // config rotator first
     for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
       layer_config->rotates[j].Reset();
@@ -211,6 +213,20 @@
     if (error != kErrorNone)
       break;
 
+    // 1. Normalize Video layer source rectangle to multiple of 2, as MDP hardware require source
+    //    rectangle of video layer to be even.
+    // 2. Normalize source and destination rect of a layer to multiple of 1.
+    uint32_t factor = (1 << layer.input_buffer->flags.video);
+    if (left_pipe.pipe_id == kPipeIdNeedsAssignment) {
+      NormalizeRect(factor, &left_pipe.src_roi);
+      NormalizeRect(1, &left_pipe.dst_roi);
+    }
+
+    if (right_pipe.pipe_id == kPipeIdNeedsAssignment) {
+      NormalizeRect(factor, &right_pipe.src_roi);
+      NormalizeRect(1, &right_pipe.dst_roi);
+    }
+
     DLOGV_IF(kTagResources, "layer = %d, left pipe_id = %x",
              i, layer_config->left_pipe.pipe_id);
     LogRectVerbose("input layer src_rect", layer.src_rect);
@@ -248,6 +264,12 @@
     return kErrorNotSupported;
   }
 
+  if (((crop_width - dst_width) == 1) || ((crop_height - dst_height) == 1)) {
+    DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w %d, dst_w %d, crop_h %d, " \
+             "dst_h %d", crop_width, dst_width, crop_height, dst_height);
+    return kErrorNotSupported;
+  }
+
   float scale_x = crop_width / dst_width;
   float scale_y = crop_height / dst_height;
 
@@ -404,22 +426,41 @@
   }
 }
 
-void ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
+DisplayError ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
   float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
   float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
   float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
-  float down_scale = src_h / dst_h;
-  pipe->decimation = 1;
+  float down_scale_h = src_h / dst_h;
 
-  if (!hw_res_info_.has_decimation || (down_scale <= max_down_scale))
-    return;
+  float src_w = pipe->src_roi.right - pipe->src_roi.left;
+  float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
+  float down_scale_w = src_w / dst_w;
+
+
+  pipe->horizontal_decimation = 0;
+  pipe->vertical_decimation = 0;
+
+  // TODO(user): Need to check for the maximum downscale limit for decimation and return error
+  if (!hw_res_info_.has_decimation && ((down_scale_w > max_down_scale) ||
+      (down_scale_h > max_down_scale))) {
+    DLOGV("Downscaling exceeds the maximum MDP downscale limit and decimation not enabled");
+    return kErrorNotSupported;
+  }
+
+  if ((down_scale_w <= max_down_scale) && (down_scale_h <= max_down_scale))
+    return kErrorNone;
 
   // Decimation is the remaining downscale factor after doing max SDE downscale.
   // In SDE, decimation is supported in powers of 2.
   // For ex: If a pipe needs downscale of 8 but max_down_scale is 4
   // So decimation = powf(2.0, ceilf(log2f(8) - log2f(4))) = powf(2.0, 1.0) = 2
-  float decimation_factor = ceilf(log2f(down_scale) - log2f(max_down_scale));
-  pipe->decimation = UINT8(powf(2.0f, decimation_factor));
+  pipe->horizontal_decimation = UINT8(ceilf(log2f(down_scale_w) - log2f(max_down_scale)));
+  pipe->vertical_decimation = UINT8(ceilf(log2f(down_scale_h) - log2f(max_down_scale)));
+
+  DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
+           pipe->horizontal_decimation, pipe->vertical_decimation);
+
+  return kErrorNone;
 }
 
 void ResManager::SplitRect(bool flip_horizontal, const LayerRect &src_rect,
@@ -476,4 +517,16 @@
            prefix, roi.left, roi.top, roi.right, roi.bottom);
 }
 
+void ResManager::NormalizeRect(const uint32_t &factor, LayerRect *rect) {
+  uint32_t left = UINT32(ceilf(rect->left));
+  uint32_t top = UINT32(ceilf(rect->top));
+  uint32_t right = UINT32(floorf(rect->right));
+  uint32_t bottom = UINT32(floorf(rect->bottom));
+
+  rect->left = FLOAT(CeilToMultipleOf(left, factor));
+  rect->top = FLOAT(CeilToMultipleOf(top, factor));
+  rect->right = FLOAT(FloorToMultipleOf(right, factor));
+  rect->bottom = FLOAT(FloorToMultipleOf(bottom, factor));
+}
+
 }  // namespace sde
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 7b36563..12ef5bd 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -22,6 +22,7 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <math.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
 
@@ -286,7 +287,10 @@
       src_pipes_[left_index].reserved_hw_block = hw_block_id;
     }
 
-    SetDecimationFactor(pipe_info);
+    error = SetDecimationFactor(pipe_info);
+    if (error != kErrorNone) {
+      goto CleanupOnError;
+    }
 
     pipe_info =  &layer_config.right_pipe;
     if (pipe_info->pipe_id == 0) {
@@ -318,7 +322,10 @@
     src_pipes_[left_index].reserved_hw_block = hw_block_id;
     src_pipes_[left_index].at_right = false;
     layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
-    SetDecimationFactor(pipe_info);
+    error = SetDecimationFactor(pipe_info);
+    if (error != kErrorNone) {
+      goto CleanupOnError;
+    }
 
     DLOGV_IF(kTagResources, "Pipe acquired, layer index = %d, left_pipe = %x, right_pipe = %x",
             i, layer_config.left_pipe.pipe_id,  pipe_info->pipe_id);
@@ -418,7 +425,8 @@
   float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
 
   // Adjust src_h with pipe decimation
-  src_h /= FLOAT(pipe->decimation);
+  float decimation = powf(2.0f, pipe->vertical_decimation);
+  src_h /= decimation;
 
   float bw = src_w * src_h * bpp * display_attributes.fps;
 
@@ -440,7 +448,9 @@
   float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
 
   // Adjust src_h with pipe decimation
-  src_h /= FLOAT(pipe->decimation);
+  float decimation = powf(2.0f, pipe->vertical_decimation);
+  src_h /= decimation;
+
 
   // SDE Clock requirement in MHz
   float clk = (dst_w * v_total * fps) / 1000000.0f;
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 5b63299..cf0a55f 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -166,7 +166,7 @@
   float GetPipeBw(DisplayResourceContext *display_ctx, HWPipeInfo *pipe, float bpp);
   float GetClockForPipe(DisplayResourceContext *display_ctx, HWPipeInfo *pipe);
   float GetOverlapBw(HWLayers *hw_layers, float *pipe_bw, bool left_mixer);
-  void SetDecimationFactor(HWPipeInfo *pipe);
+  DisplayError SetDecimationFactor(HWPipeInfo *pipe);
   float GetBpp(LayerBufferFormat format);
   void SplitRect(bool flip_horizontal, const LayerRect &src_rect, const LayerRect &dst_rect,
                  LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
@@ -183,6 +183,7 @@
                               const uint32_t roate_cnt);
   void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
   void ClearRotator(DisplayResourceContext *display_resource_ctx);
+  void NormalizeRect(const uint32_t &factor, LayerRect *rect);
 
   template <class T>
   inline void Swap(T &a, T &b) {
@@ -191,6 +192,17 @@
     b = c;
   }
 
+  // factor value should be in powers of 2(eg: 1, 2, 4, 8)
+  template <class T1, class T2>
+  inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
+    return (T1)(value & (~(factor - 1)));
+  }
+
+  template <class T1, class T2>
+  inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
+    return (T1)((value + (factor - 1)) & (~(factor - 1)));
+  }
+
   Locker locker_;
   HWResourceInfo hw_res_info_;
   HWBlockContext hw_block_ctx_[kHWBlockMax];
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index ce8f933..d765e04 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -302,9 +302,11 @@
       layer_buffer->height = pvt_handle->height;
       if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
         layer_stack_.flags.video_present = true;
+        layer_buffer->flags.video = true;
       }
       if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
         layer_stack_.flags.secure_present = true;
+        layer_buffer->flags.secure = true;
       }
     }
 
@@ -348,6 +350,10 @@
     Layer &layer = layer_stack_.layers[i];
     LayerComposition composition = layer.composition;
 
+    if (composition == kCompositionSDE) {
+      hwc_layer.hints |= HWC_HINT_CLEAR_FB;
+    }
+
     // If current layer does not need frame buffer redraw, then mark it as HWC_OVERLAY
     if (!needs_fb_refresh && (composition != kCompositionGPUTarget)) {
       composition = kCompositionSDE;
diff --git a/libgralloc/adreno_utils.h b/libgralloc/adreno_utils.h
new file mode 100644
index 0000000..6cb7810
--- /dev/null
+++ b/libgralloc/adreno_utils.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2015, 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 met:
+*    * Redistributions of source code must retain the above copyright notice, this list of
+*      conditions and the following disclaimer.
+*    * Redistributions in binary form must reproduce the above copyright notice, this list of
+*      conditions and the following disclaimer in the documentation and/or other materials provided
+*      with the distribution.
+*    * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+*      endorse or promote products derived from this software without specific prior written
+*      permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Adreno Pixel Formats
+typedef enum {
+
+    ADRENO_PIXELFORMAT_UNKNOWN       = 0,
+    ADRENO_PIXELFORMAT_R8G8B8A8      = 27,
+    ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+    ADRENO_PIXELFORMAT_B5G6R5        = 85,
+    ADRENO_PIXELFORMAT_B5G5R5A1      = 86,
+    ADRENO_PIXELFORMAT_B8G8R8A8      = 90,
+    ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
+    ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
+    ADRENO_PIXELFORMAT_NV12          = 103,
+    ADRENO_PIXELFORMAT_YUY2          = 107,
+    ADRENO_PIXELFORMAT_B4G4R4A4      = 115,
+    ADRENO_PIXELFORMAT_R8G8B8        = 508,  // GL_RGB8
+    ADRENO_PIXELFORMAT_A1B5G5R5      = 519,  // GL_RGB5_A1
+    ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520,  // GL_SRGB8
+    ADRENO_PIXELFORMAT_R8G8B8_SRGB   = 521,  // GL_SRGB8
+    ADRENO_PIXELFORMAT_R5G6B5        = 610,  // RGBA version of B5G6R5
+    ADRENO_PIXELFORMAT_R5G5B5A1      = 611,  // RGBA version of B5G5R5A1
+    ADRENO_PIXELFORMAT_R4G4B4A4      = 612,  // RGBA version of B4G4R4A4
+    ADRENO_PIXELFORMAT_UYVY          = 614,  // YUV 4:2:2 packed progressive (1 plane)
+    ADRENO_PIXELFORMAT_NV21          = 619,
+    ADRENO_PIXELFORMAT_Y8U8V8A8      = 620,  // YUV 4:4:4 packed (1 plane)
+    ADRENO_PIXELFORMAT_Y8            = 625,  // Single 8-bit luma only channel YUV format
+
+} ADRENOPIXELFORMAT;
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 596ca77..a7c4a9a 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)
 {
@@ -98,6 +101,7 @@
     LINK_adreno_compute_padding = NULL;
     LINK_adreno_isMacroTilingSupportedByGpu = NULL;
     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
+    LINK_adreno_isUBWCSupportedByGpu = NULL;
 
     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
     if (libadreno_utils) {
@@ -110,6 +114,8 @@
         *(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");
     }
 }
 
@@ -132,136 +138,183 @@
 
 
 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 tileEnabled = isMacroTileEnabled(format, usage);
+        AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
+            height, format, tileEnabled, aligned_w, aligned_h);
+        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);
+    if (isUBwcEnabled(format, usage)) {
+        getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
+        return;
+    }
 
-            } 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__);
+    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_surface_padding and " \
-                    "compute_aligned_width_and_height not found", __FUNCTION__);
+                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__);
         }
-    } 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 AdrenoMemInfo::isUBWCSupportedByGPU(int format)
+{
+    if (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_RGB_565:
+            return ADRENO_PIXELFORMAT_B5G6R5;
+        case HAL_PIXEL_FORMAT_sRGB_A_8888:
+            return ADRENO_PIXELFORMAT_R8G8B8A8_SRGB;
+        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+            return ADRENO_PIXELFORMAT_NV12;
+        default:
+            ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+            break;
+    }
+    return ADRENO_PIXELFORMAT_UNKNOWN;
 }
 
 //-------------- IAllocController-----------------------//
@@ -404,10 +457,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 +564,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 +578,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 +592,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 +614,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 +732,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..5ee0cf8 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -27,6 +27,7 @@
 
 #include <cutils/native_handle.h>
 #include <utils/Singleton.h>
+#include "adreno_utils.h"
 
 /*****************************************************************************/
 
@@ -71,6 +72,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 +110,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 +135,18 @@
      */
     int isMacroTilingSupportedByGPU();
 
+    /*
+     * Function to query whether GPU supports UBWC for given HAL format
+     * @return > 0 : supported
+     *           0 : not supported
+     */
+    int isUBWCSupportedByGPU(int format);
+
+    /*
+     * Function to get the corresponding Adreno format for given HAL format
+     */
+    ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
+
     private:
         // Pointer to the padding library.
         void *libadreno_utils;
@@ -153,5 +178,7 @@
                                                 int *aligned_w,
                                                 int *aligned_h,
                                                 int *bpp);
+
+        int (*LINK_adreno_isUBWCSupportedByGpu) (ADRENOPIXELFORMAT format);
 };
 #endif /* GR_H_ */
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/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp
index 1aee664..7d709cb 100644
--- a/libhdmi/hdmi.cpp
+++ b/libhdmi/hdmi.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are
  * retained for attribution purposes only.
@@ -109,11 +109,6 @@
         //Get the best mode and set
         mActiveConfig = getBestConfig();
     }
-    // Set the mode corresponding to the active index
-    mCurrentMode = mEDIDModes[mActiveConfig];
-    setAttributes();
-    // set system property
-    property_set("hw.hdmiON", "1");
 
     // Read the system property to determine if downscale feature is enabled.
     char value[PROPERTY_VALUE_MAX];
@@ -123,6 +118,12 @@
         mMDPDownscaleEnabled = true;
     }
 
+    // Set the mode corresponding to the active index
+    mCurrentMode = mEDIDModes[mActiveConfig];
+    setAttributes();
+    // set system property
+    property_set("hw.hdmiON", "1");
+
     // XXX: A debug property can be used to enable resolution change for
     // testing purposes: debug.hwc.enable_resolution_change
     mEnableResolutionChange = false;
@@ -148,7 +149,7 @@
 
 HDMIDisplay::HDMIDisplay():mFd(-1),
     mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
-    mUnderscanSupported(false)
+    mUnderscanSupported(false), mMDPDownscaleEnabled(false)
 {
     memset(&mVInfo, 0, sizeof(mVInfo));
 
@@ -159,10 +160,12 @@
     }
 
     mFbNum = overlay::Overlay::getInstance()->getFbForDpy(mDisplayId);
-    // disable HPD at start, it will be enabled later
+    // Disable HPD at start if HDMI is external, it will be enabled later
     // when the display powers on
     // This helps for framework reboot or adb shell stop/start
-    writeHPDOption(0);
+    if (mDisplayId) {
+        writeHPDOption(0);
+    }
 
     // for HDMI - retreive all the modes supported by the driver
     if(mFbNum != -1) {
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 2bf421f..fd3bb69 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -255,7 +255,7 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     const int dpy = HWC_DISPLAY_PRIMARY;
     bool fbComp = false;
-    if (LIKELY(list && list->numHwLayers > 1) &&
+    if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected &&
             (ctx->dpyAttr[dpy].isActive ||
              ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
             && !ctx->dpyAttr[dpy].isPause) {
@@ -814,7 +814,8 @@
     if (hotPluggable) {
         ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres, yres, refresh);
         if(ret < 0) {
-            ALOGE("%s Error getting attributes for config %d", config);
+            ALOGE("%s Error getting attributes for config %d",
+                    __FUNCTION__, config);
             return ret;
         }
     }
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/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 61e88c8..06418bf 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -91,9 +91,9 @@
             ctx->dpyAttr[dpy].vsync_period
                               = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
             init(ctx);
-            // XXX: for architectures with limited resources we would normally
-            // allow one padding round to free up resources but this breaks
-            // certain use cases.
+            // Do one padding round for cases where primary has all pipes
+            // The virtual composition falls back to GPU in such cases.
+            ctx->isPaddingRound = true;
         }
         if(!ctx->dpyAttr[dpy].isPause) {
             ctx->dpyAttr[dpy].isConfiguring = false;
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index b120246..6dc9774 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -107,7 +107,7 @@
 
         if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
 
-            if (flags[6] == 'Y')
+            if (flags[5] == 'Y')
                 accounted_size += size;
             else
                 unaccounted_size += size;
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,