Loading graphics/composer/aidl/vts/GraphicsComposerCallback.cpp +30 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ void GraphicsComposerCallback::setVsyncAllowed(bool allowed) { mVsyncAllowed = allowed; } void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) { std::scoped_lock lock(mMutex); mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed; } std::vector<int64_t> GraphicsComposerCallback::getDisplays() const { std::scoped_lock lock(mMutex); return mDisplays; Loading Loading @@ -79,6 +84,21 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() { return ret; } std::vector<RefreshRateChangedDebugData> GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() { std::scoped_lock lock(mMutex); std::vector<RefreshRateChangedDebugData> ret; ret.swap(mRefreshRateChangedDebugData); return ret; } int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const { std::scoped_lock lock(mMutex); return mInvalidRefreshRateDebugEnabledCallbackCount; } ::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) { std::scoped_lock lock(mMutex); Loading Loading @@ -125,9 +145,16 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() { } ::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug( const RefreshRateChangedDebugData&) { // TODO(b/202734676) Add implementation for Vts tests return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); const RefreshRateChangedDebugData& data) { std::scoped_lock lock(mMutex); const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display); if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) { mRefreshRateChangedDebugData.push_back(data); } else { mInvalidRefreshRateDebugEnabledCallbackCount++; } return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged( Loading graphics/composer/aidl/vts/GraphicsComposerCallback.h +11 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ class GraphicsComposerCallback : public BnComposerCallback { public: void setVsyncAllowed(bool allowed); void setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed); std::vector<int64_t> getDisplays() const; int32_t getInvalidHotplugCount() const; Loading @@ -44,6 +46,10 @@ class GraphicsComposerCallback : public BnComposerCallback { std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline(); std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData(); int32_t getInvalidRefreshRateDebugEnabledCallbackCount() const; private: virtual ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override; virtual ::ndk::ScopedAStatus onRefresh(int64_t in_display) override; Loading @@ -63,9 +69,13 @@ class GraphicsComposerCallback : public BnComposerCallback { std::vector<int64_t> mDisplays GUARDED_BY(mMutex); // true only when vsync is enabled bool mVsyncAllowed GUARDED_BY(mMutex) = true; // true only when RefreshRateChangedCallbackDebugEnabled is set to true. bool mRefreshRateChangedDebugDataEnabledCallbackAllowed GUARDED_BY(mMutex) = false; std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex); std::vector<RefreshRateChangedDebugData> mRefreshRateChangedDebugData GUARDED_BY(mMutex); int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0; int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0; Loading @@ -75,6 +85,7 @@ class GraphicsComposerCallback : public BnComposerCallback { int32_t mInvalidVsyncCount GUARDED_BY(mMutex) = 0; int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0; int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0; int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0; }; } // namespace aidl::android::hardware::graphics::composer3::vts graphics/composer/aidl/vts/VtsComposerClient.cpp +31 −4 Original line number Diff line number Diff line Loading @@ -119,6 +119,24 @@ ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t return updateDisplayProperties(vtsDisplay, config); } ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) { const auto displayId = vtsDisplay->getDisplayId(); auto [activeStatus, activeConfig] = getActiveConfig(displayId); EXPECT_TRUE(activeStatus.isOk()); auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig); auto peakConfig = activeConfig; const auto displayConfigs = vtsDisplay->getDisplayConfigs(); for (const auto [config, displayConfig] : displayConfigs) { if (displayConfig.configGroup == peakDisplayConfig.configGroup && displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) { peakDisplayConfig = displayConfig; peakConfig = config; } } return setActiveConfig(vtsDisplay, peakConfig); } std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute( int64_t display, int32_t config, DisplayAttribute displayAttribute) { int32_t outDisplayAttribute; Loading Loading @@ -375,10 +393,15 @@ int64_t VtsComposerClient::getVsyncIdleTime() { return mComposerCallback->getVsyncIdleTime(); } ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled( int64_t /* display */, bool /* enabled */) { // TODO(b/202734676) Add implementation for VTS tests return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled) { mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled); return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled); } std::vector<RefreshRateChangedDebugData> VtsComposerClient::takeListOfRefreshRateChangedDebugData() { return mComposerCallback->takeListOfRefreshRateChangedDebugData(); } int64_t VtsComposerClient::getInvalidDisplayId() { Loading Loading @@ -545,6 +568,10 @@ bool VtsComposerClient::verifyComposerCallbackParams() { ALOGE("Invalid seamless possible count"); isValid = false; } if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) { ALOGE("Invalid refresh rate debug enabled callback count"); isValid = false; } } return isValid; } Loading graphics/composer/aidl/vts/VtsComposerClient.h +11 −6 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ class VtsComposerClient { ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay); std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config, DisplayAttribute displayAttribute); Loading Loading @@ -183,6 +185,10 @@ class VtsComposerClient { std::pair<ScopedAStatus, OverlayProperties> getOverlaySupport(); ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled); std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData(); private: ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config); Loading @@ -197,9 +203,6 @@ class VtsComposerClient { bool verifyComposerCallbackParams(); ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t /* display */, bool /* enabled */); // Keep track of displays and layers. When a test fails/ends, // the VtsComposerClient::tearDown should be called from the // test tearDown to clean up the resources for the test. Loading Loading @@ -245,15 +248,17 @@ class VtsDisplay { }; void addDisplayConfig(int32_t config, DisplayConfig displayConfig) { displayConfigs.insert({config, displayConfig}); mDisplayConfigs.insert({config, displayConfig}); } DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; } DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; } std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; } private: int64_t mDisplayId; int32_t mDisplayWidth; int32_t mDisplayHeight; std::unordered_map<int32_t, DisplayConfig> displayConfigs; std::unordered_map<int32_t, DisplayConfig> mDisplayConfigs; }; } // namespace aidl::android::hardware::graphics::composer3::vts graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp +196 −2 Original line number Diff line number Diff line Loading @@ -1217,6 +1217,14 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { } } bool checkIfCallbackRefreshRateChangedDebugEnabledReceived( std::function<bool(RefreshRateChangedDebugData)> filter) { const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData(); return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) { return filter(refreshRateChangedDebugData); }); } sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) { return sp<GraphicBuffer>::make( static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()), Loading Loading @@ -1316,7 +1324,7 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { return vsyncPeriod; } int64_t createOnScreenLayer() { int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) { const auto& [status, layer] = mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount); EXPECT_TRUE(status.isOk()); Loading @@ -1324,12 +1332,25 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { getPrimaryDisplay().getDisplayHeight()}; FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(), (float)getPrimaryDisplay().getDisplayHeight()}; configureLayer(getPrimaryDisplay(), layer, Composition::DEVICE, displayFrame, cropRect); configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect); auto& writer = getWriter(getPrimaryDisplayId()); writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN); return layer; } void sendBufferUpdate(int64_t layer) { const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888); ASSERT_NE(nullptr, buffer->handle); auto& writer = getWriter(getPrimaryDisplayId()); writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle, /*acquireFence*/ -1); const sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp); presentFence->waitForever(LOG_TAG); } bool hasDisplayCapability(int64_t display, DisplayCapability cap) { const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display); EXPECT_TRUE(status.isOk()); Loading Loading @@ -2268,6 +2289,179 @@ TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) { EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Unsupported) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled( getPrimaryDisplayId(), /*enabled*/ true); EXPECT_FALSE(status.isOk()); EXPECT_NO_FATAL_FAILURE( assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED)); status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(), /*enabled*/ false); EXPECT_FALSE(status.isOk()); EXPECT_NO_FATAL_FAILURE( assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED)); } } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Enabled) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } const auto displayId = getPrimaryDisplayId(); EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); std::this_thread::sleep_for(100ms); const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { return displayId == refreshRateChangedDebugData.display; }); // Check that we immediately got a callback EXPECT_TRUE(isCallbackReceived); ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } auto display = getEditablePrimaryDisplay(); const auto displayId = display.getDisplayId(); if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) { GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported"; return; } EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk()); ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { return displayId == refreshRateChangedDebugData.display; }); int retryCount = 3; do { // Wait for 1s so that we enter the idle state std::this_thread::sleep_for(1s); if (!isCallbackReceived) { // DID NOT receive a callback, we are in the idle state. break; } } while (--retryCount > 0); if (retryCount == 0) { GTEST_SUCCEED() << "Unable to enter the idle mode"; return; } // Send the REFRESH_RATE_INDICATOR update ASSERT_NO_FATAL_FAILURE( sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR))); std::this_thread::sleep_for(1s); EXPECT_FALSE(isCallbackReceived) << "A callback should not be received for REFRESH_RATE_INDICATOR"; EXPECT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); for (VtsDisplay& display : mDisplays) { const auto displayId = display.getDisplayId(); EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) { const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod; const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod; if (vsyncPeriod1 == vsyncPeriod2) { return; // continue } EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk()); sendRefreshFrame(display, nullptr); const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints); EXPECT_TRUE(status.isOk()); if (timeline.refreshRequired) { sendRefreshFrame(display, &timeline); } const auto isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { constexpr int kVsyncThreshold = 1000; return displayId == refreshRateChangedDebugData.display && std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <= kVsyncThreshold; }); int retryCount = 3; do { std::this_thread::sleep_for(100ms); if (isCallbackReceived) { GTEST_SUCCEED() << "Received a callback successfully"; break; } } while (--retryCount > 0); if (retryCount == 0) { GTEST_FAIL() << "failed to get a callback for the display " << displayId << " with config " << config2; } }); EXPECT_TRUE( mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } } /* * Test that no two display configs are exactly the same. */ Loading Loading
graphics/composer/aidl/vts/GraphicsComposerCallback.cpp +30 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ void GraphicsComposerCallback::setVsyncAllowed(bool allowed) { mVsyncAllowed = allowed; } void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) { std::scoped_lock lock(mMutex); mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed; } std::vector<int64_t> GraphicsComposerCallback::getDisplays() const { std::scoped_lock lock(mMutex); return mDisplays; Loading Loading @@ -79,6 +84,21 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() { return ret; } std::vector<RefreshRateChangedDebugData> GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() { std::scoped_lock lock(mMutex); std::vector<RefreshRateChangedDebugData> ret; ret.swap(mRefreshRateChangedDebugData); return ret; } int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const { std::scoped_lock lock(mMutex); return mInvalidRefreshRateDebugEnabledCallbackCount; } ::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) { std::scoped_lock lock(mMutex); Loading Loading @@ -125,9 +145,16 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() { } ::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug( const RefreshRateChangedDebugData&) { // TODO(b/202734676) Add implementation for Vts tests return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); const RefreshRateChangedDebugData& data) { std::scoped_lock lock(mMutex); const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display); if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) { mRefreshRateChangedDebugData.push_back(data); } else { mInvalidRefreshRateDebugEnabledCallbackCount++; } return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged( Loading
graphics/composer/aidl/vts/GraphicsComposerCallback.h +11 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ class GraphicsComposerCallback : public BnComposerCallback { public: void setVsyncAllowed(bool allowed); void setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed); std::vector<int64_t> getDisplays() const; int32_t getInvalidHotplugCount() const; Loading @@ -44,6 +46,10 @@ class GraphicsComposerCallback : public BnComposerCallback { std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline(); std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData(); int32_t getInvalidRefreshRateDebugEnabledCallbackCount() const; private: virtual ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override; virtual ::ndk::ScopedAStatus onRefresh(int64_t in_display) override; Loading @@ -63,9 +69,13 @@ class GraphicsComposerCallback : public BnComposerCallback { std::vector<int64_t> mDisplays GUARDED_BY(mMutex); // true only when vsync is enabled bool mVsyncAllowed GUARDED_BY(mMutex) = true; // true only when RefreshRateChangedCallbackDebugEnabled is set to true. bool mRefreshRateChangedDebugDataEnabledCallbackAllowed GUARDED_BY(mMutex) = false; std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex); std::vector<RefreshRateChangedDebugData> mRefreshRateChangedDebugData GUARDED_BY(mMutex); int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0; int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0; Loading @@ -75,6 +85,7 @@ class GraphicsComposerCallback : public BnComposerCallback { int32_t mInvalidVsyncCount GUARDED_BY(mMutex) = 0; int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0; int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0; int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0; }; } // namespace aidl::android::hardware::graphics::composer3::vts
graphics/composer/aidl/vts/VtsComposerClient.cpp +31 −4 Original line number Diff line number Diff line Loading @@ -119,6 +119,24 @@ ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t return updateDisplayProperties(vtsDisplay, config); } ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) { const auto displayId = vtsDisplay->getDisplayId(); auto [activeStatus, activeConfig] = getActiveConfig(displayId); EXPECT_TRUE(activeStatus.isOk()); auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig); auto peakConfig = activeConfig; const auto displayConfigs = vtsDisplay->getDisplayConfigs(); for (const auto [config, displayConfig] : displayConfigs) { if (displayConfig.configGroup == peakDisplayConfig.configGroup && displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) { peakDisplayConfig = displayConfig; peakConfig = config; } } return setActiveConfig(vtsDisplay, peakConfig); } std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute( int64_t display, int32_t config, DisplayAttribute displayAttribute) { int32_t outDisplayAttribute; Loading Loading @@ -375,10 +393,15 @@ int64_t VtsComposerClient::getVsyncIdleTime() { return mComposerCallback->getVsyncIdleTime(); } ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled( int64_t /* display */, bool /* enabled */) { // TODO(b/202734676) Add implementation for VTS tests return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled) { mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled); return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled); } std::vector<RefreshRateChangedDebugData> VtsComposerClient::takeListOfRefreshRateChangedDebugData() { return mComposerCallback->takeListOfRefreshRateChangedDebugData(); } int64_t VtsComposerClient::getInvalidDisplayId() { Loading Loading @@ -545,6 +568,10 @@ bool VtsComposerClient::verifyComposerCallbackParams() { ALOGE("Invalid seamless possible count"); isValid = false; } if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) { ALOGE("Invalid refresh rate debug enabled callback count"); isValid = false; } } return isValid; } Loading
graphics/composer/aidl/vts/VtsComposerClient.h +11 −6 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ class VtsComposerClient { ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay); std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config, DisplayAttribute displayAttribute); Loading Loading @@ -183,6 +185,10 @@ class VtsComposerClient { std::pair<ScopedAStatus, OverlayProperties> getOverlaySupport(); ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled); std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData(); private: ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config); Loading @@ -197,9 +203,6 @@ class VtsComposerClient { bool verifyComposerCallbackParams(); ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t /* display */, bool /* enabled */); // Keep track of displays and layers. When a test fails/ends, // the VtsComposerClient::tearDown should be called from the // test tearDown to clean up the resources for the test. Loading Loading @@ -245,15 +248,17 @@ class VtsDisplay { }; void addDisplayConfig(int32_t config, DisplayConfig displayConfig) { displayConfigs.insert({config, displayConfig}); mDisplayConfigs.insert({config, displayConfig}); } DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; } DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; } std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; } private: int64_t mDisplayId; int32_t mDisplayWidth; int32_t mDisplayHeight; std::unordered_map<int32_t, DisplayConfig> displayConfigs; std::unordered_map<int32_t, DisplayConfig> mDisplayConfigs; }; } // namespace aidl::android::hardware::graphics::composer3::vts
graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp +196 −2 Original line number Diff line number Diff line Loading @@ -1217,6 +1217,14 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { } } bool checkIfCallbackRefreshRateChangedDebugEnabledReceived( std::function<bool(RefreshRateChangedDebugData)> filter) { const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData(); return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) { return filter(refreshRateChangedDebugData); }); } sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) { return sp<GraphicBuffer>::make( static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()), Loading Loading @@ -1316,7 +1324,7 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { return vsyncPeriod; } int64_t createOnScreenLayer() { int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) { const auto& [status, layer] = mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount); EXPECT_TRUE(status.isOk()); Loading @@ -1324,12 +1332,25 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { getPrimaryDisplay().getDisplayHeight()}; FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(), (float)getPrimaryDisplay().getDisplayHeight()}; configureLayer(getPrimaryDisplay(), layer, Composition::DEVICE, displayFrame, cropRect); configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect); auto& writer = getWriter(getPrimaryDisplayId()); writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN); return layer; } void sendBufferUpdate(int64_t layer) { const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888); ASSERT_NE(nullptr, buffer->handle); auto& writer = getWriter(getPrimaryDisplayId()); writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle, /*acquireFence*/ -1); const sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp); presentFence->waitForever(LOG_TAG); } bool hasDisplayCapability(int64_t display, DisplayCapability cap) { const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display); EXPECT_TRUE(status.isOk()); Loading Loading @@ -2268,6 +2289,179 @@ TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) { EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Unsupported) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled( getPrimaryDisplayId(), /*enabled*/ true); EXPECT_FALSE(status.isOk()); EXPECT_NO_FATAL_FAILURE( assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED)); status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(), /*enabled*/ false); EXPECT_FALSE(status.isOk()); EXPECT_NO_FATAL_FAILURE( assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED)); } } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Enabled) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } const auto displayId = getPrimaryDisplayId(); EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); std::this_thread::sleep_for(100ms); const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { return displayId == refreshRateChangedDebugData.display; }); // Check that we immediately got a callback EXPECT_TRUE(isCallbackReceived); ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } auto display = getEditablePrimaryDisplay(); const auto displayId = display.getDisplayId(); if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) { GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported"; return; } EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk()); ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); const bool isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { return displayId == refreshRateChangedDebugData.display; }); int retryCount = 3; do { // Wait for 1s so that we enter the idle state std::this_thread::sleep_for(1s); if (!isCallbackReceived) { // DID NOT receive a callback, we are in the idle state. break; } } while (--retryCount > 0); if (retryCount == 0) { GTEST_SUCCEED() << "Unable to enter the idle mode"; return; } // Send the REFRESH_RATE_INDICATOR update ASSERT_NO_FATAL_FAILURE( sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR))); std::this_thread::sleep_for(1s); EXPECT_FALSE(isCallbackReceived) << "A callback should not be received for REFRESH_RATE_INDICATOR"; EXPECT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) { if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) { GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported"; return; } VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); for (VtsDisplay& display : mDisplays) { const auto displayId = display.getDisplayId(); EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk()); // Enable the callback ASSERT_TRUE(mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true) .isOk()); forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) { const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod; const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod; if (vsyncPeriod1 == vsyncPeriod2) { return; // continue } EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk()); sendRefreshFrame(display, nullptr); const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints); EXPECT_TRUE(status.isOk()); if (timeline.refreshRequired) { sendRefreshFrame(display, &timeline); } const auto isCallbackReceived = checkIfCallbackRefreshRateChangedDebugEnabledReceived( [&](auto refreshRateChangedDebugData) { constexpr int kVsyncThreshold = 1000; return displayId == refreshRateChangedDebugData.display && std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <= kVsyncThreshold; }); int retryCount = 3; do { std::this_thread::sleep_for(100ms); if (isCallbackReceived) { GTEST_SUCCEED() << "Received a callback successfully"; break; } } while (--retryCount > 0); if (retryCount == 0) { GTEST_FAIL() << "failed to get a callback for the display " << displayId << " with config " << config2; } }); EXPECT_TRUE( mComposerClient ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false) .isOk()); } } /* * Test that no two display configs are exactly the same. */ Loading