composer: fix 2.4 vts for multi-display
Fix the way the test handles multi-displays by caching all the hotplug events received when registering the callback Test: VTS on Pixel 4 Bug: 174174253 Change-Id: I9a69b18bcef0722e603f2ca58cfbd176ea60f5f2
This commit is contained in:
parent
ba59ee15d6
commit
be3fce4193
1 changed files with 182 additions and 176 deletions
|
@ -57,6 +57,25 @@ using V2_2::vts::Gralloc;
|
|||
using ContentType = IComposerClient::ContentType;
|
||||
using DisplayCapability = IComposerClient::DisplayCapability;
|
||||
|
||||
class VtsDisplay {
|
||||
public:
|
||||
VtsDisplay(Display display, int32_t displayWidth, int32_t displayHeight)
|
||||
: mDisplay(display), mDisplayWidth(displayWidth), mDisplayHeight(displayHeight) {}
|
||||
|
||||
Display get() const { return mDisplay; }
|
||||
|
||||
IComposerClient::FRect getCrop() const {
|
||||
return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
|
||||
}
|
||||
|
||||
IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
|
||||
|
||||
private:
|
||||
const Display mDisplay;
|
||||
const int32_t mDisplayWidth;
|
||||
const int32_t mDisplayHeight;
|
||||
};
|
||||
|
||||
class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
|
@ -67,15 +86,19 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
|||
mComposerCallback = new GraphicsComposerCallback;
|
||||
mComposerClient->registerCallback_2_4(mComposerCallback);
|
||||
|
||||
// assume the first display is primary and is never removed
|
||||
mPrimaryDisplay = waitForFirstDisplay();
|
||||
// assume the first displays are built-in and are never removed
|
||||
mDisplays = waitForDisplays();
|
||||
|
||||
mInvalidDisplayId = GetInvalidDisplayId();
|
||||
|
||||
// explicitly disable vsync
|
||||
mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
|
||||
for (const auto& display : mDisplays) {
|
||||
mComposerClient->setVsyncEnabled(display.get(), false);
|
||||
}
|
||||
mComposerCallback->setVsyncAllowed(false);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
|
||||
|
||||
mWriter = std::make_unique<CommandWriterBase>(1024);
|
||||
mReader = std::make_unique<TestCommandReader>();
|
||||
}
|
||||
|
@ -83,6 +106,7 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
|||
void TearDown() override {
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
ASSERT_EQ(0, mReader->mCompositionChanges.size());
|
||||
|
||||
if (mComposerCallback != nullptr) {
|
||||
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
|
||||
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
|
||||
|
@ -97,10 +121,10 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
|||
// display. Currently assuming that a device will never have close to
|
||||
// std::numeric_limit<uint64_t>::max() displays registered while running tests
|
||||
Display GetInvalidDisplayId() {
|
||||
std::vector<Display> validDisplays = mComposerCallback->getDisplays();
|
||||
uint64_t id = std::numeric_limits<uint64_t>::max();
|
||||
while (id > 0) {
|
||||
if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
|
||||
if (std::none_of(mDisplays.begin(), mDisplays.end(),
|
||||
[&](const VtsDisplay& display) { return id == display.get(); })) {
|
||||
return id;
|
||||
}
|
||||
id--;
|
||||
|
@ -127,6 +151,30 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
|||
|
||||
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
|
||||
|
||||
const native_handle_t* allocate() {
|
||||
return mGralloc->allocate(
|
||||
/*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
|
||||
static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888),
|
||||
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN));
|
||||
}
|
||||
|
||||
struct TestParameters {
|
||||
nsecs_t delayForChange;
|
||||
bool refreshMiss;
|
||||
};
|
||||
|
||||
void Test_setActiveConfigWithConstraints(const TestParameters& params);
|
||||
|
||||
void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline*);
|
||||
|
||||
void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
|
||||
int64_t desiredTimeNanos, int64_t oldPeriodNanos,
|
||||
int64_t newPeriodNanos);
|
||||
|
||||
std::unique_ptr<ComposerClient> mComposerClient;
|
||||
std::vector<VtsDisplay> mDisplays;
|
||||
Display mInvalidDisplayId;
|
||||
|
||||
void forEachTwoConfigs(Display display, std::function<void(Config, Config)> func) {
|
||||
const auto displayConfigs = mComposerClient->getDisplayConfigs(display);
|
||||
for (const Config config1 : displayConfigs) {
|
||||
|
@ -138,88 +186,44 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
|
|||
}
|
||||
}
|
||||
|
||||
// use the slot count usually set by SF
|
||||
static constexpr uint32_t kBufferSlotCount = 64;
|
||||
|
||||
void Test_setContentType(const ContentType& contentType, const char* contentTypeStr);
|
||||
void Test_setContentTypeForDisplay(const Display& display,
|
||||
const std::vector<ContentType>& capabilities,
|
||||
const ContentType& contentType, const char* contentTypeStr);
|
||||
|
||||
std::unique_ptr<Composer> mComposer;
|
||||
std::unique_ptr<ComposerClient> mComposerClient;
|
||||
sp<GraphicsComposerCallback> mComposerCallback;
|
||||
// the first display and is assumed never to be removed
|
||||
Display mPrimaryDisplay;
|
||||
Display mInvalidDisplayId;
|
||||
std::unique_ptr<CommandWriterBase> mWriter;
|
||||
std::unique_ptr<TestCommandReader> mReader;
|
||||
|
||||
private:
|
||||
Display waitForFirstDisplay() {
|
||||
// use the slot count usually set by SF
|
||||
static constexpr uint32_t kBufferSlotCount = 64;
|
||||
|
||||
std::vector<VtsDisplay> waitForDisplays() {
|
||||
while (true) {
|
||||
// Sleep for a small period of time to allow all built-in displays
|
||||
// to post hotplug events
|
||||
std::this_thread::sleep_for(5ms);
|
||||
std::vector<Display> displays = mComposerCallback->getDisplays();
|
||||
if (displays.empty()) {
|
||||
usleep(5 * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
return displays[0];
|
||||
std::vector<VtsDisplay> vtsDisplays;
|
||||
vtsDisplays.reserve(displays.size());
|
||||
for (Display display : displays) {
|
||||
const Config activeConfig = mComposerClient->getActiveConfig(display);
|
||||
const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, activeConfig, IComposerClient::Attribute::WIDTH);
|
||||
const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, activeConfig, IComposerClient::Attribute::HEIGHT);
|
||||
vtsDisplays.emplace_back(VtsDisplay{display, displayWidth, displayHeight});
|
||||
}
|
||||
|
||||
return vtsDisplays;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Tests for IComposerClient::Command.
|
||||
class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
|
||||
|
||||
const Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
|
||||
mDisplayWidth = mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, activeConfig,
|
||||
IComposerClient::Attribute::WIDTH);
|
||||
mDisplayHeight = mComposerClient->getDisplayAttribute_2_4(
|
||||
mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT);
|
||||
|
||||
mWriter = std::make_unique<CommandWriterBase>(1024);
|
||||
mReader = std::make_unique<TestCommandReader>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_EQ(0, mReader->mErrors.size());
|
||||
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
|
||||
}
|
||||
|
||||
const native_handle_t* allocate() {
|
||||
return mGralloc->allocate(
|
||||
/*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
|
||||
static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888),
|
||||
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN));
|
||||
}
|
||||
|
||||
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
|
||||
|
||||
struct TestParameters {
|
||||
nsecs_t delayForChange;
|
||||
bool refreshMiss;
|
||||
};
|
||||
|
||||
void Test_setActiveConfigWithConstraints(const TestParameters& params);
|
||||
|
||||
void sendRefreshFrame(const VsyncPeriodChangeTimeline*);
|
||||
|
||||
void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
|
||||
int64_t desiredTimeNanos, int64_t oldPeriodNanos,
|
||||
int64_t newPeriodNanos);
|
||||
|
||||
std::unique_ptr<Composer> mComposer;
|
||||
std::unique_ptr<CommandWriterBase> mWriter;
|
||||
std::unique_ptr<TestCommandReader> mReader;
|
||||
int32_t mDisplayWidth;
|
||||
int32_t mDisplayHeight;
|
||||
|
||||
private:
|
||||
sp<GraphicsComposerCallback> mComposerCallback;
|
||||
std::unique_ptr<Gralloc> mGralloc;
|
||||
};
|
||||
|
||||
|
@ -230,9 +234,10 @@ TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
|
|||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlTest, getDisplayCapabilities) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
for (const auto& display : mDisplays) {
|
||||
std::vector<IComposerClient::DisplayCapability> capabilities;
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->getDisplayCapabilities(display, &capabilities));
|
||||
EXPECT_EQ(Error::NONE,
|
||||
mComposerClient->getDisplayCapabilities(display.get(), &capabilities));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,38 +246,40 @@ TEST_P(GraphicsComposerHidlTest, getDisplayConnectionType) {
|
|||
EXPECT_EQ(Error::BAD_DISPLAY,
|
||||
mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type));
|
||||
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display, &type));
|
||||
for (const auto& display : mDisplays) {
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display.get(), &type));
|
||||
}
|
||||
}
|
||||
|
||||
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->getRaw()->getDisplayAttribute_2_4(
|
||||
mPrimaryDisplay, config, attribute,
|
||||
[&](const auto& tmpError, const auto& value) {
|
||||
EXPECT_EQ(Error::NONE, tmpError);
|
||||
EXPECT_NE(-1, value);
|
||||
});
|
||||
}
|
||||
for (const auto& display : mDisplays) {
|
||||
std::vector<Config> configs = mComposerClient->getDisplayConfigs(display.get());
|
||||
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->getRaw()->getDisplayAttribute_2_4(
|
||||
display.get(), config, attribute,
|
||||
[&](const auto& tmpError, const auto& value) {
|
||||
EXPECT_EQ(Error::NONE, tmpError);
|
||||
EXPECT_NE(-1, value);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
|
||||
IComposerClient::Attribute::DPI_X,
|
||||
IComposerClient::Attribute::DPI_Y,
|
||||
}};
|
||||
for (auto attribute : optionalAttributes) {
|
||||
mComposerClient->getRaw()->getDisplayAttribute_2_4(
|
||||
display.get(), config, attribute, [&](const auto& tmpError, const auto&) {
|
||||
EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,11 +290,12 @@ TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) {
|
|||
mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
for (Config config : mComposerClient->getDisplayConfigs(display)) {
|
||||
TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
|
||||
for (const auto& display : mDisplays) {
|
||||
for (Config config : mComposerClient->getDisplayConfigs(display.get())) {
|
||||
VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
display.get(), config,
|
||||
IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
|
||||
VsyncPeriodChangeTimeline timeline;
|
||||
IComposerClient::VsyncPeriodChangeConstraints constraints;
|
||||
|
@ -295,12 +303,12 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
|
|||
constraints.desiredTimeNanos = systemTime();
|
||||
constraints.seamlessRequired = false;
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
|
||||
display, config, constraints, &timeline));
|
||||
display.get(), config, constraints, &timeline));
|
||||
|
||||
if (timeline.refreshRequired) {
|
||||
sendRefreshFrame(&timeline);
|
||||
sendRefreshFrame(display, &timeline);
|
||||
}
|
||||
waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0,
|
||||
waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
|
||||
expectedVsyncPeriodNanos);
|
||||
|
||||
VsyncPeriodNanos vsyncPeriodNanos;
|
||||
|
@ -309,7 +317,7 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
|
|||
std::this_thread::sleep_for(10ms);
|
||||
vsyncPeriodNanos = 0;
|
||||
EXPECT_EQ(Error::NONE,
|
||||
mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
|
||||
mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
|
||||
--retryCount;
|
||||
} while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
|
||||
|
||||
|
@ -322,7 +330,7 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
|
|||
timeout *= 2;
|
||||
vsyncPeriodNanos = 0;
|
||||
EXPECT_EQ(Error::NONE,
|
||||
mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
|
||||
mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
|
||||
EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
|
||||
}
|
||||
}
|
||||
|
@ -347,31 +355,34 @@ TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) {
|
|||
constraints.seamlessRequired = false;
|
||||
constraints.desiredTimeNanos = systemTime();
|
||||
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
Config invalidConfigId = GetInvalidConfigId(display);
|
||||
EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints(
|
||||
display, invalidConfigId, constraints, &timeline));
|
||||
for (const auto& display : mDisplays) {
|
||||
Config invalidConfigId = GetInvalidConfigId(display.get());
|
||||
EXPECT_EQ(Error::BAD_CONFIG,
|
||||
mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId,
|
||||
constraints, &timeline));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
|
||||
TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
|
||||
VsyncPeriodChangeTimeline timeline;
|
||||
IComposerClient::VsyncPeriodChangeConstraints constraints;
|
||||
|
||||
constraints.seamlessRequired = true;
|
||||
constraints.desiredTimeNanos = systemTime();
|
||||
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
forEachTwoConfigs(display, [&](Config config1, Config config2) {
|
||||
for (const auto& display : mDisplays) {
|
||||
forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
|
||||
const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, config1, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
|
||||
display.get(), config1,
|
||||
IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
|
||||
const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, config2, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
|
||||
display.get(), config2,
|
||||
IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
|
||||
if (configGroup1 != configGroup2) {
|
||||
mComposerClient->setActiveConfig(display, config1);
|
||||
sendRefreshFrame(nullptr);
|
||||
mComposerClient->setActiveConfig(display.get(), config1);
|
||||
sendRefreshFrame(display, nullptr);
|
||||
EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
|
||||
mComposerClient->setActiveConfigWithConstraints(display, config2,
|
||||
mComposerClient->setActiveConfigWithConstraints(display.get(), config2,
|
||||
constraints, &timeline));
|
||||
}
|
||||
});
|
||||
|
@ -382,7 +393,8 @@ static inline auto toTimePoint(nsecs_t time) {
|
|||
return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
|
||||
}
|
||||
|
||||
void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTimeline* timeline) {
|
||||
void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display,
|
||||
const VsyncPeriodChangeTimeline* timeline) {
|
||||
if (timeline != nullptr) {
|
||||
// Refresh time should be before newVsyncAppliedTimeNanos
|
||||
EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
|
||||
|
@ -390,29 +402,25 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi
|
|||
std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
|
||||
}
|
||||
|
||||
mWriter->selectDisplay(mPrimaryDisplay);
|
||||
mComposerClient->setPowerMode(mPrimaryDisplay, V2_1::IComposerClient::PowerMode::ON);
|
||||
mComposerClient->setColorMode_2_3(mPrimaryDisplay, ColorMode::NATIVE,
|
||||
RenderIntent::COLORIMETRIC);
|
||||
mWriter->selectDisplay(display.get());
|
||||
mComposerClient->setPowerMode(display.get(), V2_1::IComposerClient::PowerMode::ON);
|
||||
mComposerClient->setColorMode_2_3(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC);
|
||||
|
||||
auto handle = allocate();
|
||||
ASSERT_NE(nullptr, handle);
|
||||
|
||||
IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
|
||||
|
||||
Layer layer;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
|
||||
ASSERT_NO_FATAL_FAILURE(layer = mComposerClient->createLayer(display.get(), kBufferSlotCount));
|
||||
mWriter->selectLayer(layer);
|
||||
mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
|
||||
mWriter->setLayerDisplayFrame(displayFrame);
|
||||
mWriter->setLayerDisplayFrame(display.getFrameRect());
|
||||
mWriter->setLayerPlaneAlpha(1);
|
||||
mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
|
||||
mWriter->setLayerSourceCrop(display.getCrop());
|
||||
mWriter->setLayerTransform(static_cast<Transform>(0));
|
||||
mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame));
|
||||
mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
|
||||
mWriter->setLayerZOrder(10);
|
||||
mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
|
||||
mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame));
|
||||
mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
|
||||
mWriter->setLayerBuffer(0, handle, -1);
|
||||
mWriter->setLayerDataspace(Dataspace::UNKNOWN);
|
||||
|
||||
|
@ -440,9 +448,11 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi
|
|||
execute();
|
||||
}
|
||||
|
||||
void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange(
|
||||
Display display, const VsyncPeriodChangeTimeline& timeline, int64_t desiredTimeNanos,
|
||||
int64_t oldPeriodNanos, int64_t newPeriodNanos) {
|
||||
void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display,
|
||||
const VsyncPeriodChangeTimeline& timeline,
|
||||
int64_t desiredTimeNanos,
|
||||
int64_t oldPeriodNanos,
|
||||
int64_t newPeriodNanos) {
|
||||
const auto CHANGE_DEADLINE = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
|
||||
while (std::chrono::steady_clock::now() <= CHANGE_DEADLINE) {
|
||||
VsyncPeriodNanos vsyncPeriodNanos;
|
||||
|
@ -456,17 +466,18 @@ void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange(
|
|||
}
|
||||
}
|
||||
|
||||
void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
|
||||
const TestParameters& params) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
forEachTwoConfigs(display, [&](Config config1, Config config2) {
|
||||
mComposerClient->setActiveConfig(display, config1);
|
||||
sendRefreshFrame(nullptr);
|
||||
void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) {
|
||||
for (const auto& display : mDisplays) {
|
||||
forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
|
||||
mComposerClient->setActiveConfig(display.get(), config1);
|
||||
sendRefreshFrame(display, nullptr);
|
||||
|
||||
int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, config1, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
display.get(), config1,
|
||||
IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
|
||||
display, config2, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
display.get(), config2,
|
||||
IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
|
||||
|
||||
if (vsyncPeriod1 == vsyncPeriod2) {
|
||||
return; // continue
|
||||
|
@ -477,7 +488,7 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
|
|||
.desiredTimeNanos = systemTime() + params.delayForChange,
|
||||
.seamlessRequired = false};
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
|
||||
display, config2, constraints, &timeline));
|
||||
display.get(), config2, constraints, &timeline));
|
||||
|
||||
EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
|
||||
// Refresh rate should change within a reasonable time
|
||||
|
@ -491,10 +502,10 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
|
|||
// callback
|
||||
std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms);
|
||||
}
|
||||
sendRefreshFrame(&timeline);
|
||||
sendRefreshFrame(display, &timeline);
|
||||
}
|
||||
waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, vsyncPeriod1,
|
||||
vsyncPeriod2);
|
||||
waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
|
||||
vsyncPeriod1, vsyncPeriod2);
|
||||
|
||||
// At this point the refresh rate should have changed already, however in rare
|
||||
// cases the implementation might have missed the deadline. In this case a new
|
||||
|
@ -506,30 +517,30 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
|
|||
|
||||
if (newTimeline.has_value()) {
|
||||
if (newTimeline->refreshRequired) {
|
||||
sendRefreshFrame(&newTimeline.value());
|
||||
sendRefreshFrame(display, &newTimeline.value());
|
||||
}
|
||||
waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos,
|
||||
vsyncPeriod1, vsyncPeriod2);
|
||||
waitForVsyncPeriodChange(display.get(), newTimeline.value(),
|
||||
constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
|
||||
}
|
||||
|
||||
VsyncPeriodNanos vsyncPeriodNanos;
|
||||
EXPECT_EQ(Error::NONE,
|
||||
mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
|
||||
mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
|
||||
EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints) {
|
||||
TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) {
|
||||
Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_Delayed) {
|
||||
TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_Delayed) {
|
||||
Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
|
||||
.refreshMiss = false});
|
||||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
|
||||
TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_MissRefresh) {
|
||||
Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
|
||||
}
|
||||
|
||||
|
@ -539,9 +550,9 @@ TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) {
|
|||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
for (const auto& display : mDisplays) {
|
||||
std::vector<DisplayCapability> capabilities;
|
||||
const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities);
|
||||
const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities);
|
||||
EXPECT_EQ(Error::NONE, error);
|
||||
|
||||
const bool allmSupport =
|
||||
|
@ -550,16 +561,16 @@ TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
|
|||
|
||||
if (!allmSupport) {
|
||||
EXPECT_EQ(Error::UNSUPPORTED,
|
||||
mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
|
||||
mComposerClient->setAutoLowLatencyMode(display.get(), true));
|
||||
EXPECT_EQ(Error::UNSUPPORTED,
|
||||
mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
|
||||
mComposerClient->setAutoLowLatencyMode(display.get(), false));
|
||||
GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
|
||||
<< std::to_string(display) << ", skipping test";
|
||||
<< std::to_string(display.get()) << ", skipping test";
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), true));
|
||||
EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,10 +583,10 @@ TEST_P(GraphicsComposerHidlTest, getSupportedContentTypesBadDisplay) {
|
|||
|
||||
TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
|
||||
std::vector<ContentType> supportedContentTypes;
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
for (const auto& display : mDisplays) {
|
||||
supportedContentTypes.clear();
|
||||
const auto error =
|
||||
mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
|
||||
mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
|
||||
const bool noneSupported =
|
||||
std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
|
||||
ContentType::NONE) != supportedContentTypes.end();
|
||||
|
@ -585,8 +596,8 @@ TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
|
|||
}
|
||||
|
||||
TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
const auto error = mComposerClient->setContentType(display, ContentType::NONE);
|
||||
for (const auto& display : mDisplays) {
|
||||
const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE);
|
||||
EXPECT_NE(Error::UNSUPPORTED, error);
|
||||
}
|
||||
}
|
||||
|
@ -618,13 +629,14 @@ void GraphicsComposerHidlTest::Test_setContentTypeForDisplay(
|
|||
|
||||
void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType,
|
||||
const char* contentTypeStr) {
|
||||
for (Display display : mComposerCallback->getDisplays()) {
|
||||
for (const auto& display : mDisplays) {
|
||||
std::vector<ContentType> supportedContentTypes;
|
||||
const auto error =
|
||||
mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
|
||||
mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
|
||||
EXPECT_EQ(Error::NONE, error);
|
||||
|
||||
Test_setContentTypeForDisplay(display, supportedContentTypes, contentType, contentTypeStr);
|
||||
Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
|
||||
contentTypeStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,13 +662,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
|
||||
android::hardware::PrintInstanceNameToString);
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, GraphicsComposerHidlCommandTest,
|
||||
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
|
||||
android::hardware::PrintInstanceNameToString);
|
||||
|
||||
TEST_P(GraphicsComposerHidlCommandTest, getLayerGenericMetadataKeys) {
|
||||
TEST_P(GraphicsComposerHidlTest, getLayerGenericMetadataKeys) {
|
||||
std::vector<IComposerClient::LayerGenericMetadataKey> keys;
|
||||
mComposerClient->getLayerGenericMetadataKeys(&keys);
|
||||
|
||||
|
|
Loading…
Reference in a new issue