sdm: Support ControlPartialUpdate api in libqdutils
Implement CONTROL_PARTIAL_UPDATE binder support. DPSS module
use this api to control partial update feature.
Remove support for sdm.partial_update property as it is no
longer applicable.
Change-Id: Ib463aff0042dcfc0d0b2f296b54016b1ee70115d
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 3941137..7849d7f 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -286,7 +286,26 @@
// Screen refresh for native daemons linking dynamically to libqdutils
// ----------------------------------------------------------------------------
extern "C" int refreshScreen() {
- int ret = 0;
- ret = screenRefresh();
- return ret;
+ int ret = 0;
+ ret = screenRefresh();
+ return ret;
}
+
+extern "C" int controlPartialUpdate(int dpy, int mode) {
+ status_t err = (status_t) FAILED_TRANSACTION;
+ sp<IQService> binder = getBinder();
+ if(binder != NULL) {
+ Parcel inParcel, outParcel;
+ inParcel.writeInt32(dpy);
+ inParcel.writeInt32(mode);
+ err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
+ if(err != 0) {
+ ALOGE("%s() failed with err %d", __FUNCTION__, err);
+ } else {
+ return outParcel.readInt32();
+ }
+ }
+
+ return err;
+}
+
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index c877d06..4c0271a 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -58,7 +58,7 @@
TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
/* Enable/Disable/Set refresh rate dynamically */
CONFIGURE_DYN_REFRESH_RATE = 18,
- SET_PARTIAL_UPDATE = 19, // Preference on partial update feature
+ CONTROL_PARTIAL_UPDATE = 19, // Provides ability to enable/disable partial update
CONTROL_BACKLIGHT = 20, // Provides ability to control backlight
SET_FRAME_DUMP_CONFIG = 21, // Provides ability to set the frame dump config
SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
diff --git a/libqservice/QServiceUtils.h b/libqservice/QServiceUtils.h
index b677188..fbad484 100644
--- a/libqservice/QServiceUtils.h
+++ b/libqservice/QServiceUtils.h
@@ -79,10 +79,6 @@
return sendSingleParam(qService::IQService::CONTROL_BACKLIGHT, on);
}
-inline android::status_t setPartialUpdate(uint32_t enable) {
- return sendSingleParam(qService::IQService::SET_PARTIAL_UPDATE, enable);
-}
-
inline android::status_t setExtOrientation(uint32_t orientation) {
return sendSingleParam(qService::IQService::EXTERNAL_ORIENTATION,
orientation);
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 40ef738..f9b3fa4 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -327,6 +327,15 @@
*/
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages) = 0;
+ /*! @brief Method to control partial update feature for each display.
+
+ @param[in] enable partial update feature control flag
+ @param[out] pending whether the operation is completed or pending for completion
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) = 0;
+
/*! @brief Method to set the mode of the primary display.
@param[in] mode the new display mode.
diff --git a/sdm/include/private/partial_update_interface.h b/sdm/include/private/partial_update_interface.h
index 8b421c4..3159b56 100644
--- a/sdm/include/private/partial_update_interface.h
+++ b/sdm/include/private/partial_update_interface.h
@@ -36,6 +36,7 @@
class PartialUpdateInterface {
public:
virtual DisplayError GenerateROI(HWLayersInfo *hw_layers_info) = 0;
+ virtual void ControlPartialUpdate(bool enable) = 0;
protected:
virtual ~PartialUpdateInterface() { }
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index a384509..943747b 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -65,7 +65,6 @@
static int GetIdleTimeoutMs();
static bool IsRotatorDownScaleDisabled();
static bool IsDecimationDisabled();
- static bool IsPartialUpdateEnabled();
static int GetMaxPipesPerMixer(DisplayType display_type);
static bool IsVideoModeEnabled();
static bool IsRotatorUbwcDisabled();
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 078b7dc..5ee904f 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -191,7 +191,8 @@
SCOPE_LOCK(locker_);
DisplayCompositionContext *display_comp_ctx =
reinterpret_cast<DisplayCompositionContext *>(display_ctx);
- display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies);
+ display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
+ display_comp_ctx->partial_update_enable);
display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
// Avoid idle fallback, if there is only one app layer.
@@ -366,6 +367,14 @@
return error;
}
+void CompManager::ControlPartialUpdate(Handle display_ctx, bool enable) {
+ SCOPE_LOCK(locker_);
+
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+ display_comp_ctx->partial_update_enable = enable;
+}
+
void CompManager::AppendDump(char *buffer, uint32_t length) {
SCOPE_LOCK(locker_);
}
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index f7143ff..3f46d52 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -56,6 +56,7 @@
void ProcessIdleTimeout(Handle display_ctx);
void ProcessThermalEvent(Handle display_ctx, int64_t thermal_level);
DisplayError SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages);
+ void ControlPartialUpdate(Handle display_ctx, bool enable);
DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
// DumpImpl method
@@ -76,11 +77,12 @@
bool idle_fallback;
bool handle_idle_timeout;
bool fallback_;
+ uint32_t partial_update_enable;
DisplayCompositionContext()
: display_resource_ctx(NULL), display_type(kPrimary), max_strategies(0),
remaining_strategies(0), idle_fallback(false), handle_idle_timeout(true),
- fallback_(false) { }
+ fallback_(false), partial_update_enable(true) { }
};
Locker locker_;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index c1d2905..68423bf 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -43,7 +43,7 @@
rotator_intf_(rotator_intf), state_(kStateOff), hw_device_(0), display_comp_ctx_(0),
display_attributes_(NULL), num_modes_(0), active_mode_index_(0), pending_commit_(false),
vsync_enable_(false), underscan_supported_(false), max_mixer_stages_(0),
- hw_info_intf_(hw_info_intf), color_mgr_(NULL) {
+ hw_info_intf_(hw_info_intf), color_mgr_(NULL), partial_update_control_(true) {
}
DisplayError DisplayBase::Init() {
@@ -420,17 +420,44 @@
DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
DisplayError error = kErrorNone;
- if (comp_manager_) {
- error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
+ error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
- if (error == kErrorNone) {
- max_mixer_stages_ = max_mixer_stages;
- }
+ if (error == kErrorNone) {
+ max_mixer_stages_ = max_mixer_stages;
}
return error;
}
+DisplayError DisplayBase::ControlPartialUpdate(bool enable, uint32_t *pending) {
+ if (!pending) {
+ return kErrorParameters;
+ }
+
+ if (!hw_panel_info_.partial_update) {
+ // Nothing to be done.
+ DLOGI("partial update is not applicable for display=%d", display_type_);
+ return kErrorNotSupported;
+ }
+
+ *pending = false;
+ if (enable == partial_update_control_) {
+ DLOGI("Same state transition is requested.");
+ return kErrorNone;
+ }
+
+ partial_update_control_ = enable;
+ comp_manager_->ControlPartialUpdate(display_comp_ctx_, enable);
+
+ if (!enable) {
+ // If the request is to turn off feature, new draw call is required to have
+ // the new setting into effect.
+ *pending = true;
+ }
+
+ return kErrorNone;
+}
+
DisplayError DisplayBase::SetDisplayMode(uint32_t mode) {
return kErrorNotSupported;
}
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 531217e..4289c6b 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -61,6 +61,7 @@
virtual DisplayError SetDisplayState(DisplayState state);
virtual DisplayError SetActiveConfig(uint32_t index);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
virtual DisplayError SetDisplayMode(uint32_t mode);
virtual DisplayError IsScalingValid(const LayerRect &crop, const LayerRect &dst, bool rotate90);
virtual bool IsUnderscanSupported();
@@ -101,6 +102,7 @@
uint32_t max_mixer_stages_;
HWInfoInterface *hw_info_intf_;
ColorManagerProxy *color_mgr_; // each display object owns its ColorManagerProxy
+ bool partial_update_control_;
};
} // namespace sdm
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
index f009d3a..076aa20 100644
--- a/sdm/libs/core/strategy.cpp
+++ b/sdm/libs/core/strategy.cpp
@@ -70,7 +70,8 @@
return kErrorNone;
}
-DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
+DisplayError Strategy::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
+ bool partial_update_enable) {
DisplayError error = kErrorNone;
hw_layers_info_ = hw_layers_info;
@@ -90,6 +91,9 @@
return kErrorUndefined;
}
+ if (partial_update_intf_) {
+ partial_update_intf_->ControlPartialUpdate(partial_update_enable);
+ }
GenerateROI();
if (strategy_intf_) {
diff --git a/sdm/libs/core/strategy.h b/sdm/libs/core/strategy.h
index c7a67d9..22fd82a 100644
--- a/sdm/libs/core/strategy.h
+++ b/sdm/libs/core/strategy.h
@@ -38,7 +38,8 @@
DisplayError Init();
DisplayError Deinit();
- DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts);
+ DisplayError Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts,
+ bool partial_update_enable);
DisplayError GetNextStrategy(StrategyConstraints *constraints);
DisplayError Stop();
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index c9828d8..733914a 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -872,6 +872,16 @@
return error;
}
+DisplayError HWCDisplay:: ControlPartialUpdate(bool enable, uint32_t *pending) {
+ DisplayError error = kErrorNone;
+
+ if (display_intf_) {
+ error = display_intf_->ControlPartialUpdate(enable, pending);
+ }
+
+ return error;
+}
+
LayerBufferFormat HWCDisplay::GetSDMFormat(const int32_t &source, const int flags) {
LayerBufferFormat format = kFormatInvalid;
if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 7020fce..e2b860c 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -49,6 +49,7 @@
virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
+ virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
virtual uint32_t GetLastPowerMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 058b933..c8c9da9 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -525,6 +525,10 @@
status = QdcmCMDHandler(*input_parcel, output_parcel);
break;
+ case qService::IQService::CONTROL_PARTIAL_UPDATE:
+ status = ControlPartialUpdate(input_parcel, output_parcel);
+ break;
+
default:
DLOGW("QService command = %d is not supported", command);
return -EINVAL;
@@ -572,6 +576,55 @@
return display->SetDisplayStatus(display_status);
}
+android::status_t HWCSession::ControlPartialUpdate(const android::Parcel *input_parcel,
+ android::Parcel *out) {
+ DisplayError error = kErrorNone;
+ int ret = 0;
+ uint32_t disp_id = UINT32(input_parcel->readInt32());
+ uint32_t enable = UINT32(input_parcel->readInt32());
+
+ if (disp_id != HWC_DISPLAY_PRIMARY) {
+ DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_id);
+ ret = -EINVAL;
+ out->writeInt32(ret);
+ return ret;
+ }
+
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGE("primary display object is not instantiated");
+ ret = -EINVAL;
+ out->writeInt32(ret);
+ return ret;
+ }
+
+ uint32_t pending = 0;
+ error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlPartialUpdate(enable, &pending);
+
+ if (error == kErrorNone) {
+ if (!pending) {
+ out->writeInt32(ret);
+ return ret;
+ }
+ } else if (error == kErrorNotSupported) {
+ out->writeInt32(ret);
+ return ret;
+ } else {
+ ret = -EINVAL;
+ out->writeInt32(ret);
+ return ret;
+ }
+
+ hwc_procs_->invalidate(hwc_procs_);
+
+ // Wait until partial update control is complete
+ ret = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
+ locker_.Unlock();
+
+ out->writeInt32(ret);
+
+ return ret;
+}
+
android::status_t HWCSession::SetSecondaryDisplayStatus(const android::Parcel *input_parcel) {
uint32_t display_id = UINT32(input_parcel->readInt32());
uint32_t display_status = UINT32(input_parcel->readInt32());
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index c8550d5..04aeb70 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -51,6 +51,7 @@
private:
static const int kExternalConnectionTimeoutMs = 500;
+ static const int kPartialUpdateControlTimeoutMs = 100;
// hwc methods
static int Open(const hw_module_t *module, const char* name, hw_device_t **device);
@@ -90,6 +91,7 @@
android::status_t ControlBackLight(const android::Parcel *input_parcel);
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel &in, android::Parcel *out);
+ android::status_t ControlPartialUpdate(const android::Parcel *input_parcel, android::Parcel *out);
static Locker locker_;
CoreInterface *core_intf_;
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index 98f5626..4df63d9 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -73,13 +73,6 @@
return (value == 1);
}
-bool Debug::IsPartialUpdateEnabled() {
- int value = 0;
- debug_.debug_handler_->GetProperty("sdm.partial_update", &value);
-
- return (value == 1);
-}
-
int Debug::GetMaxPipesPerMixer(DisplayType display_type) {
int value = -1;
switch (display_type) {