Merge "sdm: Do not use H/W cursor on a display with scaled composition"
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 4f80f86..a98bf44 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -273,6 +273,13 @@
                                 //!< Specifies the buffer id.
 };
 
+// This enum represents buffer layout types.
+enum BufferLayout {
+  kLinear,    //!< Linear data
+  kUBWC,      //!< UBWC aligned data
+  kTPTiled    //!< Tightly Packed data
+};
+
 }  // namespace sdm
 
 #endif  // __LAYER_BUFFER_H__
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index b960955..e6e8b6c 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -128,6 +128,7 @@
   uint32_t num_rotator = 0;
   bool has_downscale = false;
   std::string device_path = "";
+  float min_downscale = 2.0f;
 
   void Reset() { *this = HWRotatorInfo(); }
 };
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index 3f34e91..48b7a02 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -51,7 +51,7 @@
   virtual void Purge(Handle display_ctx) = 0;
   virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) = 0;
   virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                       bool rotate90, bool ubwc_tiled,
+                                       bool rotate90, BufferLayout layout,
                                        bool use_rotator_downscale) = 0;
   virtual DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer,
                                             bool is_top) = 0;
diff --git a/sdm/include/utils/formats.h b/sdm/include/utils/formats.h
index 67548f3..dd819dc 100644
--- a/sdm/include/utils/formats.h
+++ b/sdm/include/utils/formats.h
@@ -37,6 +37,7 @@
 bool IsUBWCFormat(LayerBufferFormat format);
 bool Is10BitFormat(LayerBufferFormat format);
 const char *GetFormatString(const LayerBufferFormat &format);
+BufferLayout GetBufferLayout(LayerBufferFormat format);
 
 }  // namespace sdm
 
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 2c24f62..e747878 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -435,8 +435,8 @@
 
 DisplayError CompManager::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
                                           bool rotate90) {
-  return resource_intf_->ValidateScaling(crop, dst, rotate90, Debug::IsUbwcTiledFrameBuffer(),
-                                         true /* use_rotator_downscale */);
+  BufferLayout layout = Debug::IsUbwcTiledFrameBuffer() ? kUBWC : kLinear;
+  return resource_intf_->ValidateScaling(crop, dst, rotate90, layout, true);
 }
 
 DisplayError CompManager::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index ef450c0..9f9cae4 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -386,18 +386,20 @@
     }
   }
 
-  DLOGI("MDSS Rotator: Count = %d, Downscale = %d", hw_resource->hw_rot_info.num_rotator,
-        hw_resource->hw_rot_info.has_downscale);
+  DLOGI("MDSS Rotator: Count = %d, Downscale = %d, Min_downscale = %f",
+        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
+        hw_resource->hw_rot_info.min_downscale);
 
   return kErrorNone;
 }
 
 DisplayError HWInfo::GetV4L2RotatorInfo(HWResourceInfo *hw_resource) {
+  string v4l2_path = "/sys/class/video4linux/video";
   const uint32_t kMaxV4L2Nodes = 64;
   bool found = false;
 
   for (uint32_t i = 0; (i < kMaxV4L2Nodes) && (false == found); i++) {
-    string path = "/sys/class/video4linux/video" + to_string(i) + "/name";
+    string path = v4l2_path + to_string(i) + "/name";
     Sys::fstream fs(path, fstream::in);
     if (!fs.is_open()) {
       continue;
@@ -410,13 +412,32 @@
        hw_resource->hw_rot_info.num_rotator++;
        hw_resource->hw_rot_info.type = HWRotatorInfo::ROT_TYPE_V4L2;
        hw_resource->hw_rot_info.has_downscale = true;
+
+       string caps_path = v4l2_path + to_string(i) + "/device/caps";
+       Sys::fstream caps_fs(caps_path, fstream::in);
+
+       if (caps_fs.is_open()) {
+         uint32_t token_count = 0;
+         const uint32_t max_count = 10;
+         char *tokens[max_count] = { NULL };
+         string caps;
+         while (Sys::getline_(caps_fs, caps)) {
+           if (!ParseString(caps.c_str(), tokens, max_count, ":, =\n", &token_count)) {
+             if (!strncmp(tokens[0], "min_downscale", strlen("min_downscale"))) {
+               hw_resource->hw_rot_info.min_downscale = FLOAT(atof(tokens[1]));
+             }
+           }
+         }
+       }
+
        // We support only 1 rotator
        found = true;
     }
   }
 
-  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d", hw_resource->hw_rot_info.num_rotator,
-        hw_resource->hw_rot_info.has_downscale);
+  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f",
+        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
+        hw_resource->hw_rot_info.min_downscale);
 
   return kErrorNone;
 }
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 6f62143..e4a055e 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -223,10 +223,11 @@
     return kErrorHardware;
   }
 
-  // If driver doesn't return width/height information, default to 160 dpi
+  // If driver doesn't return width/height information, default to 320 dpi
   if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
