Merge "Add VTS test for clearing buffer slots to Composer HIDL and AIDL"

This commit is contained in:
Brian Lindahl 2022-12-09 21:06:46 +00:00 committed by Android (Google) Code Review
commit b0ef4fc286
3 changed files with 105 additions and 13 deletions

View file

@ -657,6 +657,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
IComposerClient::Attribute::WIDTH);
mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
IComposerClient::Attribute::HEIGHT);
mWriter = std::make_unique<CommandWriterBase>(1024);
mReader = std::make_unique<TestCommandReader>();
}
@ -666,11 +667,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 +886,57 @@ 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_TO_CLEAR_BUFFER_SLOTS) {
// A buffer used to clear buffer slots
auto clearSlotBuffer = allocate(1u, 1u);
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());
// Ensure we can clear a buffer slot and then set that same slot with a new buffer
auto handle2 = allocate();
ASSERT_NE(nullptr, handle2.get());
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerBuffer(0, clearSlotBuffer.get(), -1);
mWriter->selectDisplay(mPrimaryDisplay);
mWriter->selectLayer(layer);
mWriter->setLayerBuffer(0, handle2.get(), -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

@ -91,7 +91,7 @@ class ComposerClientWriter final {
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
ClientTarget clientTargetCommand;
clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
@ -100,7 +100,7 @@ class ComposerClientWriter final {
void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
int releaseFence) {
getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
getBuffer(slot, buffer, releaseFence));
getBufferCommand(slot, buffer, releaseFence));
}
void validateDisplay(int64_t display,
@ -132,7 +132,14 @@ class ComposerClientWriter final {
void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
}
void setLayerBufferWithNewCommand(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
flushLayerCommand();
getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
flushLayerCommand();
}
void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
@ -234,7 +241,7 @@ class ComposerClientWriter final {
std::vector<DisplayCommand> mCommands;
const int64_t mDisplay;
Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));

View file

@ -1131,17 +1131,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
@ -1642,6 +1646,33 @@ TEST_P(GraphicsComposerAidlCommandTest, SetLayerBuffer) {
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferWithSlotsToClear) {
auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
ASSERT_NE(nullptr, clearSlotBuffer);
auto clearSlotBufferHandle = clearSlotBuffer->handle;
const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer1);
const auto handle1 = buffer1->handle;
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
auto& writer = getWriter(getPrimaryDisplayId());
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
// Ensure we can clear a buffer slot and then set that same slot with a new buffer
const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer2);
const auto handle2 = buffer2->handle;
writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
clearSlotBufferHandle, /*acquireFence*/ -1);
writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2, /*acquireFence*/ -1);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);