mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Add VTS test for clearing buffer slots to Composer HIDL and AIDL" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ac28d06464
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user