drm_hwcomposer: Add property that allows disabling of hardware scaling

Set `hwc.drm.scale_with_gpu` property to 1 in case composer hardware
do not have scaling support.

That will force layers that require scaling to be merged by GPU,
and allow other layers to be merged by DRM.

Signed-off-by: Roman Stratiienko <roman.stratiienko@globallogic.com>
diff --git a/drm/resourcemanager.cpp b/drm/resourcemanager.cpp
index 6e23561..da1a2db 100644
--- a/drm/resourcemanager.cpp
+++ b/drm/resourcemanager.cpp
@@ -50,6 +50,10 @@
     return ret ? -EINVAL : ret;
   }
 
+  char scale_with_gpu[PROPERTY_VALUE_MAX];
+  property_get("hwc.drm.scale_with_gpu", scale_with_gpu, "0");
+  scale_with_gpu_ = bool(strncmp(scale_with_gpu, "0", 1));
+
   return hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
                        (const hw_module_t **)&gralloc_);
 }
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index 5e07f2f..e2c943a 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -903,7 +903,9 @@
   for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
     if (!HardwareSupportsLayerType(l.second->sf_type()) ||
         !importer_->CanImportBuffer(l.second->buffer()) ||
-        color_transform_hint_ != HAL_COLOR_TRANSFORM_IDENTITY) {
+        color_transform_hint_ != HAL_COLOR_TRANSFORM_IDENTITY ||
+        (l.second->RequireScalingOrPhasing() &&
+         resource_manager_->ForcedScalingWithGpu())) {
       if (client_start < 0)
         client_start = l.first;
       client_size = (l.first - client_start) + 1;
diff --git a/include/drmhwctwo.h b/include/drmhwctwo.h
index 89ae2f6..444c6ed 100644
--- a/include/drmhwctwo.h
+++ b/include/drmhwctwo.h
@@ -22,6 +22,7 @@
 
 #include <hardware/hwcomposer2.h>
 
+#include <math.h>
 #include <array>
 #include <map>
 
@@ -93,6 +94,19 @@
 
     void PopulateDrmLayer(DrmHwcLayer *layer);
 
+    bool RequireScalingOrPhasing() {
+      float src_width = source_crop_.right - source_crop_.left;
+      float src_height = source_crop_.bottom - source_crop_.top;
+
+      float dest_width = display_frame_.right - display_frame_.left;
+      float dest_height = display_frame_.bottom - display_frame_.top;
+
+      bool scaling = src_width != dest_width || src_height != dest_height;
+      bool phasing = (source_crop_.left - floor(source_crop_.left) != 0) ||
+                     (source_crop_.top - floor(source_crop_.top) != 0);
+      return scaling || phasing;
+    }
+
     // Layer hooks
     HWC2::Error SetCursorPosition(int32_t x, int32_t y);
     HWC2::Error SetLayerBlendMode(int32_t mode);
diff --git a/include/resourcemanager.h b/include/resourcemanager.h
index f10af45..7a86828 100644
--- a/include/resourcemanager.h
+++ b/include/resourcemanager.h
@@ -40,6 +40,9 @@
   int getDisplayCount() const {
     return num_displays_;
   }
+  bool ForcedScalingWithGpu() {
+    return scale_with_gpu_;
+  }
 
  private:
   int AddDrmDevice(std::string path);
@@ -48,6 +51,8 @@
   std::vector<std::unique_ptr<DrmDevice>> drms_;
   std::vector<std::shared_ptr<Importer>> importers_;
   const gralloc_module_t *gralloc_;
+
+  bool scale_with_gpu_;
 };
 }  // namespace android