Merge "sdm: Allow draw cycle in doze state." into dev-1.0
diff --git a/libcopybit/c2d2.h b/libcopybit/c2d2.h
index 886f38a..315a3ba 100644
--- a/libcopybit/c2d2.h
+++ b/libcopybit/c2d2.h
@@ -72,6 +72,7 @@
     C2D_FORMAT_MACROTILED        = (1 << 16), /* tiled in macro level */
     C2D_FORMAT_TILED_4x4         = (1 << 17), /* 4x4 tiled format */
     C2D_FORMAT_SWAP_RB           = (1 << 18), /* Swap R & B color components */
+    C2D_FORMAT_UBWC_COMPRESSED   = (1 << 23), /* UBWC compressed format */
 } C2D_FORMAT_MODE;
 
 /* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
@@ -408,7 +409,8 @@
     C2D_DRIVER_SUPPORTS_TARGET_RECT_OP            = (1 << 15),
     C2D_DRIVER_SUPPORTS_ROTATE_OP                 = (1 << 16), /* all rotations */
     C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP    = (1 << 17), /* all rotations */
-    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 17)) /* mask for all capabilities supported */
+    C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP        = (1 << 18), /* UBWC Compression */
+    C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP       = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
 } C2D_DRIVER_CAPABILITIES;
 
 /* 2D driver workaround bits used by the 2D applications */
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 1fc17ed..de585ee 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -80,6 +80,10 @@
     COPYBIT_FRAMEBUFFER_HEIGHT = 8,
     COPYBIT_FG_LAYER = 9,
     COPYBIT_DYNAMIC_FPS = 10,
+    /* Source Format Mode */
+    COPYBIT_SRC_FORMAT_MODE = 11,
+    /* Destination Format Mode */
+    COPYBIT_DST_FORMAT_MODE = 12,
 };
 
 /* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
@@ -116,6 +120,13 @@
     COPYBIT_BLENDING_COVERAGE = 0x0405
 };
 
+enum {
+    /* Linear format mode*/
+    COPYBIT_LINEAR = 0x0000,
+    /* UBWC format mode*/
+    COPYBIT_UBWC_COMPRESSED = 0x0001,
+};
+
 /* use get_static_info() to query static informations about the hardware */
 enum {
     /* Maximum amount of minification supported by the hardware*/
@@ -126,6 +137,8 @@
     COPYBIT_SCALING_FRAC_BITS   = 3,
     /* Supported rotation step in degres. */
     COPYBIT_ROTATION_STEP_DEG   = 4,
+    /* UBWC support*/
+    COPYBIT_UBWC_SUPPORT        = 5,
 };
 
 /* Image structure */
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index cc13fec..9936eb6 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -124,7 +124,8 @@
 enum eC2DFlags {
     FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
     FLAGS_YUV_DESTINATION      = 1<<1,
-    FLAGS_TEMP_SRC_DST         = 1<<2
+    FLAGS_TEMP_SRC_DST         = 1<<2,
+    FLAGS_UBWC_FORMAT_MODE     = 1<<3
 };
 
 static gralloc::IAllocController* sAlloc = 0;
@@ -159,6 +160,8 @@
     void* time_stamp;
     bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
     void* dst_surface_base; // Stores the dst surface addr
+    bool is_src_ubwc_format;
+    bool is_dst_ubwc_format;
 
     // used for signaling the wait thread
     bool wait_timestamp;
@@ -543,6 +546,10 @@
 
         surfaceDef.format = c2d_format |
             ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
+
+        surfaceDef.format = surfaceDef.format |
+            ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
+
         surfaceDef.width = rhs->w;
         surfaceDef.height = rhs->h;
         int aligned_width = ALIGN((int)surfaceDef.width,32);
@@ -699,6 +706,8 @@
     int flags = FLAGS_PREMULTIPLIED_ALPHA;
     int mapped_dst_idx = -1;
     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+    if (ctx->is_dst_ubwc_format)
