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