mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "composer: add API to control display idle timer"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b20697869b
@@ -42,4 +42,5 @@ enum DisplayCapability {
|
||||
AUTO_LOW_LATENCY_MODE = 5,
|
||||
SUSPEND = 6,
|
||||
DISPLAY_DECORATION = 7,
|
||||
DISPLAY_IDLE_TIMER = 8,
|
||||
}
|
||||
|
||||
@@ -39,4 +39,5 @@ interface IComposerCallback {
|
||||
oneway void onSeamlessPossible(long display);
|
||||
oneway void onVsync(long display, long timestamp, int vsyncPeriodNanos);
|
||||
oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);
|
||||
oneway void onVsyncIdle(long display);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ interface IComposerClient {
|
||||
void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
|
||||
void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
|
||||
void setVsyncEnabled(long display, boolean enabled);
|
||||
void setIdleTimerEnabled(long display, int timeoutMs);
|
||||
const int EX_BAD_CONFIG = 1;
|
||||
const int EX_BAD_DISPLAY = 2;
|
||||
const int EX_BAD_LAYER = 3;
|
||||
|
||||
@@ -79,4 +79,9 @@ enum DisplayCapability {
|
||||
* Indicates that the display supports Composition.DISPLAY_DECORATION.
|
||||
*/
|
||||
DISPLAY_DECORATION = 7,
|
||||
/**
|
||||
* Indicates that the display supports IComposerClient.setIdleTimerEnabled and
|
||||
* IComposerCallback.onVsyncIdle.
|
||||
*/
|
||||
DISPLAY_IDLE_TIMER = 8,
|
||||
}
|
||||
|
||||
@@ -86,4 +86,14 @@ interface IComposerCallback {
|
||||
*/
|
||||
oneway void onVsyncPeriodTimingChanged(
|
||||
long display, in VsyncPeriodChangeTimeline updatedTimeline);
|
||||
|
||||
/**
|
||||
* Notifies the client that the display is idle, the refresh rate changed to a lower setting to
|
||||
* preserve power and vsync cadence changed. When a new frame is queued for presentation, the
|
||||
* client is expected to enable vsync callbacks to learn the new vsync cadence before sending
|
||||
* a new frame.
|
||||
*
|
||||
* @param display is the display whose vsync cadence changed due to panel idle mode.
|
||||
*/
|
||||
oneway void onVsyncIdle(long display);
|
||||
}
|
||||
|
||||
@@ -779,4 +779,25 @@ interface IComposerClient {
|
||||
* @exception EX_BAD_PARAMETER when enabled was an invalid value.
|
||||
*/
|
||||
void setVsyncEnabled(long display, boolean enabled);
|
||||
|
||||
/**
|
||||
* Enables or disables the idle timer on this display.
|
||||
*
|
||||
* Idle timer is used to allow the display to go into a panel idle mode after some
|
||||
* idle period.
|
||||
*
|
||||
* This function should only be called if the display reports support for
|
||||
* DisplayCapability.DISPLAY_IDLE from getDisplayCapabilities.
|
||||
*
|
||||
* @param display is the display to which the idle timer is set.
|
||||
* @param timeoutMs is the minimum requirements of idle period in milliseconds. Panel
|
||||
* should not go into the idle state within the minimum requirement after
|
||||
* idle for a while. 0 means disabled, panel should not go into idle state.
|
||||
*
|
||||
* @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
|
||||
* @exception EX_BAD_PARAMETER when timeout is a negative number.
|
||||
* @exception EX_UNSUPPORTED when idle is not supported on this display.
|
||||
*
|
||||
*/
|
||||
void setIdleTimerEnabled(long display, int timeoutMs);
|
||||
}
|
||||
|
||||
@@ -1394,6 +1394,14 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
|
||||
return layer;
|
||||
}
|
||||
|
||||
bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
|
||||
std::vector<DisplayCapability> capabilities;
|
||||
const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities);
|
||||
EXPECT_TRUE(error.isOk());
|
||||
|
||||
return std::find(capabilities.begin(), capabilities.end(), cap) != capabilities.end();
|
||||
}
|
||||
|
||||
void Test_setActiveConfigWithConstraints(const TestParameters& params) {
|
||||
for (VtsDisplay& display : mDisplays) {
|
||||
forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
|
||||
@@ -2165,6 +2173,74 @@ TEST_P(GraphicsComposerAidlCommandTest, expectedPresentTime_5) {
|
||||
ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(5));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerAidlCommandTest, setIdleTimerEnabled_Unsupported) {
|
||||
const bool hasDisplayIdleTimerSupport = hasDisplayCapability(mPrimaryDisplay,
|
||||
DisplayCapability::DISPLAY_IDLE_TIMER);
|
||||
if (!hasDisplayIdleTimerSupport) {
|
||||
const auto error = mComposerClient->setIdleTimerEnabled(mPrimaryDisplay, 0);
|
||||
EXPECT_FALSE(error.isOk());
|
||||
EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerAidlCommandTest, setIdleTimerEnabled_BadParameter) {
|
||||
const bool hasDisplayIdleTimerSupport = hasDisplayCapability(mPrimaryDisplay,
|
||||
DisplayCapability::DISPLAY_IDLE_TIMER);
|
||||
if (!hasDisplayIdleTimerSupport) {
|
||||
GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto error = mComposerClient->setIdleTimerEnabled(mPrimaryDisplay, -1);
|
||||
EXPECT_FALSE(error.isOk());
|
||||
EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerAidlCommandTest, setIdleTimerEnabled_Disable) {
|
||||
const bool hasDisplayIdleTimerSupport = hasDisplayCapability(mPrimaryDisplay,
|
||||
DisplayCapability::DISPLAY_IDLE_TIMER);
|
||||
if (!hasDisplayIdleTimerSupport) {
|
||||
GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(mPrimaryDisplay, 0).isOk());
|
||||
std::this_thread::sleep_for(1s);
|
||||
EXPECT_EQ(0, mComposerCallback->getVsyncIdleCount());
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerAidlCommandTest, setIdleTimerEnabled_Timeout_2) {
|
||||
const bool hasDisplayIdleTimerSupport = hasDisplayCapability(mPrimaryDisplay,
|
||||
DisplayCapability::DISPLAY_IDLE_TIMER);
|
||||
if (!hasDisplayIdleTimerSupport) {
|
||||
GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
|
||||
EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(mPrimaryDisplay, 0).isOk());
|
||||
|
||||
const auto buffer = allocate();
|
||||
ASSERT_NE(nullptr, buffer->handle);
|
||||
|
||||
const auto layer = createOnScreenLayer();
|
||||
mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, buffer->handle, -1);
|
||||
int32_t vsyncIdleCount = mComposerCallback->getVsyncIdleCount();
|
||||
auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
|
||||
EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(mPrimaryDisplay, 2000).isOk());
|
||||
|
||||
const sp<::android::Fence> presentFence =
|
||||
presentAndGetFence(ComposerClientWriter::kNoTimestamp);
|
||||
presentFence->waitForever(LOG_TAG);
|
||||
|
||||
std::this_thread::sleep_for(3s);
|
||||
if (vsyncIdleCount < mComposerCallback->getVsyncIdleCount()) {
|
||||
EXPECT_GE(mComposerCallback->getVsyncIdleTime(), earlyVsyncIdleTime);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, GraphicsComposerAidlCommandTest,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "include/GraphicsComposerCallback.h"
|
||||
#include <log/log_main.h>
|
||||
#include <utils/Timers.h>
|
||||
|
||||
#pragma push_macro("LOG_TAG")
|
||||
#undef LOG_TAG
|
||||
@@ -58,6 +59,16 @@ int32_t GraphicsComposerCallback::getInvalidSeamlessPossibleCount() const {
|
||||
return mInvalidSeamlessPossibleCount;
|
||||
}
|
||||
|
||||
int32_t GraphicsComposerCallback::getVsyncIdleCount() const {
|
||||
std::scoped_lock lock(mMutex);
|
||||
return mVsyncIdleCount;
|
||||
}
|
||||
|
||||
int64_t GraphicsComposerCallback::getVsyncIdleTime() const {
|
||||
std::scoped_lock lock(mMutex);
|
||||
return mVsyncIdleTime;
|
||||
}
|
||||
|
||||
std::optional<VsyncPeriodChangeTimeline>
|
||||
GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() {
|
||||
std::scoped_lock lock(mMutex);
|
||||
@@ -125,4 +136,13 @@ GraphicsComposerCallback::takeLastVsyncPeriodChangeTimeline() {
|
||||
return ::ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncIdle(int64_t in_display) {
|
||||
std::scoped_lock lock(mMutex);
|
||||
if (mDisplays.count(in_display)) {
|
||||
mVsyncIdleCount++;
|
||||
mVsyncIdleTime = systemTime();
|
||||
}
|
||||
return ::ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
|
||||
@@ -45,6 +45,10 @@ class GraphicsComposerCallback : public BnComposerCallback {
|
||||
|
||||
int32_t getInvalidSeamlessPossibleCount() const;
|
||||
|
||||
int32_t getVsyncIdleCount() const;
|
||||
|
||||
int64_t getVsyncIdleTime() const;
|
||||
|
||||
std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();
|
||||
|
||||
private:
|
||||
@@ -57,6 +61,7 @@ class GraphicsComposerCallback : public BnComposerCallback {
|
||||
int64_t in_display,
|
||||
const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
|
||||
in_updatedTimeline) override;
|
||||
virtual ::ndk::ScopedAStatus onVsyncIdle(int64_t in_display) override;
|
||||
|
||||
mutable std::mutex mMutex;
|
||||
// the set of all currently connected displays
|
||||
@@ -66,6 +71,9 @@ class GraphicsComposerCallback : public BnComposerCallback {
|
||||
|
||||
std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex);
|
||||
|
||||
int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0;
|
||||
int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0;
|
||||
|
||||
// track invalid callbacks
|
||||
int32_t mInvalidHotplugCount GUARDED_BY(mMutex) = 0;
|
||||
int32_t mInvalidRefreshCount GUARDED_BY(mMutex) = 0;
|
||||
@@ -74,4 +82,4 @@ class GraphicsComposerCallback : public BnComposerCallback {
|
||||
int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
|
||||
Reference in New Issue
Block a user