+        flags |= FLAGS_UBWC_FORMAT_MODE;
     C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
     pthread_mutex_lock(&ctx->wait_cleanup_lock);
     if(!ctx->dst_surface_mapped) {
@@ -864,6 +873,12 @@
         case COPYBIT_BLIT_TO_FRAMEBUFFER:
             // Do nothing
             break;
+        case COPYBIT_SRC_FORMAT_MODE:
+            ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+            break;
+        case COPYBIT_DST_FORMAT_MODE:
+            ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+            break;
         default:
             ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
             status = -EINVAL;
@@ -897,6 +912,12 @@
         case COPYBIT_ROTATION_STEP_DEG:
             value = 1;
             break;
+        case COPYBIT_UBWC_SUPPORT:
+            value = 0;
+            if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
+                value = 1;
+            }
+            break;
         default:
             ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
             value = -EINVAL;
@@ -1123,6 +1144,9 @@
     }
 
     int dst_surface_type;
+    if (ctx->is_dst_ubwc_format)
+        flags |= FLAGS_UBWC_FORMAT_MODE;
+
     if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
         dst_surface_type = RGB_SURFACE;
         flags |= FLAGS_PREMULTIPLIED_ALPHA;
@@ -1305,6 +1329,7 @@
 
     flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
     flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
+    flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
     status = set_image(ctx, src_surface.surface_id, &src_image,
                        (eC2DFlags)flags, mapped_src_idx);
     if(status) {
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 1b59fde..4e9e264 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -844,6 +844,10 @@
         return -ENOMEM;
     }
 
+    if(isUBwcEnabled(format, usage)) {
+      data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+    }
+
     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
                                                  data.allocType, 0, format,
                                                  alignedw, alignedh);
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 38a6235..efc7d67 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -88,6 +88,7 @@
 #define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
 #define GRALLOC_MODULE_PERFORM_GET_IGC 11
 #define GRALLOC_MODULE_PERFORM_SET_IGC 12
+#define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
 
 /* OEM specific HAL formats */
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 8d8532b..5e8e59f 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -480,6 +480,15 @@
                 }
             } break;
 
