sde: Add support resolution change on HDMI and fix comp_manager

- Provide a debug hook to change resolution on HDMI.
- Config(edid) set by user is validated before setting and this
  overrides the best mode
- Add max_attempts in strategy interface which will be used for
  looping through the strategy selection which removes infinite loop
- Set Max SDE layers on HDMI as 2
- Fix incorrect sde layer index in Dump

Change-Id: I9ae1d0b115a06774470be5c0f9b78c4d930b7065
diff --git a/displayengine/include/private/strategy_interface.h b/displayengine/include/private/strategy_interface.h
old mode 100755
new mode 100644
index b56789e..eac88cc
--- a/displayengine/include/private/strategy_interface.h
+++ b/displayengine/include/private/strategy_interface.h
@@ -30,6 +30,7 @@
 #define __STRATEGY_INTERFACE_H__
 
 #include <core/sde_types.h>
+#include <core/display_interface.h>
 
 namespace sde {
 
@@ -85,12 +86,14 @@
   @details This function is used to create StrategyInterface object which resides in the composer
   strategy library loaded at runtime.
 
-  @param[out] version \link STRATEGY_VERSION_TAG \endlink
+  @param[in] version \link STRATEGY_VERSION_TAG \endlink
+  @param[in] type \link DisplayType \endlink
   @param[out] interface \link StrategyInterface \endlink
 
   @return \link DisplayError \endlink
 */
-typedef DisplayError (*CreateStrategyInterface)(uint16_t version, StrategyInterface **interface);
+typedef DisplayError (*CreateStrategyInterface)(uint16_t version, DisplayType type,
+                      StrategyInterface **interface);
 
 /*! @brief Function to destroy composer strategy interface.
 
@@ -155,10 +158,11 @@
     preprocessing for a given layer stack.
 
     @param[in] layers_info \link HWLayersInfo \endlink
+    @param[out] max_attempts Maximum calls to \link GetNextStrategy \endlink
 
     @return \link DisplayError \endlink
   */
-  virtual DisplayError Start(HWLayersInfo *hw_layers_info) = 0;
+  virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) = 0;
 
 
   /*! @brief Method to get strategy for a layer stack. Caller can loop through this method to try
diff --git a/displayengine/include/utils/debug.h b/displayengine/include/utils/debug.h
index 3462b96..99d3968 100755
--- a/displayengine/include/utils/debug.h
+++ b/displayengine/include/utils/debug.h
@@ -49,6 +49,7 @@
   static inline LogHandler* GetLogHandler() { return debug_.log_handler_; }
   static inline bool IsVirtualDriver() { return debug_.virtual_driver_; }
   static uint32_t GetSimulationFlag();
+  static uint32_t GetHDMIResolution();
 
  private:
   Debug();
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 6a9f006..40191e5 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -104,7 +104,8 @@
     return kErrorMemory;
   }
 
-  if (create_strategy_intf_(STRATEGY_VERSION_TAG, &display_comp_ctx->strategy_intf) != kErrorNone) {
+  if (create_strategy_intf_(STRATEGY_VERSION_TAG, type,
+                            &display_comp_ctx->strategy_intf) != kErrorNone) {
     DLOGW("Unable to create strategy interface");
     delete display_comp_ctx;
     return kErrorUndefined;
@@ -151,15 +152,14 @@
 
   constraints->safe_mode = safe_mode_;
 
-  // TODO(user): Need to enable SDE Comp on HDMI
+  // Limit 2 layer SDE Comp on HDMI
   if (display_comp_ctx->display_type == kHDMI) {
-    constraints->max_layers = 1;
+    constraints->max_layers = 2;
   }
-  // If validation for the best available composition strategy with driver has failed, just
-  // fallback to safe mode composition e.g. GPU or video only.
-  if (display_comp_ctx->strategy_selected) {
+
+  // If a strategy fails after successfully allocating resources, then set safe mode
+  if (display_comp_ctx->remaining_strategies != display_comp_ctx->max_strategies) {
     constraints->safe_mode = true;
-    return;
   }
 }
 
@@ -167,8 +167,9 @@
   SCOPE_LOCK(locker_);
   DisplayCompositionContext *display_comp_ctx =
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  display_comp_ctx->strategy_intf->Start(&hw_layers->info);
-  display_comp_ctx->strategy_selected = false;
+  display_comp_ctx->strategy_intf->Start(&hw_layers->info,
+                                         &display_comp_ctx->max_strategies);
+  display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
 }
 
 DisplayError CompManager::Prepare(Handle display_ctx, HWLayers *hw_layers) {
@@ -178,31 +179,34 @@
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
   Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
 
-  DisplayError error = kErrorNone;
+  DisplayError error = kErrorUndefined;
 
   PrepareStrategyConstraints(display_ctx, hw_layers);
 
   // Select a composition strategy, and try to allocate resources for it.
   res_mgr_.Start(display_resource_ctx);
-  while (true) {
+
+  bool exit = false;
+  uint32_t &count = display_comp_ctx->remaining_strategies;
+  for (; !exit && count > 0; count--) {
     error = display_comp_ctx->strategy_intf->GetNextStrategy(&display_comp_ctx->constraints);
-    if (UNLIKELY(error != kErrorNone)) {
+    if (error != kErrorNone) {
       // Composition strategies exhausted. Resource Manager could not allocate resources even for
       // GPU composition. This will never happen.
-      DLOGE("Unexpected failure. Composition strategies exhausted.");
-      break;
+      exit = true;
     }
 
-    error = res_mgr_.Acquire(display_resource_ctx, hw_layers);
-    if (error != kErrorNone) {
-      // Not enough resources, try next strategy.
-      continue;
-    } else {
-      // Successfully selected and configured a composition strategy.
-      break;
+    if (!exit) {
+      error = res_mgr_.Acquire(display_resource_ctx, hw_layers);
+      // Exit if successfully allocated resource, else try next strategy.
+      exit = (error == kErrorNone);
     }
   }
-  display_comp_ctx->strategy_selected = true;
+
+  if (error != kErrorNone) {
+    DLOGE("Composition strategies exhausted for display = %d", display_comp_ctx->display_type);
+  }
+
   res_mgr_.Stop(display_resource_ctx);
 
   return error;
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
index 1c22618..aed357b 100644
--- a/displayengine/libs/core/comp_manager.h
+++ b/displayengine/libs/core/comp_manager.h
@@ -58,7 +58,8 @@
     StrategyConstraints constraints;
     Handle display_resource_ctx;
     DisplayType display_type;
-    bool strategy_selected;
+    uint32_t max_strategies;
+    uint32_t remaining_strategies;
   };
 
   Locker locker_;
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index 7cd88e7..080deb7 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -150,7 +150,7 @@
   }
 
   if (!pending_commit_) {
-    DLOGE("Commit: Corresponding Prepare() is not called.");
+    DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
     return kErrorUndefined;
   }
 
@@ -345,7 +345,7 @@
                                 num_layers, num_hw_layers);
 
   for (uint32_t i = 0; i < num_hw_layers; i++) {
-    Layer &layer = hw_layers_.info.stack->layers[i];
+    Layer &layer = hw_layers_.info.stack->layers[hw_layers_.info.index[i]];
     LayerBuffer *input_buffer = layer.input_buffer;
     HWLayerConfig &layer_config = hw_layers_.config[i];
     HWPipeInfo &left_pipe = hw_layers_.config[i].left_pipe;
diff --git a/displayengine/libs/core/display_hdmi.cpp b/displayengine/libs/core/display_hdmi.cpp
index f7c42f4..14a09f1 100644
--- a/displayengine/libs/core/display_hdmi.cpp
+++ b/displayengine/libs/core/display_hdmi.cpp
@@ -64,6 +64,16 @@
     }
   }
 
+  // Used for changing HDMI Resolution - override the best with user set config
+  uint32_t user_config = Debug::GetHDMIResolution();
+  if (user_config) {
+    uint32_t config_index = -1;
+    // For the config, get the corresponding index
+    DisplayError error = hw_intf_->GetConfigIndex(hw_device_, user_config, &config_index);
+    if (error == kErrorNone)
+      return config_index;
+  }
+
   return best_config_mode;
 }
 
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 93bec4d..0644e7d 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -423,6 +423,33 @@
   return error;
 }
 
+DisplayError HWFrameBuffer::GetConfigIndex(Handle device, uint32_t mode, uint32_t *index) {
+  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
+
+  switch (hw_context->type) {
+  case kDevicePrimary:
+  case kDeviceVirtual:
+    return kErrorNone;
+    break;
+  case kDeviceHDMI:
+    // Check if the mode is valid and return corresponding index
+    for (uint32_t i = 0; i < hdmi_mode_count_; i++) {
+      if (hdmi_modes_[i] == mode) {
+        *index = i;
+        DLOGI("Index = %d for config = %d", *index, mode);
+        return kErrorNone;
+      }
+    }
+    break;
+  default:
+    return kErrorParameters;
+  }
+
+  DLOGE("Config = %d not supported", mode);
+  return kErrorNotSupported;
+}
+
+
 DisplayError HWFrameBuffer::PowerOn(Handle device) {
   HWContext *hw_context = reinterpret_cast<HWContext *>(device);
 
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
index 5816878..2fe5078 100644
--- a/displayengine/libs/core/hw_framebuffer.h
+++ b/displayengine/libs/core/hw_framebuffer.h
@@ -25,6 +25,7 @@
 #ifndef __HW_FRAMEBUFFER_H__
 #define __HW_FRAMEBUFFER_H__
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <linux/msm_mdp_ext.h>
@@ -49,6 +50,7 @@
   virtual DisplayError GetDisplayAttributes(Handle device, HWDisplayAttributes *display_attributes,
                                             uint32_t index);
   virtual DisplayError SetDisplayAttributes(Handle device, uint32_t index);
+  virtual DisplayError GetConfigIndex(Handle device, uint32_t mode, uint32_t *index);
   virtual DisplayError PowerOn(Handle device);
   virtual DisplayError PowerOff(Handle device);
   virtual DisplayError Doze(Handle device);
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 7309c32..f4f33f9 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -160,6 +160,7 @@
   virtual DisplayError GetDisplayAttributes(Handle device,
                             HWDisplayAttributes *display_attributes, uint32_t index) = 0;
   virtual DisplayError SetDisplayAttributes(Handle device, uint32_t index) = 0;
+  virtual DisplayError GetConfigIndex(Handle device, uint32_t mode, uint32_t *index) = 0;
   virtual DisplayError PowerOn(Handle device) = 0;
   virtual DisplayError PowerOff(Handle device) = 0;
   virtual DisplayError Doze(Handle device) = 0;
diff --git a/displayengine/libs/core/strategy_default.cpp b/displayengine/libs/core/strategy_default.cpp
old mode 100755
new mode 100644
index 5c0c66f..e3270b7
--- a/displayengine/libs/core/strategy_default.cpp
+++ b/displayengine/libs/core/strategy_default.cpp
@@ -34,7 +34,7 @@
 StrategyDefault::StrategyDefault() : hw_layers_info_(NULL) {
 }
 
-DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version,
+DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
                                                       StrategyInterface **interface) {
   StrategyDefault *strategy_default  = new StrategyDefault();
 
@@ -59,12 +59,13 @@
   return kErrorNone;
 }
 
-DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info) {
+DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
   if (!hw_layers_info) {
     return kErrorParameters;
   }
 
   hw_layers_info_ = hw_layers_info;
+  *max_attempts = 1;
 
   return kErrorNone;
 }
diff --git a/displayengine/libs/core/strategy_default.h b/displayengine/libs/core/strategy_default.h
index 94db9e9..2ba19f8 100644
--- a/displayengine/libs/core/strategy_default.h
+++ b/displayengine/libs/core/strategy_default.h
@@ -34,10 +34,11 @@
  public:
   StrategyDefault();
 
-  static DisplayError CreateStrategyInterface(uint16_t version, StrategyInterface **interface);
+  static DisplayError CreateStrategyInterface(uint16_t version, DisplayType type,
+                                              StrategyInterface **interface);
   static DisplayError DestroyStrategyInterface(StrategyInterface *interface);
 
-  virtual DisplayError Start(HWLayersInfo *hw_layers_info);
+  virtual DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts);
   virtual DisplayError GetNextStrategy(StrategyConstraints *constraints);
   virtual DisplayError Stop();
 
diff --git a/displayengine/libs/utils/debug_android.cpp b/displayengine/libs/utils/debug_android.cpp
index 8b46371..31bd40b 100755
--- a/displayengine/libs/utils/debug_android.cpp
+++ b/displayengine/libs/utils/debug_android.cpp
@@ -47,5 +47,14 @@
   return 0;
 }
 
+uint32_t Debug::GetHDMIResolution() {
+  char property[PROPERTY_VALUE_MAX];
+  if (property_get("hw.hdmi.resolution", property, NULL) > 0) {
+    return atoi(property);
+  }
+
+  return 0;
+}
+
 }  // namespace sde