| /* |
| * Copyright 2019 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_hidl_hal_readback_tests@2.2" |
| |
| #include <composer-command-buffer/2.2/ComposerCommandBuffer.h> |
| #include <composer-vts/2.1/GraphicsComposerCallback.h> |
| #include <composer-vts/2.1/TestCommandReader.h> |
| #include <composer-vts/2.2/ComposerVts.h> |
| #include <composer-vts/2.2/ReadbackVts.h> |
| #include <composer-vts/2.2/RenderEngineVts.h> |
| #include <gtest/gtest.h> |
| #include <hidl/GtestPrinter.h> |
| #include <hidl/ServiceManagement.h> |
| #include <ui/GraphicBuffer.h> |
| #include <ui/PixelFormat.h> |
| #include <ui/Rect.h> |
| #include <ui/Region.h> |
| |
| namespace android { |
| namespace hardware { |
| namespace graphics { |
| namespace composer { |
| namespace V2_2 { |
| namespace vts { |
| namespace { |
| |
| using android::Rect; |
| using common::V1_1::BufferUsage; |
| using common::V1_1::Dataspace; |
| using common::V1_1::PixelFormat; |
| using V2_1::Config; |
| using V2_1::Display; |
| using V2_1::vts::TestCommandReader; |
| |
| class GraphicsCompositionTestBase : public ::testing::Test { |
| protected: |
| using PowerMode = V2_1::IComposerClient::PowerMode; |
| void SetUpBase(const std::string& service_name) { |
| ASSERT_NO_FATAL_FAILURE( |
| mComposer = std::make_unique<Composer>(IComposer::getService(service_name))); |
| ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient()); |
| mComposerCallback = new V2_1::vts::GraphicsComposerCallback; |
| mComposerClient->registerCallback(mComposerCallback); |
| |
| // assume the first display is primary and is never removed |
| mPrimaryDisplay = waitForFirstDisplay(); |
| Config activeConfig; |
| ASSERT_NO_FATAL_FAILURE(activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay)); |
| ASSERT_NO_FATAL_FAILURE( |
| mDisplayWidth = mComposerClient->getDisplayAttribute( |
| mPrimaryDisplay, activeConfig, IComposerClient::Attribute::WIDTH)); |
| ASSERT_NO_FATAL_FAILURE( |
| mDisplayHeight = mComposerClient->getDisplayAttribute( |
| mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT)); |
| |
| setTestColorModes(); |
| |
| // explicitly disable vsync |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false)); |
| mComposerCallback->setVsyncAllowed(false); |
| |
| // set up command writer/reader and gralloc |
| mWriter = std::make_shared<CommandWriterBase>(1024); |
| mReader = std::make_unique<TestCommandReader>(); |
| |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON)); |
| |
| ASSERT_NO_FATAL_FAILURE( |
| mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine( |
| renderengine::RenderEngineCreationArgs::Builder() |
| .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888)) |
| .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers) |
| .setEnableProtectedContext(false) |
| .setPrecacheToneMapperShaderOnly(false) |
| .setContextPriority( |
| renderengine::RenderEngine::ContextPriority::HIGH) |
| .build()))); |
| |
| renderengine::DisplaySettings clientCompositionDisplay; |
| clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight); |
| clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay; |
| |
| mTestRenderEngine->initGraphicBuffer( |
| static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1, |
| static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | |
| BufferUsage::GPU_RENDER_TARGET)); |
| mTestRenderEngine->setDisplaySettings(clientCompositionDisplay); |
| } |
| |
| void TearDown() override { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF)); |
| EXPECT_EQ(0, mReader->mErrors.size()); |
| EXPECT_EQ(0, mReader->mCompositionChanges.size()); |
| if (mComposerCallback != nullptr) { |
| EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount()); |
| EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount()); |
| EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount()); |
| } |
| } |
| |
| void clearCommandReaderState() { |
| mReader->mCompositionChanges.clear(); |
| mReader->mErrors.clear(); |
| } |
| |
| void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) { |
| for (auto layer : layers) { |
| layer->write(mWriter); |
| } |
| execute(); |
| } |
| |
| void execute() { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get())); |
| } |
| |
| std::unique_ptr<Composer> mComposer; |
| std::shared_ptr<ComposerClient> mComposerClient; |
| |
| sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback; |
| // the first display and is assumed never to be removed |
| Display mPrimaryDisplay; |
| int32_t mDisplayWidth; |
| int32_t mDisplayHeight; |
| std::vector<ColorMode> mTestColorModes; |
| std::shared_ptr<CommandWriterBase> mWriter; |
| std::unique_ptr<TestCommandReader> mReader; |
| std::unique_ptr<TestRenderEngine> mTestRenderEngine; |
| |
| bool mHasReadbackBuffer; |
| PixelFormat mPixelFormat; |
| Dataspace mDataspace; |
| |
| static constexpr uint32_t kClientTargetSlotCount = 64; |
| |
| private: |
| Display waitForFirstDisplay() { |
| while (true) { |
| std::vector<Display> displays = mComposerCallback->getDisplays(); |
| if (displays.empty()) { |
| usleep(5 * 1000); |
| continue; |
| } |
| return displays[0]; |
| } |
| } |
| |
| void setTestColorModes() { |
| mTestColorModes.clear(); |
| mComposerClient->getRaw()->getColorModes_2_2(mPrimaryDisplay, [&](const auto& tmpError, |
| const auto& tmpModes) { |
| ASSERT_EQ(Error::NONE, tmpError); |
| for (ColorMode mode : tmpModes) { |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight}); |
| layer->setColor(BLUE); |
| layer->setDisplayFrame(coloredSquare); |
| layer->setZOrder(10); |
| |
| std::vector<std::shared_ptr<TestLayer>> layers = {layer}; |
| |
| // expected color for each pixel |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| // if hwc cannot handle and asks for composition change, |
| // just succeed the test |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, |
| GREEN); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, |
| BLUE); |
| |
| auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight, PixelFormat::RGBA_8888); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| 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_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->presentDisplay(); |
| execute(); |
| |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight}); |
| layer->setColor(BLUE); |
| layer->setDisplayFrame(coloredSquare); |
| layer->setZOrder(10); |
| layer->write(mWriter); |
| |
| // This following buffer call should have no effect |
| uint64_t usage = |
| static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN); |
| sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make( |
| mDisplayWidth, mDisplayHeight, (int32_t)PixelFormat::RGBA_8888, 1, usage); |
| ASSERT_EQ(STATUS_OK, buffer->initCheck()); |
| mWriter->setLayerBuffer(0, buffer->handle, -1); |
| |
| // expected color for each pixel |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| mWriter->validateDisplay(); |
| execute(); |
| |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| } |
| } |
| |
| TEST_P(GraphicsCompositionTest, ClientComposition) { |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)); |
| |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, |
| GREEN); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, |
| BLUE); |
| |
| auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight, PixelFormat::RGBA_FP16); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| layer->setZOrder(10); |
| layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| |
| std::vector<std::shared_ptr<TestLayer>> layers = {layer}; |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| |
| if (mReader->mCompositionChanges.size() != 0) { |
| ASSERT_EQ(1, mReader->mCompositionChanges.size()); |
| ASSERT_EQ(1, mReader->mCompositionChanges[0].second); |
| |
| PixelFormat clientFormat = PixelFormat::RGBA_8888; |
| uint64_t clientUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | |
| BufferUsage::CPU_WRITE_OFTEN | |
| BufferUsage::COMPOSER_CLIENT_TARGET); |
| Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode); |
| IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight}; |
| |
| bool clientTargetSupported = mComposerClient->getClientTargetSupport_2_2( |
| mPrimaryDisplay, layer->mWidth, layer->mHeight, clientFormat, clientDataspace); |
| // if the client target format is not supported, skip this |
| // configuration |
| if (!clientTargetSupported) { |
| std::cout << "Client target configuration width: " << layer->mWidth |
| << " height: " << layer->mHeight |
| << " pixel format: PixelFormat::RGBA_8888 dataspace: " |
| << ReadbackHelper::getDataspaceString(clientDataspace) |
| << " unsupported for display" << std::endl; |
| mReader->mCompositionChanges.clear(); |
| continue; |
| } |
| |
| // create client target buffer |
| sp<GraphicBuffer> clientBuffer = |
| sp<GraphicBuffer>::make(layer->mWidth, layer->mHeight, (int32_t)clientFormat, |
| layer->mLayerCount, clientUsage); |
| ASSERT_EQ(STATUS_OK, clientBuffer->initCheck()); |
| |
| void* clientBufData = nullptr; |
| ASSERT_EQ(STATUS_OK, clientBuffer->lock(clientUsage, &clientBufData)); |
| |
| ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(layer->mWidth, layer->mHeight, |
| clientBuffer->stride, clientBufData, |
| clientFormat, expectedColors)); |
| clientBuffer->unlock(); |
| |
| mWriter->setClientTarget(0, clientBuffer->handle, -1, clientDataspace, |
| std::vector<IComposerClient::Rect>(1, damage)); |
| |
| layer->setToClientComposition(mWriter); |
| mWriter->validateDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mCompositionChanges.size()); |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->presentDisplay(); |
| execute(); |
| |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| } |
| } |
| |
| TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)); |
| |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| auto deviceLayer = std::make_shared<TestBufferLayer>( |
| mComposerClient, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight / 2, PixelFormat::RGBA_8888); |
| std::vector<IComposerClient::Color> deviceColors(deviceLayer->mWidth * |
| deviceLayer->mHeight); |
| ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth, |
| {0, 0, static_cast<int32_t>(deviceLayer->mWidth), |
| static_cast<int32_t>(deviceLayer->mHeight)}, |
| GREEN); |
| deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mWidth), |
| static_cast<int32_t>(deviceLayer->mHeight)}); |
| deviceLayer->setZOrder(10); |
| deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors)); |
| deviceLayer->write(mWriter); |
| |
| PixelFormat clientFormat = PixelFormat::RGBA_8888; |
| uint64_t clientUsage = |
| static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | |
| BufferUsage::COMPOSER_CLIENT_TARGET); |
| Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode); |
| int32_t clientWidth = mDisplayWidth; |
| int32_t clientHeight = mDisplayHeight / 2; |
| |
| bool clientTargetSupported = mComposerClient->getClientTargetSupport_2_2( |
| mPrimaryDisplay, clientWidth, clientHeight, clientFormat, clientDataspace); |
| // if the client target format is not supported, skip this |
| // configuration |
| if (!clientTargetSupported) { |
| std::cout << "Client target configuration width: " << clientWidth |
| << " height: " << clientHeight |
| << " pixel format: PixelFormat::RGBA_8888 dataspace: " |
| << ReadbackHelper::getDataspaceString(clientDataspace) |
| << " unsupported for display" << std::endl; |
| continue; |
| } |
| |
| auto clientLayer = std::make_shared<TestBufferLayer>( |
| mComposerClient, *mTestRenderEngine, mPrimaryDisplay, clientWidth, clientHeight, |
| PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); |
| IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; |
| clientLayer->setDisplayFrame(clientFrame); |
| clientLayer->setZOrder(0); |
| clientLayer->write(mWriter); |
| mWriter->validateDisplay(); |
| execute(); |
| |
| if (mReader->mCompositionChanges.size() != 1) { |
| std::cout << "HWC asked for none or more than 1 composition change, skipping" |
| << std::endl; |
| mReader->mCompositionChanges.clear(); |
| continue; |
| } |
| // create client target buffer |
| ASSERT_EQ(1, mReader->mCompositionChanges[0].second); |
| sp<GraphicBuffer> clientBuffer = |
| sp<GraphicBuffer>::make(mDisplayWidth, mDisplayHeight, (int32_t)clientFormat, |
| clientLayer->mLayerCount, clientUsage); |
| ASSERT_EQ(STATUS_OK, clientBuffer->initCheck()); |
| |
| void* clientBufData = nullptr; |
| ASSERT_EQ(STATUS_OK, clientBuffer->lock(clientUsage, &clientBufData)); |
| |
| std::vector<IComposerClient::Color> clientColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(clientColors, mDisplayWidth, clientFrame, RED); |
| ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mDisplayWidth, mDisplayHeight, |
| clientBuffer->stride, clientBufData, |
| clientFormat, clientColors)); |
| EXPECT_EQ(STATUS_OK, clientBuffer->unlock()); |
| |
| mWriter->setClientTarget(0, clientBuffer->handle, -1, clientDataspace, |
| std::vector<IComposerClient::Rect>(1, clientFrame)); |
| clientLayer->setToClientComposition(mWriter); |
| mWriter->validateDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mCompositionChanges.size()); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| } |
| } |
| |
| TEST_P(GraphicsCompositionTest, SetLayerDamage) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| IComposerClient::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4}; |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); |
| |
| auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight, PixelFormat::RGBA_8888); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| 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(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| |
| // update surface damage and recheck |
| redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2}; |
| ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); |
| |
| ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors)); |
| layer->setSurfaceDamage(std::vector<IComposerClient::Rect>( |
| 1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2})); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| ASSERT_EQ(0, mReader->mCompositionChanges.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| } |
| } |
| |
| TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| layer->setColor(RED); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| layer->setZOrder(10); |
| layer->setAlpha(0); |
| layer->setBlendMode(IComposerClient::BlendMode::PREMULTIPLIED); |
| |
| std::vector<std::shared_ptr<TestLayer>> layers = {layer}; |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, |
| BLUE); |
| |
| auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight, PixelFormat::RGBA_8888); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| layer->setZOrder(10); |
| layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2), |
| static_cast<float>(mDisplayWidth), |
| static_cast<float>(mDisplayHeight)}); |
| ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors)); |
| |
| std::vector<std::shared_ptr<TestLayer>> layers = {layer}; |
| |
| // update expected colors to match crop |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight}, BLUE); |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| IComposerClient::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2}; |
| IComposerClient::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight}; |
| auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| redLayer->setColor(RED); |
| redLayer->setDisplayFrame(redRect); |
| |
| auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| blueLayer->setColor(BLUE); |
| blueLayer->setDisplayFrame(blueRect); |
| blueLayer->setZOrder(5); |
| |
| std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer}; |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| |
| // red in front of blue |
| redLayer->setZOrder(10); |
| |
| // fill blue first so that red will overwrite on overlap |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| |
| redLayer->setZOrder(1); |
| ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| writeLayers(layers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mCompositionChanges.size()); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| 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())); |
| mTestColorModes = {ColorMode::SRGB}; // TODO: add more color mode support |
| mBackgroundColor = BLACK; |
| mTopLayerColor = RED; |
| } |
| |
| void setBackgroundColor(IComposerClient::Color color) { mBackgroundColor = color; } |
| |
| void setTopLayerColor(IComposerClient::Color color) { mTopLayerColor = color; } |
| |
| void setUpLayers(IComposerClient::BlendMode blendMode) { |
| mLayers.clear(); |
| std::vector<IComposerClient::Color> topLayerPixelColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(topLayerPixelColors, mDisplayWidth, |
| {0, 0, mDisplayWidth, mDisplayHeight}, mTopLayerColor); |
| |
| auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| backgroundLayer->setZOrder(0); |
| backgroundLayer->setColor(mBackgroundColor); |
| |
| auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mDisplayWidth, |
| mDisplayHeight, PixelFormat::RGBA_8888); |
| layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| 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<IComposerClient::Color>& expectedColors) { |
| ASSERT_EQ(2, mLayers.size()); |
| ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth); |
| |
| auto layer = mLayers[1]; |
| IComposerClient::BlendMode blendMode = layer->mBlendMode; |
| float alpha = mTopLayerColor.a / 255.0 * layer->mAlpha; |
| if (blendMode == IComposerClient::BlendMode::NONE) { |
| for (int i = 0; i < expectedColors.size(); i++) { |
| expectedColors[i].r = mTopLayerColor.r * layer->mAlpha; |
| expectedColors[i].g = mTopLayerColor.g * layer->mAlpha; |
| expectedColors[i].b = mTopLayerColor.b * layer->mAlpha; |
| expectedColors[i].a = alpha * 255.0; |
| } |
| } else if (blendMode == IComposerClient::BlendMode::PREMULTIPLIED) { |
| for (int i = 0; i < expectedColors.size(); i++) { |
| expectedColors[i].r = |
| mTopLayerColor.r * layer->mAlpha + mBackgroundColor.r * (1.0 - alpha); |
| expectedColors[i].g = |
| mTopLayerColor.g * layer->mAlpha + mBackgroundColor.g * (1.0 - alpha); |
| expectedColors[i].b = |
| mTopLayerColor.b * layer->mAlpha + mBackgroundColor.b * (1.0 - alpha); |
| expectedColors[i].a = alpha + mBackgroundColor.a * (1.0 - alpha); |
| } |
| } else if (blendMode == IComposerClient::BlendMode::COVERAGE) { |
| for (int i = 0; i < expectedColors.size(); i++) { |
| expectedColors[i].r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0 - alpha); |
| expectedColors[i].g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0 - alpha); |
| expectedColors[i].b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0 - alpha); |
| expectedColors[i].a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0 - alpha); |
| } |
| } |
| } |
| |
| protected: |
| std::vector<std::shared_ptr<TestLayer>> mLayers; |
| IComposerClient::Color mBackgroundColor; |
| IComposerClient::Color mTopLayerColor; |
| }; |
| |
| // TODO(b/145557764): Re-enable after the bug is fixed. |
| TEST_P(GraphicsBlendModeCompositionTest, DISABLED_None) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| |
| setBackgroundColor(BLACK); |
| setTopLayerColor(TRANSLUCENT_RED); |
| setUpLayers(IComposerClient::BlendMode::NONE); |
| setExpectedColors(expectedColors); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| mTestRenderEngine->setRenderLayers(mLayers); |
| ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers()); |
| ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors)); |
| } |
| } |
| |
| // TODO: bug 116865056: Readback returns (245, 0, 0) for layer plane |
| // alpha of .2, expected 10.2 |
| TEST_P(GraphicsBlendModeCompositionTest, DISABLED_Coverage) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| |
| setBackgroundColor(BLACK); |
| setTopLayerColor(TRANSLUCENT_RED); |
| |
| setUpLayers(IComposerClient::BlendMode::COVERAGE); |
| setExpectedColors(expectedColors); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors)); |
| } |
| } |
| |
| TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| |
| setBackgroundColor(BLACK); |
| setTopLayerColor(TRANSLUCENT_RED); |
| setUpLayers(IComposerClient::BlendMode::PREMULTIPLIED); |
| setExpectedColors(expectedColors); |
| |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| 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(); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| |
| auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay); |
| backgroundLayer->setColor({0, 0, 0, 0}); |
| backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); |
| backgroundLayer->setZOrder(0); |
| |
| mSideLength = mDisplayWidth < mDisplayHeight ? mDisplayWidth : mDisplayHeight; |
| IComposerClient::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2}; |
| IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, |
| mSideLength}; |
| |
| mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine, |
| mPrimaryDisplay, mSideLength, mSideLength, |
| PixelFormat::RGBA_8888); |
| mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength}); |
| mLayer->setZOrder(10); |
| |
| std::vector<IComposerClient::Color> baseColors(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<IComposerClient::Color> baseColors; |
| std::vector<std::shared_ptr<TestLayer>> mLayers; |
| int mSideLength; |
| }; |
| |
| TEST_P(GraphicsTransformCompositionTest, FLIP_H) { |
| for (ColorMode mode : mTestColorModes) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| mLayer->setTransform(Transform::FLIP_H); |
| mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE); |
| |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| mLayer->setTransform(Transform::FLIP_V); |
| mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE); |
| |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| 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) { |
| std::cout << "---Testing Color Mode " << ReadbackHelper::getColorModeString(mode) << "---" |
| << std::endl; |
| mWriter->selectDisplay(mPrimaryDisplay); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)); |
| |
| mComposerClient->getRaw()->getReadbackBufferAttributes( |
| mPrimaryDisplay, |
| [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) { |
| mHasReadbackBuffer = ReadbackHelper::readbackSupported(tmpPixelFormat, |
| tmpDataspace, tmpError); |
| mPixelFormat = tmpPixelFormat; |
| mDataspace = tmpDataspace; |
| }); |
| |
| if (!mHasReadbackBuffer) { |
| std::cout << "Readback not supported or unsupported pixelFormat/dataspace" << std::endl; |
| GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace"; |
| return; |
| } |
| ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mDisplayWidth, |
| mDisplayHeight, mPixelFormat, mDataspace); |
| ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); |
| |
| mLayer->setTransform(Transform::ROT_180); |
| mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); |
| |
| std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}, |
| RED); |
| ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, |
| {0, 0, mSideLength / 2, mSideLength / 2}, BLUE); |
| |
| writeLayers(mLayers); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| clearCommandReaderState(); |
| GTEST_SUCCEED(); |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| 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::hardware::getAllHalInstanceNames(IComposer::descriptor)), |
| android::hardware::PrintInstanceNameToString); |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest); |
| INSTANTIATE_TEST_CASE_P( |
| BlendModeTest, GraphicsBlendModeCompositionTest, |
| testing::Combine( |
| testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), |
| testing::Values("0.2", "1.0")), |
| android::hardware::PrintInstanceTupleNameToString<>); |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest); |
| INSTANTIATE_TEST_SUITE_P( |
| PerInstance, GraphicsTransformCompositionTest, |
| testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), |
| android::hardware::PrintInstanceNameToString); |
| |
| } // anonymous namespace |
| } // namespace vts |
| } // namespace V2_2 |
| } // namespace composer |
| } // namespace graphics |
| } // namespace hardware |
| } // namespace android |