+        case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE:
+            {
+                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                bool *enable = va_arg(args, bool*);
+                if (private_handle_t::validate(hnd)) {
+                    return res;
+                }
+                setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable);
+            } break;
         default:
             break;
     }
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index a66704e..635e676 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -60,27 +60,9 @@
     MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
     data->operation |= paramType;
     switch (paramType) {
-        case PP_PARAM_HSIC:
-            data->hsicData = *((HSICData_t *)param);
-            break;
-        case PP_PARAM_SHARPNESS:
-            data->sharpness = *((int32_t *)param);
-            break;
-        case PP_PARAM_VID_INTFC:
-            data->video_interface = *((int32_t *)param);
-            break;
         case PP_PARAM_INTERLACED:
             data->interlaced = *((int32_t *)param);
             break;
-        case PP_PARAM_IGC:
-            memcpy((void *)&data->igcData, param, sizeof(IGCData_t));
-            break;
-        case PP_PARAM_SHARP2:
-            data->Sharp2Data = *((Sharp2Data_t *)param);
-            break;
-        case PP_PARAM_TIMESTAMP:
-            data->timestamp = *((int64_t *)param);
-            break;
         case UPDATE_BUFFER_GEOMETRY:
             data->bufferDim = *((BufferDim_t *)param);
             break;
@@ -102,6 +84,9 @@
         case SET_IGC:
             data->igc = *((IGC_t *)param);
             break;
+        case SET_SINGLE_BUFFER_MODE:
+            data->isSingleBufferMode = *((bool *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 532a6d8..a927f75 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -34,8 +34,6 @@
 extern "C" {
 #endif
 
-#define MAX_IGC_LUT_ENTRIES 256
-
 enum ColorSpace_t{
     ITU_R_601,
     ITU_R_601_FR,
@@ -54,19 +52,6 @@
     float   contrast;
 };
 
-struct Sharp2Data_t {
-    int32_t strength;
-    uint32_t edge_thr;
-    uint32_t smooth_thr;
-    uint32_t noise_thr;
-};
-
-struct IGCData_t{
-    uint16_t c0[MAX_IGC_LUT_ENTRIES];
-    uint16_t c1[MAX_IGC_LUT_ENTRIES];
-    uint16_t c2[MAX_IGC_LUT_ENTRIES];
-};
-
 struct BufferDim_t {
     int32_t sliceWidth;
     int32_t sliceHeight;
@@ -76,12 +61,6 @@
     int32_t operation;
     int32_t interlaced;
     struct BufferDim_t bufferDim;
-    struct HSICData_t hsicData;
-    int32_t sharpness;
-    int32_t video_interface;
-    struct IGCData_t igcData;
-    struct Sharp2Data_t Sharp2Data;
-    int64_t timestamp;
     uint32_t refreshrate;
     enum ColorSpace_t colorSpace;
     enum IGC_t igc;
@@ -97,16 +76,19 @@
     uint32_t s3dFormat;
     /* VENUS output buffer is linear for UBWC Interlaced video */
     uint32_t linearFormat;
+    /* Set by graphics to indicate that this buffer will be written to but not
+     * swapped out */
+    bool isSingleBufferMode;
 };
 
 enum DispParamType {
-    PP_PARAM_HSIC       = 0x0001,
-    PP_PARAM_SHARPNESS  = 0x0002,
+    UNUSED0             = 0x0001,
+    UNUSED1             = 0x0002,
     PP_PARAM_INTERLACED = 0x0004,
-    PP_PARAM_VID_INTFC  = 0x0008,
-    PP_PARAM_IGC        = 0x0010,
-    PP_PARAM_SHARP2     = 0x0020,
-    PP_PARAM_TIMESTAMP  = 0x0040,
+    UNUSED2             = 0x0008,
+    UNUSED3             = 0x0010,
+    UNUSED4             = 0x0020,
+    UNUSED5             = 0x0040,
     UPDATE_BUFFER_GEOMETRY = 0x0080,
     UPDATE_REFRESH_RATE = 0x0100,
     UPDATE_COLOR_SPACE = 0x0200,
@@ -114,6 +96,7 @@
     S3D_FORMAT = 0x800,
     LINEAR_FORMAT = 0x1000,
     SET_IGC = 0x2000,
+    SET_SINGLE_BUFFER_MODE = 0x4000,
 };
 
 struct private_handle_t;
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index a34d84c..2a261ee 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -30,6 +30,7 @@
 #ifndef __COLOR_PARAMS_H__
 #define __COLOR_PARAMS_H__
 
+#include <stdio.h>
 #include <string.h>
 #include <utils/locker.h>
 #include <utils/constants.h>
@@ -105,20 +106,11 @@
 };
 
 struct PPHWAttributes : HWResourceInfo, HWPanelInfo, DisplayConfigVariableInfo {
-  const char *panel_name = "generic_panel";  // TODO(user):  Add into HWPanelInfo
-                                             // to retrieve panel_name from HW.
+  char panel_name[256] = "generic_panel";
   PPFeatureVersion version;
 
-  inline void Set(const HWResourceInfo &hw_res, const HWPanelInfo &panel_info,
-                  const DisplayConfigVariableInfo &attr, const PPFeatureVersion &feature_ver) {
-    HWResourceInfo &res = *this;
-    res = hw_res;
-    HWPanelInfo &panel = *this;
-    panel = panel_info;
-    DisplayConfigVariableInfo &attributes = *this;
-    attributes = attr;
-    version = feature_ver;
-  }
+  void Set(const HWResourceInfo &hw_res, const HWPanelInfo &panel_info,
+           const DisplayConfigVariableInfo &attr, const PPFeatureVersion &feature_ver);
 };
 
 struct PPDisplayAPIPayload {
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 6aa7eab..164d438 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -134,6 +134,7 @@
   uint32_t max_fps = 0;               // Max fps supported by panel
   bool is_primary_panel = false;      // Panel is primary display
   HWSplitInfo split_info;             // Panel split configuration
+  char panel_name[256] = {0};         // Panel name
 
   bool operator !=(const HWPanelInfo &panel_info) {
     return ((port != panel_info.port) || (mode != panel_info.mode) ||
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index aea55b0..1d224ad 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -196,4 +196,26 @@
   return ret;
 }
 
+void PPHWAttributes::Set(const HWResourceInfo &hw_res,
+                         const HWPanelInfo &panel_info,
+                         const DisplayConfigVariableInfo &attr,
+                         const PPFeatureVersion &feature_ver) {
+  HWResourceInfo &res = *this;
+  res = hw_res;
+  HWPanelInfo &panel = *this;
+  panel = panel_info;
+  DisplayConfigVariableInfo &attributes = *this;
+  attributes = attr;
+  version = feature_ver;
+
+  if (strlen(panel_info.panel_name)) {
+    snprintf(&panel_name[0], sizeof(panel_name), "%s", &panel_info.panel_name[0]);
+    char *tmp = panel_name;
+    while ((tmp = strstr(tmp, " ")) != NULL)
+      *tmp = '_';
+    if ((tmp = strstr(panel_name, "\n")) != NULL)
+      *tmp = '\0';
+  }
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 5ac049c..a72fe6c 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -679,6 +679,40 @@
         hw_panel_info_.split_info.right_split);
 }
 
+void HWDevice::GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info) {
+  if (!panel_info) {
+    DLOGE("PanelInfo pointer in invalid.");
+    return;
+  }
+  char *string_buffer = new char[kMaxStringLength]();
+  if (!string_buffer) {
+    DLOGE("Failed to allocated string_buffer memory");
+    return;
+  }
+  snprintf(string_buffer, kMaxStringLength, "%s%d/msm_fb_panel_info", fb_path_, device_node);
+  FILE *fileptr = Sys::fopen_(string_buffer, "r");
+  if (!fileptr) {
+    DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
+  } else {
+    char *line = string_buffer;
+    size_t len = kMaxStringLength;
+
+    while ((Sys::getline_(&line, &len, fileptr)) != -1) {
+      uint32_t token_count = 0;
+      const uint32_t max_count = 10;
+      char *tokens[max_count] = { NULL };
+      if (!ParseLine(line, "=\n", tokens, max_count, &token_count)) {
+        if (!strncmp(tokens[0], "panel_name", strlen("panel_name"))) {
+          snprintf(panel_info->panel_name, sizeof(panel_info->panel_name), "%s", tokens[1]);
+          break;
+        }
+      }
+    }
+    Sys::fclose_(fileptr);
+  }
+  delete[] string_buffer;
+}
+
 void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
   if (!panel_info) {
     DLOGE("PanelInfo pointer in invalid.");
@@ -733,6 +767,7 @@
   panel_info->port = GetHWDisplayPort(device_node);
   panel_info->mode = GetHWDisplayMode(device_node);
   GetSplitInfo(device_node, panel_info);
+  GetHWPanelNameByNode(device_node, panel_info);
 }
 
 HWDisplayPort HWDevice::GetHWDisplayPort(int device_node) {
@@ -855,6 +890,24 @@
   return 0;
 }
 
+int HWDevice::ParseLine(char *input, const char *delim, char *tokens[],
+                        const uint32_t max_token, uint32_t *count) {
+  char *tmp_token = NULL;
+  char *temp_ptr;
+  uint32_t index = 0;
+  if (!input) {
+    return -1;
+  }
+  tmp_token = strtok_r(input, delim, &temp_ptr);
+  while (tmp_token && index < max_token) {
+    tokens[index++] = tmp_token;
+    tmp_token = strtok_r(NULL, delim, &temp_ptr);
+  }
+  *count = index;
+
+  return 0;
+}
+
 bool HWDevice::EnableHotPlugDetection(int enable) {
   char hpdpath[kMaxStringLength];
   int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index b4205e0..a2610d1 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -101,10 +101,13 @@
   // Populates HWPanelInfo based on node index
   void PopulateHWPanelInfo();
   void GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info);
+  void GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info);
   HWDisplayPort GetHWDisplayPort(int device_node);
   HWDisplayMode GetHWDisplayMode(int device_node);
   void GetSplitInfo(int device_node, HWPanelInfo *panel_info);
   int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
+  int ParseLine(char *input, const char *delim, char *tokens[],
+                const uint32_t max_token, uint32_t *count);
   mdp_scale_data* GetScaleDataRef(uint32_t index) { return &scale_data_[index]; }
   void SetHWScaleData(const ScaleData &scale, uint32_t index);
   void ResetDisplayParams();
diff --git a/sdm/libs/hwc/blit_engine_c2d.cpp b/sdm/libs/hwc/blit_engine_c2d.cpp
index e85e28c..8d9c09a 100644
--- a/sdm/libs/hwc/blit_engine_c2d.cpp
+++ b/sdm/libs/hwc/blit_engine_c2d.cpp
@@ -128,7 +128,8 @@
   }
 }
 
