diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 91318bc..db4c914 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -44,6 +44,12 @@
 using V2_1::Layer;
 using V2_1::vts::TestCommandReader;
 
+static const IComposerClient::Color BLACK = {0, 0, 0, 0xff};
+static const IComposerClient::Color RED = {0xff, 0, 0, 0xff};
+static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33};
+static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff};
+static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff};
+
 // Test environment for graphics.composer
 class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
@@ -61,106 +67,57 @@
 
 class TestLayer {
    public:
-    TestLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : mLayer(client->createLayer(display, kBufferSlotCount)),
-          mComposerClient(client),
-          mDisplay(display) {}
+    TestLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : mLayer(client->createLayer(display, kBufferSlotCount)), mComposerClient(client) {}
 
-    virtual ~TestLayer() { mComposerClient->destroyLayer(mDisplay, mLayer); }
+    // ComposerClient will take care of destroying layers, no need to explicitly
+    // call destroyLayers here
+    virtual ~TestLayer(){};
 
-    virtual void write(std::shared_ptr<CommandWriterBase> writer) {
+    virtual void write(const std::shared_ptr<CommandWriterBase>& writer) {
         writer->selectLayer(mLayer);
         writer->setLayerDisplayFrame(mDisplayFrame);
+        writer->setLayerSourceCrop(mSourceCrop);
         writer->setLayerZOrder(mZOrder);
+        writer->setLayerSurfaceDamage(mSurfaceDamage);
+        writer->setLayerTransform(mTransform);
+        writer->setLayerPlaneAlpha(mAlpha);
+        writer->setLayerBlendMode(mBlendMode);
     }
 
     void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
+    void setSourceCrop(IComposerClient::FRect crop) { mSourceCrop = crop; }
     void setZOrder(uint32_t z) { mZOrder = z; }
 
+    void setSurfaceDamage(std::vector<IComposerClient::Rect> surfaceDamage) {
+        mSurfaceDamage = surfaceDamage;
+    }
+
+    void setTransform(Transform transform) { mTransform = transform; }
+    void setAlpha(float alpha) { mAlpha = alpha; }
+    void setBlendMode(IComposerClient::BlendMode blendMode) { mBlendMode = blendMode; }
+
+    static constexpr uint32_t kBufferSlotCount = 64;
+
+    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
+    uint32_t mZOrder = 0;
+    std::vector<IComposerClient::Rect> mSurfaceDamage;
+    Transform mTransform = static_cast<Transform>(0);
+    IComposerClient::FRect mSourceCrop = {0, 0, 0, 0};
+    float mAlpha = 1.0;
+    IComposerClient::BlendMode mBlendMode = IComposerClient::BlendMode::NONE;
+
    protected:
     Layer mLayer;
-    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
-    uint32_t mZOrder = 0;
 
    private:
     std::shared_ptr<ComposerClient> const mComposerClient;
-    const Display mDisplay;
-    static constexpr uint32_t kBufferSlotCount = 64;
-};
-
-class TestColorLayer : public TestLayer {
-   public:
-    TestColorLayer(std::shared_ptr<ComposerClient> const client, Display display)
-        : TestLayer{client, display} {}
-
-    void write(std::shared_ptr<CommandWriterBase> writer) override {
-        TestLayer::write(writer);
-        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
-        writer->setLayerColor(mColor);
-    }
-
-    void setColor(IComposerClient::Color color) { mColor = color; }
-
-   private:
-    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
 };
 
 class GraphicsComposerReadbackTest : public ::testing::VtsHalHidlTargetTestBase {
-   protected:
-    using PowerMode = V2_1::IComposerClient::PowerMode;
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(
-            mComposer = std::make_unique<Composer>(
-                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
-        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 = mComposerClient->getActiveConfig(mPrimaryDisplay);
-        mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                             IComposerClient::Attribute::WIDTH);
-        mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
-                                                              IComposerClient::Attribute::HEIGHT);
-
-        // explicitly disable vsync
-        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>();
-        mGralloc = std::make_unique<Gralloc>();
-
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
-                mHasReadbackBuffer = tmpError == Error::NONE;
-            });
-    }
-
-    ~GraphicsComposerReadbackTest() override {
-        if (mComposerCallback != nullptr) {
-            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
-            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
-        }
-    }
-
-    void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
-
-    void render(const std::vector<std::shared_ptr<TestLayer>>& layers) {
-        for (auto layer : layers) {
-            layer->write(mWriter);
-        }
-        execute();
-        mWriter->validateDisplay();
-        mWriter->presentDisplay();
-        execute();
-    }
-
-    int32_t GetBytesPerPixel(PixelFormat format) {
-        switch (format) {
+   public:
+    static int32_t GetBytesPerPixel(PixelFormat pixelFormat) {
+        switch (pixelFormat) {
             case PixelFormat::RGBA_8888:
                 return 4;
             case PixelFormat::RGB_888:
@@ -170,9 +127,120 @@
         }
     }
 
+    static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
+                           PixelFormat pixelFormat,
+                           std::vector<IComposerClient::Color> desiredPixelColors) {
+        ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * width + col;
+                IComposerClient::Color srcColor = desiredPixelColors[pixel];
+
+                int offset = (row * stride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+                pixelColor[0] = srcColor.r;
+                pixelColor[1] = srcColor.g;
+                pixelColor[2] = srcColor.b;
+
+                if (bytesPerPixel == 4) {
+                    pixelColor[3] = srcColor.a;
+                }
+            }
+        }
+    }
+
+   protected:
+    using PowerMode = V2_1::IComposerClient::PowerMode;
+    void SetUp() override {
+        VtsHalHidlTargetTestBase::SetUp();
+        ASSERT_NO_FATAL_FAILURE(
+            mComposer = std::make_unique<Composer>(
+                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+        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));
+
+        // 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>();
+        mGralloc = std::make_shared<Gralloc>();
+
+        mComposerClient->getRaw()->getReadbackBufferAttributes(
+            mPrimaryDisplay,
+            [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+                mHasReadbackBuffer = readbackSupported(tmpPixelFormat, tmpDataspace, tmpError);
+                mPixelFormat = tmpPixelFormat;
+                mDataspace = tmpDataspace;
+            });
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+    }
+
+    void TearDown() override {
+        mWriter->validateDisplay();
+        mWriter->presentDisplay();
+        execute();
+        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());
+        }
+        VtsHalHidlTargetTestBase::TearDown();
+    }
+
+    void execute() {
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->execute(mReader.get(), mWriter.get()));
+    }
+
+    void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+        for (auto layer : layers) {
+            layer->write(mWriter);
+        }
+        execute();
+    }
+
+    void clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
+                     int32_t height) {
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * mDisplayWidth + col;
+                expectedColors[pixel] = BLACK;
+            }
+        }
+    }
+
+    void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
+                        IComposerClient::Rect area, IComposerClient::Color color) {
+        for (int row = area.top; row < area.bottom; row++) {
+            for (int col = area.left; col < area.right; col++) {
+                int pixel = row * stride + col;
+                expectedColors[pixel] = color;
+            }
+        }
+    }
+
     bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
                            const Error error) {
-        if (error == Error::UNSUPPORTED) {
+        if (error != Error::NONE) {
             return false;
         }
         // TODO: add support for RGBA_1010102
@@ -185,33 +253,6 @@
         return true;
     }
 
-    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
-                                     Dataspace* outDataspace) {
-        mComposerClient->getRaw()->getReadbackBufferAttributes(
-            display, [&](const auto&, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
-                *outPixelFormat = tmpOutPixelFormat;
-                *outDataspace = tmpOutDataspace;
-            });
-    }
-
-    void checkReadbackBuffer(IMapper::BufferDescriptorInfo info, uint32_t stride, void* bufferData,
-                             std::vector<IComposerClient::Color> expectedColors) {
-        int32_t bytesPerPixel = GetBytesPerPixel(info.format);
-        ASSERT_NE(-1, bytesPerPixel)
-            << "unexpected pixel format " << static_cast<int32_t>(info.format)
-            << "(expected RGBA_8888 or RGB_888)";
-        for (int row = 0; row < mDisplayHeight; row++) {
-            for (int col = 0; col < mDisplayWidth; col++) {
-                int pixel = row * mDisplayWidth + col;
-                int offset = (row * stride + col) * bytesPerPixel;
-                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-
-                EXPECT_EQ(expectedColors[pixel].r, pixelColor[0]);
-                EXPECT_EQ(expectedColors[pixel].g, pixelColor[1]);
-                EXPECT_EQ(expectedColors[pixel].b, pixelColor[2]);
-            }
-        }
-    }
 
     std::unique_ptr<Composer> mComposer;
     std::shared_ptr<ComposerClient> mComposerClient;
