sde: partial update implementation
1. Partial update for non-split and split panels.
2. Currently, partial update is enabled on qualified
primary displays only.
Change-Id: I4d37e83e0991693cce950dc1428ed8c30d4f6caa
diff --git a/displayengine/include/private/strategy_interface.h b/displayengine/include/private/strategy_interface.h
index df01c7f..a0a52f8 100644
--- a/displayengine/include/private/strategy_interface.h
+++ b/displayengine/include/private/strategy_interface.h
@@ -96,7 +96,7 @@
@return \link DisplayError \endlink
*/
typedef DisplayError (*CreateStrategyInterface)(uint16_t version, DisplayType type,
- const HWResourceInfo *hw_resource_info, const HWPanelInfo *hw_panel_info,
+ const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
StrategyInterface **interface);
/*! @brief Function to destroy composer strategy interface.
diff --git a/displayengine/include/utils/debug.h b/displayengine/include/utils/debug.h
index 2cef5d7..1dbf0c3 100644
--- a/displayengine/include/utils/debug.h
+++ b/displayengine/include/utils/debug.h
@@ -65,7 +65,7 @@
static uint32_t GetIdleTimeoutMs();
static bool IsRotatorDownScaleDisabled();
static bool IsDecimationDisabled();
- static bool IsPartialUpdate();
+ static bool IsPartialUpdateEnabled();
private:
Debug();
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 75d520f..fa02e94 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -107,7 +107,7 @@
return kErrorMemory;
}
- if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, &hw_res_info_, &hw_panel_info,
+ if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, hw_res_info_, hw_panel_info,
&display_comp_ctx->strategy_intf) != kErrorNone) {
DLOGW("Unable to create strategy interface");
delete display_comp_ctx;
diff --git a/displayengine/libs/core/fb/hw_device.cpp b/displayengine/libs/core/fb/hw_device.cpp
index d96820f..809e817 100644
--- a/displayengine/libs/core/fb/hw_device.cpp
+++ b/displayengine/libs/core/fb/hw_device.cpp
@@ -194,7 +194,6 @@
DTRACE_SCOPED();
DisplayError error = kErrorNone;
- ResetDisplayParams();
HWLayersInfo &hw_layer_info = hw_layers->info;
LayerStack *stack = hw_layer_info.stack;
@@ -206,6 +205,12 @@
mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
+ DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
+ mdp_commit.left_roi.w, mdp_commit.left_roi.h);
+ DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
+ mdp_commit.right_roi.y, mdp_commit.right_roi.w,
+ mdp_commit.right_roi.h);
+
for (uint32_t i = 0; i < hw_layer_info.count; i++) {
uint32_t layer_index = hw_layer_info.index[i];
Layer &layer = stack->layers[layer_index];
diff --git a/displayengine/libs/core/fb/hw_hdmi.cpp b/displayengine/libs/core/fb/hw_hdmi.cpp
index fec8661..f8279b2 100644
--- a/displayengine/libs/core/fb/hw_hdmi.cpp
+++ b/displayengine/libs/core/fb/hw_hdmi.cpp
@@ -326,6 +326,7 @@
}
DisplayError HWHDMI::Validate(HWLayers *hw_layers) {
+ HWDevice::ResetDisplayParams();
return HWDevice::Validate(hw_layers);
}
diff --git a/displayengine/libs/core/fb/hw_primary.cpp b/displayengine/libs/core/fb/hw_primary.cpp
index 6ff94b4..1fa4b4e 100644
--- a/displayengine/libs/core/fb/hw_primary.cpp
+++ b/displayengine/libs/core/fb/hw_primary.cpp
@@ -299,6 +299,27 @@
}
DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
+ HWDevice::ResetDisplayParams();
+
+ mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+
+ LayerRect left_roi = hw_layers->info.left_partial_update;
+ LayerRect right_roi = hw_layers->info.right_partial_update;
+ mdp_commit.left_roi.x = INT(left_roi.left);
+ mdp_commit.left_roi.y = INT(left_roi.top);
+ mdp_commit.left_roi.w = INT(left_roi.right - left_roi.left);
+ mdp_commit.left_roi.h = INT(left_roi.bottom - left_roi.top);
+
+ // SDE treats ROI as one full coordinate system.
+ // In case source split is disabled, However, Driver assumes Mixer to operate in
+ // different co-ordinate system.
+ if (!hw_resource_.is_src_split) {
+ mdp_commit.right_roi.x = INT(right_roi.left) - hw_panel_info_.split_info.left_split;
+ mdp_commit.right_roi.y = INT(right_roi.top);
+ mdp_commit.right_roi.w = INT(right_roi.right - right_roi.left);
+ mdp_commit.right_roi.h = INT(right_roi.bottom - right_roi.top);
+ }
+
return HWDevice::Validate(hw_layers);
}
@@ -402,7 +423,7 @@
thermal_level = strtoull(data + strlen("thermal_level="), NULL, 0);
}
- DLOGI("Received thermal notification with thermal level = %d",thermal_level);
+ DLOGI("Received thermal notification with thermal level = %d", thermal_level);
event_handler_->ThermalEvent(thermal_level);
}
diff --git a/displayengine/libs/core/fb/hw_virtual.cpp b/displayengine/libs/core/fb/hw_virtual.cpp
index 374cc45..f108cfa 100644
--- a/displayengine/libs/core/fb/hw_virtual.cpp
+++ b/displayengine/libs/core/fb/hw_virtual.cpp
@@ -119,6 +119,7 @@
}
DisplayError HWVirtual::Validate(HWLayers *hw_layers) {
+ HWDevice::ResetDisplayParams();
return HWDevice::Validate(hw_layers);
}
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index c5a8a06..a8f9017 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -142,31 +142,39 @@
DisplayError ResManager::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
const LayerTransform &transform,
const LayerRect &src_rect, const LayerRect &dst_rect,
- HWLayerConfig *layer_config, uint32_t align_x) {
+ const HWLayers &hw_layers, HWLayerConfig *layer_config,
+ uint32_t align_x) {
LayerRect scissor_dst_left, scissor_dst_right;
HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
// for display split case
HWPipeInfo *left_pipe = &layer_config->left_pipe;
HWPipeInfo *right_pipe = &layer_config->right_pipe;
- LayerRect scissor, dst_left, crop_left, crop_right, dst_right;
- scissor.right = FLOAT(display_attributes.split_left);
- scissor.bottom = FLOAT(display_attributes.y_pixels);
+ LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
+
+ scissor_left.right = FLOAT(display_attributes.split_left);
+ scissor_left.bottom = FLOAT(display_attributes.y_pixels);
+
+ scissor_right.left = FLOAT(display_attributes.split_left);
+ scissor_right.top = 0.0f;
+ scissor_right.right = FLOAT(display_attributes.x_pixels);
+ scissor_right.bottom = FLOAT(display_attributes.y_pixels);
+
+ if (IsValid(hw_layers.info.left_partial_update) ||
+ IsValid(hw_layers.info.right_partial_update)) {
+ scissor_left = hw_layers.info.left_partial_update;
+ scissor_right = hw_layers.info.right_partial_update;
+ }
crop_left = src_rect;
dst_left = dst_rect;
crop_right = crop_left;
dst_right = dst_left;
- bool crop_left_valid = CalculateCropRects(scissor, transform, &crop_left, &dst_left);
-
- scissor.left = FLOAT(display_attributes.split_left);
- scissor.top = 0.0f;
- scissor.right = FLOAT(display_attributes.x_pixels);
- scissor.bottom = FLOAT(display_attributes.y_pixels);
+ bool crop_left_valid = CalculateCropRects(scissor_left, transform, &crop_left, &dst_left);
bool crop_right_valid = false;
- if (IsValid(scissor)) {
- crop_right_valid = CalculateCropRects(scissor, transform, &crop_right, &dst_right);
+ if (IsValid(scissor_right)) {
+ crop_right_valid = CalculateCropRects(scissor_right, transform, &crop_right, &dst_right);
}
if (crop_left_valid && (crop_left.right - crop_left.left) > hw_res_info_.max_pipe_width) {
@@ -248,6 +256,10 @@
scissor.right = FLOAT(display_attributes.x_pixels);
scissor.bottom = FLOAT(display_attributes.y_pixels);
+ if (IsValid(hw_layers->info.left_partial_update)) {
+ scissor = hw_layers->info.left_partial_update;
+ }
+
struct HWLayerConfig *layer_config = &hw_layers->config[i];
HWPipeInfo &left_pipe = layer_config->left_pipe;
HWPipeInfo &right_pipe = layer_config->right_pipe;
@@ -295,19 +307,21 @@
transform = LayerTransform();
}
+ // TODO(user): need to revisit this logic
if (hw_res_info_.is_src_split) {
- error = SrcSplitConfig(display_resource_ctx, transform, src_rect,
- dst_rect, layer_config, align_x);
+ error = SrcSplitConfig(display_resource_ctx, transform, src_rect, dst_rect, layer_config,
+ align_x);
} else {
- error = DisplaySplitConfig(display_resource_ctx, transform, src_rect,
- dst_rect, layer_config, align_x);
+ error = DisplaySplitConfig(display_resource_ctx, transform, src_rect, dst_rect, *hw_layers,
+ layer_config, align_x);
}
if (error != kErrorNone) {
break;
}
- error = AlignPipeConfig(layer, transform, &left_pipe, &right_pipe, align_x, align_y);
+ error = AlignPipeConfig(layer, transform, *hw_layers, &left_pipe, &right_pipe, align_x,
+ align_y);
if (error != kErrorNone) {
break;
}
@@ -742,8 +756,9 @@
}
DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
- HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
- uint32_t align_x, uint32_t align_y) {
+ const HWLayers &hw_layers, HWPipeInfo *left_pipe,
+ HWPipeInfo *right_pipe, uint32_t align_x,
+ uint32_t align_y) {
DisplayError error = kErrorNone;
if (!left_pipe->valid) {
DLOGE_IF(kTagResources, "left_pipe should not be invalid");
@@ -753,7 +768,6 @@
// rectangle of video layer to be even.
// 2. Normalize source and destination rect of a layer to multiple of 1.
// TODO(user) Check buffer format and check if rotate is involved.
-
Normalize(align_x, align_y, &left_pipe->src_roi);
Normalize(1, 1, &left_pipe->dst_roi);
@@ -762,8 +776,10 @@
Normalize(1, 1, &right_pipe->dst_roi);
}
- if (right_pipe->valid) {
- // Make sure the left and right ROI are conjunct
+ // Make sure the left and right ROI are conjunct, then make pipes ROI conjunct.
+ if (right_pipe->valid &&
+ (!IsValid(hw_layers.info.right_partial_update) ||
+ (hw_layers.info.left_partial_update.right == hw_layers.info.right_partial_update.left))) {
if (transform.flip_horizontal) {
left_pipe->src_roi.left = right_pipe->src_roi.right;
} else {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index d9c6c8b..1f8f48e 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -164,9 +164,12 @@
DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
uint32_t *rotate_count);
DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
- const LayerTransform &transform, const LayerRect &src_rect,
- const LayerRect &dst_rect, HWLayerConfig *layer_config,
+ const LayerTransform &transform,
+ const LayerRect &src_rect, const LayerRect &dst_rect,
+ const HWLayers &hw_layers, HWLayerConfig *layer_config,
uint32_t align_x);
+ DisplayError ValidateScaling(const Layer &layer, const LayerRect &crop,
+ const LayerRect &dst, float *rot_scale);
DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
const LayerTransform &transform, const LayerRect &src_rect,
const LayerRect &dst_rect, HWLayerConfig *layer_config,
@@ -210,8 +213,8 @@
const bool &rot90, const bool &downscale,
LayerBufferFormat *output_format);
DisplayError AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
- HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
- uint32_t align_x, uint32_t align_y);
+ const HWLayers &hw_layers, HWPipeInfo *left_pipe,
+ HWPipeInfo *right_pipe, uint32_t align_x, uint32_t align_y);
void ResourceStateLog(void);
DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
diff --git a/displayengine/libs/core/strategy_default.cpp b/displayengine/libs/core/strategy_default.cpp
index 48fc79d..4aab34d 100644
--- a/displayengine/libs/core/strategy_default.cpp
+++ b/displayengine/libs/core/strategy_default.cpp
@@ -31,14 +31,17 @@
namespace sde {
-StrategyDefault::StrategyDefault() : hw_layers_info_(NULL) {
+StrategyDefault::StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
+ const HWPanelInfo &hw_panel_info) : type_(type),
+ hw_resource_info_(hw_resource_info),
+ hw_panel_info_(hw_panel_info), hw_layers_info_(NULL) {
}
DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
- const HWResourceInfo *hw_resource_info,
- const HWPanelInfo *hw_panel_info,
+ const HWResourceInfo &hw_resource_info,
+ const HWPanelInfo &hw_panel_info,
StrategyInterface **interface) {
- StrategyDefault *strategy_default = new StrategyDefault();
+ StrategyDefault *strategy_default = new StrategyDefault(type, hw_resource_info, hw_panel_info);
if (!strategy_default) {
return kErrorMemory;
@@ -61,6 +64,18 @@
return kErrorNone;
}
+bool StrategyDefault::IsDisplaySplit(uint32_t fb_x_res) {
+ if (fb_x_res > hw_resource_info_.max_mixer_width) {
+ return true;
+ }
+
+ if ((type_ == kPrimary) && hw_panel_info_.split_info.right_split) {
+ return true;
+ }
+
+ return false;
+}
+
DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
if (!hw_layers_info) {
return kErrorParameters;
@@ -69,6 +84,29 @@
hw_layers_info_ = hw_layers_info;
*max_attempts = 1;
+ const LayerStack *layer_stack = hw_layers_info_->stack;
+ for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
+ LayerComposition &composition = layer_stack->layers[i].composition;
+ if (composition == kCompositionGPUTarget) {
+ fb_layer_index_ = i;
+ break;
+ }
+ }
+
+ const LayerRect &src_rect = hw_layers_info_->stack->layers[fb_layer_index_].src_rect;
+ // TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
+ const float fb_x_res = src_rect.right - src_rect.left;
+ const float fb_y_res = src_rect.bottom - src_rect.top;
+
+ if (IsDisplaySplit(INT(fb_x_res))) {
+ float left_split = FLOAT(hw_panel_info_.split_info.left_split);
+ hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, left_split, fb_y_res};
+ hw_layers_info->right_partial_update = (LayerRect) {left_split, 0.0, fb_x_res, fb_y_res};
+ } else {
+ hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, fb_x_res, fb_y_res};
+ hw_layers_info->right_partial_update = (LayerRect) {0.0, 0.0, 0.0, 0.0};
+ }
+
return kErrorNone;
}
diff --git a/displayengine/libs/core/strategy_default.h b/displayengine/libs/core/strategy_default.h
index 7b6f594..37d5f9d 100644
--- a/displayengine/libs/core/strategy_default.h
+++ b/displayengine/libs/core/strategy_default.h
@@ -32,11 +32,11 @@
class StrategyDefault : public StrategyInterface {
public:
- StrategyDefault();
-
+ StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
+ const HWPanelInfo &hw_panel_info);
static DisplayError CreateStrategyInterface(uint16_t version, DisplayType type,
- const HWResourceInfo *hw_resource_info,
- const HWPanelInfo *hw_panel_info,
+ const HWResourceInfo &hw_resource_info,
+ const HWPanelInfo &hw_panel_info,
StrategyInterface **interface);
static DisplayError DestroyStrategyInterface(StrategyInterface *interface);
@@ -45,7 +45,12 @@
virtual DisplayError Stop();
private:
+ bool IsDisplaySplit(uint32_t fb_x_res);
+ DisplayType type_;
+ HWResourceInfo hw_resource_info_;
+ HWPanelInfo hw_panel_info_;
HWLayersInfo *hw_layers_info_;
+ int fb_layer_index_;
};
} // namespace sde
diff --git a/displayengine/libs/utils/debug_android.cpp b/displayengine/libs/utils/debug_android.cpp
index 77c82b0..779c441 100644
--- a/displayengine/libs/utils/debug_android.cpp
+++ b/displayengine/libs/utils/debug_android.cpp
@@ -90,7 +90,7 @@
}
// This property serves to disable/enable partial update
-bool Debug::IsPartialUpdate() {
+bool Debug::IsPartialUpdateEnabled() {
char property[PROPERTY_VALUE_MAX];
if (property_get("sde.hwc.partial_update", property, NULL) > 0) {
return (atoi(property) ? 1 : true, false);
diff --git a/displayengine/libs/utils/rect.cpp b/displayengine/libs/utils/rect.cpp
index 9b05951..630cebb 100644
--- a/displayengine/libs/utils/rect.cpp
+++ b/displayengine/libs/utils/rect.cpp
@@ -122,11 +122,11 @@
return LayerRect();
}
- if(!IsValid(rect1)){
+ if (!IsValid(rect1)) {
return rect2;
}
- if(!IsValid(rect2)){
+ if (!IsValid(rect2)) {
return rect1;
}