Merge "sdm: Fix hdmi resolution return value."
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index a7e00c5..26e3ec5 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -149,6 +149,26 @@
     return 0;
 }
 
+void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
+                          int& aligned_h) {
+    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        int w = metadata->bufferDim.sliceWidth;
+        int h = metadata->bufferDim.sliceHeight;
+        int f = hnd->format;
+        int usage = 0;
+
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+        }
+
+        getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
+    } else {
+        aligned_w = hnd->width;
+        aligned_h = hnd->height;
+    }
+
+}
 
 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
                             int usage, int& aligned_w, int& aligned_h)
@@ -158,8 +178,7 @@
     // Currently surface padding is only computed for RGB* surfaces.
     if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
         int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
-        AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
-            height, format, tileEnabled, aligned_w, aligned_h);
+        getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
         return;
     }
 
@@ -649,6 +668,7 @@
     int width = hnd->width;
     int height = hnd->height;
     int format = hnd->format;
+
     unsigned int ystride, cstride;
     unsigned int alignment = 4096;
 
@@ -662,8 +682,14 @@
 
     // Check metadata if the geometry has been updated.
     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
+        int usage = 0;
+
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+        }
+
         AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
-                   metadata->bufferDim.sliceHeight, format, 0, width, height);
+                   metadata->bufferDim.sliceHeight, format, usage, width, height);
     }
 
     // Get the chroma offsets from the handle width/height. We take advantage
@@ -836,12 +862,18 @@
     if (isUBwcFormat(format))
         return true;
 
-    // Allow UBWC, if client sets UBWC gralloc usage flag & GPU supports format.
-    if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format) &&
-        AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format)) {
+    // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
+    // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
+    // usage flag and MDP supports the format.
+    if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
+        bool enable = true;
+        // Query GPU for UBWC only if buffer is intended to be used by GPU.
+        if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
+            enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
+        }
         // Allow UBWC, only if CPU usage flags are not set
-        if (!(usage & (GRALLOC_USAGE_SW_READ_MASK |
-                      GRALLOC_USAGE_SW_WRITE_MASK))) {
+        if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
+            GRALLOC_USAGE_SW_WRITE_MASK))) {
             return true;
         }
     }
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 98ae919..13b0638 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -145,8 +145,7 @@
             flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
         }
 
