Merge "hwc2: Skip SDM prepare for consecutive GPU composed frames" into pi-dev
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index b53610b..15add54 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1062,6 +1062,11 @@
}
UpdateRefreshRate();
+
+ if (CanSkipSdmPrepare(out_num_types, out_num_requests)) {
+ return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
+ }
+
if (!skip_prepare_) {
DisplayError error = display_intf_->Prepare(&layer_stack_);
if (error != kErrorNone) {
@@ -2168,4 +2173,37 @@
}
}
+// Skip SDM prepare if all the layers in the current draw cycle are marked as Skip and
+// previous draw cycle had GPU Composition, as the resources for GPU Target layer have
+// already been validated and configured to the driver.
+bool HWCDisplay::CanSkipSdmPrepare(uint32_t *num_types, uint32_t *num_requests) {
+ if (!validated_ || layer_set_.empty()) {
+ return false;
+ }
+
+ bool skip_prepare = true;
+ for (auto hwc_layer : layer_set_) {
+ if (!hwc_layer->GetSDMLayer()->flags.skip ||
+ (hwc_layer->GetDeviceSelectedCompositionType() != HWC2::Composition::Client)) {
+ skip_prepare = false;
+ layer_changes_.clear();
+ break;
+ }
+ if (hwc_layer->GetClientRequestedCompositionType() != HWC2::Composition::Client) {
+ layer_changes_[hwc_layer->GetId()] = HWC2::Composition::Client;
+ }
+ }
+
+ if (skip_prepare) {
+ *num_types = UINT32(layer_changes_.size());
+ *num_requests = 0;
+ layer_stack_invalid_ = false;
+ has_client_composition_ = true;
+ client_target_->ResetValidation();
+ validate_state_ = kNormalValidate;
+ }
+
+ return skip_prepare;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 8cbd6bb..084a2a5 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -345,6 +345,8 @@
private:
void DumpInputBuffers(void);
void UpdateRefreshRate();
+ bool CanSkipSdmPrepare(uint32_t *num_types, uint32_t *num_requests);
+
qService::QService *qservice_ = NULL;
DisplayClass display_class_;
uint32_t geometry_changes_ = GeometryChanges::kNone;