composer: add support for advanced offset based wakeup

Add support to get the Display elapse time via. composer HIDL.
This is needed to wait till the specified timestamp is expired
before committing the frame to DRM driver.

Change-Id: Id16965acdc82c858203c6b27fe127e708ad92e33
CRs-Fixed: 2576715
diff --git a/composer/Android.mk b/composer/Android.mk
index b9560b2..d6dfc60 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -24,6 +24,7 @@
                                  libgpu_tonemapper libEGL libGLESv2 libGLESv3 \
                                  vendor.qti.hardware.display.composer@1.0 \
                                  vendor.qti.hardware.display.composer@2.0 \
+                                 vendor.qti.hardware.display.composer@2.1 \
                                  android.hardware.graphics.composer@2.1 \
                                  android.hardware.graphics.composer@2.2 \
                                  android.hardware.graphics.composer@2.3 \
diff --git a/composer/QtiComposer.cpp b/composer/QtiComposer.cpp
index 4d0013d..de72eef 100644
--- a/composer/QtiComposer.cpp
+++ b/composer/QtiComposer.cpp
@@ -35,7 +35,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
 QtiComposerClient* QtiComposerClient::qti_composerclient_instance_ = nullptr;
@@ -141,7 +141,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposer.h b/composer/QtiComposer.h
index d912628..395aefb 100644
--- a/composer/QtiComposer.h
+++ b/composer/QtiComposer.h
@@ -35,7 +35,7 @@
 
 // TODO(user): recheck on this header inclusion
 #include <hardware/hwcomposer2.h>
-#include <vendor/qti/hardware/display/composer/2.0/IQtiComposer.h>
+#include <vendor/qti/hardware/display/composer/2.1/IQtiComposer.h>
 #include <log/log.h>
 #include <unordered_set>
 
@@ -44,10 +44,10 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
-using ::vendor::qti::hardware::display::composer::V2_0::IQtiComposer;
+using ::vendor::qti::hardware::display::composer::V2_1::IQtiComposer;
 
 class QtiComposer : public IQtiComposer {
  public:
@@ -72,7 +72,7 @@
 extern "C" IQtiComposer* HIDL_FETCH_IQtiComposer(const char* name);
 
 }  // namespace implementation
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposerClient.cpp b/composer/QtiComposerClient.cpp
index 253978d..c81e3f5 100644
--- a/composer/QtiComposerClient.cpp
+++ b/composer/QtiComposerClient.cpp
@@ -26,7 +26,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
 ComposerHandleImporter mHandleImporter;
@@ -1129,6 +1129,9 @@
       case IQtiComposerClient::Command::SET_LAYER_TYPE:
         parsed = parseSetLayerType(length);
         break;
+      case IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME:
+        parsed = parseSetDisplayElapseTime(length);
+        break;
       default:
         parsed = parseCommonCmd(static_cast<IComposerClient::Command>(qticommand), length);
         break;
@@ -1769,6 +1772,20 @@
   return true;
 }
 
