Merge "gralloc: Return aligned w,h for UPDATE_BUFFER_GEOMETRY"
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 0070fa1..26e3ec5 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -862,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/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/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index f8175f3..1d0b5e8 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/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 97aa5c9..ddef5c2 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
@@ -444,7 +445,9 @@
   DLOGI_IF(kTagDriverConfig, "retire_fence_fd %d", stack->retire_fence_fd);
   DLOGI_IF(kTagDriverConfig, "*******************************************************************");
 
-  Sys::close_(mdp_commit.release_fence);
+  if (mdp_commit.release_fence >= 0) {
+    Sys::close_(mdp_commit.release_fence);
+  }
 
   if (synchronous_commit_) {
     // A synchronous commit can be requested when changing the display mode so we need to update
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index d5c913d..e5d0d12 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -151,21 +151,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.
@@ -174,21 +174,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(':');
@@ -210,12 +230,11 @@
       }
     }
 
+    free(buffer);
     Sys::fclose_(fd);
   } else {
     DLOGI("Unable to process modes");
   }
-
-  free(buffer);
 }
 
 DisplayError HWPrimary::Deinit() {
@@ -223,14 +242,17 @@
   pthread_join(event_thread_, NULL);
 
   for (int event = 0; event < kNumDisplayEvents; event++) {
-    Sys::close_(poll_fds_[event].fd);
+    int &fd = poll_fds_[event].fd;
+    if (fd >= 0) {
+      Sys::close_(fd);
+    }
   }
 
   return HWDevice::Deinit();
 }
 
 DisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) {
-  *count = isResolutionSwitchEnabled() ? display_configs_.size() : 1;
+  *count = IsResolutionSwitchEnabled() ? display_configs_.size() : 1;
   return kErrorNone;
 }
 
@@ -245,7 +267,7 @@
     return kErrorParameters;
   }
 
-  if (isResolutionSwitchEnabled() && index >= display_configs_.size()) {
+  if (IsResolutionSwitchEnabled() && index >= display_configs_.size()) {
     return kErrorParameters;
   }
 
@@ -258,11 +280,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;
@@ -320,7 +341,7 @@
 DisplayError HWPrimary::SetDisplayAttributes(uint32_t index) {
   DisplayError ret = kErrorNone;
 
-  if (!isResolutionSwitchEnabled()) {
+  if (!IsResolutionSwitchEnabled()) {
     return kErrorNotSupported;
   }
 
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 602c416..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;
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 aa79a5f..cd1f5ff 100644
--- a/sdm/libs/hwc/hwc_display_virtual.cpp
+++ b/sdm/libs/hwc/hwc_display_virtual.cpp
@@ -61,6 +61,7 @@
 
   status = hwc_display_virtual->SetOutputSliceFromMetadata(content_list);
   if (status) {
+    Destroy(hwc_display_virtual);
     return status;
   }
 
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);