Merge "composer: Implement QsyncCallback API"
diff --git a/composer/Android.mk b/composer/Android.mk
index 306a7dc..cc57203 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -46,7 +46,8 @@
vendor.display.config@1.11 \
vendor.display.config@1.12 \
vendor.display.config@1.13 \
- vendor.display.config@1.14
+ vendor.display.config@1.14 \
+ vendor.display.config@1.15
LOCAL_SRC_FILES := QtiComposer.cpp QtiComposerClient.cpp service.cpp \
QtiComposerHandleImporter.cpp \
diff --git a/composer/display_null.h b/composer/display_null.h
index bcc8dbb..8c2e8bf 100644
--- a/composer/display_null.h
+++ b/composer/display_null.h
@@ -117,6 +117,7 @@
MAKE_NO_OP(SetFrameTriggerMode(FrameTriggerMode))
MAKE_NO_OP(SetPanelLuminanceAttributes(float min_lum, float max_lum))
MAKE_NO_OP(SetBLScale(uint32_t))
+ MAKE_NO_OP(GetQSyncMode(QSyncMode *))
protected:
DisplayConfigVariableInfo default_variable_config_ = {};
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index fa09cfa..7dae1a2 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -377,6 +377,10 @@
pending_power_mode_ = current_power_mode_;
}
virtual void NotifyClientStatus(bool connected) { client_connected_ = connected; }
+ virtual bool IsQsyncCallbackNeeded(bool *qsync_enabled, int32_t *refresh_rate,
+ int32_t *qsync_refresh_rate) {
+ return false;
+ }
protected:
static uint32_t throttling_refresh_rate_;
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index 439170a..f40bbf4 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -296,6 +296,44 @@
return HWC2::Error::None;
}
+void HWCDisplayBuiltIn::CacheAvrStatus() {
+ QSyncMode qsync_mode = kQSyncModeNone;
+
+ DisplayError error = display_intf_->GetQSyncMode(&qsync_mode);
+ if (error != kErrorNone) {
+ return;
+ }
+
+ bool qsync_enabled = (qsync_mode != kQSyncModeNone);
+ if (qsync_enabled_ != qsync_enabled) {
+ qsync_reconfigured_ = true;
+ qsync_enabled_ = qsync_enabled;
+ } else {
+ qsync_reconfigured_ = false;
+ }
+}
+
+bool HWCDisplayBuiltIn::IsQsyncCallbackNeeded(bool *qsync_enabled, int32_t *refresh_rate,
+ int32_t *qsync_refresh_rate) {
+ if (!qsync_reconfigured_) {
+ return false;
+ }
+
+ bool vsync_source = (callbacks_->GetVsyncSource() == id_);
+ // Qsync callback not needed if this display is not the source of vsync
+ if (!vsync_source) {
+ return false;
+ }
+
+ *qsync_enabled = qsync_enabled_;
+ uint32_t current_rate = 0;
+ display_intf_->GetRefreshRate(¤t_rate);
+ *refresh_rate = INT32(current_rate);
+ *qsync_refresh_rate = min_refresh_rate_;
+
+ return true;
+}
+
HWC2::Error HWCDisplayBuiltIn::Present(int32_t *out_retire_fence) {
auto status = HWC2::Error::None;
@@ -310,6 +348,8 @@
DLOGE("Flush failed. Error = %d", error);
}
} else {
+ CacheAvrStatus();
+
status = CommitStitchLayers();
if (status != HWC2::Error::None) {
DLOGE("Stitch failed: %d", status);
diff --git a/composer/hwc_display_builtin.h b/composer/hwc_display_builtin.h
index b1c0421..b6b92ec 100644
--- a/composer/hwc_display_builtin.h
+++ b/composer/hwc_display_builtin.h
@@ -128,6 +128,8 @@
int32_t dataspace, hwc_region_t damage);
virtual bool IsSmartPanelConfig(uint32_t config_id);
virtual int Deinit();
+ virtual bool IsQsyncCallbackNeeded(bool *qsync_enabled, int32_t *refresh_rate,
+ int32_t *qsync_refresh_rate);
private:
HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
@@ -152,6 +154,7 @@
bool InitLayerStitch();
void InitStitchTarget();
bool AllocateStitchBuffer();
+ void CacheAvrStatus();
// SyncTask methods.
void OnTask(const LayerStitchTaskCode &task_code,
@@ -184,6 +187,9 @@
GLLayerStitch* gl_layer_stitch_ = nullptr;
BufferInfo buffer_info_ = {};
DisplayConfigVariableInfo fb_config_ = {};
+
+ bool qsync_enabled_ = false;
+ bool qsync_reconfigured_ = false;
};
} // namespace sdm
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 9b71448..786e359 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -676,6 +676,19 @@
out_fences);
}
+void HWCSession::PerformQsyncCallback(hwc2_display_t display) {
+ if (qsync_callback_ == nullptr) {
+ return;
+ }
+
+ bool qsync_enabled = 0;
+ int32_t refresh_rate = 0, qsync_refresh_rate = 0;
+ if (hwc_display_[display]->IsQsyncCallbackNeeded(&qsync_enabled,
+ &refresh_rate, &qsync_refresh_rate)) {
+ qsync_callback_->onQsyncReconfigured(qsync_enabled, refresh_rate, qsync_refresh_rate);
+ }
+}
+
int32_t HWCSession::PresentDisplay(hwc2_display_t display, int32_t *out_retire_fence) {
auto status = HWC2::Error::BadDisplay;
DTRACE_SCOPED();
@@ -720,6 +733,9 @@
callbacks_.ResetRefresh(display);
}
status = hwc_display_[target_display]->Present(out_retire_fence);
+ if (status == HWC2::Error::None) {
+ PerformQsyncCallback(target_display);
+ }
}
}
}
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index 0bfa281..dabd9b9 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -20,7 +20,7 @@
#ifndef __HWC_SESSION_H__
#define __HWC_SESSION_H__
-#include <vendor/display/config/1.14/IDisplayConfig.h>
+#include <vendor/display/config/1.15/IDisplayConfig.h>
#include <vendor/qti/hardware/display/composer/2.0/IQtiComposerClient.h>
#include <core/core_interface.h>
@@ -49,8 +49,9 @@
namespace sdm {
-using vendor::display::config::V1_14::IDisplayConfig;
+using vendor::display::config::V1_15::IDisplayConfig;
using vendor::display::config::V1_10::IDisplayCWBCallback;
+using vendor::display::config::V1_15::IDisplayQsyncCallback;
using ::android::hardware::Return;
using ::android::hardware::hidl_string;
@@ -411,6 +412,7 @@
Return<int32_t> setQsyncMode(uint32_t disp_id, IDisplayConfig::QsyncMode mode) override;
Return<bool> isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) override;
Return<bool> isRotatorSupportedFormat(int hal_format, bool ubwc) override;
+ Return<int32_t> registerQsyncCallback(const sp<IDisplayQsyncCallback> &callback) override;
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
@@ -460,6 +462,7 @@
void HandlePendingRefresh();
void NotifyClientStatus(bool connected);
int32_t GetVirtualDisplayId();
+ void PerformQsyncCallback(hwc2_display_t display);
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[HWCCallbacks::kNumDisplays] = {nullptr};
@@ -501,6 +504,7 @@
float set_min_lum_ = -1.0;
std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
CWB cwb_;
+ android::sp<IDisplayQsyncCallback> qsync_callback_ = nullptr;
bool async_powermode_ = false;
bool async_vds_creation_ = false;
bool power_state_transition_[HWCCallbacks::kNumDisplays] = {};
diff --git a/composer/hwc_session_services.cpp b/composer/hwc_session_services.cpp
index a9c340a..f538760 100644
--- a/composer/hwc_session_services.cpp
+++ b/composer/hwc_session_services.cpp
@@ -1117,6 +1117,16 @@
return 0;
}
+Return<int32_t> HWCSession::registerQsyncCallback(const sp<IDisplayQsyncCallback> &callback) {
+ if (qsync_callback_ != nullptr) {
+ DLOGE("Qsync callback already registered, rejecting new request");
+ return -1;
+ }
+ qsync_callback_ = callback;
+
+ return 0;
+}
+
Return<bool> HWCSession::isAsyncVDSCreationSupported() {
if (!async_vds_creation_) {
return false;
diff --git a/composer/vendor.qti.hardware.display.composer-service.xml b/composer/vendor.qti.hardware.display.composer-service.xml
index 0d4ef00..4c8f5cd 100644
--- a/composer/vendor.qti.hardware.display.composer-service.xml
+++ b/composer/vendor.qti.hardware.display.composer-service.xml
@@ -48,7 +48,7 @@
<hal format="hidl">
<name>vendor.display.config</name>
<transport>hwbinder</transport>
- <version>1.14</version>
+ <version>1.15</version>
<interface>
<name>IDisplayConfig</name>
<instance>default</instance>
diff --git a/config/display-product.mk b/config/display-product.mk
index 761272a..08cf9a2 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -30,6 +30,7 @@
vendor.display.config@1.12.vendor \
vendor.display.config@1.13.vendor \
vendor.display.config@1.14.vendor \
+ vendor.display.config@1.15.vendor \
vendor.qti.hardware.display.mapper@2.0.vendor \
vendor.qti.hardware.display.mapper@3.0.vendor \
modetest
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index db9d961..ed2aedf 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -916,6 +916,12 @@
*/
virtual bool GameEnhanceSupported() = 0;
+ /*! @brief Method to get the current qsync mode used.
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetQSyncMode(QSyncMode *qsync_mode) = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 77a2539..6b5ceeb 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -161,6 +161,7 @@
virtual DisplayError SetBLScale(uint32_t level) { return kErrorNotSupported; }
virtual bool CheckResourceState();
virtual bool GameEnhanceSupported();
+ virtual DisplayError GetQSyncMode(QSyncMode *qsync_mode) { return kErrorNotSupported; }
protected:
const char *kBt2020Pq = "bt2020_pq";
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 7c0fd4e..8d0e1bd 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -784,6 +784,11 @@
return kErrorNone;
}
+DisplayError DisplayBuiltIn::GetQSyncMode(QSyncMode *qsync_mode) {
+ *qsync_mode = qsync_mode_;
+ return kErrorNone;
+}
+
DisplayError DisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!hw_panel_info_.qsync_support || qsync_mode_ == qsync_mode || first_cycle_) {
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index ee55bb4..233f6a0 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -85,6 +85,7 @@
virtual DisplayError GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates);
virtual DisplayError SetFrameTriggerMode(FrameTriggerMode mode);
virtual DisplayError SetBLScale(uint32_t level);
+ virtual DisplayError GetQSyncMode(QSyncMode *qsync_mode);
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);