-int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format) {
+int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format,
+                                             uint32_t usage) {
   int status = 0;
   if (width <= 0 || height <= 0) {
     return false;
@@ -144,8 +145,7 @@
 
   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
     if (blit_target_buffer_[i] == NULL) {
-      status = alloc_buffer(&blit_target_buffer_[i], width, height, format,
-                         GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+      status = alloc_buffer(&blit_target_buffer_[i], width, height, format, usage);
     }
     if (status < 0) {
       DLOGE("Allocation of Blit target Buffer failed");
@@ -182,6 +182,11 @@
   buffer.format = hnd->format;
   buffer.base = reinterpret_cast<void *>(hnd->base);
   buffer.handle = reinterpret_cast<native_handle_t *>(hnd);
+  int dst_format_mode = COPYBIT_LINEAR;
+  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+    dst_format_mode = COPYBIT_UBWC_COMPRESSED;
+  }
+  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DST_FORMAT_MODE, dst_format_mode);
 
   status = blit_engine_c2d_->clear(blit_engine_c2d_, &buffer, &clear_rect);
   return status;
@@ -299,6 +304,7 @@
   uint32_t processed_blit = 0;
   LayerRect dst_rects[kMaxBlitTargetLayers];
   bool blit_needed = false;
+  uint32_t usage = 0;
 
   for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_); i--) {
     Layer &layer = layer_stack->layers[i];
@@ -312,9 +318,13 @@
     LayerRect &blit_src_rect = blit_layer.src_rect;
     int width = INT(layer.dst_rect.right - layer.dst_rect.left);
     int height = INT(layer.dst_rect.bottom - layer.dst_rect.top);
+    usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE;
+    if (blit_engine_c2d_->get(blit_engine_c2d_, COPYBIT_UBWC_SUPPORT) > 0) {
+      usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+    }
     // TODO(user): FrameBuffer is assumed to be RGBA
     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height,
-                                 INT(HAL_PIXEL_FORMAT_RGBA_8888), 0, width, height);
+                                 INT(HAL_PIXEL_FORMAT_RGBA_8888), usage, width, height);
 
     target_width = MAX(target_width, width);
     target_height += height;
