Merge "Add VTS test for clearing buffer slots to Composer HIDL and AIDL" into udc-dev

This commit is contained in:
TreeHugger Robot
2023-03-31 22:34:15 +00:00
committed by Android (Google) Code Review
2 changed files with 213 additions and 9 deletions

View File

@@ -666,11 +666,13 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
}
NativeHandleWrapper allocate() {
NativeHandleWrapper allocate() { return allocate(mDisplayWidth, mDisplayHeight); }
NativeHandleWrapper allocate(uint32_t width, uint32_t height) {
uint64_t usage =
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN |
BufferUsage::COMPOSER_OVERLAY);
return mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage);
return mGralloc->allocate(width, height, 1, PixelFormat::RGBA_8888, usage);
}
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
@@ -883,6 +885,106 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) {
execute();
}
/**
* Test IComposerClient::Command::SET_LAYER_BUFFER with the behavior used for clearing buffer slots.
*/
TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER_multipleTimes) {
// A placeholder buffer used to clear buffer slots
auto clearSlotBuffer = allocate(1u, 1u);
//
// Set the layer buffer to the first buffer
//
auto handle1 = allocate();
ASSERT_NE(nullptr, handle1.get());
IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
Layer layer;
ASSERT_NO_FATAL_FAILURE(
layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
mWriter->setLayerDisplayFrame(displayFrame);
mWriter->setLayerBuffer(0, handle1.get(), -1);
mWriter->setLayerDataspace(Dataspace::UNKNOWN);
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
ASSERT_EQ(0, mReader->mErrors.size());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->presentDisplay();
execute();
ASSERT_EQ(0, mReader->mErrors.size());
//
// Set the layer buffer to the second buffer
//
auto handle2 = allocate();
ASSERT_NE(nullptr, handle2.get());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
mWriter->setLayerDisplayFrame(displayFrame);
mWriter->setLayerBuffer(1, handle2.get(), -1);
mWriter->setLayerDataspace(Dataspace::UNKNOWN);
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
ASSERT_EQ(0, mReader->mErrors.size());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->presentDisplay();
execute();
ASSERT_EQ(0, mReader->mErrors.size());
//
// Set the layer buffer to the third buffer
//
auto handle3 = allocate();
ASSERT_NE(nullptr, handle3.get());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
mWriter->setLayerDisplayFrame(displayFrame);
mWriter->setLayerBuffer(2, handle3.get(), -1);
mWriter->setLayerDataspace(Dataspace::UNKNOWN);
mWriter->validateDisplay();
execute();
if (mReader->mCompositionChanges.size() != 0) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
ASSERT_EQ(0, mReader->mErrors.size());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->presentDisplay();
execute();
ASSERT_EQ(0, mReader->mErrors.size());
// Ensure we can clear multiple buffer slots and then restore the active buffer at the end
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerBuffer(0, clearSlotBuffer.get(), -1);
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerBuffer(1, clearSlotBuffer.get(), -1);
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerBuffer(2, nullptr, -1);
mWriter->validateDisplay();
execute();
ASSERT_EQ(0, mReader->mErrors.size());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->presentDisplay();
execute();
ASSERT_EQ(0, mReader->mErrors.size());
}
/**
* Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE.
*/

View File

@@ -1229,17 +1229,21 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
});
}
sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
::android::PixelFormat pixelFormat) {
return sp<GraphicBuffer>::make(
static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat,
/*layerCount*/ 1U,
(static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY)),
width, height, pixelFormat, /*layerCount*/ 1U,
static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
"VtsHalGraphicsComposer3_TargetTest");
}
sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
}
void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
if (timeline != nullptr) {
// Refresh time should be before newVsyncAppliedTimeNanos
@@ -1753,6 +1757,104 @@ TEST_P(GraphicsComposerAidlCommandTest, SetLayerBuffer) {
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferSlotsToClear) {
// Older HAL versions use a backwards compatible way of clearing buffer slots
const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
ASSERT_TRUE(versionStatus.isOk());
if (version <= 1) {
GTEST_SUCCEED() << "HAL at version 1 or lower does not have "
"LayerCommand::bufferSlotsToClear.";
return;
}
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
// setup 3 buffers in the buffer cache, with the last buffer being active
// then emulate the Android platform code that clears all 3 buffer slots
const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer1);
const auto handle1 = buffer1->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer2);
const auto handle2 = buffer2->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer3);
const auto handle3 = buffer3->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
// Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
// current active buffer's slot will be cleared, but still remain the active buffer and no
// errors will occur.
writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
// Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
// Android platform code that clears all 3 buffer slots by setting all but the active buffer
// slot to a placeholder buffer, and then restoring the active buffer.
// This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer1);
const auto handle1 = buffer1->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer2);
const auto handle2 = buffer2->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer3);
const auto handle3 = buffer3->handle;
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
// Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
// and then restoring the current active buffer at the end
auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
ASSERT_NE(nullptr, clearSlotBuffer);
auto clearSlotBufferHandle = clearSlotBuffer->handle;
// clear buffer slots 0 and 1 with new layer commands... and then...
writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
clearSlotBufferHandle, /*acquireFence*/ -1);
writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
clearSlotBufferHandle, /*acquireFence*/ -1);
// ...reset the layer buffer to the current active buffer slot with a final new command
writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
/*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);