Merge "drm_hwcomposer: style fixes with clang-format" into mnc-dr-dev
diff --git a/drmcomposition.cpp b/drmcomposition.cpp
index 3f5f356..805fd26 100644
--- a/drmcomposition.cpp
+++ b/drmcomposition.cpp
@@ -126,4 +126,49 @@
     int display) {
   return std::move(composition_map_[display]);
 }
+
+int DrmComposition::DisableUnusedPlanes() {
+  for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
+       iter != drm_->end_connectors(); ++iter) {
+    int display = (*iter)->display();
+    DrmDisplayComposition *comp = GetDisplayComposition(display);
+
+    /*
+     * Leave empty compositions alone
+     * TODO: re-visit this and potentially disable leftover planes after the
+     *       active compositions have gobbled up all they can
+     */
+    if (comp->type() == DRM_COMPOSITION_TYPE_EMPTY)
+      continue;
+
+    DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
+    if (!crtc) {
+      ALOGE("Failed to find crtc for display %d", display);
+      continue;
+    }
+
+    for (std::vector<DrmPlane *>::iterator iter = primary_planes_.begin();
+         iter != primary_planes_.end(); ++iter) {
+      if ((*iter)->GetCrtcSupported(*crtc)) {
+        comp->AddPlaneDisable(*iter);
+        primary_planes_.erase(iter);
+        break;
+      }
+    }
+    for (std::vector<DrmPlane *>::iterator iter = overlay_planes_.begin();
+         iter != overlay_planes_.end();) {
+      if ((*iter)->GetCrtcSupported(*crtc)) {
+        comp->AddPlaneDisable(*iter);
+        iter = overlay_planes_.erase(iter);
+      } else {
+        iter++;
+      }
+    }
+  }
+  return 0;
+}
+
+DrmDisplayComposition *DrmComposition::GetDisplayComposition(int display) {
+  return composition_map_[display].get();
+}
 }
diff --git a/drmcomposition.h b/drmcomposition.h
index 902d7c7..06af71d 100644
--- a/drmcomposition.h
+++ b/drmcomposition.h
@@ -43,7 +43,10 @@
   virtual int AddLayer(int display, hwc_layer_1_t *layer, hwc_drm_bo_t *bo);
   int AddDpmsMode(int display, uint32_t dpms_mode);
 
+  int DisableUnusedPlanes();
+
   std::unique_ptr<DrmDisplayComposition> TakeDisplayComposition(int display);
+  DrmDisplayComposition *GetDisplayComposition(int display);
 
  private:
   DrmComposition(const DrmComposition &) = delete;
