sde: Transition to safe mode in case of resource failures

1. No Pipe resources available for any display, move to safe mode
   composition for all displays, so that strategy manager selects
   the composition mode which requires optimal resource.
2. Move back to normal mode once all the displays are configured
   successfully with the resources for the current drawcycle.

Change-Id: Ic66d893a6ba50eb88cf8c70dae4df3772d47e1a0
diff --git a/displayengine/include/core/layer_buffer.h b/displayengine/include/core/layer_buffer.h
index e6dcf1c..421ab87 100644
--- a/displayengine/include/core/layer_buffer.h
+++ b/displayengine/include/core/layer_buffer.h
@@ -106,7 +106,8 @@
 struct LayerBufferFlags {
   uint64_t secure : 1;  //!< This flag shall be set by client to indicate that the buffer need
                         //!< to be handled securely.
-
+  uint64_t video  : 1;  //!< This flag shall be set by client to indicate that the buffer is
+                        //!< video/ui buffer
   LayerBufferFlags() : secure(0) { }
 };
 
diff --git a/displayengine/include/core/layer_stack.h b/displayengine/include/core/layer_stack.h
index fddfa8e..e361ac7 100644
--- a/displayengine/include/core/layer_stack.h
+++ b/displayengine/include/core/layer_stack.h
@@ -93,10 +93,13 @@
   @sa LayerBuffer
 */
 struct LayerFlags {
-  uint64_t skip : 1;  //!< This flag shall be set by client to indicate that this layer will be
-                      //!< handled by GPU. Device Device will not consider it for composition.
-
-  LayerFlags() : skip(0) { }
+  uint64_t skip : 1;      //!< This flag shall be set by client to indicate that this layer will be
+                          //!< handled by GPU. Display Device will not consider it for composition.
+  uint64_t updating : 1;  //!< This flag shall be set by client to indicate that this is updating/
+                          //!< non-updating. so strategy manager will mark them for SDE/GPU
+                          //!< composition respectively when the layer stack qualifies for cache
+                          //!< based composition.
+  LayerFlags() : skip(0), updating(0) { }
 };
 
 /*! @brief This structure defines flags associated with a layer stack. The 1-bit flag can be set to
diff --git a/displayengine/include/private/strategy_interface.h b/displayengine/include/private/strategy_interface.h
index 7050929..f14fbfb 100644
--- a/displayengine/include/private/strategy_interface.h
+++ b/displayengine/include/private/strategy_interface.h
@@ -75,11 +75,13 @@
     @sa GetNextStrategy
 */
 struct StrategyConstraints {
-  bool gpu_only;          //!< Select GPU only composition for this layer stack.
+  bool safe_mode;         //!< In this mode, strategy manager chooses the composition strategy
+                          //!< that requires minimum number of pipe for the current frame. i.e.,
+                          //!< video only composition, secure only composition or GPU composition
   uint32_t max_layers;    //!< Maximum number of layers that shall be programmed on hardware for the
                           //!< given layer stack.
 
-  StrategyConstraints() : gpu_only(false), max_layers(kNumLayersMax) { }
+  StrategyConstraints() : safe_mode(false), max_layers(kNumLayersMax) { }
 };
 
 /*! @brief Flag to denote that GPU composition is performed for the given layer stack.
diff --git a/displayengine/include/utils/constants.h b/displayengine/include/utils/constants.h
index 4b18ed6..7d7a39c 100644
--- a/displayengine/include/utils/constants.h
+++ b/displayengine/include/utils/constants.h
@@ -43,6 +43,9 @@
 
 #define ROUND_UP(number, step) ((((number) + ((step) - 1)) / (step)) * (step))
 
+#define SET_BIT(value, bit) ((value) | (1 << (bit)))
+#define CLEAR_BIT(value, bit) ((value) & (~(1 << (bit))))
+
 namespace sde {
 
   const int kThreadPriorityUrgent = -9;
diff --git a/displayengine/include/utils/debug.h b/displayengine/include/utils/debug.h
index 10d5ea6..0691dfc 100644
--- a/displayengine/include/utils/debug.h
+++ b/displayengine/include/utils/debug.h
@@ -46,9 +46,9 @@
 namespace sde {
 
 enum LogTag {
-  kTagNone = 0,   //!< Log tag name is not specified.
-  kTagCore,       //!< Log is tagged for display core.
-  kTagStrategy,   //!< Log is tagged for composition strategy.
+  kTagNone = 0,   // Log tag name is not specified.
+  kTagCore,       // Log is tagged for display core.
+  kTagStrategy,   // Log is tagged for composition strategy.
 };
 
 class Debug {
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 560db52..49572f9 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -34,7 +34,8 @@
 
 namespace sde {
 
-CompManager::CompManager() : strategy_lib_(NULL), strategy_intf_(NULL) {
+CompManager::CompManager() : strategy_lib_(NULL), strategy_intf_(NULL), registered_displays_(0),
+                             configured_displays_(0), safe_mode_(false) {
 }
 
 DisplayError CompManager::Init(const HWResourceInfo &hw_res_info) {
@@ -102,9 +103,12 @@
     delete comp_mgr_device;
     return error;
   }
-
+  SET_BIT(registered_displays_, type);
   comp_mgr_device->device_type = type;
   *device = comp_mgr_device;
+  // New device has been added, so move the composition mode to safe mode until unless resources
+  // for the added display is configured properly.
+  safe_mode_ = true;
 
   return kErrorNone;
 }
@@ -115,11 +119,26 @@
   CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
 
   res_mgr_.UnregisterDevice(comp_mgr_device->res_mgr_device);
+  CLEAR_BIT(registered_displays_, comp_mgr_device->device_type);
+  CLEAR_BIT(configured_displays_, comp_mgr_device->device_type);
   delete comp_mgr_device;
 
   return kErrorNone;
 }
 
+void CompManager::PrepareStrategyConstraints(Handle device, HWLayers *hw_layers) {
+  CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+  StrategyConstraints *constraints = &comp_mgr_device->constraints;
+
+  constraints->safe_mode = safe_mode_;
+  // If validation for the best available composition strategy with driver has failed, just
+  // fallback to GPU composition.
+  if (UNLIKELY(hw_layers->info.flags)) {
+    constraints->safe_mode = true;
+    return;
+  }
+}
+
 DisplayError CompManager::Prepare(Handle device, HWLayers *hw_layers) {
   SCOPE_LOCK(locker_);
 
@@ -128,19 +147,7 @@
 
   DisplayError error = kErrorNone;
 
-  comp_mgr_device->constraints.gpu_only = false;
-
-  // If validation for the best available composition strategy with driver has failed, just
-  // fallback to GPU composition.
-  if (UNLIKELY(hw_layers->info.flags)) {
-    // Did driver reject GPU composition as well? This will never happen.
-    if (UNLIKELY(hw_layers->info.flags & kFlagGPU)) {
-      DLOGE("Unexpected error. GPU composition validation failed.");
-      return kErrorHardware;
-    }
-
-    comp_mgr_device->constraints.gpu_only = true;
-  }
+  PrepareStrategyConstraints(device, hw_layers);
 
   // Select a composition strategy, and try to allocate resources for it.
   res_mgr_.Start(res_mgr_device);
@@ -175,6 +182,10 @@
   SCOPE_LOCK(locker_);
 
   CompManagerDevice *comp_mgr_device = reinterpret_cast<CompManagerDevice *>(device);
+  SET_BIT(configured_displays_, comp_mgr_device->device_type);
+  if (configured_displays_ == registered_displays_) {
+      safe_mode_ = false;
+  }
 
   res_mgr_.PostCommit(comp_mgr_device->res_mgr_device, hw_layers);
 }
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
index e6954a8..55ec5d6 100644
--- a/displayengine/libs/core/comp_manager.h
+++ b/displayengine/libs/core/comp_manager.h
@@ -51,6 +51,7 @@
   virtual uint32_t GetDump(uint8_t *buffer, uint32_t length);
 
  private:
+  void PrepareStrategyConstraints(Handle device, HWLayers *hw_layers);
   struct CompManagerDevice {
     StrategyConstraints constraints;
     Handle res_mgr_device;
@@ -62,6 +63,11 @@
   StrategyInterface *strategy_intf_;
   StrategyDefault strategy_default_;
   ResManager res_mgr_;
+  uint64_t registered_displays_;        // Stores the bit mask of registered displays
+  uint64_t configured_displays_;        // Stores the bit mask of sucessfully configured displays
+  bool safe_mode_;                      // Flag to notify all displays to be in resource crunch
+                                        // mode, where strategy manager chooses the best strategy
+                                        // that uses optimal number of pipes for each display
 };
 
 }  // namespace sde