Merge "sdm: Merge release fence after set power mode"
diff --git a/libdisplayconfig/Android.mk b/libdisplayconfig/Android.mk
index 9f84c61..ec9340d 100644
--- a/libdisplayconfig/Android.mk
+++ b/libdisplayconfig/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES               := DisplayConfig.cpp
 LOCAL_SHARED_LIBRARIES        := libhidlbase libhidltransport libutils \
                                  vendor.display.config@1.0
+LOCAL_EXPORT_C_INCLUDE_DIRS   := $(LOCAL_PATH)
 
 ifeq ($(LLVM_SA), true)
     LOCAL_CFLAGS += --compile-and-analyze --analyzer-perf --analyzer-Werror
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 0338bb7..3bb3441 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -60,6 +60,7 @@
   hw_intf_->GetHWPanelInfo(&hw_panel_info_);
 
   uint32_t active_index = 0;
+  int drop_vsync = 0;
   hw_intf_->GetActiveConfig(&active_index);
   hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
   fb_config_ = display_attributes_;
@@ -117,7 +118,8 @@
   // TODO(user): Temporary changes, to be removed when DRM driver supports
   // Partial update with Destination scaler enabled.
   SetPUonDestScaler();
-
+  Debug::Get()->GetProperty("sdm.drop_skewed_vsync", &drop_vsync);
+  drop_skewed_vsync_ = (drop_vsync == 1);
   return kErrorNone;
 
 CleanupOnError:
@@ -342,7 +344,8 @@
   if (error != kErrorNone) {
     return error;
   }
-
+  // Stop dropping vsync when first commit is received after idle fallback.
+  drop_hw_vsync_ = false;
   DLOGI_IF(kTagDisplay, "Exiting commit for display type : %d", display_type_);
   return kErrorNone;
 }
@@ -1029,6 +1032,10 @@
   if (vsync_enable_ != enable) {
     error = hw_intf_->SetVSyncState(enable);
     if (error == kErrorNotSupported) {
+      if (drop_skewed_vsync_ && (hw_panel_info_.mode == kModeVideo) &&
+        enable && (current_refresh_rate_ == hw_panel_info_.min_fps)) {
+        drop_hw_vsync_ = true;
+      }
       error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
     }
     if (error == kErrorNone) {
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index bd597c9..5e697d9 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -189,6 +189,9 @@
   bool hdr_mode_ = false;
   int disable_hdr_lut_gen_ = 0;
   DisplayState last_power_mode_ = kStateOff;
+  bool drop_hw_vsync_ = false;
+  uint32_t current_refresh_rate_ = 0;
+  bool drop_skewed_vsync_ = false;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index d9fef33..718dd1e 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -291,7 +291,7 @@
 }
 
 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
-  if (vsync_enable_) {
+  if (vsync_enable_ && !drop_hw_vsync_) {
     DisplayEventVSync vsync;
     vsync.timestamp = timestamp;
     event_handler_->VSync(vsync);
@@ -302,7 +302,9 @@
 
 void DisplayPrimary::IdleTimeout() {
   if (hw_panel_info_.mode == kModeVideo) {
-    event_handler_->HandleEvent(kIdleTimeout);
+    if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
+      return;
+    }
     handle_idle_timeout_ = true;
     event_handler_->Refresh();
     lock_guard<recursive_mutex> obj(recursive_mutex_);
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index e14c6d7..21ada7c 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -71,7 +71,6 @@
   bool avr_prop_disabled_ = false;
   bool switch_to_cmd_ = false;
   bool handle_idle_timeout_ = false;
-  uint32_t current_refresh_rate_ = 0;
   bool reset_panel_ = false;
 };
 
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index dfe4fd3..d46c8c0 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -161,6 +161,14 @@
   return DisplayBase::Prepare(layer_stack);
 }
 
+DisplayError DisplayVirtual::GetColorModeCount(uint32_t *mode_count) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  // Color Manager isn't supported for virtual displays.
+  *mode_count = 1;
+
+  return kErrorNone;
+}
 
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index eeade9d..ca154c4 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -63,6 +63,7 @@
     // on virtual display is functional.
     return kErrorNone;
   }
+  virtual DisplayError GetColorModeCount(uint32_t *mode_count);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 4c0b969..a1d21d8 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -634,8 +634,6 @@
   }
   // set secure display
   SetSecureDisplay(secure_display_active);
-
-  layer_stack_invalid_ = false;
 }
 
 void HWCDisplay::BuildSolidFillStack() {
@@ -1014,7 +1012,17 @@
 
 DisplayError HWCDisplay::HandleEvent(DisplayEvent event) {
   switch (event) {
-    case kIdleTimeout:
+    case kIdleTimeout: {
+      SCOPE_LOCK(HWCSession::locker_[type_]);
+      if (pending_commit_) {
+        // If idle timeout event comes in between prepare
+        // and commit, drop it since device is not really
+        // idle.
+        return kErrorNotSupported;
+      }
+      validated_ = false;
+      break;
+    }
     case kThermalEvent:
     case kIdlePowerCollapse:
     case kPanelDeadEvent: {
@@ -1084,11 +1092,13 @@
   *out_num_types = UINT32(layer_changes_.size());
   *out_num_requests = UINT32(layer_requests_.size());
   skip_validate_ = false;
+  layer_stack_invalid_ = false;
+
   if (*out_num_types > 0) {
     return HWC2::Error::HasChanges;
-  } else {
-    return HWC2::Error::None;
   }
+
+  return HWC2::Error::None;
 }
 
 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 3977e73..f3b1565 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -306,6 +306,7 @@
   int disable_hdr_handling_ = 0;  // disables HDR handling.
   uint32_t display_config_ = 0;
   bool config_pending_ = false;
+  bool pending_commit_ = false;
 
  private:
   void DumpInputBuffers(void);
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index bb4ea89..45ed891 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -127,6 +127,7 @@
 
   if (layer_set_.empty()) {
     flush_ = true;
+    validated_ = true;
     return status;
   }
 
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index 531f209..6149831 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -223,6 +223,7 @@
   }
 
   status = PrepareLayerStack(out_num_types, out_num_requests);
+  pending_commit_ = true;
   return status;
 }
 
@@ -245,7 +246,7 @@
       status = HWCDisplay::PostCommitLayerStack(out_retire_fence);
     }
   }
-
+  pending_commit_ = false;
   return status;
 }
 
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index aed9334..96094f9 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -72,6 +72,7 @@
 
 static HWCUEvent g_hwc_uevent_;
 Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
+static const int kSolidFillDelay = 100 * 1000;
 
 void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
   const char *uevent_thread_name = "HWC_UeventThread";
@@ -1519,14 +1520,22 @@
           ret = color_mgr_->EnableQDCMMode(false, hwc_display_[HWC_DISPLAY_PRIMARY]);
           break;
         case kApplySolidFill:
-          ret = color_mgr_->SetSolidFill(pending_action.params,
+          {
+            SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+            ret = color_mgr_->SetSolidFill(pending_action.params,
                                             true, hwc_display_[HWC_DISPLAY_PRIMARY]);
+          }
           Refresh(HWC_DISPLAY_PRIMARY);
+          usleep(kSolidFillDelay);
           break;
         case kDisableSolidFill:
-          ret = color_mgr_->SetSolidFill(pending_action.params,
+          {
+            SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+            ret = color_mgr_->SetSolidFill(pending_action.params,
                                             false, hwc_display_[HWC_DISPLAY_PRIMARY]);
+          }
           Refresh(HWC_DISPLAY_PRIMARY);
+          usleep(kSolidFillDelay);
           break;
         case kSetPanelBrightness:
           brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);