diff --git a/drmcompositor.cpp b/drmcompositor.cpp
index 9ade368..3bab93f 100644
--- a/drmcompositor.cpp
+++ b/drmcompositor.cpp
@@ -64,6 +64,13 @@
 
 int DrmCompositor::QueueComposition(Composition *composition) {
   DrmComposition *drm_composition = (DrmComposition *)composition;
+
+  int ret = drm_composition->DisableUnusedPlanes();
+  if (ret) {
+    ALOGE("Failed to disable unused planes %d", ret);
+    return ret;
+  }
+
   for (DrmResources::ConnectorIter iter = drm_->begin_connectors();
        iter != drm_->end_connectors(); ++iter) {
     int display = (*iter)->display();
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 2f8d651..d8dc886 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -51,7 +51,7 @@
 DrmDisplayComposition::~DrmDisplayComposition() {
   for (DrmCompositionLayerVector_t::iterator iter = layers_.begin();
        iter != layers_.end(); ++iter) {
-    if (importer_)
+    if (importer_ && iter->bo.fb_id)
       importer_->ReleaseBuffer(&iter->bo);
 
     if (iter->layer.acquireFenceFd >= 0)
@@ -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;
 
@@ -119,6 +116,14 @@
   return 0;
 }
 
+int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
+  DrmCompositionLayer_t c_layer;
+  c_layer.crtc = NULL;
+  c_layer.plane = plane;
+  layers_.push_back(c_layer);
+  return 0;
+}
+
 int DrmDisplayComposition::FinishComposition() {
   int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
   if (ret)
diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h
index 2ae696f..09ad3ff 100644
--- a/drmdisplaycomposition.h
+++ b/drmdisplaycomposition.h
@@ -56,6 +56,7 @@
 
   int AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo, DrmCrtc *crtc,
                DrmPlane *plane);
+  int AddPlaneDisable(DrmPlane *plane);
   int AddDpmsMode(uint32_t dpms_mode);
 
   int FinishComposition();
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 1da12fe..0fd6874 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>
@@ -157,9 +158,57 @@
     }
 
     DrmPlane *plane = iter->plane;
+    DrmCrtc *crtc = iter->crtc;
+
+    // Disable the plane if there's no crtc
+    if (!crtc) {
+      ret =
+          drmModePropertySetAdd(pset, plane->id(), plane->crtc_property().id(),
+                                0) ||
+          drmModePropertySetAdd(pset, plane->id(), plane->fb_property().id(),
+                                0);
+      if (ret) {
+        ALOGE("Failed to add plane %d disable to pset", plane->id());
+        break;
+      }
+      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(),
-                              iter->crtc->id()) ||
+                              crtc->id()) ||
         drmModePropertySetAdd(pset, plane->id(), plane->fb_property().id(),
                               iter->bo.fb_id) ||
         drmModePropertySetAdd(pset, plane->id(), plane->crtc_x_property().id(),
@@ -173,9 +222,9 @@
             pset, plane->id(), plane->crtc_h_property().id(),
             layer->displayFrame.bottom - layer->displayFrame.top) ||
         drmModePropertySetAdd(pset, plane->id(), plane->src_x_property().id(),
-                              layer->sourceCropf.left) ||
+                              (int)(layer->sourceCropf.left) << 16) ||
         drmModePropertySetAdd(pset, plane->id(), plane->src_y_property().id(),
-                              layer->sourceCropf.top) ||
+                              (int)(layer->sourceCropf.top) << 16) ||
         drmModePropertySetAdd(
             pset, plane->id(), plane->src_w_property().id(),
             (int)(layer->sourceCropf.right - layer->sourceCropf.left) << 16) ||
@@ -186,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) {
@@ -262,7 +321,17 @@
   if (active_composition_)
     active_composition_->FinishComposition();
 
+  ret = pthread_mutex_lock(&lock_);
+  if (ret)
+    ALOGE("Failed to acquire lock for active_composition swap");
+
   active_composition_.swap(composition);
+
+  if (!ret)
+    ret = pthread_mutex_unlock(&lock_);
+    if (ret)
+      ALOGE("Failed to release lock for active_composition swap");
+
   return ret;
 }
 
@@ -297,18 +366,50 @@
   struct timespec ts;
   ret = clock_gettime(CLOCK_MONOTONIC, &ts);
 
+  DrmCompositionLayerVector_t layers;
+  if (active_composition_)
+    layers = *active_composition_->GetCompositionLayers();
+  else
+    ret = -EAGAIN;
+
   ret |= pthread_mutex_unlock(&lock_);
   if (ret)
     return;
 
   cur_ts = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
   uint64_t num_ms = (cur_ts - dump_last_timestamp_ns_) / (1000 * 1000);
-  unsigned fps = num_ms ? (num_frames * 1000) / (num_ms) : 0;
+  float fps = num_ms ? (num_frames * 1000.0f) / (num_ms) : 0.0f;
 
   *out << "--DrmDisplayCompositor[" << display_
        << "]: num_frames=" << num_frames << " num_ms=" << num_ms
        << " fps=" << fps << "\n";
 
   dump_last_timestamp_ns_ = cur_ts;
+
+  *out << "---- DrmDisplayCompositor Layers: num=" << layers.size() << "\n";
+  for (DrmCompositionLayerVector_t::iterator iter = layers.begin();
+       iter != layers.end(); ++iter) {
+    hwc_layer_1_t *layer = &iter->layer;
+    DrmPlane *plane = iter->plane;
+
+    *out << "------ DrmDisplayCompositor Layer: plane=" << plane->id() << " ";
+
+    DrmCrtc *crtc = iter->crtc;
+    if (!crtc) {
+      *out << "disabled\n";
+      continue;
+    }
+
+    *out << "crtc=" << crtc->id() << " crtc[x/y/w/h]=" <<
+        layer->displayFrame.left << "/" << layer->displayFrame.top << "/" <<
+        layer->displayFrame.right - layer->displayFrame.left << "/" <<
+        layer->displayFrame.bottom - layer->displayFrame.top << " " <<
+        " src[x/y/w/h]=" << layer->sourceCropf.left << "/" <<
+        layer->sourceCropf.top << "/" <<
+        layer->sourceCropf.right - layer->sourceCropf.left << "/" <<
+        layer->sourceCropf.bottom - layer->sourceCropf.top <<  " transform=" <<
+        layer->transform << "\n";
+  }
+
 }
 }