@@ -223,9 +264,13 @@
     int32_t mDisplayHeight;
     std::shared_ptr<CommandWriterBase> mWriter;
     std::unique_ptr<TestCommandReader> mReader;
-    std::unique_ptr<Gralloc> mGralloc;
+    std::shared_ptr<Gralloc> mGralloc;
 
     bool mHasReadbackBuffer;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+
+    static constexpr uint32_t kClientTargetSlotCount = 64;
 
    private:
     Display waitForFirstDisplay() {
@@ -239,6 +284,178 @@
         }
     }
 };
+class ReadbackBuffer {
+   public:
+    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
+                   const std::shared_ptr<Gralloc>& gralloc, uint32_t width, uint32_t height,
+                   PixelFormat pixelFormat, Dataspace dataspace) {
+        mDisplay = display;
+
+        mComposerClient = client;
+        mGralloc = gralloc;
+
+        mPixelFormat = pixelFormat;
+        mDataspace = dataspace;
+
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = mPixelFormat;
+        mInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+    };
+
+    ~ReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void setReadbackBuffer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
+    }
+
+    void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        // lock buffer for reading
+        int32_t fenceHandle;
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
+
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, fenceHandle);
+        ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+        int32_t bytesPerPixel = GraphicsComposerReadbackTest::GetBytesPerPixel(mPixelFormat);
+        ASSERT_NE(-1, bytesPerPixel);
+        for (int row = 0; row < mInfo.height; row++) {
+            for (int col = 0; col < mInfo.width; col++) {
+                int pixel = row * mInfo.width + col;
+                int offset = (row * mStride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufData + offset;
+
+                ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
+                ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
+                ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+            }
+        }
+        int32_t unlockFence = mGralloc->unlock(mBufferHandle);
+        if (unlockFence != -1) {
+            sync_wait(unlockFence, -1);
+            close(unlockFence);
+        }
+    }
+
+   protected:
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+    const native_handle_t* mBufferHandle = nullptr;
+    PixelFormat mPixelFormat;
+    Dataspace mDataspace;
+    Display mDisplay;
+    std::shared_ptr<Gralloc> mGralloc;
+    std::shared_ptr<ComposerClient> mComposerClient;
+};
+
+class TestColorLayer : public TestLayer {
+   public:
+    TestColorLayer(const std::shared_ptr<ComposerClient>& client, Display display)
+        : TestLayer{client, display} {}
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
+        writer->setLayerColor(mColor);
+    }
+
+    void setColor(IComposerClient::Color color) { mColor = color; }
+
+   private:
+    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
+};
+
+class TestBufferLayer : public TestLayer {
+   public:
+    TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
+                    const std::shared_ptr<Gralloc>& gralloc, Display display, int32_t width,
+                    int32_t height, PixelFormat format,
+                    IComposerClient::Composition composition = IComposerClient::Composition::DEVICE)
+        : TestLayer{client, display} {
+        mGralloc = gralloc;
+        mComposition = composition;
+        mInfo.width = width;
+        mInfo.height = height;
+        mInfo.layerCount = 1;
+        mInfo.format = format;
+        mInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_OVERLAY);
+
+        mAccessRegion.top = 0;
+        mAccessRegion.left = 0;
+        mAccessRegion.width = width;
+        mAccessRegion.height = height;
+
+        setSourceCrop({0, 0, (float)width, (float)height});
+    }
+
+    ~TestBufferLayer() {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+        }
+    }
+
+    void write(const std::shared_ptr<CommandWriterBase>& writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(mComposition);
+        writer->setLayerDataspace(Dataspace::UNKNOWN);
+        writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
+        if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
+    }
+
+    void fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
+        void* bufData = mGralloc->lock(mBufferHandle, mInfo.usage, mAccessRegion, -1);
+        ASSERT_NO_FATAL_FAILURE(GraphicsComposerReadbackTest::fillBuffer(
+            mInfo.width, mInfo.height, mStride, bufData, mInfo.format, expectedColors));
+        mFillFence = mGralloc->unlock(mBufferHandle);
+        if (mFillFence != -1) {
+            sync_wait(mFillFence, -1);
+            close(mFillFence);
+        }
+    }
+    void setBuffer(std::vector<IComposerClient::Color> colors) {
+        if (mBufferHandle != nullptr) {
+            mGralloc->freeBuffer(mBufferHandle);
+            mBufferHandle = nullptr;
+        }
+        mBufferHandle = mGralloc->allocate(mInfo, /*import*/ true, &mStride);
+        ASSERT_NE(nullptr, mBufferHandle);
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+        ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mInfo, mStride));
+    }
+
+    void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
+        writer->selectLayer(mLayer);
+        writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
+    }
+
+    IMapper::BufferDescriptorInfo mInfo;
+    IMapper::Rect mAccessRegion;
+    uint32_t mStride;
+
+   protected:
+    IComposerClient::Composition mComposition;
+    std::shared_ptr<Gralloc> mGralloc;
+    int32_t mFillFence;
+    const native_handle_t* mBufferHandle = nullptr;
+};
 
 TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
     if (!mHasReadbackBuffer) {
@@ -246,13 +463,12 @@
         return;
     }
     mWriter->selectDisplay(mPrimaryDisplay);