-    var_screeninfo.width  = UINT32(((FLOAT(var_screeninfo.xres) * 25.4f)/160.0f) + 0.5f);
-    var_screeninfo.height = UINT32(((FLOAT(var_screeninfo.yres) * 25.4f)/160.0f) + 0.5f);
+    var_screeninfo.width  = UINT32(((FLOAT(var_screeninfo.xres) * 25.4f)/320.0f) + 0.5f);
+    var_screeninfo.height = UINT32(((FLOAT(var_screeninfo.yres) * 25.4f)/320.0f) + 0.5f);
+    DLOGW("Driver doesn't report panel physical width and height - defaulting to 320dpi");
   }
 
   display_attributes_.x_pixels = var_screeninfo.xres;
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 54a6658..39b792e 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -558,8 +558,8 @@
     return error;
   }
 
-  bool ubwc_tiled = IsUBWCFormat(layer->input_buffer->format);
-  error = ValidateScaling(src_rect, dst_rect, false /*rotated90 */, ubwc_tiled,
+  BufferLayout layout = GetBufferLayout(layer->input_buffer->format);
+  error = ValidateScaling(src_rect, dst_rect, false /*rotated90 */, layout,
                           false /* use_rotator_downscale */);
   if (error != kErrorNone) {
     return error;
@@ -716,7 +716,7 @@
   return kErrorNone;
 }
 
-DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info, bool ubwc_tiled) {
+DisplayError ResourceDefault::ValidatePipeParams(HWPipeInfo *pipe_info, LayerBufferFormat format) {
   DisplayError error = kErrorNone;
 
   const LayerRect &src_rect = pipe_info->src_roi;
@@ -727,7 +727,8 @@
     return error;
   }
 
-  error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */, ubwc_tiled,
+  BufferLayout layout = GetBufferLayout(format);
+  error = ValidateScaling(src_rect, dst_rect, false /* rotated90 */, layout,
                           false /* use_rotator_downscale */);
   if (error != kErrorNone) {
     return error;
@@ -737,7 +738,7 @@
 }
 
 DisplayError ResourceDefault::ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                              bool rotate90, bool ubwc_tiled,
+                                              bool rotate90, BufferLayout layout,
                                               bool use_rotator_downscale) {
   DisplayError error = kErrorNone;
 
@@ -749,7 +750,7 @@
     return error;
   }
 
-  error = ValidateDownScaling(scale_x, scale_y, ubwc_tiled);
+  error = ValidateDownScaling(scale_x, scale_y, (layout != kLinear));
   if (error != kErrorNone) {
     return error;
   }
@@ -884,8 +885,7 @@
     return kErrorNotSupported;
   }
 
-  bool ubwc_tiled = IsUBWCFormat(layer->input_buffer->format);
-  error = ValidatePipeParams(left_pipe, ubwc_tiled);
+  error = ValidatePipeParams(left_pipe, layer->input_buffer->format);
   if (error != kErrorNone) {
     goto PipeConfigExit;
   }
@@ -894,7 +894,7 @@
     // Make sure the  left and right ROI are conjunct
     right_pipe->src_roi.left = left_pipe->src_roi.right;
     right_pipe->dst_roi.left = left_pipe->dst_roi.right;
-    error = ValidatePipeParams(right_pipe, ubwc_tiled);
+    error = ValidatePipeParams(right_pipe, layer->input_buffer->format);
   }
 
 PipeConfigExit:
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
index 9f08155..9fab0d0 100644
--- a/sdm/libs/core/resource_default.h
+++ b/sdm/libs/core/resource_default.h
@@ -57,8 +57,8 @@
   virtual DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
   virtual void Purge(Handle display_ctx);
   virtual DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
-  virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
-                                       bool rotate90, bool ubwc_tiled, bool use_rotator_downscale);
+  virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90,
+                                       BufferLayout layout, bool use_rotator_downscale);
   DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer, bool is_top);
   DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
   DisplayError SetMaxBandwidthMode(HWBwModes mode);
@@ -121,7 +121,7 @@
   bool CalculateCropRects(const LayerRect &scissor, LayerRect *crop, LayerRect *dst);
   DisplayError ValidateLayerParams(const Layer *layer);
   DisplayError ValidateDimensions(const LayerRect &crop, const LayerRect &dst);
-  DisplayError ValidatePipeParams(HWPipeInfo *pipe_info, bool ubwc_tiled);
+  DisplayError ValidatePipeParams(HWPipeInfo *pipe_info, LayerBufferFormat format);
   DisplayError ValidateDownScaling(float scale_x, float scale_y, bool ubwc_tiled);
   DisplayError ValidateUpScaling(float scale_x, float scale_y);
   DisplayError GetScaleFactor(const LayerRect &crop, const LayerRect &dst, float *scale_x,
diff --git a/sdm/libs/utils/formats.cpp b/sdm/libs/utils/formats.cpp
index 546c0c7..8e9d0b8 100644
--- a/sdm/libs/utils/formats.cpp
+++ b/sdm/libs/utils/formats.cpp
@@ -114,5 +114,14 @@
   }
 }
 
+BufferLayout GetBufferLayout(LayerBufferFormat format) {
+  switch (format) {
+  case kFormatYCbCr420TP10Ubwc:
+    return kTPTiled;
+  default:
+    return (IsUBWCFormat(format) ? kUBWC : kLinear);
+  }
+}
+
 }  // namespace sdm