sdm: Defer brightness on deferred Doze

Doze mode is deferred to draw cycle, so brightness application during
Doze must also be deferred till after the fences signal for that commit

Change-Id: I046b18069014c0198f3d929b04fa460c305b28ee
CRs-Fixed: 2472116
diff --git a/sdm/include/core/sdm_types.h b/sdm/include/core/sdm_types.h
index 5817539..6ba1538 100644
--- a/sdm/include/core/sdm_types.h
+++ b/sdm/include/core/sdm_types.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2020, 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
@@ -60,6 +60,7 @@
   kErrorCriticalResource,   //!< Critical resource allocation has failed.
   kErrorDeviceRemoved,    //!< A device was removed unexpectedly.
   kErrorDriverData,       //!< Expected information from the driver is missing
+  kErrorDeferred,         //!< Call's intended action is being deferred to a later time
 };
 
 /*! @brief This structure is defined for client and library compatibility check purpose only. This
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 26e89a9..07030da 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -226,6 +226,11 @@
   if (error != kErrorNone) {
     return error;
   }
+  if (pending_brightness_) {
+    buffer_sync_handler_->SyncWait(layer_stack->retire_fence_fd);
+    SetPanelBrightness(cached_brightness_);
+    pending_brightness_ = false;
+  }
 
   if (commit_event_enabled_) {
     dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_));
@@ -362,7 +367,7 @@
   }
 
   // -1.0f = off, 0.0f = min, 1.0f = max
-  level_remainder_ = 0.0f;
+  float level_remainder = 0.0f;
   int level = 0;
   if (brightness == -1.0f) {
     level = 0;
@@ -376,13 +381,21 @@
     }
     float t = (brightness * (max - min)) + min;
     level = static_cast<int>(t);
-    level_remainder_ = t - level;
+    level_remainder = t - level;
   }
 
-  DisplayError err = kErrorNone;
-  if ((err = hw_intf_->SetPanelBrightness(level)) == kErrorNone) {
+  DisplayError err = hw_intf_->SetPanelBrightness(level);
+  if (err == kErrorNone) {
+    level_remainder_ = level_remainder;
     DLOGI_IF(kTagDisplay, "Setting brightness to level %d (%f percent)", level,
              brightness * 100);
+  } else if (err == kErrorDeferred) {
+    // TODO(user): I8508d64a55c3b30239c6ed2886df391407d22f25 causes mismatch between perceived
+    // power state and actual panel power state. Requires a rework. Below check will set up
+    // deferment of brightness operation if DAL reports defer use case.
+    cached_brightness_ = brightness;
+    pending_brightness_ = true;
+    return kErrorNone;
   }
 
   return err;
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index a6a272e..8d54df6 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -159,6 +159,8 @@
   DeferFpsConfig deferred_config_ = {};
   float level_remainder_ = 0.0f;
   recursive_mutex brightness_lock_;
+  float cached_brightness_ = 0.0f;
+  bool pending_brightness_ = false;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index f718efb..8b8ca5b 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -228,13 +228,13 @@
   uint64_t bit_clk_rate_ = 0;
   bool update_mode_ = false;
   DRMPowerMode last_power_mode_ = DRMPowerMode::OFF;
+  bool pending_doze_ = false;
 
  private:
   std::string interface_str_ = "DSI";
   bool resolution_switch_enabled_ = false;
   bool autorefresh_ = false;
   std::unique_ptr<HWColorManagerDrm> hw_color_mgr_ = {};
-  bool pending_doze_ = false;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index 964ff28..faee43b 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -507,6 +507,11 @@
 }
 
 DisplayError HWPeripheralDRM::SetPanelBrightness(int level) {
+  if (pending_doze_) {
+    DLOGI("Doze state pending!! Skip for now");
+    return kErrorDeferred;
+  }
+
   char buffer[kMaxSysfsCommandLength] = {0};
 
   if (brightness_base_path_.empty()) {