diff --git a/drmmode.cpp b/drmmode.cpp
index dce9803..abd3b32 100644
--- a/drmmode.cpp
+++ b/drmmode.cpp
@@ -36,7 +36,6 @@
       v_sync_end_(m->vsync_end),
       v_total_(m->vtotal),
       v_scan_(m->vscan),
-      v_refresh_(m->vrefresh),
       flags_(m->flags),
       type_(m->type),
       name_(m->name) {
@@ -55,7 +54,6 @@
       v_sync_end_(0),
       v_total_(0),
       v_scan_(0),
-      v_refresh_(0),
       flags_(0),
       type_(0),
       name_("") {
@@ -70,7 +68,7 @@
          h_total_ == m.htotal && h_skew_ == m.hskew &&
          v_display_ == m.vdisplay && v_sync_start_ == m.vsync_start &&
          v_sync_end_ == m.vsync_end && v_total_ == m.vtotal &&
-         v_scan_ == m.vscan && v_refresh_ == m.vrefresh && flags_ == m.flags &&
+         v_scan_ == m.vscan && flags_ == m.flags &&
          type_ == m.type;
 }
 
@@ -86,7 +84,6 @@
   m->vsync_end = v_sync_end_;
   m->vtotal = v_total_;
   m->vscan = v_scan_;
-  m->vrefresh = v_refresh_;
   m->flags = flags_;
   m->type = type_;
   strncpy(m->name, name_.c_str(), DRM_DISPLAY_MODE_LEN);
@@ -144,8 +141,8 @@
   return v_scan_;
 }
 
-uint32_t DrmMode::v_refresh() const {
-  return v_refresh_;
+float DrmMode::v_refresh() const {
+  return clock_ / (float)(v_total_ * h_total_) * 1000.0f;
 }
 
 uint32_t DrmMode::flags() const {
diff --git a/drmmode.h b/drmmode.h
index ab213ef..3088b7a 100644
--- a/drmmode.h
+++ b/drmmode.h
@@ -48,7 +48,7 @@
   uint32_t v_sync_end() const;
   uint32_t v_total() const;
   uint32_t v_scan() const;
-  uint32_t v_refresh() const;
+  float v_refresh() const;
 
   uint32_t flags() const;
   uint32_t type() const;
@@ -71,7 +71,6 @@
   uint32_t v_sync_end_;
   uint32_t v_total_;
   uint32_t v_scan_;
-  uint32_t v_refresh_;
 
   uint32_t flags_;
   uint32_t type_;
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_;
 };
 }
 
diff --git a/vsyncworker.cpp b/vsyncworker.cpp
index 9626022..29709f7 100644
--- a/vsyncworker.cpp
+++ b/vsyncworker.cpp
@@ -113,13 +113,13 @@
   struct timespec vsync;
   int ret = clock_gettime(CLOCK_MONOTONIC, &vsync);
 
-  int64_t refresh = 60;  // Default to 60Hz refresh rate
+  float refresh = 60.0f;  // Default to 60Hz refresh rate
   DrmConnector *conn = drm_->GetConnectorForDisplay(display_);
-  if (conn && conn->active_mode().v_refresh())
+  if (conn && conn->active_mode().v_refresh() != 0.0f)
     refresh = conn->active_mode().v_refresh();
   else
-    ALOGW("Vsync worker active with conn=%p refresh=%d\n", conn,
-          conn ? conn->active_mode().v_refresh() : -1);
+    ALOGW("Vsync worker active with conn=%p refresh=%f\n", conn,
+          conn ? conn->active_mode().v_refresh() : 0.0f);
 
   int64_t phased_timestamp = GetPhasedVSync(
       kOneSecondNs / refresh, vsync.tv_sec * kOneSecondNs + vsync.tv_nsec);