Merge "sdm: Enforce concise conditionals"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index d9163d3..6031a32 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -2,6 +2,10 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.graphics.composer@2.1-service)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.graphics.composer@2.1-service.rc)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.graphics.composer@2.1-impl.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.graphics.composer@2.2-service)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.graphics.composer@2.2-service.rc)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.graphics.composer@2.2-impl.so)
+
 
 # Clean old target objs
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/hwcomposer.msmnile.so)
@@ -29,6 +33,5 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/memtrack.talos.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib/hw/memtrack.talos.so)
 
-
 #Clean display includes
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/qcom/display)
diff --git a/config/display-product.mk b/config/display-product.mk
index b337dff..855ff51 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -1,7 +1,7 @@
 # Display product definitions
 PRODUCT_PACKAGES += \
-    android.hardware.graphics.composer@2.2-impl \
-    android.hardware.graphics.composer@2.2-service \
+    android.hardware.graphics.composer@2.3-impl \
+    android.hardware.graphics.composer@2.3-service \
     android.hardware.graphics.mapper@2.0-impl-qti-display \
     vendor.qti.hardware.display.allocator@1.0-service \
     android.hardware.memtrack@1.0-impl \
diff --git a/config/msmnile.mk b/config/msmnile.mk
index 2b93a92..8ffac4b 100644
--- a/config/msmnile.mk
+++ b/config/msmnile.mk
@@ -1,8 +1,8 @@
 #Display related packages and configuration
 
 PRODUCT_PACKAGES += \
-    android.hardware.graphics.composer@2.2-impl \
-    android.hardware.graphics.composer@2.2-service \
+    android.hardware.graphics.composer@2.3-impl \
+    android.hardware.graphics.composer@2.3-service \
     android.hardware.graphics.mapper@2.0-impl-qti-display \
     vendor.qti.hardware.display.allocator@1.0-service \
     android.hardware.memtrack@1.0-impl \
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 77250e1..1db20ba 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;
     }
   }