sde: Add binder support to set maximum mixer stages.
Add binder support to set maximum mixer stages for each displays.
Syntax:
adb shell "service call display.qservice 13 i32 <DISPLAY_TYPE>
i32 <MAX_STAGE_COUNT>"
DISPLAY_TYPE = Set bit 1 -> To enable dump on primary display
Set bit 2 -> To enable dump on hdmi display
Set bit 3 -> To enable dump on virtual display
MAX_STAGE_COUNT = 3 -> Set the max layer mixer stages to 3.
Set max_mixer stages all displays to 3:
adb shell "service call display.qservice 13 i32 7 i32 3"
Change-Id: I10d521308077efca6a532fb679c04066bae9e8d3
diff --git a/displayengine/include/core/display_interface.h b/displayengine/include/core/display_interface.h
index c054fae..9aae0a1 100644
--- a/displayengine/include/core/display_interface.h
+++ b/displayengine/include/core/display_interface.h
@@ -314,6 +314,14 @@
*/
virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
+ /*! @brief Method to set maximum number of mixer stages for each display.
+
+ @param[in] max_mixer_stages maximum number of mixer stages.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages) = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 06028a2..cc58465 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -318,6 +318,20 @@
return false;
}
+DisplayError CompManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+
+ if (display_comp_ctx) {
+ error = res_mgr_.SetMaxMixerStages(display_comp_ctx->display_resource_ctx, max_mixer_stages);
+ }
+
+ return error;
+}
+
void CompManager::AppendDump(char *buffer, uint32_t length) {
SCOPE_LOCK(locker_);
}
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
index 24a0fff..0a21ee0 100644
--- a/displayengine/libs/core/comp_manager.h
+++ b/displayengine/libs/core/comp_manager.h
@@ -48,6 +48,7 @@
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
void Purge(Handle display_ctx);
bool ProcessIdleTimeout(Handle display_ctx);
+ DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
// DumpImpl method
virtual void AppendDump(char *buffer, uint32_t length);
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index d403450..8bfc6dd 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -409,6 +409,18 @@
hw_intf_->SetIdleTimeoutMs(hw_device_, timeout_ms);
}
+DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ DisplayError error = kErrorNone;
+
+ if (comp_manager_) {
+ error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
+ }
+
+ return error;
+}
+
DisplayError DisplayBase::VSync(int64_t timestamp) {
if (vsync_enable_) {
DisplayEventVSync vsync;
diff --git a/displayengine/libs/core/display_base.h b/displayengine/libs/core/display_base.h
index d2b67e3..10e11f8 100644
--- a/displayengine/libs/core/display_base.h
+++ b/displayengine/libs/core/display_base.h
@@ -60,6 +60,7 @@
virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetVSyncState(bool enable);
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 27a4e41..cd439ec 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -325,8 +325,9 @@
layer_config->right_pipe.z_order = z_order;
}
z_order++;
- if (z_order >= hw_res_info_.num_blending_stages) {
- DLOGV_IF(kTagResources, "z_order is over the limit: z_order = %d", z_order);
+ if (z_order > display_resource_ctx->max_mixer_stages) {
+ DLOGV_IF(kTagResources, "z_order is over the limit of max_mixer_stages = %d",
+ display_resource_ctx->max_mixer_stages);
return kErrorResources;
}
}
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 14cf11f..238dfa8 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -186,6 +186,8 @@
display_resource_ctx->display_attributes.split_left =
display_resource_ctx->display_attributes.x_pixels;
+ display_resource_ctx->max_mixer_stages = hw_res_info_.num_blending_stages;
+
*display_ctx = display_resource_ctx;
return error;
}
@@ -271,8 +273,15 @@
DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
- if (layer_info.count > num_pipe_ || layer_info.count >= hw_res_info_.num_blending_stages) {
- DLOGV_IF(kTagResources, "layer count is over the limit: layer count = %d", layer_info.count);
+ if (layer_info.count > num_pipe_) {
+ DLOGV_IF(kTagResources, "layer count exceeds pipe limit of %d, layer count %d", num_pipe_,
+ layer_info.count);
+ return kErrorResources;
+ }
+
+ if (layer_info.count > display_resource_ctx->max_mixer_stages) {
+ DLOGV_IF(kTagResources, "layer count exceeds max mixer stage limit of %d, layer count %d",
+ display_resource_ctx->max_mixer_stages, layer_info.count);
return kErrorResources;
}
@@ -811,6 +820,26 @@
DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
}
+DisplayError ResManager::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
+ SCOPE_LOCK(locker_);
+
+ if (max_mixer_stages < 1 || max_mixer_stages > hw_res_info_.num_blending_stages) {
+ DLOGE("Max mixer stages = %d and that should be in between 1 to %d", max_mixer_stages,
+ hw_res_info_.num_blending_stages);
+
+ return kErrorParameters;
+ }
+
+ DisplayResourceContext *display_resource_ctx =
+ reinterpret_cast<DisplayResourceContext *>(display_ctx);
+
+ if (display_resource_ctx) {
+ display_resource_ctx->max_mixer_stages = max_mixer_stages;
+ }
+
+ return kErrorNone;
+}
+
uint32_t ResManager::GetMdssPipeId(PipeType type, uint32_t index) {
uint32_t mdss_id = kPipeIdMax;
switch (type) {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index d21984e..8cf08f5 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -49,6 +49,7 @@
DisplayError PostPrepare(Handle display_ctx, HWLayers *hw_layers);
DisplayError PostCommit(Handle display_ctx, HWLayers *hw_layers);
void Purge(Handle display_ctx);
+ DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
// DumpImpl method
virtual void AppendDump(char *buffer, uint32_t length);
@@ -122,9 +123,10 @@
int32_t session_id; // applicable for virtual display sessions only
uint32_t rotate_count;
bool frame_start;
+ uint32_t max_mixer_stages;
DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0), session_id(-1),
- rotate_count(0), frame_start(false) { }
+ rotate_count(0), frame_start(false), max_mixer_stages(0) { }
~DisplayResourceContext() {
if (buffer_manager) {
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index dd1beac..1be682d 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -600,6 +600,16 @@
}
}
+DisplayError HWCDisplay::SetMaxMixerStages(uint32_t max_mixer_stages) {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->SetMaxMixerStages(max_mixer_stages);
+ }
+
+ return error;
+}
+
LayerBufferFormat HWCDisplay::GetSDEFormat(const int32_t &source, const int flags) {
LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index a574d6b..8feddf6 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -45,6 +45,7 @@
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual int SetActiveConfig(hwc_display_contents_1_t *content_list);
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
+ virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
protected:
// Maximum number of layers supported by display engine.
diff --git a/displayengine/libs/hwc/hwc_session.cpp b/displayengine/libs/hwc/hwc_session.cpp
index 40eae99..b6d0c18 100644
--- a/displayengine/libs/hwc/hwc_session.cpp
+++ b/displayengine/libs/hwc/hwc_session.cpp
@@ -562,6 +562,8 @@
android::Parcel */*output_parcel*/) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ android::status_t status = 0;
+
switch (command) {
case qService::IQService::DYNAMIC_DEBUG:
DynamicDebug(input_parcel);
@@ -573,7 +575,7 @@
case qService::IQService::SET_IDLE_TIMEOUT:
if (display_primary_) {
- uint32_t timeout = (uint32_t)input_parcel->readInt32();
+ uint32_t timeout = UINT32(input_parcel->readInt32());
display_primary_->SetIdleTimeoutMs(timeout);
}
break;
@@ -582,11 +584,50 @@
SetFrameDumpConfig(input_parcel);
break;
+ case qService::IQService::SET_MAX_PIPES_PER_MIXER:
+ status = SetMaxMixerStages(input_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
}
+ return status;
+}
+
+android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
+ DisplayError error = kErrorNone;
+ uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
+ uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
+ if (display_primary_) {
+ error = display_primary_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
+ if (display_external_) {
+ error = display_external_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
+ if (display_virtual_) {
+ error = display_virtual_->SetMaxMixerStages(max_mixer_stages);
+ if (error != kErrorNone) {
+ return -EINVAL;
+ }
+ }
+ }
+
return 0;
}
@@ -595,19 +636,19 @@
uint32_t bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_PRIMARY_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_PRIMARY)) {
if (display_primary_) {
display_primary_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_HDMI_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_EXTERNAL)) {
if (display_external_) {
display_external_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
- if (bit_mask_display_type & (1 << qService::IQService::DUMP_VIRTUAL_DISPLAY)) {
+ if (IS_BIT_SET(bit_mask_display_type, HWC_DISPLAY_VIRTUAL)) {
if (display_virtual_) {
display_virtual_->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
diff --git a/displayengine/libs/hwc/hwc_session.h b/displayengine/libs/hwc/hwc_session.h
index 4b8c8ce..1608ce5 100644
--- a/displayengine/libs/hwc/hwc_session.h
+++ b/displayengine/libs/hwc/hwc_session.h
@@ -85,6 +85,7 @@
android::Parcel *output_parcel);
void DynamicDebug(const android::Parcel *input_parcel);
void SetFrameDumpConfig(const android::Parcel *input_parcel);
+ android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
static Locker locker_;
CoreInterface *core_intf_;
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 932d670..6a9d7f8 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -91,12 +91,6 @@
ENABLE_PARTIAL_UPDATE,
};
- enum {
- DUMP_PRIMARY_DISPLAY,
- DUMP_HDMI_DISPLAY,
- DUMP_VIRTUAL_DISPLAY,
- };
-
// Register a HWC client that can be notified
// This client is generic and is intended to get
// dispatches of all events calling into QService