drm_hwcomposer: Add rotation support for hw planes

This patch adds support for transformed layers by using the
rotation property on drm planes.

Bug: chrome-os-partner:42093
Test: On smaug using
	adb shell content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:<R>

Change-Id: I86bb8ef2f77b5d046a5fddd57db4b87070b5801f
Signed-off-by: Sean Paul <seanpaul@chromium.org>
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 364a64e..d8dc886 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -85,9 +85,6 @@
 
 int DrmDisplayComposition::AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo,
                                     DrmCrtc *crtc, DrmPlane *plane) {
-  if (layer->transform != 0)
-    return -EINVAL;
-
   if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
     return -EINVAL;
 
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 10b4480..dc5859a 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -28,6 +28,7 @@
 #include <time.h>
 #include <vector>
 
+#include <drm/drm_mode.h>
 #include <cutils/log.h>
 #include <sync/sync.h>
 #include <utils/Trace.h>
@@ -173,6 +174,38 @@
       continue;
     }
 
+    uint64_t rotation;
+    switch (layer->transform) {
+      case HWC_TRANSFORM_FLIP_H:
+        rotation = 1 << DRM_REFLECT_X;
+        break;
+      case HWC_TRANSFORM_FLIP_V:
+        rotation = 1 << DRM_REFLECT_Y;
+        break;
+      case HWC_TRANSFORM_ROT_90:
+        rotation = 1 << DRM_ROTATE_90;
+        break;
+      case HWC_TRANSFORM_ROT_180:
+        rotation = 1 << DRM_ROTATE_180;
+        break;
+      case HWC_TRANSFORM_ROT_270:
+        rotation = 1 << DRM_ROTATE_270;
+        break;
+      case 0:
+        rotation = 0;
+        break;
+      default:
+        ALOGE("Invalid transform value 0x%x given", layer->transform);
+        ret = -EINVAL;
+        break;
+    }
+    // TODO: Once we have atomic test, this should fall back to GL
+    if (rotation && plane->rotation_property().id() == 0) {
+      ALOGE("Rotation is not supported on plane %d", plane->id());
+      ret = -EINVAL;
+      break;
+    }
+
     ret =
         drmModePropertySetAdd(pset, plane->id(), plane->crtc_property().id(),
                               crtc->id()) ||
@@ -202,6 +235,16 @@
       ALOGE("Failed to add plane %d to set", plane->id());
       break;
     }
+
+    if (plane->rotation_property().id()) {
+      ret = drmModePropertySetAdd(
+              pset, plane->id(), plane->rotation_property().id(), rotation);
+      if (ret) {
+        ALOGE("Failed to add rotation property %d to plane %d",
+              plane->rotation_property().id(), plane->id());
+        break;
+      }
+    }
   }
 
   if (!ret) {
@@ -364,7 +407,8 @@
         " src[x/y/w/h]=" << layer->sourceCropf.left << "/" <<
         layer->sourceCropf.top << "/" <<
         layer->sourceCropf.right - layer->sourceCropf.left << "/" <<
-        layer->sourceCropf.bottom - layer->sourceCropf.top << "\n";
+        layer->sourceCropf.bottom - layer->sourceCropf.top <<  " transform=" <<
+        layer->transform << "\n";
   }
 
 }
diff --git a/drmplane.cpp b/drmplane.cpp
index d6ac875..3f17d7c 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -120,6 +120,10 @@
     return ret;
   }
 
+  ret = drm_->GetPlaneProperty(*this, "rotation", &rotation_property_);
+  if (ret)
+    ALOGE("Could not get rotation property");
+
   return 0;
 }
 
@@ -174,4 +178,8 @@
 const DrmProperty &DrmPlane::src_h_property() const {
   return src_h_property_;
 }
+
+const DrmProperty &DrmPlane::rotation_property() const {
+  return rotation_property_;
+}
 }
diff --git a/drmplane.h b/drmplane.h
index 96cd85c..1969d52 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -51,6 +51,7 @@
   const DrmProperty &src_y_property() const;
   const DrmProperty &src_w_property() const;
   const DrmProperty &src_h_property() const;
+  const DrmProperty &rotation_property() const;
 
  private:
   DrmPlane(const DrmPlane &);
@@ -72,6 +73,7 @@
   DrmProperty src_y_property_;
   DrmProperty src_w_property_;
   DrmProperty src_h_property_;
+  DrmProperty rotation_property_;
 };
 }