sdm: Add support for Fast Path Composition
During Fast Path optimization, the driver validation happens in
the COMMIT IOCTL only. In Validate phase, SDM doesn't set the DRM
properties and it doesn't call the VALIDATE IOCTL, which avoids
redundant CPU cycles. To disable this feature, set the value of
vendor prop "vendor.display.disable_fast_path" as 1.
CRs-Fixed: 2354405
Change-Id: I06380108ddc1d78543981a99cb90acb4be45997f
diff --git a/include/display_properties.h b/include/display_properties.h
index 3fd4599..7eddc3b 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -113,6 +113,7 @@
#define QDCM_MODE_COMBINE_PROP DISPLAY_PROP("qdcm.mode_combine")
#define PREFER_MULTIRECT_PROP DISPLAY_PROP("prefer_multirect")
#define DROP_SKEWED_VSYNC DISPLAY_PROP("drop_skewed_vsync")
+#define DISABLE_FAST_PATH DISPLAY_PROP("disable_fast_path")
#define ZERO_SWAP_INTERVAL "vendor.debug.egl.swapinterval"
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index b0e042f..24d4f80 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -262,6 +262,8 @@
// This applies only to primary displays currently
uint32_t hdr_present : 1; //!< Set if stack has HDR content
+
+ uint32_t fast_path : 1; //!< Preference for fast/slow path draw-cycle, set by client.
};
uint32_t flags = 0; //!< For initialization purpose only.
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 2fcae89..21948d5 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -650,6 +650,7 @@
LayerRect partial_fb_roi = {}; // Damaged area in framebuffer.
bool roi_split = false; // Indicates separated left and right ROI
bool async_cursor_updates = false; // Cursor layer allowed to have async updates
+ bool fast_path_composition = false; // Indicates frame has fast path composition
DestScaleInfoMap dest_scale_info_map = {};
HWHDRLayerInfo hdr_layer_info = {};
Handle pvt_data = NULL; // Private data used by sdm extension only.
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index aba0b8b..54cde85 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -82,6 +82,7 @@
const std::vector<PrimariesTransfer> &colormodes_cs);
DisplayError SetBlendSpace(Handle display_ctx, const PrimariesTransfer &blend_space);
void HandleSecureEvent(Handle display_ctx, SecureEvent secure_event);
+ void SetSafeMode(bool enable) { safe_mode_ = enable; }
private:
static const int kMaxThermalLevel = 3;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index f219726..6e5cac4 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -312,6 +312,13 @@
break;
}
+ if (layer_stack->flags.fast_path && hw_layers_.info.fast_path_composition) {
+ // In Fast Path, driver validation happens in COMMIT Phase.
+ DLOGI_IF(kTagDisplay, "Draw cycle qualifies for Fast Path!");
+ needs_validate_ = false;
+ break;
+ }
+
error = hw_intf_->Validate(&hw_layers_);
if (error == kErrorNone) {
// Strategy is successful now, wait for Commit().
@@ -380,6 +387,12 @@
error = hw_intf_->Commit(&hw_layers_);
if (error != kErrorNone) {
+ if (layer_stack->flags.fast_path && hw_layers_.info.fast_path_composition) {
+ // If COMMIT fails on the Fast Path, set Safe Mode.
+ DLOGE("COMMIT failed in Fast Path, set Safe Mode!");
+ comp_manager_->SetSafeMode(true);
+ error = kErrorNotValidated;
+ }
return error;
}
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 33ec1ef..0e2e117 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -553,6 +553,10 @@
partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
client_target_->SetPartialUpdate(partial_update_enabled_);
+ int disable_fast_path = 0;
+ HWCDebugHandler::Get()->GetProperty(DISABLE_FAST_PATH, &disable_fast_path);
+ fast_path_enabled_ = !(disable_fast_path == 1);
+
DLOGI("Display created with id: %d", id_);
return 0;
@@ -671,6 +675,7 @@
display_rect_ = LayerRect();
metadata_refresh_rate_ = 0;
layer_stack_.flags.animating = animating_;
+ layer_stack_.flags.fast_path = fast_path_enabled_ && fast_path_composition_;
// Add one layer for fb target
// TODO(user): Add blit target layers
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 8e42373..dd89f97 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -231,6 +231,7 @@
virtual HWC2::Error SetColorModeFromClientApi(int32_t color_mode_id) {
return HWC2::Error::Unsupported;
}
+ void SetFastPathComposition(bool enable) { fast_path_composition_ = enable; }
// HWC2 APIs
virtual HWC2::Error AcceptDisplayChanges(void);
@@ -395,6 +396,7 @@
bool partial_update_enabled_ = false;
std::map<uint32_t, DisplayConfigVariableInfo> variable_config_map_;
std::vector<uint32_t> hwc_config_map_;
+ bool fast_path_composition_ = false;
private:
void DumpInputBuffers(void);
@@ -407,6 +409,7 @@
int null_display_mode_ = 0;
bool has_client_composition_ = false;
DisplayValidateState validate_state_ = kNormalValidate;
+ bool fast_path_enabled_ = true;
};
inline int HWCDisplay::Perform(uint32_t operation, ...) {
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index a737c9f..6c6e56f 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1009,6 +1009,7 @@
if (power_on_pending_[display]) {
status = HWC2::Error::None;
} else if (hwc_session->hwc_display_[display]) {
+ hwc_session->hwc_display_[display]->SetFastPathComposition(false);
status = hwc_session->ValidateDisplayInternal(display, out_num_types, out_num_requests);
}
}
@@ -2662,9 +2663,11 @@
// Validation to optimize for the frames which don't require the Client composition.
if (hwc_display->IsSkipValidateState() && !hwc_display->CanSkipValidate()) {
uint32_t out_num_types = 0, out_num_requests = 0;
+ hwc_display->SetFastPathComposition(true);
HWC2::Error error = ValidateDisplayInternal(display, &out_num_types, &out_num_requests);
if ((error != HWC2::Error::None) || hwc_display->HWCClientNeedsValidate()) {
hwc_display->SetValidationState(HWCDisplay::kInternalValidate);
+ hwc_display->SetFastPathComposition(false);
return HWC2::Error::NotValidated;
}
}