+bool QtiComposerClient::CommandReader::parseSetDisplayElapseTime(uint16_t length) {
+  if (length < CommandWriter::kSetDisplayElapseTime) {
+    return false;
+  }
+  uint64_t time = read64();
+
+  auto err = mClient.hwc_session_->SetDisplayElapseTime(mDisplay, time);
+  if (static_cast<Error>(err) != Error::NONE) {
+    mWriter.setError(getCommandLoc(), static_cast<Error>(err));
+  }
+
+  return true;
+}
+
 hwc_rect_t QtiComposerClient::CommandReader::readRect() {
   return hwc_rect_t{
     readSigned(),
@@ -1911,7 +1928,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposerClient.h b/composer/QtiComposerClient.h
index 4b06900..56efaca 100644
--- a/composer/QtiComposerClient.h
+++ b/composer/QtiComposerClient.h
@@ -20,7 +20,7 @@
 #ifndef __QTICOMPOSERCLIENT_H__
 #define __QTICOMPOSERCLIENT_H__
 
-#include <vendor/qti/hardware/display/composer/2.0/IQtiComposerClient.h>
+#include <vendor/qti/hardware/display/composer/2.1/IQtiComposerClient.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 #include <log/log.h>
@@ -36,7 +36,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 namespace implementation {
 
 namespace common_V1_0 = ::android::hardware::graphics::common::V1_0;
@@ -284,6 +284,7 @@
     // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
     bool parseSetLayerColorTransform(uint16_t length);
     bool parseSetLayerPerFrameMetadataBlobs(uint16_t length);
+    bool parseSetDisplayElapseTime(uint16_t length);
 
     bool parseCommonCmd(IComposerClient::Command command, uint16_t length);
 
@@ -331,7 +332,7 @@
 extern "C" IQtiComposerClient* HIDL_FETCH_IQtiComposerClient(const char* name);
 
 }  // namespace implementation
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposerCommandBuffer.h b/composer/QtiComposerCommandBuffer.h
index 5461c56..2c8407b 100644
--- a/composer/QtiComposerCommandBuffer.h
+++ b/composer/QtiComposerCommandBuffer.h
@@ -34,7 +34,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 
 using ::android::hardware::graphics::common::V1_0::ColorTransform;
 using ::android::hardware::graphics::common::V1_0::Dataspace;
@@ -487,6 +487,13 @@
     endCommand();
   }
 
+  static constexpr uint16_t kSetDisplayElapseTime = 2;
+  void setDisplayElapseTime(uint64_t time) {
+    beginCommand(IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME, kSetDisplayElapseTime);
+    write64(time);
+    endCommand();
+  }
+
  protected:
   // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
   void beginCommand(IQtiComposerClient::Command command, uint16_t length) {
@@ -847,7 +854,7 @@
   hidl_vec<hidl_handle> mDataHandles;
 };
 
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposerHandleImporter.cpp b/composer/QtiComposerHandleImporter.cpp
index eafbe96..d0b480f 100644
--- a/composer/QtiComposerHandleImporter.cpp
+++ b/composer/QtiComposerHandleImporter.cpp
@@ -26,7 +26,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 
 using MapperV2Error = android::hardware::graphics::mapper::V2_0::Error;
 using MapperV3Error = android::hardware::graphics::mapper::V3_0::Error;
@@ -155,7 +155,7 @@
   }
 }
 
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/QtiComposerHandleImporter.h b/composer/QtiComposerHandleImporter.h
index 2c348eb..5a3a182 100644
--- a/composer/QtiComposerHandleImporter.h
+++ b/composer/QtiComposerHandleImporter.h
@@ -29,7 +29,7 @@
 namespace hardware {
 namespace display {
 namespace composer {
-namespace V2_0 {
+namespace V2_1 {
 
 using IMapperV2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
 using IMapperV3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
@@ -56,7 +56,7 @@
   sp<IMapperV3> mMapper_V3;
 };
 
-}  // namespace V2_0
+}  // namespace V2_1
 }  // namespace composer
 }  // namespace display
 }  // namespace hardware
diff --git a/composer/display_null.h b/composer/display_null.h
index 044c3a8..b90f0c3 100644
--- a/composer/display_null.h
+++ b/composer/display_null.h
@@ -120,6 +120,7 @@
   MAKE_NO_OP(GetQSyncMode(QSyncMode *))
   MAKE_NO_OP(colorSamplingOn());
   MAKE_NO_OP(colorSamplingOff());
+  MAKE_NO_OP(SetDisplayElapseTime(uint64_t))
 
  protected:
   DisplayConfigVariableInfo default_variable_config_ = {};
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index 20efb7f..d80de31 100644
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -1582,6 +1582,11 @@
       tone_mapper_->Terminate();
     }
   }
+
+  if (elapse_timestamp_) {
+    layer_stack_.elapse_timestamp = elapse_timestamp_;
+  }
+
   error = display_intf_->Commit(&layer_stack_);
 
   if (error == kErrorNone) {
@@ -2368,6 +2373,11 @@
   return HWC2::Error::None;
 }
 
+HWC2::Error HWCDisplay::SetDisplayElapseTime(uint64_t time) {
+  elapse_timestamp_ = time;
+  return HWC2::Error::None;
+}
+
 bool HWCDisplay::IsDisplayCommandMode() {
   return is_cmd_mode_;
 }
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index 74cd5bf..583e556 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -392,6 +392,7 @@
       uint64_t max_frames, uint64_t timestamp, uint64_t *numFrames,
       int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
       uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]);
