mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Before checking the service specific error we need to check that getExceptionCode returns EX_SERVICE_SPECIFIC error code. Added a method and used that to do the two checks together for exceptionCode and for the service specific error code, so that we don't repeat two lines in all the tests that need them. EXPECT_NO_FATAL_FAILURES print the correct line number of the test or iteration of the test when used with helper functions, and testing guidelines recommend it too here: go/gunitadvanced#propagating-fatal-failures Test: atest VtsHalGraphicsComposer3_TargetTest BUG: 205152739 Change-Id: I1d3c3aa9b34dcefb14be507ff61b73b6f08a5204
1466 lines
66 KiB
C++
1466 lines
66 KiB
C++
/**
|
|
* Copyright (c) 2021, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define LOG_TAG "graphics_composer_aidl_hal_readback_tests@3"
|
|
|
|
#include <aidl/Gtest.h>
|
|
#include <aidl/Vintf.h>
|
|
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
|
|
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
|
|
#include <gtest/gtest.h>
|
|
#include <ui/DisplayId.h>
|
|
#include <ui/DisplayIdentification.h>
|
|
#include <ui/GraphicBuffer.h>
|
|
#include <ui/PixelFormat.h>
|
|
#include <ui/Rect.h>
|
|
#include "GraphicsComposerCallback.h"
|
|
#include "ReadbackVts.h"
|
|
#include "RenderEngineVts.h"
|
|
#include "VtsComposerClient.h"
|
|
|
|
// tinyxml2 does implicit conversions >:(
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wconversion"
|
|
#include <tinyxml2.h>
|
|
#pragma clang diagnostic pop
|
|
|
|
namespace aidl::android::hardware::graphics::composer3::vts {
|
|
namespace {
|
|
|
|
using ::android::Rect;
|
|
using common::Dataspace;
|
|
using common::PixelFormat;
|
|
|
|
class GraphicsCompositionTestBase : public ::testing::Test {
|
|
protected:
|
|
void SetUpBase(const std::string& name) {
|
|
mComposerClient = std::make_shared<VtsComposerClient>(name);
|
|
ASSERT_TRUE(mComposerClient->createClient().isOk());
|
|
|
|
const auto& [status, displays] = mComposerClient->getDisplays();
|
|
ASSERT_TRUE(status.isOk());
|
|
mDisplays = displays;
|
|
|
|
setTestColorModes();
|
|
|
|
// explicitly disable vsync
|
|
for (const auto& display : mDisplays) {
|
|
EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), /*enable*/ false).isOk());
|
|
}
|
|
mComposerClient->setVsyncAllowed(/*isAllowed*/ false);
|
|
|
|
EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
|
|
::android::renderengine::RenderEngineCreationArgs::Builder()
|
|
.setPixelFormat(static_cast<int>(common::PixelFormat::RGBA_8888))
|
|
.setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
|
|
.setUseColorManagerment(true)
|
|
.setEnableProtectedContext(false)
|
|
.setPrecacheToneMapperShaderOnly(false)
|
|
.setContextPriority(::android::renderengine::RenderEngine::
|
|
ContextPriority::HIGH)
|
|
.build())));
|
|
|
|
::android::renderengine::DisplaySettings clientCompositionDisplay;
|
|
clientCompositionDisplay.physicalDisplay = Rect(getDisplayWidth(), getDisplayHeight());
|
|
clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
|
|
|
|
mTestRenderEngine->initGraphicBuffer(
|
|
static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
|
|
/*layerCount*/ 1U,
|
|
static_cast<uint64_t>(
|
|
static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
|
|
static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
|
static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
|
|
mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
|
|
}
|
|
|
|
void TearDown() override {
|
|
ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
|
|
ASSERT_TRUE(mComposerClient->tearDown());
|
|
mComposerClient.reset();
|
|
const auto errors = mReader.takeErrors();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
|
|
}
|
|
|
|
const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
|
|
|
|
int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
|
|
|
|
int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
|
|
|
|
int32_t getDisplayWidth() const { return getPrimaryDisplay().getDisplayWidth(); }
|
|
|
|
int32_t getDisplayHeight() const { return getPrimaryDisplay().getDisplayHeight(); }
|
|
|
|
void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
|
|
ASSERT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
|
|
ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
|
|
}
|
|
|
|
std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(uint32_t usage) {
|
|
const auto width = static_cast<uint32_t>(getDisplayWidth());
|
|
const auto height = static_cast<uint32_t>(getDisplayHeight());
|
|
|
|
const auto& graphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
|
|
width, height, ::android::PIXEL_FORMAT_RGBA_8888,
|
|
/*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest");
|
|
|
|
if (graphicBuffer && ::android::OK == graphicBuffer->initCheck()) {
|
|
return {true, graphicBuffer};
|
|
}
|
|
return {false, graphicBuffer};
|
|
}
|
|
|
|
uint64_t getStableDisplayId(int64_t display) {
|
|
const auto& [status, identification] =
|
|
mComposerClient->getDisplayIdentificationData(display);
|
|
EXPECT_TRUE(status.isOk());
|
|
|
|
if (const auto info = ::android::parseDisplayIdentificationData(
|
|
static_cast<uint8_t>(identification.port), identification.data)) {
|
|
return info->id.value;
|
|
}
|
|
|
|
return ::android::PhysicalDisplayId::fromPort(static_cast<uint8_t>(identification.port))
|
|
.value;
|
|
}
|
|
|
|
// Gets the per-display XML config
|
|
std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXml(int64_t display) {
|
|
std::stringstream pathBuilder;
|
|
pathBuilder << "/vendor/etc/displayconfig/display_id_" << getStableDisplayId(display)
|
|
<< ".xml";
|
|
const std::string path = pathBuilder.str();
|
|
auto document = std::make_unique<tinyxml2::XMLDocument>();
|
|
const tinyxml2::XMLError error = document->LoadFile(path.c_str());
|
|
if (error == tinyxml2::XML_SUCCESS) {
|
|
return document;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
// Gets the max display brightness for this display.
|
|
// If the display config xml does not exist, then assume that the display is not well-configured
|
|
// enough to provide a display brightness, so return nullopt.
|
|
std::optional<float> getMaxDisplayBrightnessNits(int64_t display) {
|
|
const auto document = getDisplayConfigXml(display);
|
|
if (!document) {
|
|
// Assume the device doesn't support display brightness
|
|
return std::nullopt;
|
|
}
|
|
|
|
const auto root = document->RootElement();
|
|
if (!root) {
|
|
// If there's somehow no root element, then this isn't a valid config
|
|
return std::nullopt;
|
|
}
|
|
|
|
const auto screenBrightnessMap = root->FirstChildElement("screenBrightnessMap");
|
|
if (!screenBrightnessMap) {
|
|
// A valid display config must have a screen brightness map
|
|
return std::nullopt;
|
|
}
|
|
|
|
auto point = screenBrightnessMap->FirstChildElement("point");
|
|
float maxNits = -1.f;
|
|
while (point != nullptr) {
|
|
const auto nits = point->FirstChildElement("nits");
|
|
if (nits) {
|
|
maxNits = std::max(maxNits, nits->FloatText(-1.f));
|
|
}
|
|
point = point->NextSiblingElement("point");
|
|
}
|
|
|
|
if (maxNits < 0.f) {
|
|
// If we got here, then there were no point elements containing a nit value, so this
|
|
// config isn't valid
|
|
return std::nullopt;
|
|
}
|
|
|
|
return maxNits;
|
|
}
|
|
|
|
void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
|
|
for (const auto& layer : layers) {
|
|
layer->write(mWriter);
|
|
}
|
|
execute();
|
|
}
|
|
|
|
void execute() {
|
|
const auto& commands = mWriter.getPendingCommands();
|
|
if (commands.empty()) {
|
|
mWriter.reset();
|
|
return;
|
|
}
|
|
|
|
auto [status, results] = mComposerClient->executeCommands(commands);
|
|
ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
|
|
|
|
mReader.parse(std::move(results));
|
|
mWriter.reset();
|
|
}
|
|
|
|
bool getHasReadbackBuffer() {
|
|
auto [status, readBackBufferAttributes] =
|
|
mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
|
|
if (status.isOk()) {
|
|
mPixelFormat = readBackBufferAttributes.format;
|
|
mDataspace = readBackBufferAttributes.dataspace;
|
|
return ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
|
|
}
|
|
EXPECT_NO_FATAL_FAILURE(
|
|
assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
|
|
return false;
|
|
}
|
|
|
|
std::shared_ptr<VtsComposerClient> mComposerClient;
|
|
std::vector<VtsDisplay> mDisplays;
|
|
// use the slot count usually set by SF
|
|
std::vector<ColorMode> mTestColorModes;
|
|
ComposerClientWriter mWriter;
|
|
ComposerClientReader mReader;
|
|
std::unique_ptr<TestRenderEngine> mTestRenderEngine;
|
|
common::PixelFormat mPixelFormat;
|
|
common::Dataspace mDataspace;
|
|
|
|
static constexpr uint32_t kClientTargetSlotCount = 64;
|
|
|
|
private:
|
|
void setTestColorModes() {
|
|
mTestColorModes.clear();
|
|
const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
|
|
ASSERT_TRUE(status.isOk());
|
|
|
|
for (ColorMode mode : modes) {
|
|
if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
|
|
mode) != ReadbackHelper::colorModes.end()) {
|
|
mTestColorModes.push_back(mode);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class GraphicsCompositionTest : public GraphicsCompositionTestBase,
|
|
public testing::WithParamInterface<std::string> {
|
|
public:
|
|
void SetUp() override { SetUpBase(GetParam()); }
|
|
};
|
|
|
|
TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setColor(BLUE);
|
|
layer->setDisplayFrame(coloredSquare);
|
|
layer->setZOrder(10);
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
// expected color for each pixel
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
// if hwc cannot handle and asks for composition change,
|
|
// just succeed the test
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
|
|
|
|
auto layer = std::make_shared<TestBufferLayer>(
|
|
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight(), common::PixelFormat::RGBA_8888);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setColor(BLUE);
|
|
layer->setDisplayFrame(coloredSquare);
|
|
layer->setZOrder(10);
|
|
layer->write(mWriter);
|
|
|
|
// This following buffer call should have no effect
|
|
const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
|
|
const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
|
|
ASSERT_TRUE(graphicBufferStatus);
|
|
const auto& buffer = graphicBuffer->handle;
|
|
mWriter.setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
|
|
/*acquireFence*/ -1);
|
|
|
|
// expected color for each pixel
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadDisplay) {
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
|
|
const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
|
|
ASSERT_TRUE(graphicBufferStatus);
|
|
const auto& bufferHandle = graphicBuffer->handle;
|
|
::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
|
|
|
|
const auto status =
|
|
mComposerClient->setReadbackBuffer(getInvalidDisplayId(), bufferHandle, fence);
|
|
|
|
EXPECT_FALSE(status.isOk());
|
|
EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadParameter) {
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
const native_handle_t bufferHandle{};
|
|
ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
|
|
const auto status =
|
|
mComposerClient->setReadbackBuffer(getPrimaryDisplayId(), &bufferHandle, releaseFence);
|
|
|
|
EXPECT_FALSE(status.isOk());
|
|
EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
const auto& [status, releaseFence] =
|
|
mComposerClient->getReadbackBufferFence(getPrimaryDisplayId());
|
|
|
|
EXPECT_FALSE(status.isOk());
|
|
EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
|
|
EXPECT_EQ(-1, releaseFence.get());
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, ClientComposition) {
|
|
EXPECT_TRUE(
|
|
mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
|
|
.isOk());
|
|
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
|
|
|
|
auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
|
|
getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight(), PixelFormat::RGBA_FP16);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
|
|
auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
|
|
if (!changedCompositionTypes.empty()) {
|
|
ASSERT_EQ(1, changedCompositionTypes.size());
|
|
ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
|
|
|
|
PixelFormat clientFormat = PixelFormat::RGBA_8888;
|
|
auto clientUsage = static_cast<uint32_t>(
|
|
static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
|
|
Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
|
|
common::Rect damage{0, 0, getDisplayWidth(), getDisplayHeight()};
|
|
|
|
// create client target buffer
|
|
const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
|
|
ASSERT_TRUE(graphicBufferStatus);
|
|
const auto& buffer = graphicBuffer->handle;
|
|
void* clientBufData;
|
|
const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
|
|
graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(), stride,
|
|
clientBufData, clientFormat, expectedColors));
|
|
int32_t clientFence;
|
|
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
|
|
ASSERT_EQ(::android::OK, unlockStatus);
|
|
mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
|
|
clientDataspace, std::vector<common::Rect>(1, damage));
|
|
layer->setToClientComposition(mWriter);
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
|
|
ASSERT_TRUE(changedCompositionTypes.empty());
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
|
|
ASSERT_TRUE(
|
|
mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
|
|
.isOk());
|
|
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, RED);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
auto deviceLayer = std::make_shared<TestBufferLayer>(
|
|
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight() / 2, PixelFormat::RGBA_8888);
|
|
std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
|
|
ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
|
|
{0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
|
|
static_cast<int32_t>(deviceLayer->getHeight())},
|
|
GREEN);
|
|
deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
|
|
static_cast<int32_t>(deviceLayer->getHeight())});
|
|
deviceLayer->setZOrder(10);
|
|
deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
|
|
deviceLayer->write(mWriter);
|
|
|
|
PixelFormat clientFormat = PixelFormat::RGBA_8888;
|
|
auto clientUsage = static_cast<uint32_t>(
|
|
static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
|
static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
|
|
Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
|
|
int32_t clientWidth = getDisplayWidth();
|
|
int32_t clientHeight = getDisplayHeight() / 2;
|
|
|
|
auto clientLayer = std::make_shared<TestBufferLayer>(
|
|
mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
|
|
clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
|
|
common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
|
|
getDisplayHeight()};
|
|
clientLayer->setDisplayFrame(clientFrame);
|
|
clientLayer->setZOrder(0);
|
|
clientLayer->write(mWriter);
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
|
|
auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
|
|
if (changedCompositionTypes.size() != 1) {
|
|
continue;
|
|
}
|
|
// create client target buffer
|
|
ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
|
|
const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
|
|
ASSERT_TRUE(graphicBufferStatus);
|
|
const auto& buffer = graphicBuffer->handle;
|
|
|
|
void* clientBufData;
|
|
graphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
|
|
&clientBufData);
|
|
|
|
std::vector<Color> clientColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(clientColors, getDisplayWidth(), clientFrame, RED);
|
|
ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
|
|
static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
|
|
graphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
|
|
int32_t clientFence;
|
|
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
|
|
ASSERT_EQ(::android::OK, unlockStatus);
|
|
mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
|
|
clientDataspace, std::vector<common::Rect>(1, clientFrame));
|
|
clientLayer->setToClientComposition(mWriter);
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
|
|
ASSERT_TRUE(changedCompositionTypes.empty());
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerDamage) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
common::Rect redRect = {0, 0, getDisplayWidth() / 4, getDisplayHeight() / 4};
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
|
|
|
|
auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
|
|
getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight(), PixelFormat::RGBA_8888);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
|
|
// update surface damage and recheck
|
|
redRect = {getDisplayWidth() / 4, getDisplayHeight() / 4, getDisplayWidth() / 2,
|
|
getDisplayHeight() / 2};
|
|
ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
|
|
getDisplayWidth());
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
|
|
layer->setSurfaceDamage(
|
|
std::vector<common::Rect>(1, {0, 0, getDisplayWidth() / 2, getDisplayWidth() / 2}));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
layer->setColor(RED);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setAlpha(0);
|
|
layer->setBlendMode(BlendMode::PREMULTIPLIED);
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
|
|
ReadbackHelper::fillColorsArea(
|
|
expectedColors, getDisplayWidth(),
|
|
{0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
|
|
|
|
auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
|
|
getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight(), PixelFormat::RGBA_8888);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
layer->setSourceCrop({0, static_cast<float>(getDisplayHeight() / 2),
|
|
static_cast<float>(getDisplayWidth()),
|
|
static_cast<float>(getDisplayHeight())});
|
|
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
|
|
|
|
// update expected colors to match crop
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight()}, BLUE);
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
|
|
common::Rect blueRect = {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight()};
|
|
auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
redLayer->setColor(RED);
|
|
redLayer->setDisplayFrame(redRect);
|
|
|
|
auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
blueLayer->setColor(BLUE);
|
|
blueLayer->setDisplayFrame(blueRect);
|
|
blueLayer->setZOrder(5);
|
|
|
|
std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
// red in front of blue
|
|
redLayer->setZOrder(10);
|
|
|
|
// fill blue first so that red will overwrite on overlap
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), blueRect, BLUE);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
|
|
redLayer->setZOrder(1);
|
|
ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
|
|
getDisplayWidth());
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), blueRect, BLUE);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
|
|
const auto& [status, capabilities] =
|
|
mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
|
|
ASSERT_TRUE(status.isOk());
|
|
|
|
const bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
|
|
DisplayCapability::BRIGHTNESS) != capabilities.end();
|
|
|
|
if (!brightnessSupport) {
|
|
GTEST_SUCCEED() << "Cannot verify dimming behavior without brightness support";
|
|
return;
|
|
}
|
|
|
|
const std::optional<float> maxBrightnessNitsOptional =
|
|
getMaxDisplayBrightnessNits(getPrimaryDisplayId());
|
|
|
|
ASSERT_TRUE(maxBrightnessNitsOptional.has_value());
|
|
|
|
const float maxBrightnessNits = *maxBrightnessNitsOptional;
|
|
|
|
// Preconditions to successfully run are knowing the max brightness and successfully applying
|
|
// the max brightness
|
|
ASSERT_GT(maxBrightnessNits, 0.f);
|
|
mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.f, maxBrightnessNits);
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace for "
|
|
"color mode: "
|
|
<< toString(mode);
|
|
continue;
|
|
}
|
|
const common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
|
|
const common::Rect dimmerRedRect = {0, getDisplayHeight() / 2, getDisplayWidth(),
|
|
getDisplayHeight()};
|
|
const auto redLayer =
|
|
std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
redLayer->setColor(RED);
|
|
redLayer->setDisplayFrame(redRect);
|
|
redLayer->setWhitePointNits(maxBrightnessNits);
|
|
redLayer->setBrightness(1.f);
|
|
|
|
const auto dimmerRedLayer =
|
|
std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
dimmerRedLayer->setColor(RED);
|
|
dimmerRedLayer->setDisplayFrame(dimmerRedRect);
|
|
// Intentionally use a small dimming ratio as some implementations may be more likely to
|
|
// kick into GPU composition to apply dithering when the dimming ratio is high.
|
|
static constexpr float kDimmingRatio = 0.9f;
|
|
dimmerRedLayer->setWhitePointNits(maxBrightnessNits * kDimmingRatio);
|
|
dimmerRedLayer->setBrightness(kDimmingRatio);
|
|
|
|
const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), dimmerRedRect, DIM_RED);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
writeLayers(layers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED()
|
|
<< "Readback verification not supported for GPU composition for color mode: "
|
|
<< toString(mode);
|
|
continue;
|
|
}
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(layers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
class GraphicsBlendModeCompositionTest
|
|
: public GraphicsCompositionTestBase,
|
|
public testing::WithParamInterface<std::tuple<std::string, std::string>> {
|
|
public:
|
|
void SetUp() override {
|
|
SetUpBase(std::get<0>(GetParam()));
|
|
// TODO(b/219590743) we should remove the below SRGB color mode
|
|
// once we have the BlendMode test fix for all the versions of the ColorMode
|
|
mTestColorModes.erase(
|
|
std::remove_if(mTestColorModes.begin(), mTestColorModes.end(),
|
|
[](ColorMode mode) { return mode != ColorMode::SRGB; }),
|
|
mTestColorModes.end());
|
|
mBackgroundColor = BLACK;
|
|
mTopLayerColor = RED;
|
|
}
|
|
|
|
void setBackgroundColor(Color color) { mBackgroundColor = color; }
|
|
|
|
void setTopLayerColor(Color color) { mTopLayerColor = color; }
|
|
|
|
void setUpLayers(BlendMode blendMode) {
|
|
mLayers.clear();
|
|
std::vector<Color> topLayerPixelColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(topLayerPixelColors, getDisplayWidth(),
|
|
{0, 0, getDisplayWidth(), getDisplayHeight()},
|
|
mTopLayerColor);
|
|
|
|
auto backgroundLayer =
|
|
std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
backgroundLayer->setZOrder(0);
|
|
backgroundLayer->setColor(mBackgroundColor);
|
|
|
|
auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
|
|
getPrimaryDisplayId(), getDisplayWidth(),
|
|
getDisplayHeight(), PixelFormat::RGBA_8888);
|
|
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
layer->setZOrder(10);
|
|
layer->setDataspace(Dataspace::UNKNOWN, mWriter);
|
|
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
|
|
|
|
layer->setBlendMode(blendMode);
|
|
layer->setAlpha(std::stof(std::get<1>(GetParam())));
|
|
|
|
mLayers.push_back(backgroundLayer);
|
|
mLayers.push_back(layer);
|
|
}
|
|
|
|
void setExpectedColors(std::vector<Color>& expectedColors) {
|
|
ASSERT_EQ(2, mLayers.size());
|
|
ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
|
|
getDisplayWidth());
|
|
|
|
auto layer = mLayers[1];
|
|
BlendMode blendMode = layer->getBlendMode();
|
|
float alpha = mTopLayerColor.a * layer->getAlpha();
|
|
if (blendMode == BlendMode::NONE) {
|
|
for (auto& expectedColor : expectedColors) {
|
|
expectedColor.r = mTopLayerColor.r * layer->getAlpha();
|
|
expectedColor.g = mTopLayerColor.g * layer->getAlpha();
|
|
expectedColor.b = mTopLayerColor.b * layer->getAlpha();
|
|
expectedColor.a = alpha;
|
|
}
|
|
} else if (blendMode == BlendMode::PREMULTIPLIED) {
|
|
for (auto& expectedColor : expectedColors) {
|
|
expectedColor.r =
|
|
mTopLayerColor.r * layer->getAlpha() + mBackgroundColor.r * (1.0f - alpha);
|
|
expectedColor.g =
|
|
mTopLayerColor.g * layer->getAlpha() + mBackgroundColor.g * (1.0f - alpha);
|
|
expectedColor.b =
|
|
mTopLayerColor.b * layer->getAlpha() + mBackgroundColor.b * (1.0f - alpha);
|
|
expectedColor.a = alpha + mBackgroundColor.a * (1.0f - alpha);
|
|
}
|
|
} else if (blendMode == BlendMode::COVERAGE) {
|
|
for (auto& expectedColor : expectedColors) {
|
|
expectedColor.r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0f - alpha);
|
|
expectedColor.g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0f - alpha);
|
|
expectedColor.b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0f - alpha);
|
|
expectedColor.a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0f - alpha);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
std::vector<std::shared_ptr<TestLayer>> mLayers;
|
|
Color mBackgroundColor;
|
|
Color mTopLayerColor;
|
|
};
|
|
|
|
TEST_P(GraphicsBlendModeCompositionTest, None) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
setBackgroundColor(BLACK);
|
|
setTopLayerColor(TRANSLUCENT_RED);
|
|
setUpLayers(BlendMode::NONE);
|
|
setExpectedColors(expectedColors);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(mLayers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
setBackgroundColor(BLACK);
|
|
setTopLayerColor(TRANSLUCENT_RED);
|
|
|
|
setUpLayers(BlendMode::COVERAGE);
|
|
setExpectedColors(expectedColors);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
|
|
setBackgroundColor(BLACK);
|
|
setTopLayerColor(TRANSLUCENT_RED);
|
|
setUpLayers(BlendMode::PREMULTIPLIED);
|
|
setExpectedColors(expectedColors);
|
|
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(mLayers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
|
|
protected:
|
|
void SetUp() override {
|
|
GraphicsCompositionTest::SetUp();
|
|
|
|
auto backgroundLayer =
|
|
std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
|
|
backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
|
|
backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
|
|
backgroundLayer->setZOrder(0);
|
|
|
|
mSideLength =
|
|
getDisplayWidth() < getDisplayHeight() ? getDisplayWidth() : getDisplayHeight();
|
|
common::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
|
|
common::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength};
|
|
|
|
mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
|
|
getPrimaryDisplayId(), mSideLength, mSideLength,
|
|
PixelFormat::RGBA_8888);
|
|
mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
|
|
mLayer->setZOrder(10);
|
|
|
|
std::vector<Color> baseColors(static_cast<size_t>(mSideLength * mSideLength));
|
|
ReadbackHelper::fillColorsArea(baseColors, mSideLength, redRect, RED);
|
|
ReadbackHelper::fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
|
|
ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
|
|
mLayers = {backgroundLayer, mLayer};
|
|
}
|
|
|
|
protected:
|
|
std::shared_ptr<TestBufferLayer> mLayer;
|
|
std::vector<std::shared_ptr<TestLayer>> mLayers;
|
|
int mSideLength;
|
|
};
|
|
|
|
TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
auto status = mComposerClient->setColorMode(getPrimaryDisplayId(), mode,
|
|
RenderIntent::COLORIMETRIC);
|
|
if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
|
|
(status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
|
|
status.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
|
|
SUCCEED() << "ColorMode not supported, skip test";
|
|
return;
|
|
}
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
mLayer->setTransform(Transform::FLIP_H);
|
|
mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
|
|
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(mLayers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
mLayer->setTransform(Transform::FLIP_V);
|
|
mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
|
|
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(mLayers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
TEST_P(GraphicsTransformCompositionTest, ROT_180) {
|
|
for (ColorMode mode : mTestColorModes) {
|
|
EXPECT_TRUE(mComposerClient
|
|
->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
|
|
.isOk());
|
|
|
|
bool isSupported;
|
|
ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
|
|
if (!isSupported) {
|
|
GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
|
|
return;
|
|
}
|
|
ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
|
|
getDisplayHeight(), mPixelFormat, mDataspace);
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
|
|
|
|
mLayer->setTransform(Transform::ROT_180);
|
|
mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
|
|
|
|
std::vector<Color> expectedColors(
|
|
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{mSideLength / 2, mSideLength / 2, mSideLength, mSideLength},
|
|
RED);
|
|
ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
|
|
{0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
|
|
|
|
writeLayers(mLayers);
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
|
|
execute();
|
|
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
|
|
GTEST_SUCCEED();
|
|
return;
|
|
}
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
mWriter.presentDisplay(getPrimaryDisplayId());
|
|
execute();
|
|
ASSERT_TRUE(mReader.takeErrors().empty());
|
|
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
|
|
mTestRenderEngine->setRenderLayers(mLayers);
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
|
|
ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
|
|
}
|
|
}
|
|
|
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest);
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
PerInstance, GraphicsCompositionTest,
|
|
testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
|
|
::android::PrintInstanceNameToString);
|
|
|
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest);
|
|
INSTANTIATE_TEST_SUITE_P(BlendMode, GraphicsBlendModeCompositionTest,
|
|
testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
|
|
IComposer::descriptor)),
|
|
testing::Values("0.2", "1.0")));
|
|
|
|
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest);
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
PerInstance, GraphicsTransformCompositionTest,
|
|
testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
|
|
::android::PrintInstanceNameToString);
|
|
|
|
} // namespace
|
|
} // namespace aidl::android::hardware::graphics::composer3::vts
|