@@ -331,7 +341,7 @@
 
   // Allocate a single buffer of RGBA8888 format
   if (blit_needed && (AllocateBlitTargetBuffers(target_width, target_height,
-                                                HAL_PIXEL_FORMAT_RGBA_8888) < 0)) {
+                                                HAL_PIXEL_FORMAT_RGBA_8888, usage) < 0)) {
       status = -1;
       return status;
   }
@@ -344,6 +354,9 @@
       if (layer.input_buffer) {
         layer.input_buffer->width = target_width;
         layer.input_buffer->height = target_height;
+        if (target_buffer->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+          layer.input_buffer->format = kFormatRGBA8888Ubwc;
+        }
         layer.input_buffer->planes[0].fd = target_buffer->fd;
         layer.input_buffer->planes[0].offset = 0;
         layer.input_buffer->planes[0].stride = target_buffer->width;
@@ -508,6 +521,13 @@
   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_BLEND_MODE, hwc_layer->blending);
   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DITHER,
     (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+  int src_format_mode = COPYBIT_LINEAR;
+  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+    src_format_mode = COPYBIT_UBWC_COMPRESSED;
+  }
+  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_SRC_FORMAT_MODE, src_format_mode);
+
   blit_engine_c2d_->set_sync(blit_engine_c2d_, acquireFd);
   int err = blit_engine_c2d_->stretch(blit_engine_c2d_, &dst, &src, &dst_rect, &src_rect,
                                       &copybitRegion);
diff --git a/sdm/libs/hwc/blit_engine_c2d.h b/sdm/libs/hwc/blit_engine_c2d.h
index 4034114..74c4b81 100644
--- a/sdm/libs/hwc/blit_engine_c2d.h
+++ b/sdm/libs/hwc/blit_engine_c2d.h
@@ -97,7 +97,7 @@
     mutable Range r;
   };
 
-  int AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format);
+  int AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
   void FreeBlitTargetBuffers();
   int ClearTargetBuffer(private_handle_t* hnd, const LayerRect& rect);
   int DrawRectUsingCopybit(hwc_layer_1_t *hwc_layer, Layer *layer, LayerRect blit_rect,