+  HWC2::Error SetDisplayElapseTime(uint64_t time);
 
  protected:
   static uint32_t throttling_refresh_rate_;
@@ -500,6 +501,7 @@
   int release_fence_ = -1;
   hwc2_config_t pending_config_index_ = 0;
   bool game_supported_ = false;
+  uint64_t elapse_timestamp_ = 0;
 };
 
 inline int HWCDisplay::Perform(uint32_t operation, ...) {
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 56e4574..2f8e590 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -1003,6 +1003,10 @@
   return CallLayerFunction(display, layer, &HWCLayer::SetLayerColorTransform, matrix);
 }
 
+int32_t HWCSession::SetDisplayElapseTime(hwc2_display_t display, uint64_t time) {
+  return CallDisplayFunction(display, &HWCDisplay::SetDisplayElapseTime, time);
+}
+
 int32_t HWCSession::SetOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
                                     int32_t releaseFence) {
   if (INT32(display) != GetDisplayIndex(qdutils::DISPLAY_VIRTUAL)) {
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index 7735b46..55a00a4 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -261,6 +261,8 @@
                                     uint64_t *numFrames,
                                     int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS],
                                     uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]);
+  int32_t SetDisplayElapseTime(hwc2_display_t display, uint64_t time);
+
   // HWCDisplayEventHandler
   virtual void DisplayPowerReset();
 
diff --git a/composer/service.cpp b/composer/service.cpp
index fbfad5b..1f987d9 100644
--- a/composer/service.cpp
+++ b/composer/service.cpp
@@ -32,8 +32,8 @@
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
 using android::ProcessState;
-using vendor::qti::hardware::display::composer::V2_0::implementation::QtiComposer;
-using vendor::qti::hardware::display::composer::V2_0::IQtiComposer;
+using vendor::qti::hardware::display::composer::V2_1::implementation::QtiComposer;
+using vendor::qti::hardware::display::composer::V2_1::IQtiComposer;
 using android::hardware::graphics::composer::V2_3::IComposer;
 using android::sp;
 
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index ec3b38e..7360c2b 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -437,6 +437,8 @@
 
 
   PrimariesTransfer blend_cs = {};     //!< o/p - Blending color space of the frame, updated by SDM
+
+  uint64_t elapse_timestamp = 0;       //!< system time until which display commit needs to be held
 };
 
 }  // namespace sdm
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 8997cc6..bb514c8 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -718,6 +718,7 @@
   HWQosData qos_data = {};
   HWAVRInfo hw_avr_info = {};
   std::bitset<kUpdateMax> updates_mask = 0;
+  uint64_t elapse_timestamp = 0;
 };
 
 struct HWDisplayAttributes : DisplayConfigVariableInfo {
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 755c416..97a84ee 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1630,6 +1630,10 @@
     }
   }
 
+  if (layer_stack->elapse_timestamp) {
+    hw_layers_.elapse_timestamp = layer_stack->elapse_timestamp;
+  }
+
   return;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index df2549f..9dac616 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -30,6 +30,7 @@
 #define __STDC_FORMAT_MACROS
 
 #include <ctype.h>
+#include <time.h>
 #include <drm/drm_fourcc.h>
 #include <drm_lib_loader.h>
 #include <drm_master.h>
@@ -1466,6 +1467,15 @@
   DTRACE_SCOPED();
   SetupAtomic(hw_layers, false /* validate */);
 
+  if (hw_layers->elapse_timestamp > 0) {
+    struct timespec t = {0, 0};
+    clock_gettime(CLOCK_MONOTONIC, &t);
+    uint64_t current_time = (UINT64(t.tv_sec) * 1000000000LL + t.tv_nsec);
+    if (current_time < hw_layers->elapse_timestamp) {
+      usleep(UINT32((hw_layers->elapse_timestamp - current_time) / 1000));
+    }
+  }
+
   int ret = drm_atomic_intf_->Commit(synchronous_commit_, false /* retain_planes*/);
   int release_fence = INT(release_fence_);
   int retire_fence = INT(retire_fence_);