Merge "sdm: Enable Hybrid composition" into dev-2.0
diff --git a/sdm/libs/core/fb/hw_virtual.cpp b/sdm/libs/core/fb/hw_virtual.cpp
index 27c979a..033159f 100644
--- a/sdm/libs/core/fb/hw_virtual.cpp
+++ b/sdm/libs/core/fb/hw_virtual.cpp
@@ -74,9 +74,5 @@
   return HWDevice::Validate(hw_layers);
 }
 
-DisplayError HWVirtual::Flush() {
-  return kErrorNone;
-}
-
 }  // namespace sdm
 
diff --git a/sdm/libs/core/fb/hw_virtual.h b/sdm/libs/core/fb/hw_virtual.h
index c0591b3..2b740d5 100644
--- a/sdm/libs/core/fb/hw_virtual.h
+++ b/sdm/libs/core/fb/hw_virtual.h
@@ -39,7 +39,6 @@
   HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
   virtual DisplayError Init(HWEventHandler *eventhandler);
   virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError Flush();
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index e68e05f..ba4c23c 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -789,8 +789,15 @@
 bool HWCDisplay::NeedsFrameBufferRefresh(hwc_display_contents_1_t *content_list) {
   uint32_t layer_count = layer_stack_.layer_count;
 
+  // Handle ongoing animation and end here, start is handled below
   if (layer_stack_cache_.animating) {
-      return false;
+      if (!layer_stack_.flags.animating) {
+        // Animation is ending.
+        return true;
+      } else {
+        // Animation is going on.
+        return false;
+      }
   }
 
   // Frame buffer needs to be refreshed for the following reasons:
@@ -838,7 +845,7 @@
 void HWCDisplay::CacheLayerStackInfo(hwc_display_contents_1_t *content_list) {
   uint32_t layer_count = layer_stack_.layer_count;
 
-  if (layer_count > kMaxLayerCount) {
+  if (layer_count > kMaxLayerCount || layer_stack_.flags.animating) {
     ResetLayerCacheStack();
     return;
   }
@@ -1192,6 +1199,7 @@
 
 int HWCDisplay::SetDisplayStatus(uint32_t display_status) {
   int status = 0;
+  const hwc_procs_t *hwc_procs = *hwc_procs_;
 
   switch (display_status) {
   case kDisplayStatusResume:
@@ -1209,6 +1217,11 @@
     return -EINVAL;
   }
 
+  if (display_status == kDisplayStatusResume ||
+      display_status == kDisplayStatusPause) {
+    hwc_procs->invalidate(hwc_procs);
+  }
+
   return status;
 }
 
@@ -1357,7 +1370,9 @@
 }
 
 int HWCDisplay::ToggleScreenUpdates(bool enable) {
+  const hwc_procs_t *hwc_procs = *hwc_procs_;
   display_paused_ = enable ? false : true;
+  hwc_procs->invalidate(hwc_procs);
   return 0;
 }
 
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index b80bfb4..3ec1fa5 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -303,14 +303,26 @@
   }
 
   if (hotplug_connect) {
+    // notify client
     hwc_procs->hotplug(hwc_procs, HWC_DISPLAY_EXTERNAL, true);
-    hwc_procs->invalidate(hwc_procs);
   }
-
   // Return 0, else client will go into bad state
   return 0;
 }
 
+int HWCSession::GetVsyncPeriod(int disp) {
+  SEQUENCE_ENTRY_SCOPE_LOCK(locker_);
+  // default value
+  int32_t vsync_period = 1000000000l / 60;
+  const uint32_t attribute = HWC_DISPLAY_VSYNC_PERIOD;
+
+  if (hwc_display_[disp]) {
+    hwc_display_[disp]->GetDisplayAttributes(0, &attribute, &vsync_period);
+  }
+
+  return vsync_period;
+}
+
 int HWCSession::Set(hwc_composer_device_1 *device, size_t num_displays,
                     hwc_display_contents_1_t **displays) {
   DTRACE_SCOPED();
@@ -1317,14 +1329,18 @@
       external_pending_connect_ = false;
     }
   }
-
-  // notify client and trigger a screen refresh
+  if (connected && notify_hotplug) {
+    // trigger screen refresh to ensure sufficient resources are available to process new
+    // new display connection.
+    hwc_procs_->invalidate(hwc_procs_);
+    int32_t vsync_period = GetVsyncPeriod(HWC_DISPLAY_PRIMARY);
+    usleep(vsync_period * 2 / 1000);
+  }
+  // notify client
   if (notify_hotplug) {
     hwc_procs_->hotplug(hwc_procs_, HWC_DISPLAY_EXTERNAL, connected);
   }
 
-  hwc_procs_->invalidate(hwc_procs_);
-
   return 0;
 }
 
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index 01cd8ec..561de35 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -84,6 +84,7 @@
   int ConnectDisplay(int disp, hwc_display_contents_1_t *content_list);
   int DisconnectDisplay(int disp);
   void HandleSecureDisplaySession(hwc_display_contents_1_t **displays);
+  int GetVsyncPeriod(int disp);
 
   // QClient methods
   virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,