hwc2: Avoid drawcycles with non-empty dirty region

--Reject drawcycle if following conditions are met.
    1. No change in layerstack attributes.
    2. No new buffer latched.
    3. No refresh request triggered by HWC.
    4. This display is not source of vsync.

--Do not return Present failed error if display is inactive.
  SF wouldn't query for release fence upon errors.

CRs-Fixed: 2354696
Change-Id: I28174a09f4b5046d25c953f568f981fdb80b42a8
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index 41ce1b1..53c9dc4 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -122,6 +122,13 @@
   HWCDebugHandler::Get()->GetProperty(ENABLE_DEFAULT_COLOR_MODE,
                                       &default_mode_status_);
 
+  int drop_refresh = 0;
+  HWCDebugHandler::Get()->GetProperty(ENABLE_DROP_REFRESH, &drop_refresh);
+  enable_drop_refresh_ = (drop_refresh == 1);
+  if (enable_drop_refresh_) {
+    DLOGI("Drop redundant drawcycles %d", id_);
+  }
+
   return status;
 }
 
@@ -193,6 +200,34 @@
   return status;
 }
 
+HWC2::Error HWCDisplayBuiltIn::CommitLayerStack() {
+  skip_commit_ = CanSkipCommit();
+  return HWCDisplay::CommitLayerStack();
+}
+
+bool HWCDisplayBuiltIn::CanSkipCommit() {
+  if (layer_stack_invalid_) {
+    return false;
+  }
+
+  // Reject repeated drawcycle requests if it satisfies all conditions.
+  // 1. None of the layerstack attributes changed.
+  // 2. No new buffer latched.
+  // 3. No refresh request triggered by HWC.
+  // 4. This display is not source of vsync.
+  bool buffers_latched = false;
+  for (auto &hwc_layer : layer_set_) {
+    buffers_latched |= hwc_layer->BufferLatched();
+    hwc_layer->ResetBufferFlip();
+  }
+
+  bool skip_commit = enable_drop_refresh_ && !pending_commit_ && !buffers_latched &&
+                     !pending_refresh_ && !vsync_source_;
+  pending_refresh_ = false;
+
+  return skip_commit;
+}
+
 HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) {
   auto status = HWC2::Error::None;
 
@@ -204,7 +239,7 @@
       DLOGE("Flush failed. Error = %d", error);
     }
   } else {
-    status = HWCDisplay::CommitLayerStack();
+    status = CommitLayerStack();
     if (status == HWC2::Error::None) {
       HandleFrameOutput();
       SolidFillCommit();
@@ -840,4 +875,14 @@
   return kErrorNotSupported;
 }
 
+HWC2::Error HWCDisplayBuiltIn::UpdateDisplayId(hwc2_display_t id) {
+  id_ = id;
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayBuiltIn::SetPendingRefresh() {
+  pending_refresh_ = true;
+  return HWC2::Error::None;
+}
+
 }  // namespace sdm