-        if (isUBwcEnabled(format, usage) &&
-            AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format)) {
+        if (isUBwcEnabled(format, usage)) {
             flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
         }
 
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index e27203a..6d7f4a7 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -120,6 +120,14 @@
                             int usage, int& aligned_w, int& aligned_h);
 
     /*
+     * Function to compute aligned width and aligned height based on
+     * private handle
+     *
+     * @return aligned width, aligned height
+     */
+    void getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, int& aligned_h);
+
+    /*
      * Function to compute the adreno aligned width and aligned height
      * based on the width and format.
      *
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 3cfdc55..a5d3e69 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -344,36 +344,33 @@
 
         case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
             {
-                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                const private_handle_t* hnd =  va_arg(args, private_handle_t*);
                 int *stride = va_arg(args, int *);
                 if (private_handle_t::validate(hnd)) {
                     return res;
                 }
-                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-                if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-                    *stride = metadata->bufferDim.sliceWidth;
-                } else {
-                    *stride = hnd->width;
-                }
+
+                int alignedw = 0, alignedh = 0;
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+                *stride = alignedw;
+
                 res = 0;
             } break;
 
         case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
             {
-                private_handle_t* hnd =  va_arg(args, private_handle_t*);
+                const private_handle_t* hnd =  va_arg(args, private_handle_t*);
                 int *stride = va_arg(args, int *);
                 int *height = va_arg(args, int *);
                 if (private_handle_t::validate(hnd)) {
                     return res;
                 }
-                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
-                if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-                    *stride = metadata->bufferDim.sliceWidth;
-                    *height = metadata->bufferDim.sliceHeight;
-                } else {
-                    *stride = hnd->width;
-                    *height = hnd->height;
-                }
+
+                int alignedw = 0, alignedh = 0;
+                AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
+                *stride = alignedw;
+                *height = alignedh;
+
                 res = 0;
             } break;
 
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 2aa4a31..952952d 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -61,7 +61,7 @@
     data->operation |= paramType;
     switch (paramType) {
         case PP_PARAM_HSIC:
-            memcpy((void *)&data->hsicData, param, sizeof(HSICData_t));
+            data->hsicData = *((HSICData_t *)param);
             break;
         case PP_PARAM_SHARPNESS:
             data->sharpness = *((int32_t *)param);
@@ -76,13 +76,13 @@
             memcpy((void *)&data->igcData, param, sizeof(IGCData_t));
             break;
         case PP_PARAM_SHARP2:
-            memcpy((void *)&data->Sharp2Data, param, sizeof(Sharp2Data_t));
+            data->Sharp2Data = *((Sharp2Data_t *)param);
             break;
         case PP_PARAM_TIMESTAMP:
             data->timestamp = *((int64_t *)param);
             break;
         case UPDATE_BUFFER_GEOMETRY:
-            memcpy((void *)&data->bufferDim, param, sizeof(BufferDim_t));
+            data->bufferDim = *((BufferDim_t *)param);
             break;
         case UPDATE_REFRESH_RATE:
             data->refreshrate = *((uint32_t *)param);
diff --git a/sdm/include/utils/sys.h b/sdm/include/utils/sys.h
index 1c7e415..0a90fc1 100644
--- a/sdm/include/utils/sys.h
+++ b/sdm/include/utils/sys.h
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <poll.h>
+#include <pthread.h>
 
 namespace sdm {
 
@@ -43,6 +44,7 @@
   typedef FILE* (*fopen)( const char *fname, const char *mode);
   typedef int (*fclose)(FILE* fileptr);
   typedef ssize_t (*getline)(char **lineptr, size_t *linelen, FILE *stream);
+  typedef int (*pthread_cancel)(pthread_t thread);
 
   static ioctl ioctl_;
   static open open_;
@@ -53,6 +55,7 @@
   static fopen fopen_;
   static fclose fclose_;
   static getline getline_;
+  static pthread_cancel pthread_cancel_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index d354e57..8db045a 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -89,8 +89,8 @@
   Locker locker_;
   ResourceInterface *resource_intf_ = NULL;
   ResourceDefault resource_default_;
-  uint64_t registered_displays_ = 0;    // Stores the bit mask of registered displays
-  uint64_t configured_displays_ = 0;    // Stores the bit mask of sucessfully configured displays
+  uint32_t registered_displays_ = 0;    // Stores the bit mask of registered displays
+  uint32_t configured_displays_ = 0;    // Stores the bit mask of sucessfully configured displays
   bool safe_mode_ = false;              // Flag to notify all displays to be in resource crunch
                                         // mode, where strategy manager chooses the best strategy
                                         // that uses optimal number of pipes for each display
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 30aac4e..c42b89f 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -302,6 +302,8 @@
     return kErrorParameters;
   }
 
+  *enabled = vsync_enable_;
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index a71f721..8a8ef9c 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -232,6 +232,7 @@
             mdp_buffer.width = pipe_info->scale_data.src_width;
           }
           SetHWScaleData(pipe_info->scale_data, mdp_layer_count);
+          mdp_layer.flags |= MDP_LAYER_ENABLE_PIXEL_EXT;
         }
 
         // Send scale data to MDP driver
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 35f1cbe..0bd4584 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -146,21 +146,21 @@
   return error;
 }
 
-void HWPrimary::InitializeConfigs() {
-  size_t curr_x_pixels = 0;
-  size_t curr_y_pixels = 0;
-  string mode_path = string(fb_path_) + string("0/mode");
-  string modes_path = string(fb_path_) + string("0/modes");
+bool HWPrimary::GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels) {
+  bool ret = false;
   size_t len = kPageSize;
-  char *buffer = static_cast<char *>(calloc(len, sizeof(char)));
-
-  if (buffer == NULL) {
-    DLOGW("Failed to allocate memory");
-    return;
-  }
+  string mode_path = string(fb_path_) + string("0/mode");
 
   FILE *fd = Sys::fopen_(mode_path.c_str(), "r");
   if (fd) {
+    char *buffer = static_cast<char *>(calloc(len, sizeof(char)));
+
+    if (buffer == NULL) {
+      DLOGW("Failed to allocate memory");
+      Sys::fclose_(fd);
+      return false;
+    }
+
     if (Sys::getline_(&buffer, &len, fd) > 0) {
       // String is of form "U:1600x2560p-0". Documentation/fb/modedb.txt in
       // kernel has more info on the format.
@@ -169,21 +169,41 @@
 
       if (xpos == string::npos || ypos == string::npos) {
         DLOGI("Resolution switch not supported");
-        free(buffer);
-        Sys::fclose_(fd);
-        return;
+      } else {
+        *curr_x_pixels = atoi(buffer + xpos + 1);
+        *curr_y_pixels = atoi(buffer + ypos + 1);
+        DLOGI("Current Config: %u x %u", *curr_x_pixels, *curr_y_pixels);
+        ret = true;
       }
-
-      curr_x_pixels = atoi(buffer + xpos + 1);
-      curr_y_pixels = atoi(buffer + ypos + 1);
-      DLOGI("Current Config: %u x %u", curr_x_pixels, curr_y_pixels);
     }
 
+    free(buffer);
     Sys::fclose_(fd);
   }
 
-  fd = Sys::fopen_(modes_path.c_str(), "r");
+  return ret;
+}
+
+void HWPrimary::InitializeConfigs() {
+  size_t curr_x_pixels = 0;
+  size_t curr_y_pixels = 0;
+  size_t len = kPageSize;
+  string modes_path = string(fb_path_) + string("0/modes");
+
+  if (!GetCurrentModeFromSysfs(&curr_x_pixels, &curr_y_pixels)) {
+    return;
+  }
+
+  FILE *fd = Sys::fopen_(modes_path.c_str(), "r");
   if (fd) {
+    char *buffer = static_cast<char *>(calloc(len, sizeof(char)));
+
+    if (buffer == NULL) {
+      DLOGW("Failed to allocate memory");
+      Sys::fclose_(fd);
+      return;
+    }
+
     while (Sys::getline_(&buffer, &len, fd) > 0) {
       DisplayConfigVariableInfo config;
       size_t xpos = string(buffer).find(':');
@@ -205,16 +225,16 @@
       }
     }
 
+    free(buffer);
     Sys::fclose_(fd);
   } else {
     DLOGI("Unable to process modes");
   }
-
-  free(buffer);
 }
 
 DisplayError HWPrimary::Deinit() {
   exit_threads_ = true;
+  Sys::pthread_cancel_(event_thread_);
   pthread_join(event_thread_, NULL);
 
   for (int event = 0; event < kNumDisplayEvents; event++) {
@@ -228,7 +248,7 @@
 }
 
 DisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) {
-  *count = isResolutionSwitchEnabled() ? display_configs_.size() : 1;
+  *count = IsResolutionSwitchEnabled() ? display_configs_.size() : 1;
   return kErrorNone;
 }
 
@@ -243,7 +263,7 @@
     return kErrorParameters;
   }
 
-  if (isResolutionSwitchEnabled() && index >= display_configs_.size()) {
+  if (IsResolutionSwitchEnabled() && index >= display_configs_.size()) {
     return kErrorParameters;
   }
 
@@ -256,11 +276,10 @@
   }
 
   *display_attributes = display_attributes_;
-  if (isResolutionSwitchEnabled()) {
+  if (IsResolutionSwitchEnabled()) {
     // Overwrite only the parent portion of object
     display_attributes->x_pixels = display_configs_.at(index).x_pixels;
     display_attributes->y_pixels = display_configs_.at(index).y_pixels;
-    display_attributes->fps = display_configs_.at(index).fps;
   }
 
   return kErrorNone;
@@ -318,7 +337,7 @@
 DisplayError HWPrimary::SetDisplayAttributes(uint32_t index) {
   DisplayError ret = kErrorNone;
 
-  if (!isResolutionSwitchEnabled()) {
+  if (!IsResolutionSwitchEnabled()) {
     return kErrorNotSupported;
   }
 
@@ -543,7 +562,7 @@
 
   // Notify driver about the timeout value
   ssize_t length = Sys::pwrite_(fd, timeout_string, strlen(timeout_string), 0);
-  if (length < -1) {
+  if (length <= 0) {
     DLOGE("Unable to write into %s, node %s", node_path, strerror(errno));
   }
 
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index 2f052fc..5615a19 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -80,7 +80,8 @@
   void HandleThermal(char *data);
   DisplayError PopulateDisplayAttributes();
   void InitializeConfigs();
-  bool isResolutionSwitchEnabled() { return !display_configs_.empty(); }
+  bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
+  bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
 
   pollfd poll_fds_[kNumDisplayEvents];
   pthread_t event_thread_;
diff --git a/sdm/libs/hwc/hwc_buffer_allocator.cpp b/sdm/libs/hwc/hwc_buffer_allocator.cpp
index 54dbefb..556780f 100644
--- a/sdm/libs/hwc/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc/hwc_buffer_allocator.cpp
@@ -78,6 +78,7 @@
 
   error = SetBufferInfo(buffer_config.format, &format, &alloc_flags);
   if (error != 0) {
+    delete meta_buffer_info;
     return kErrorParameters;
   }
 
@@ -96,6 +97,7 @@
   error = alloc_controller_->allocate(data, alloc_flags);
   if (error != 0) {
     DLOGE("Error allocating memory size %d uncached %d", data.size, data.uncached);
+    delete meta_buffer_info;
     return kErrorMemory;
   }
 
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index dc01165..8debf88 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -43,8 +43,20 @@
 
 namespace sdm {
 
-void HWCDisplay::AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height,
-                                        uint32_t *src_width, uint32_t *src_height) {
+static void AssignLayerRegionsAddress(LayerRectArray *region, uint32_t rect_count,
+                                      uint8_t **base_address) {
+  if (rect_count) {
+    region->rect = reinterpret_cast<LayerRect *>(*base_address);
+    region->count = rect_count;
+    for (size_t i = 0; i < rect_count; i++) {
+      region->rect[i] = LayerRect();
+    }
+    *base_address += rect_count * sizeof(LayerRect);
+  }
+}
+
+static void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height, uint32_t *src_width,
+                                   uint32_t *src_height) {
   *src_height = (dst_width * (*src_height)) / (*src_width);
   *src_width = dst_width;
 }
@@ -303,19 +315,27 @@
     blit_target_count = kMaxBlitTargetLayers;
   }
 
-  // Allocate memory for a) total number of layers b) buffer handle for each layer c) number of
-  // visible rectangles in each layer d) dirty rectangle for each layer
+  // Allocate memory for
+  //  a) total number of layers
+  //  b) buffer handle for each layer
+  //  c) number of visible rectangles in each layer
+  //  d) number of dirty rectangles in each layer
+  //  e) number of blit rectangles in each layer
   size_t required_size = (num_hw_layers + blit_target_count) *
                          (sizeof(Layer) + sizeof(LayerBuffer));
 
   for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) {
-    uint32_t num_visible_rects = 1;
+    uint32_t num_visible_rects = 0;
+    uint32_t num_dirty_rects = 0;
+
+    hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
     if (i < num_hw_layers) {
-      num_visible_rects = INT32(content_list->hwLayers[i].visibleRegionScreen.numRects);
+      num_visible_rects = INT32(hwc_layer.visibleRegionScreen.numRects);
+      num_dirty_rects = INT32(hwc_layer.surfaceDamage.numRects);
     }
 
-    // visible rectangles + 1 dirty rectangle + blit rectangle
-    size_t num_rects = num_visible_rects + 1 + blit_target_count;
+    // visible rectangles + dirty rectangles + blit rectangle
+    size_t num_rects = num_visible_rects + num_dirty_rects + blit_target_count;
     required_size += num_rects * sizeof(LayerRect);
   }
 
@@ -347,10 +367,12 @@
   current_address += (num_hw_layers + blit_target_count) * sizeof(Layer);
 
   for (size_t i = 0; i < num_hw_layers + blit_target_count; i++) {
-    uint32_t num_visible_rects = 1;
+    uint32_t num_visible_rects = 0;
+    uint32_t num_dirty_rects = 0;
+
     if (i < num_hw_layers) {
-      num_visible_rects =
-        static_cast<uint32_t>(content_list->hwLayers[i].visibleRegionScreen.numRects);
+      num_visible_rects = UINT32(content_list->hwLayers[i].visibleRegionScreen.numRects);
+      num_dirty_rects = UINT32(content_list->hwLayers[i].surfaceDamage.numRects);
     }
 
     Layer &layer = layer_stack_.layers[i];
@@ -361,27 +383,10 @@
     *layer.input_buffer = LayerBuffer();
     current_address += sizeof(LayerBuffer);
 
-    // Visible rectangle address
-    layer.visible_regions.rect = reinterpret_cast<LayerRect *>(current_address);
-    layer.visible_regions.count = num_visible_rects;
-    for (size_t i = 0; i < layer.visible_regions.count; i++) {
-      layer.visible_regions.rect[i] = LayerRect();
-    }
-    current_address += num_visible_rects * sizeof(LayerRect);
-
-    // Dirty rectangle address
-    layer.dirty_regions.rect = reinterpret_cast<LayerRect *>(current_address);
-    layer.dirty_regions.count = 1;
-    *layer.dirty_regions.rect = LayerRect();
-    current_address += sizeof(LayerRect);
-
-    // Blit rectangle address
-    layer.blit_regions.rect = reinterpret_cast<LayerRect *>(current_address);
-    layer.blit_regions.count = blit_target_count;
-    for (size_t i = 0; i < layer.blit_regions.count; i++) {
-      layer.blit_regions.rect[i] = LayerRect();
-    }
-    current_address += layer.blit_regions.count * sizeof(LayerRect);
+    // Visible/Dirty/Blit rectangle address
+    AssignLayerRegionsAddress(&layer.visible_regions, num_visible_rects, &current_address);
+    AssignLayerRegionsAddress(&layer.dirty_regions, num_dirty_rects, &current_address);
+    AssignLayerRegionsAddress(&layer.blit_regions, blit_target_count, &current_address);
   }
 
   return 0;
@@ -524,7 +529,9 @@
     for (size_t j = 0; j < hwc_layer.visibleRegionScreen.numRects; j++) {
       SetRect(hwc_layer.visibleRegionScreen.rects[j], &layer.visible_regions.rect[j]);
     }
-    SetRect(hwc_layer.sourceCropf, &layer.dirty_regions.rect[0]);
+    for (size_t j = 0; j < hwc_layer.surfaceDamage.numRects; j++) {
+      SetRect(hwc_layer.surfaceDamage.rects[j], &layer.dirty_regions.rect[j]);
+    }
     SetComposition(hwc_layer.compositionType, &layer.composition);
 
     // For dim layers, SurfaceFlinger
@@ -560,7 +567,7 @@
       layer.src_rect.top = 0;
       layer.src_rect.right = input_buffer->width;
       layer.src_rect.bottom = input_buffer->height;
-      layer.dirty_regions.rect[0] = layer.src_rect;
+      layer.dirty_regions.count = 0;
     }
 
     layer.plane_alpha = hwc_layer.planeAlpha;
@@ -784,13 +791,16 @@
 bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
   uint32_t layer_count = layer_stack_.layer_count;
 
+  if (layer_stack_cache_.animating) {
+      return false;
+  }
+
   // Frame buffer needs to be refreshed for the following reasons:
   // 1. Any layer is marked skip in the current layer stack.
   // 2. Any layer is added/removed/layer properties changes in the current layer stack.
   // 3. Any layer handle is changed and it is marked for GPU composition
   // 4. Any layer's current composition is different from previous composition.
-  if ((layer_stack_cache_.layer_count != layer_count) || layer_stack_.flags.skip_present ||
-      layer_stack_.flags.geometry_changed || layer_stack_.flags.animating) {
+  if (layer_stack_.flags.skip_present || layer_stack_.flags.geometry_changed) {
     return true;
   }
 
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index edb7a81..4730222 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -36,6 +36,7 @@
 
 class HWCDisplay : public DisplayEventHandler {
  public:
+  virtual ~HWCDisplay() { }
   virtual int Init();
   virtual int Deinit();
   virtual int Prepare(hwc_display_contents_1_t *content_list) = 0;
@@ -61,7 +62,6 @@
   virtual int OnMinHdcpEncryptionLevelChange();
   virtual int Perform(uint32_t operation, ...);
   virtual int SetCursorPosition(int x, int y);
-  virtual ~HWCDisplay() { }
   virtual void SetSecureDisplay(bool secure_display_active);
 
   // Display Configurations
@@ -145,9 +145,6 @@
   bool NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list);
   void CacheLayerStackInfo(hwc_display_contents_1_t *content_list);
   bool IsLayerUpdating(const hwc_layer_1_t &hwc_layer, const LayerCache &layer_cache);
-
-  static void AdjustSourceResolution(uint32_t dst_width, uint32_t dst_height, uint32_t *src_width,
-                                     uint32_t *src_height);
   static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height,
                                      uint32_t *virtual_width, uint32_t *virtual_height);
 
diff --git a/sdm/libs/hwc/hwc_display_virtual.cpp b/sdm/libs/hwc/hwc_display_virtual.cpp
index 10a8ec2..cd1f5ff 100644
--- a/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -39,24 +39,6 @@
 
 namespace sdm {
 
-static int GetWidthFromMetaData(const private_handle_t *handle) {
-  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
-  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-    return metadata->bufferDim.sliceWidth;
-  }
-
-  return handle->width;
-}
-
-static int GetHeightFromMetaData(const private_handle_t *handle) {
-  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
-  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
-    return metadata->bufferDim.sliceHeight;
-  }
-
-  return handle->height;
-}
-
 int HWCDisplayVirtual::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
                               uint32_t primary_width, uint32_t primary_height,
                               hwc_display_contents_1_t *content_list,
@@ -79,6 +61,7 @@
 
   status = hwc_display_virtual->SetOutputSliceFromMetadata(content_list);
   if (status) {
+    Destroy(hwc_display_virtual);
     return status;
   }
 
@@ -217,8 +200,11 @@
       return -EINVAL;
     }
 
-    int active_width = GetWidthFromMetaData(output_handle);
-    int active_height = GetHeightFromMetaData(output_handle);
+    int active_width;
+    int active_height;
+
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, active_width,
+                                                          active_height);
 
     if ((active_width != INT(output_buffer_->width)) ||
         (active_height!= INT(output_buffer_->height)) ||
@@ -259,8 +245,12 @@
       return -EINVAL;
     }
 
-    output_buffer_->width = GetWidthFromMetaData(output_handle);
-    output_buffer_->height = GetHeightFromMetaData(output_handle);
+    int output_buffer_width, output_buffer_height;
+    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, output_buffer_width,
+                                                          output_buffer_height);
+
+    output_buffer_->width = output_buffer_width;
+    output_buffer_->height = output_buffer_height;
     output_buffer_->flags.secure = 0;
     output_buffer_->flags.video = 0;
 
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 8fccf64..4090705 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -91,7 +91,7 @@
   hwc_procs_default_.hotplug = Hotplug;
 
   hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
-  hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
+  hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_5;
   hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
   hwc_composer_device_1_t::common.close = Close;
   hwc_composer_device_1_t::prepare = Prepare;
@@ -628,7 +628,7 @@
     // Read backlight and store it internally. Set backlight to 0 on primary.
     if (read(fd, brightness_, sizeof(brightness_)) > 0) {
       DLOGI("backlight brightness is %s", brightness_);
-      ssize_t ret = write(fd, bl_brightness, sizeof(bl_brightness));
+      ssize_t ret = write(fd, bl_brightness, strlen(bl_brightness));
       if (ret < 0) {
         DLOGE("Failed to write backlight node err = %d errstr = %s", errno, strerror(errno));
         close(fd);
diff --git a/sdm/libs/utils/sys.cpp b/sdm/libs/utils/sys.cpp
index dd62d6e..03310ff 100644
--- a/sdm/libs/utils/sys.cpp
+++ b/sdm/libs/utils/sys.cpp
@@ -38,6 +38,10 @@
 
 #ifndef SDM_VIRTUAL_DRIVER
 
+int PthreadCancel(pthread_t /* thread */) {
+  return 0;
+}
+
 // Pointer to actual driver interfaces.
 Sys::ioctl Sys::ioctl_ = ::ioctl;
 Sys::open Sys::open_ = ::open;
@@ -48,6 +52,7 @@
 Sys::fopen Sys::fopen_ = ::fopen;
 Sys::fclose Sys::fclose_ = ::fclose;
 Sys::getline Sys::getline_ = ::getline;
+Sys::pthread_cancel Sys::pthread_cancel_ = PthreadCancel;
 
 #else
 
@@ -71,6 +76,7 @@
 Sys::fopen Sys::fopen_ = virtual_fopen;
 Sys::fclose Sys::fclose_ = virtual_fclose;
 Sys::getline Sys::getline_ = virtual_getline;
+Sys::pthread_cancel Sys::pthread_cancel_ = ::pthread_cancel;
 
 #endif  // SDM_VIRTUAL_DRIVER