Update the test directory structure

vts is moved from aidl/android/ to aidl/vts
functional, include & composer-vts directory is removed as well.

BUG: 220171967
Test: atest VtsHalGraphicsComposer3_TargetTest
Change-Id: I6cafbbd99374308a1cc06e27cc590e70618f7075
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
new file mode 100644
index 0000000..f75af85
--- /dev/null
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -0,0 +1,1455 @@
+/**
+ * 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(); }
+
+    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();
+    }
+
+    std::pair<ScopedAStatus, bool> getHasReadbackBuffer() {
+        auto [status, readBackBufferAttributes] =
+                mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
+        if (status.isOk()) {
+            mPixelFormat = readBackBufferAttributes.format;
+            mDataspace = readBackBufferAttributes.dataspace;
+            return {std::move(status), ReadbackHelper::readbackSupported(mPixelFormat, mDataspace)};
+        }
+        return {std::move(status), 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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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) {
+    const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+    EXPECT_TRUE(readbackStatus.isOk());
+    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) {
+    const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+    EXPECT_TRUE(readbackStatus.isOk());
+    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());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, status.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadParameter) {
+    const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+    EXPECT_TRUE(readbackStatus.isOk());
+    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());
+    ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, status.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
+    const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+    EXPECT_TRUE(readbackStatus.isOk());
+    if (!isSupported) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    const auto& [status, releaseFence] =
+            mComposerClient->getReadbackBufferFence(getPrimaryDisplayId());
+
+    EXPECT_FALSE(status.isOk());
+    EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, status.getServiceSpecificError());
+    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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    for (ColorMode mode : mTestColorModes) {
+        EXPECT_TRUE(mComposerClient
+                            ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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 = {ColorMode::SRGB};
+        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;
+};
+// TODO(b/219576457) Enable tests once we have fixed the bug on composer.
+TEST_P(GraphicsBlendModeCompositionTest, DISABLED_None) {
+    for (ColorMode mode : mTestColorModes) {
+        EXPECT_TRUE(mComposerClient
+                            ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
+             status.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
+            SUCCEED() << "ColorMode not supported, skip test";
+            return;
+        }
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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());
+
+        const auto& [readbackStatus, isSupported] = getHasReadbackBuffer();
+        EXPECT_TRUE(readbackStatus.isOk());
+        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