-    mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
-    mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB, RenderIntent::COLORIMETRIC);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
 
     auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
-    IComposerClient::Color color({0, 0, 0xff, 0xff});
-    IComposerClient::Rect coloredSquare({100, 100, 500, 500});
-    layer->setColor(color);
+    IComposerClient::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setColor(BLUE);
     layer->setDisplayFrame(coloredSquare);
     layer->setZOrder(10);
 
@@ -260,58 +476,831 @@
 
     // expected color for each pixel
     std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
-    for (int row = 0; row < mDisplayHeight; row++) {
-        for (int col = 0; col < mDisplayWidth; col++) {
-            int pixel = row * mDisplayWidth + col;
-            if (row >= coloredSquare.top && row < coloredSquare.bottom &&
-                col >= coloredSquare.left && col < coloredSquare.right) {
-                expectedColors[pixel] = color;
-            } else {
-                expectedColors[pixel] = {0, 0, 0, 0xff};
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, 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) {
+        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_F(GraphicsComposerReadbackTest, SetLayerBuffer) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    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) {
+        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_F(GraphicsComposerReadbackTest, SetLayerBufferNoEffect) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    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
+    IMapper::BufferDescriptorInfo bufferInfo{};
+    bufferInfo.width = mDisplayWidth;
+    bufferInfo.height = mDisplayHeight;
+    bufferInfo.layerCount = 1;
+    bufferInfo.format = PixelFormat::RGBA_8888;
+    bufferInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN);
+    const native_handle_t* bufferHandle = mGralloc->allocate(bufferInfo);
+    mWriter->setLayerBuffer(0, bufferHandle, -1);
+
+    // expected color for each pixel
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mWriter->validateDisplay();
+    execute();
+
+    if (mReader->mCompositionChanges.size() != 0) {
+        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_F(GraphicsComposerReadbackTest, ClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_FP16);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, 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);
+
+        ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+        // create client target buffer
+        uint32_t clientStride;
+        IMapper::BufferDescriptorInfo clientInfo;
+        clientInfo.width = layer->mInfo.width;
+        clientInfo.height = layer->mInfo.height;
+        clientInfo.layerCount = layer->mInfo.layerCount;
+        clientInfo.format = PixelFormat::RGBA_8888;
+        clientInfo.usage =
+            static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                  BufferUsage::COMPOSER_CLIENT_TARGET);
+        const native_handle_t* clientBufferHandle =
+            mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+        ASSERT_NE(nullptr, clientBufferHandle);
+
+        void* clientBufData =
+            mGralloc->lock(clientBufferHandle, clientInfo.usage, layer->mAccessRegion, -1);
+
+        ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                           clientBufData, clientInfo.format, expectedColors));
+        int clientFence = mGralloc->unlock(clientBufferHandle);
+        if (clientFence != -1) {
+            sync_wait(clientFence, -1);
+            close(clientFence);
+        }
+
+        IComposerClient::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+        mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                                 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_F(GraphicsComposerReadbackTest, DeviceAndClientComposition) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(
+        mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    auto deviceLayer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight / 2, PixelFormat::RGBA_8888);
+    std::vector<IComposerClient::Color> deviceColors(deviceLayer->mInfo.width *
+                                                     deviceLayer->mInfo.height);
+    fillColorsArea(deviceColors, deviceLayer->mInfo.width,
+                   {0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                    static_cast<int32_t>(deviceLayer->mInfo.height)},
+                   GREEN);
+    deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->mInfo.width),
+                                  static_cast<int32_t>(deviceLayer->mInfo.height)});
+    deviceLayer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+    deviceLayer->write(mWriter);
+
+    auto clientLayer = std::make_shared<TestBufferLayer>(
+        mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2,
+        PixelFormat::RGBA_8888, IComposerClient::Composition::CLIENT);
+    IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+    clientLayer->setDisplayFrame(clientFrame);
+    clientLayer->setZOrder(0);
+    clientLayer->write(mWriter);
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    IMapper::BufferDescriptorInfo clientInfo;
+    clientInfo.width = mDisplayWidth;
+    clientInfo.height = mDisplayHeight;
+    clientInfo.layerCount = 1;
+    clientInfo.format = PixelFormat::RGBA_8888;
+    clientInfo.usage =
+        static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                              BufferUsage::COMPOSER_CLIENT_TARGET);
+
+    uint32_t clientStride;
+    const native_handle_t* clientBufferHandle =
+        mGralloc->allocate(clientInfo, /*import*/ true, &clientStride);
+    ASSERT_NE(nullptr, clientBufferHandle);
+
+    IMapper::Rect clientAccessRegion;
+    clientAccessRegion.left = 0;
+    clientAccessRegion.top = 0;
+    clientAccessRegion.width = mDisplayWidth;
+    clientAccessRegion.height = mDisplayHeight;
+    void* clientData = mGralloc->lock(clientBufferHandle, clientInfo.usage, clientAccessRegion, -1);
+    std::vector<IComposerClient::Color> clientColors(clientInfo.width * clientInfo.height);
+    fillColorsArea(clientColors, clientInfo.width, clientFrame, RED);
+    ASSERT_NO_FATAL_FAILURE(fillBuffer(clientInfo.width, clientInfo.height, clientStride,
+                                       clientData, clientInfo.format, clientColors));
+    int clientFence = mGralloc->unlock(clientBufferHandle);
+    if (clientFence != -1) {
+        sync_wait(clientFence, -1);
+        close(clientFence);
+    }
+
+    mWriter->setClientTarget(0, clientBufferHandle, clientFence, Dataspace::UNKNOWN,
+                             std::vector<IComposerClient::Rect>(1, clientFrame));
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        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_F(GraphicsComposerReadbackTest, SetLayerDamage) {
+    if (!mHasReadbackBuffer) {
+        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);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, 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) {
+        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};
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    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_F(GraphicsComposerReadbackTest, SetLayerPlaneAlpha) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    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, mGralloc, 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) {
+        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));
+}
+
+TEST_F(GraphicsComposerReadbackTest, SetLayerSourceCrop) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE);
+
+    auto layer =
+        std::make_shared<TestBufferLayer>(mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth,
+                                          mDisplayHeight, PixelFormat::RGBA_8888);
+    layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+    layer->setZOrder(10);
+    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
+    fillColorsArea(expectedColors, mDisplayWidth, {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, 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) {
+        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_F(GraphicsComposerReadbackTest, SetLayerZOrder) {
+    if (!mHasReadbackBuffer) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                          RenderIntent::COLORIMETRIC));
+
+    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
+    fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, 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) {
+        GTEST_SUCCEED();
+        return;
+    }
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+    redLayer->setZOrder(1);
+    clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+    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));
+}
+
+class GraphicsComposerBlendModeReadbackTest : public GraphicsComposerReadbackTest,
+                                              public ::testing::WithParamInterface<float> {
+   public:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+        mBackgroundColor = BLACK;
+        mTopLayerColor = RED;
+    }
+
+    void TearDown() override { GraphicsComposerReadbackTest::TearDown(); }
+
+    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);
+        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, mGralloc, mPrimaryDisplay,
+                                                       mDisplayWidth, mDisplayHeight,
+                                                       PixelFormat::RGBA_8888);
+        layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+        layer->setZOrder(10);
+        ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
+
+        layer->setBlendMode(blendMode);
+        layer->setAlpha(GetParam());
+
+        mLayers.push_back(backgroundLayer);
+        mLayers.push_back(layer);
+    }
+
+    void setExpectedColors(std::vector<IComposerClient::Color>& expectedColors) {
+        ASSERT_EQ(2, mLayers.size());
+        clearColors(expectedColors, mDisplayWidth, mDisplayHeight);
+
+        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);
             }
         }
     }
 
