composer: few changes for refresh rate switching
- getDisplayConfigs is required to remain backward compatible with
composer@2.3 and older versions. To keep it that way a new config
attribute was added to group similar configs.
- getSupportedDisplayVsyncPeriods was removed as the vsync period
can be obtained by getDisplayAttribute for each individual config.
- renamed setActiveConfigAndVsyncPeriod -> setActiveConfigWithConstraints
to better describe what this function does.
- added VsyncPeriodChangeTimeline and onVsyncPeriodTimingChanged
With these changes composer is expected to return all possible
configurations when getDisplayConfigs (similar to older composer versions).
The client knows whether a seamless vsync period is possible or not by
the config groups.
Test: rev up composer to 2.4 and test refresh rate switching
Bug: 141329414
Change-Id: I1b4525f7e00b62cdaf260274abe4a6a5962ed1ab
diff --git a/graphics/composer/2.4/IComposerCallback.hal b/graphics/composer/2.4/IComposerCallback.hal
index 5c3f8bd..fea24a1 100644
--- a/graphics/composer/2.4/IComposerCallback.hal
+++ b/graphics/composer/2.4/IComposerCallback.hal
@@ -32,4 +32,14 @@
* is expected to be called vsyncPeriodNanos nanoseconds after this call.
*/
oneway onVsync_2_4(Display display, int64_t timestamp, VsyncPeriodNanos vsyncPeriodNanos);
+
+ /**
+ * Notifies the client that the previously reported timing for vsync period change has been
+ * updated. This may occur if the composer missed the deadline for changing the vsync period
+ * or the client submitted a refresh frame too late.
+ *
+ * @param display is the display which vsync period change is in progress
+ * @param updatedTimeline is the new timeline for the vsync period change.
+ */
+ oneway onVsyncPeriodTimingChanged(Display display, VsyncPeriodChangeTimeline updatedTimeline);
};
diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index c2102d5..f23536c 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -20,10 +20,23 @@
import @2.1::Config;
import @2.1::Display;
import @2.1::Error;
+import @2.1::IComposerClient;
import @2.3::IComposerClient;
interface IComposerClient extends @2.3::IComposerClient {
/**
+ * Display attributes queryable through getDisplayAttribute_2_4.
+ */
+ enum Attribute : @2.1::IComposerClient.Attribute {
+ /**
+ * The configuration group ID (as int32_t) this config is associated to.
+ * Switching between configurations within the same group may be done seamlessly
+ * in some conditions via setActiveConfigWithConstraints.
+ */
+ CONFIG_GROUP = 7,
+ };
+
+ /**
* Required capabilities which are supported by the display. The
* particular set of supported capabilities for a given display may be
* retrieved using getDisplayCapabilities.
@@ -60,6 +73,7 @@
* (i.e., the vsync period must not change before this time).
*/
int64_t desiredTimeNanos;
+
/**
* If true, requires that the vsync period change must happen seamlessly without
* a noticeable visual artifact.
@@ -74,7 +88,6 @@
*
* @param callback is the IComposerCallback object.
*/
- @entry
registerCallback_2_4(IComposerCallback callback);
/**
@@ -99,25 +112,29 @@
getDisplayConnectionType(Display display) generates (Error error, DisplayConnectionType type);
/**
- * Provides a list of the vsync periods supported by the display in the given configuration
+ * Returns a display attribute value for a particular display
+ * configuration.
*
- * @param display is the display for which the vsync periods are queried.
- * @param config is the display configuration for which the vsync periods are queried.
- *
+ * @param display is the display to query.
+ * @param config is the display configuration for which to return
+ * attribute values.
* @return error is NONE upon success. Otherwise,
- * BAD_DISPLAY when an invalid display handle was passed in.
- * BAD_CONFIG when an invalid config handle was passed in.
- * @return supportedVsyncPeriods is a list of supported vsync periods.
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * BAD_CONFIG when config does not name a valid configuration for
+ * this display.
+ * BAD_PARAMETER when attribute is unrecognized.
+ * UNSUPPORTED when attribute cannot be queried for the config.
+ * @return value is the value of the attribute.
*/
- getSupportedDisplayVsyncPeriods(Display display, Config config)
- generates (Error error, vec<VsyncPeriodNanos> supportedVsyncPeriods);
+ getDisplayAttribute_2_4(Display display, Config config, Attribute attribute)
+ generates (Error error, int32_t value);
/**
* Retrieves which vsync period the display is currently using.
*
* If no display configuration is currently active, this function must
* return BAD_CONFIG. If the vsync period is about to change due to a
- * setActiveConfigAndVsyncPeriod call, this function must return the current vsync period
+ * setActiveConfigWithConstraints call, this function must return the current vsync period
* until the change takes place.
*
* @param display is the display for which the vsync period is queried.
@@ -131,7 +148,8 @@
/**
* Sets the active configuration and the refresh rate for this display.
- * If the config is the same as the current config, only the vsync period shall change.
+ * If the new config shares the same config group as the current config,
+ * only the vsync period shall change.
* Upon returning, the given display configuration, except vsync period, must be active and
* remain so until either this function is called again or the display is disconnected.
* When the display starts to refresh at the new vsync period, onVsync_2_4 callback must be
@@ -139,21 +157,19 @@
*
* @param display is the display for which the active config is set.
* @param config is the new display configuration.
- * @param vsyncPeriodNanos is the new display vsync period.
* @param vsyncPeriodChangeConstraints are the constraints required for changing vsync period.
*
* @return error is NONE upon success. Otherwise,
* BAD_DISPLAY when an invalid display handle was passed in.
* BAD_CONFIG when the configuration handle passed in is not valid
* for this display.
- * BAD_VSYNC_PERIOD when an invalid vsync period is passed in.
+ * SEAMLESS_NOT_ALLOWED when seamlessRequired was true but config provided doesn't
+ * share the same config group as the current config.
* SEAMLESS_NOT_POSSIBLE when seamlessRequired was true but the display cannot achieve
* the vsync period change without a noticeable visual artifact.
- * @return newVsyncAppliedTime is the time in CLOCK_MONOTONIC when the new display will start to
- * refresh at the new vsync period.
+ * @return timeline is the timeline for the vsync period change.
*/
- setActiveConfigAndVsyncPeriod(Display display, Config config,
- VsyncPeriodNanos vsyncPeriodNanos,
+ setActiveConfigWithConstraints(Display display, Config config,
VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints)
- generates (Error error, int64_t newVsyncAppliedTime);
+ generates (Error error, VsyncPeriodChangeTimeline timeline);
};
diff --git a/graphics/composer/2.4/types.hal b/graphics/composer/2.4/types.hal
index b45d7a6..065f024 100644
--- a/graphics/composer/2.4/types.hal
+++ b/graphics/composer/2.4/types.hal
@@ -20,13 +20,36 @@
enum Error : @2.1::Error {
/**
- * Invalid vsync period
+ * Seamless cannot be required for configurations that don't share a config group
*/
- BAD_VSYNC_PERIOD = 9,
+ SEAMLESS_NOT_ALLOWED = 9,
/**
* Seamless requirements cannot be met
*/
SEAMLESS_NOT_POSSIBLE = 10,
};
+/**
+ * Timing for a vsync period change.
+ */
+struct VsyncPeriodChangeTimeline {
+ /**
+ * The time in CLOCK_MONOTONIC when the new display will start to refresh at
+ * the new vsync period.
+ */
+ int64_t newVsyncAppliedTimeNanos;
+
+ /**
+ * Set to true if the client is required to send a frame to be displayed before
+ * the change can take place.
+ */
+ bool refreshRequired;
+
+ /**
+ * The time in CLOCK_MONOTONIC when the client is expected to send the new frame.
+ * Should be ignored if refreshRequired is false.
+ */
+ int64_t refreshTimeNanos;
+};
+
typedef uint32_t VsyncPeriodNanos;
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index ddf209b..4160ed9 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -76,6 +76,13 @@
ALOGE_IF(!ret.isOk(), "failed to send onVsync_2_4: %s", ret.description().c_str());
}
+ void onVsyncPeriodTimingChanged(Display display,
+ const VsyncPeriodChangeTimeline& updatedTimeline) override {
+ auto ret = mCallback->onVsyncPeriodTimingChanged(display, updatedTimeline);
+ ALOGE_IF(!ret.isOk(), "failed to send onVsyncPeriodTimingChanged: %s",
+ ret.description().c_str());
+ }
+
protected:
const sp<IComposerCallback> mCallback;
V2_1::hal::ComposerResources* const mResources;
@@ -104,13 +111,12 @@
return Void();
}
- Return<void> getSupportedDisplayVsyncPeriods(
- Display display, Config config,
- IComposerClient::getSupportedDisplayVsyncPeriods_cb hidl_cb) override {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- Error error =
- mHal->getSupportedDisplayVsyncPeriods(display, config, &supportedVsyncPeriods);
- hidl_cb(error, supportedVsyncPeriods);
+ Return<void> getDisplayAttribute_2_4(
+ Display display, Config config, IComposerClient::Attribute attribute,
+ IComposerClient::getDisplayAttribute_2_4_cb hidl_cb) override {
+ int32_t value = 0;
+ Error error = mHal->getDisplayAttribute_2_4(display, config, attribute, &value);
+ hidl_cb(error, value);
return Void();
}
@@ -122,15 +128,14 @@
return Void();
}
- Return<void> setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Return<void> setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- IComposerClient::setActiveConfigAndVsyncPeriod_cb hidl_cb) override {
- int64_t newVsyncAppliedTime = 0;
- Error error = mHal->setActiveConfigAndVsyncPeriod(display, config, vsyncPeriodNanos,
- vsyncPeriodChangeConstraints,
- &newVsyncAppliedTime);
- hidl_cb(error, newVsyncAppliedTime);
+ IComposerClient::setActiveConfigWithConstraints_cb hidl_cb) override {
+ VsyncPeriodChangeTimeline timeline = {};
+ Error error = mHal->setActiveConfigWithConstraints(display, config,
+ vsyncPeriodChangeConstraints, &timeline);
+ hidl_cb(error, timeline);
return Void();
}
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index 0739f62..89dbe66 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -47,6 +47,8 @@
virtual void onVsync(Display display, int64_t timestamp) = 0;
virtual void onVsync_2_4(Display display, int64_t timestamp,
VsyncPeriodNanos vsyncPeriodNanos) = 0;
+ virtual void onVsyncPeriodTimingChanged(Display display,
+ const VsyncPeriodChangeTimeline& timeline) = 0;
};
virtual void registerEventCallback_2_4(EventCallback_2_4* callback) = 0;
@@ -57,13 +59,14 @@
Display display, std::vector<IComposerClient::DisplayCapability>* outCapabilities) = 0;
virtual Error getDisplayConnectionType(Display display,
IComposerClient::DisplayConnectionType* outType) = 0;
- virtual Error getSupportedDisplayVsyncPeriods(
- Display display, Config config, std::vector<VsyncPeriodNanos>* outVsyncPeriod) = 0;
+ virtual Error getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute,
+ int32_t* outValue) = 0;
virtual Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) = 0;
- virtual Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ virtual Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) = 0;
+ VsyncPeriodChangeTimeline* timeline) = 0;
};
} // namespace hal
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index 3420c8c..d59d0d5 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -25,6 +25,7 @@
#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
#include <composer-hal/2.4/ComposerHal.h>
#include <composer-passthrough/2.3/HwcHal.h>
+#include <hardware/hwcomposer_defs.h>
namespace android {
namespace hardware {
@@ -51,14 +52,22 @@
void registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4* callback) override {
mEventCallback_2_4 = callback;
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
- reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
- reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
- reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
- reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_HOTPLUG, this,
+ reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_REFRESH, this,
+ reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
+
+ BaseType2_1::mDispatch.registerCallback(
+ mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
+ reinterpret_cast<hwc2_function_pointer_t>(vsyncPeriodTimingChangedHook));
}
void unregisterEventCallback_2_4() override {
@@ -69,10 +78,12 @@
// - will never be called afterward
//
// which is likely incorrect
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr);
- mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
+ BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED,
+ this, nullptr);
mEventCallback_2_4 = nullptr;
}
@@ -106,26 +117,16 @@
return static_cast<Error>(error);
}
- Error getSupportedDisplayVsyncPeriods(Display display, Config config,
- std::vector<VsyncPeriodNanos>* outVsyncPeriods) override {
- if (!mDispatch.getSupportedDisplayVsyncPeriods) {
- return Error::UNSUPPORTED;
+ Error getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute,
+ int32_t* outValue) override {
+ int32_t err = BaseType2_1::mDispatch.getDisplayAttribute(
+ mDevice, display, config, static_cast<int32_t>(attribute), outValue);
+ if (err != HWC2_ERROR_NONE && *outValue == -1) {
+ // Convert the error from hwcomposer2 to IComposerClient definition
+ return Error::BAD_PARAMETER;
}
-
- uint32_t count = 0;
- int32_t error = mDispatch.getSupportedDisplayVsyncPeriods(mDevice, display, config, &count,
- nullptr);
- if (error != HWC2_ERROR_NONE) {
- return static_cast<Error>(error);
- }
- outVsyncPeriods->resize(count);
- error = mDispatch.getSupportedDisplayVsyncPeriods(mDevice, display, config, &count,
- outVsyncPeriods->data());
- if (error != HWC2_ERROR_NONE) {
- *outVsyncPeriods = std::vector<VsyncPeriodNanos>();
- return static_cast<Error>(error);
- }
- return Error::NONE;
+ return static_cast<Error>(err);
}
Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) override {
@@ -140,11 +141,11 @@
return Error::NONE;
}
- Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) override {
- if (!mDispatch.setActiveConfigAndVsyncPeriod) {
+ VsyncPeriodChangeTimeline* timeline) override {
+ if (!mDispatch.setActiveConfigWithConstraints) {
return Error::UNSUPPORTED;
}
@@ -154,12 +155,15 @@
vsync_period_change_constraints.seamlessRequired =
vsyncPeriodChangeConstraints.seamlessRequired;
- int32_t error = mDispatch.setActiveConfigAndVsyncPeriod(
- mDevice, display, config, vsyncPeriodNanos, &vsync_period_change_constraints,
- outNewVsyncAppliedTime);
+ hwc_vsync_period_change_timeline_t out_timeline;
+ int32_t error = mDispatch.setActiveConfigWithConstraints(
+ mDevice, display, config, &vsync_period_change_constraints, &out_timeline);
if (error != HWC2_ERROR_NONE) {
return static_cast<Error>(error);
}
+ timeline->newVsyncAppliedTimeNanos = out_timeline.newVsyncAppliedTimeNanos;
+ timeline->refreshRequired = out_timeline.refreshRequired;
+ timeline->refreshTimeNanos = out_timeline.refreshTimeNanos;
return Error::NONE;
}
@@ -171,13 +175,10 @@
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE,
&mDispatch.getDisplayConnectionType);
- this->initOptionalDispatch(HWC2_FUNCTION_REGISTER_CALLBACK, &mDispatch.registerCallback);
- this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_DISPLAY_VSYNC_PERIODS,
- &mDispatch.getSupportedDisplayVsyncPeriods);
this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,
&mDispatch.getDisplayVsyncPeriod);
- this->initOptionalDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_AND_VSYNC_PERIOD,
- &mDispatch.setActiveConfigAndVsyncPeriod);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,
+ &mDispatch.setActiveConfigWithConstraints);
return true;
}
@@ -205,13 +206,22 @@
hal->mEventCallback_2_4->onVsync_2_4(display, timestamp, vsyncPeriodNanos);
}
+ static void vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData,
+ hwc2_display_t display,
+ hwc_vsync_period_change_timeline_t* updated_timeline) {
+ auto hal = static_cast<HwcHalImpl*>(callbackData);
+ VsyncPeriodChangeTimeline timeline;
+ timeline.newVsyncAppliedTimeNanos = updated_timeline->newVsyncAppliedTimeNanos;
+ timeline.refreshRequired = updated_timeline->refreshRequired;
+ timeline.refreshTimeNanos = updated_timeline->refreshTimeNanos;
+ hal->mEventCallback_2_4->onVsyncPeriodTimingChanged(display, timeline);
+ }
+
private:
struct {
HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType;
- HWC2_PFN_REGISTER_CALLBACK registerCallback;
- HWC2_PFN_GET_SUPPORTED_DISPLAY_VSYNC_PERIODS getSupportedDisplayVsyncPeriods;
HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod;
- HWC2_PFN_SET_ACTIVE_CONFIG_AND_VSYNC_PERIOD setActiveConfigAndVsyncPeriod;
+ HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints;
} mDispatch = {};
hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr;
diff --git a/graphics/composer/2.4/utils/vts/ComposerVts.cpp b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
index b02a59a..35ac23f 100644
--- a/graphics/composer/2.4/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
@@ -70,15 +70,18 @@
return error;
}
-Error ComposerClient::getSupportedDisplayVsyncPeriods(
- Display display, Config config, std::vector<VsyncPeriodNanos>* outSupportedVsyncPeriods) {
- Error error = Error::NONE;
- mClient->getSupportedDisplayVsyncPeriods(
- display, config, [&](const auto& tmpError, const auto& tmpSupportedVsyncPeriods) {
- error = tmpError;
- *outSupportedVsyncPeriods = tmpSupportedVsyncPeriods;
+int32_t ComposerClient::getDisplayAttribute_2_4(
+ android::hardware::graphics::composer::V2_1::Display display,
+ android::hardware::graphics::composer::V2_1::Config config,
+ IComposerClient::Attribute attribute) {
+ int32_t value = 0;
+ mClient->getDisplayAttribute_2_4(
+ display, config, attribute, [&](const auto& tmpError, const auto& tmpValue) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get display attribute";
+ value = tmpValue;
});
- return error;
+
+ return value;
}
Error ComposerClient::getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) {
@@ -90,17 +93,16 @@
return error;
}
-Error ComposerClient::setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+Error ComposerClient::setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime) {
+ VsyncPeriodChangeTimeline* timeline) {
Error error = Error::NONE;
- mClient->setActiveConfigAndVsyncPeriod(
- display, config, vsyncPeriodNanos, vsyncPeriodChangeConstraints,
- [&](const auto& tmpError, const auto& tmpNewVsyncAppliedTime) {
- error = tmpError;
- *outNewVsyncAppliedTime = tmpNewVsyncAppliedTime;
- });
+ mClient->setActiveConfigWithConstraints(display, config, vsyncPeriodChangeConstraints,
+ [&](const auto& tmpError, const auto& tmpTimeline) {
+ error = tmpError;
+ *timeline = tmpTimeline;
+ });
return error;
}
diff --git a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
index 5db3e16..83e74ed 100644
--- a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
+++ b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
@@ -74,15 +74,15 @@
Error getDisplayConnectionType(Display display,
IComposerClient::DisplayConnectionType* outType);
- Error getSupportedDisplayVsyncPeriods(Display display, Config config,
- std::vector<VsyncPeriodNanos>* outSupportedVsyncPeriods);
+ int32_t getDisplayAttribute_2_4(Display display, Config config,
+ IComposerClient::Attribute attribute);
Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriods);
- Error setActiveConfigAndVsyncPeriod(
- Display display, Config config, VsyncPeriodNanos vsyncPeriodNanos,
+ Error setActiveConfigWithConstraints(
+ Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
- int64_t* outNewVsyncAppliedTime);
+ VsyncPeriodChangeTimeline* timeline);
private:
const sp<IComposerClient> mClient;
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 2c87666..f038f55 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -114,7 +114,7 @@
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
- void Test_setActiveConfigAndVsyncPeriod(
+ void Test_setActiveConfigWithConstraints(
const IComposerClient::VsyncPeriodChangeConstraints& constraints);
std::unique_ptr<Composer> mComposer;
@@ -194,42 +194,28 @@
}
}
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadDisplay) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->getSupportedDisplayVsyncPeriods(
- mInvalidDisplayId, Config(0), &supportedVsyncPeriods));
-}
+TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) {
+ std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+ for (auto config : configs) {
+ const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
+ IComposerClient::Attribute::WIDTH,
+ IComposerClient::Attribute::HEIGHT,
+ IComposerClient::Attribute::VSYNC_PERIOD,
+ IComposerClient::Attribute::CONFIG_GROUP,
+ }};
+ for (auto attribute : requiredAttributes) {
+ mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, config, attribute);
+ }
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadConfig) {
- for (Display display : mComposerCallback->getDisplays()) {
- Config invalidConfigId = GetInvalidConfigId(display);
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
- EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, invalidConfigId, &supportedVsyncPeriods));
- }
-}
-
-TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods) {
- for (Display display : mComposerCallback->getDisplays()) {
- for (Config config : mComposerClient->getDisplayConfigs(display)) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
-
- // Get the default vsync period from the config
- VsyncPeriodNanos defaultVsyncPeiord = mComposerClient->getDisplayAttribute(
- display, config, IComposerClient::Attribute::VSYNC_PERIOD);
- // Get all supported vsync periods for this config
- EXPECT_EQ(Error::NONE, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, config, &supportedVsyncPeriods));
- // Default vsync period must be present in the list
- EXPECT_NE(std::find(supportedVsyncPeriods.begin(), supportedVsyncPeriods.end(),
- defaultVsyncPeiord),
- supportedVsyncPeriods.end());
-
- // Each vsync period must be unique
- std::unordered_set<VsyncPeriodNanos> vsyncPeriodSet;
- for (VsyncPeriodNanos vsyncPeriodNanos : supportedVsyncPeriods) {
- EXPECT_TRUE(vsyncPeriodSet.insert(vsyncPeriodNanos).second);
- }
+ const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
+ IComposerClient::Attribute::DPI_X,
+ IComposerClient::Attribute::DPI_Y,
+ }};
+ for (auto attribute : optionalAttributes) {
+ mComposerClient->getRaw()->getDisplayAttribute_2_4(
+ mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) {
+ EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
+ });
}
}
}
@@ -240,20 +226,40 @@
mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadDisplay) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
+ for (Display display : mComposerCallback->getDisplays()) {
+ for (Config config : mComposerClient->getDisplayConfigs(display)) {
+ mComposerClient->setActiveConfig(display, config);
+
+ VsyncPeriodNanos vsyncPeriodNanos;
+ VsyncPeriodNanos expectedvsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ int retryCount = 100;
+ do {
+ std::this_thread::sleep_for(10ms);
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ --retryCount;
+ } while (retryCount > 0);
+
+ EXPECT_EQ(vsyncPeriodNanos, expectedvsyncPeriodNanos);
+ }
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadDisplay) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigAndVsyncPeriod(
- mInvalidDisplayId, Config(0), VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
+ EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigWithConstraints(
+ mInvalidDisplayId, Config(0), constraints, &timeline));
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadConfig) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
@@ -261,93 +267,114 @@
for (Display display : mComposerCallback->getDisplays()) {
Config invalidConfigId = GetInvalidConfigId(display);
- EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, invalidConfigId, VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
+ EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints(
+ display, invalidConfigId, constraints, &timeline));
}
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadVsyncPeriod) {
- int64_t newVsyncAppliedTime;
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+ VsyncPeriodChangeTimeline timeline;
IComposerClient::VsyncPeriodChangeConstraints constraints;
- constraints.seamlessRequired = false;
+ constraints.seamlessRequired = true;
constraints.desiredTimeNanos = systemTime();
for (Display display : mComposerCallback->getDisplays()) {
for (Config config : mComposerClient->getDisplayConfigs(display)) {
- EXPECT_EQ(Error::BAD_VSYNC_PERIOD, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, config, VsyncPeriodNanos(0),
- constraints, &newVsyncAppliedTime));
- }
- }
-}
+ int32_t configGroup = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
-void GraphicsComposerHidlTest::Test_setActiveConfigAndVsyncPeriod(
- const IComposerClient::VsyncPeriodChangeConstraints& constraints) {
- int64_t newVsyncAppliedTime;
-
- for (Display display : mComposerCallback->getDisplays()) {
- for (Config config : mComposerClient->getDisplayConfigs(display)) {
- std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
-
- EXPECT_EQ(Error::NONE, mComposerClient->getSupportedDisplayVsyncPeriods(
- display, config, &supportedVsyncPeriods));
- for (VsyncPeriodNanos newVsyncPeriod : supportedVsyncPeriods) {
- VsyncPeriodNanos vsyncPeriodNanos;
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
-
- if (vsyncPeriodNanos == newVsyncPeriod) {
- continue;
+ for (Config otherConfig : mComposerClient->getDisplayConfigs(display)) {
+ int32_t otherConfigGroup = mComposerClient->getDisplayAttribute_2_4(
+ display, otherConfig,
+ IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
+ if (configGroup != otherConfigGroup) {
+ mComposerClient->setActiveConfig(display, config);
+ EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
+ mComposerClient->setActiveConfigWithConstraints(
+ display, otherConfig, constraints, &timeline));
}
-
- EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigAndVsyncPeriod(
- display, config, newVsyncPeriod, constraints,
- &newVsyncAppliedTime));
-
- EXPECT_TRUE(newVsyncAppliedTime >= constraints.desiredTimeNanos);
-
- // Refresh rate should change within a reasonable time
- constexpr nsecs_t kReasonableTimeForChange = 1'000'000'000; // 1 second
- EXPECT_TRUE(newVsyncAppliedTime - constraints.desiredTimeNanos <=
- kReasonableTimeForChange);
-
- while (systemTime() <= newVsyncAppliedTime) {
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
- if (systemTime() <= constraints.desiredTimeNanos) {
- EXPECT_NE(vsyncPeriodNanos, newVsyncPeriod);
- }
-
- if (vsyncPeriodNanos == newVsyncPeriod) {
- break;
- }
- std::this_thread::sleep_for(10ms);
- }
- EXPECT_EQ(Error::NONE,
- mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
- EXPECT_EQ(vsyncPeriodNanos, newVsyncPeriod);
}
}
}
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod) {
+void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(
+ const IComposerClient::VsyncPeriodChangeConstraints& constraints) {
+ VsyncPeriodChangeTimeline timeline = {};
+
+ for (Display display : mComposerCallback->getDisplays()) {
+ for (Config config : mComposerClient->getDisplayConfigs(display)) {
+ mComposerClient->setActiveConfig(display, config);
+
+ int32_t configVsyncPeriod = mComposerClient->getDisplayAttribute_2_4(
+ display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+ for (Config otherConfig : mComposerClient->getDisplayConfigs(display)) {
+ if (config == otherConfig) {
+ continue;
+ }
+
+ int32_t otherVsyncPeriod = mComposerClient->getDisplayAttribute_2_4(
+ display, otherConfig,
+ IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
+
+ if (configVsyncPeriod == otherVsyncPeriod) {
+ continue;
+ }
+
+ EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
+ display, otherConfig, constraints, &timeline));
+
+ if (timeline.refreshRequired) {
+ // TODO(b/143775556): handle this case;
+ continue;
+ }
+
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+
+ // Refresh rate should change within a reasonable time
+ constexpr nsecs_t kReasonableTimeForChange = 1'000'000'000; // 1 second
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+ kReasonableTimeForChange);
+
+ while (systemTime() <= timeline.newVsyncAppliedTimeNanos) {
+ VsyncPeriodNanos vsyncPeriodNanos;
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+
+ if (systemTime() <= constraints.desiredTimeNanos) {
+ EXPECT_NE(vsyncPeriodNanos, otherVsyncPeriod);
+ }
+
+ if (vsyncPeriodNanos == otherVsyncPeriod) {
+ break;
+ }
+ std::this_thread::sleep_for(10ms);
+ }
+ VsyncPeriodNanos vsyncPeriodNanos;
+ EXPECT_EQ(Error::NONE,
+ mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+ EXPECT_EQ(vsyncPeriodNanos, otherVsyncPeriod);
+ }
+ }
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) {
IComposerClient::VsyncPeriodChangeConstraints constraints;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime();
- Test_setActiveConfigAndVsyncPeriod(constraints);
+ Test_setActiveConfigWithConstraints(constraints);
}
-TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_delayed) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_delayed) {
IComposerClient::VsyncPeriodChangeConstraints constraints;
constexpr auto kDelayForChange = 300ms;
constraints.seamlessRequired = false;
constraints.desiredTimeNanos = systemTime() + kDelayForChange.count();
- Test_setActiveConfigAndVsyncPeriod(constraints);
+ Test_setActiveConfigWithConstraints(constraints);
}
INSTANTIATE_TEST_SUITE_P(