-    PixelFormat pixelFormat;
-    Dataspace dataspace;
+   protected:
+    std::vector<std::shared_ptr<TestLayer>> mLayers;
+    IComposerClient::Color mBackgroundColor;
+    IComposerClient::Color mTopLayerColor;
+};
 
-    getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
-
-    IMapper::BufferDescriptorInfo info;
-    info.width = mDisplayWidth;
-    info.height = mDisplayHeight;
-    info.layerCount = 1;
-    info.format = pixelFormat;
-    info.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
-
-    uint32_t stride;
-    const native_handle_t* buffer = mGralloc->allocate(info, /*import*/ true, &stride);
-    mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
-
-    render(layers);
-
-    int32_t fenceHandle;
-    mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle);
-
-    // lock buffer
-    // Create Rect accessRegion to specify reading the entire buffer
-    IMapper::Rect accessRegion;
-    accessRegion.left = 0;
-    accessRegion.top = 0;
-    accessRegion.width = info.width;
-    accessRegion.height = info.height;
-
-    void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fenceHandle);
-    checkReadbackBuffer(info, stride, bufData, expectedColors);
-    int unlockFence = mGralloc->unlock(buffer);
-
-    if (unlockFence != -1) {
-        close(unlockFence);
+TEST_P(GraphicsComposerBlendModeReadbackTest, None) {
+    if (!mHasReadbackBuffer) {
+        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, mGralloc, 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) {
+        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));
+}
+
+// TODO: bug 116865056: Readback returns (245, 0, 0) for layer plane
+// alpha of .2, expected 10.2
+TEST_P(GraphicsComposerBlendModeReadbackTest, DISABLED_Coverage) {
+    if (!mHasReadbackBuffer) {
+        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, mGralloc, 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) {
+        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(GraphicsComposerBlendModeReadbackTest, Premultiplied) {
+    if (!mHasReadbackBuffer) {
+        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, mGralloc, 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) {
+        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));
+}
+
+INSTANTIATE_TEST_CASE_P(BlendModeTest, GraphicsComposerBlendModeReadbackTest,
+                        ::testing::Values(.2, 1.0));
+
+class GraphicsComposerTransformReadbackTest : public GraphicsComposerReadbackTest {
+   protected:
+    void SetUp() override {
+        GraphicsComposerReadbackTest::SetUp();
+        if (!mHasReadbackBuffer) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+            return;
+        }
+
+        mWriter->selectDisplay(mPrimaryDisplay);
+        ASSERT_NO_FATAL_FAILURE(mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB,
+                                                              RenderIntent::COLORIMETRIC));
+
+        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, mGralloc, mPrimaryDisplay,
+                                              mSideLength, mSideLength, PixelFormat::RGBA_8888);
+        mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
+        mLayer->setZOrder(10);
+
+        std::vector<IComposerClient::Color> baseColors(mSideLength * mSideLength);
+        fillColorsArea(baseColors, mSideLength, redRect, RED);
+        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_F(GraphicsComposerTransformReadbackTest, FLIP_H) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+    mLayer->setTransform(Transform::FLIP_H);
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
+    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) {
+        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_F(GraphicsComposerTransformReadbackTest, FLIP_V) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::FLIP_V);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
+    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) {
+        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_F(GraphicsComposerTransformReadbackTest, ROT_180) {
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGralloc, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+    mLayer->setTransform(Transform::ROT_180);
+
+    std::vector<IComposerClient::Color> expectedColors(mDisplayWidth * mDisplayHeight);
+    fillColorsArea(expectedColors, mDisplayWidth,
+                   {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}, RED);
+    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) {
+        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));
 }
 
 }  // anonymous namespace
