Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit feaab4f0 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9392159 from 377328c7 to udc-release

Change-Id: I13a977f6961220b5af449940a741cf324bff3170
parents d90d70c8 377328c7
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -126,15 +126,23 @@ void ComposerClient::setReadbackBuffer(Display display, const native_handle_t* b
    ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer";
}

void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
void ComposerClient::getRequiredReadbackBufferAttributes(Display display,
                                                         PixelFormat* outPixelFormat,
                                                         Dataspace* outDataspace) {
    ASSERT_EQ(Error::NONE, getReadbackBufferAttributes(display, outPixelFormat, outDataspace));
}

Error ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                                  Dataspace* outDataspace) {
    Error error;
    mClient->getReadbackBufferAttributes(
        display,
        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
            *outPixelFormat = tmpOutPixelFormat;
            *outDataspace = tmpOutDataspace;
            display, [&](const Error& tmpError, const PixelFormat& tmpPixelFormat,
                         const Dataspace& tmpDataspace) {
                error = tmpError;
                *outPixelFormat = tmpPixelFormat;
                *outDataspace = tmpDataspace;
            });
    return error;
}

void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
+113 −52
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include "renderengine/ExternalTexture.h"
#include "renderengine/impl/ExternalTexture.h"

using ::android::status_t;

namespace android {
namespace hardware {
namespace graphics {
@@ -107,6 +109,40 @@ int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
    }
}

void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
                                           IComposerClient::Color desiredColor, int* fillFence) {
    ASSERT_NE(nullptr, fillFence);
    std::vector<IComposerClient::Color> desiredColors(
            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
    ::android::Rect bounds = graphicBuffer->getBounds();
    fillColorsArea(desiredColors, static_cast<int32_t>(graphicBuffer->getWidth()),
                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, desiredColor);
    ASSERT_NO_FATAL_FAILURE(fillBufferAndGetFence(graphicBuffer, desiredColors, fillFence));
}

void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
                                           const std::vector<IComposerClient::Color>& desiredColors,
                                           int* fillFence) {
    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
    void* bufData;
    int32_t bytesPerPixel = -1;
    int32_t bytesPerStride = -1;
    status_t status =
            graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                                &bufData, &bytesPerPixel, &bytesPerStride);
    ASSERT_EQ(::android::OK, status);

    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
                                    : graphicBuffer->getStride();
    ReadbackHelper::fillBuffer(graphicBuffer->getWidth(), graphicBuffer->getHeight(), stride,
                               bufData, static_cast<PixelFormat>(graphicBuffer->getPixelFormat()),
                               desiredColors);
    status = graphicBuffer->unlockAsync(fillFence);
    ASSERT_EQ(::android::OK, status);
}

void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
                                PixelFormat pixelFormat,
                                std::vector<IComposerClient::Color> desiredPixelColors) {
@@ -116,16 +152,16 @@ void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride,
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            int pixel = row * width + col;
            IComposerClient::Color srcColor = desiredPixelColors[pixel];
            IComposerClient::Color desiredColor = 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;
            pixelColor[0] = desiredColor.r;
            pixelColor[1] = desiredColor.g;
            pixelColor[2] = desiredColor.b;

            if (bytesPerPixel == 4) {
                pixelColor[3] = srcColor.a;
                pixelColor[3] = desiredColor.a;
            }
        }
    }
@@ -152,12 +188,14 @@ void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expecte
    }
}

bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
                                       const Error error) {
bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error) {
    if (error != Error::NONE) {
        return false;
    }
    // TODO: add support for RGBA_1010102
    return readbackSupported(pixelFormat, dataspace);
}

bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace) {
    if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
        return false;
    }
@@ -167,71 +205,94 @@ bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dat
    return true;
}

void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
                                         void* bufferData, const uint32_t stride,
                                         const uint32_t width, const uint32_t height,
                                         const PixelFormat pixelFormat) {
    const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
void ReadbackHelper::createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
                                          Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer) {
    ASSERT_NE(nullptr, graphicBuffer);
    if (!readbackSupported(pixelFormat, dataspace)) {
        *graphicBuffer = nullptr;
    }
    android::PixelFormat bufferFormat = static_cast<android::PixelFormat>(pixelFormat);
    uint32_t layerCount = 1;
    uint64_t usage = static_cast<uint64_t>(static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) |
                                           static_cast<uint64_t>(BufferUsage::GPU_TEXTURE));
    *graphicBuffer = sp<GraphicBuffer>::make(width, height, bufferFormat, layerCount, usage,
                                             "ReadbackBuffer");
    ASSERT_NE(nullptr, *graphicBuffer);
    ASSERT_EQ(::android::OK, (*graphicBuffer)->initCheck());
}

void ReadbackHelper::compareColorToBuffer(IComposerClient::Color expectedColor,
                                          const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
    std::vector<IComposerClient::Color> expectedColors(
            static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
    ::android::Rect bounds = graphicBuffer->getBounds();
    fillColorsArea(expectedColors, static_cast<int32_t>(graphicBuffer->getWidth()),
                   {bounds.left, bounds.top, bounds.right, bounds.bottom}, expectedColor);
    compareColorsToBuffer(expectedColors, graphicBuffer, fence);
}

void ReadbackHelper::compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
                                           const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
    ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
                graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);

    int bytesPerPixel = -1;
    int bytesPerStride = -1;
    void* bufData = nullptr;
    status_t status = graphicBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN, &bufData, fence,
                                               &bytesPerPixel, &bytesPerStride);
    ASSERT_EQ(::android::OK, status);

    const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
                                    ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
                                    : graphicBuffer->getStride();

    if (bytesPerPixel == -1) {
        PixelFormat pixelFormat = static_cast<PixelFormat>(graphicBuffer->getPixelFormat());
        bytesPerPixel = ReadbackHelper::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;
            int offset = (row * stride + col) * bytesPerPixel;
            uint8_t* pixelColor = (uint8_t*)bufferData + offset;

            ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
            ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
            ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
    for (int row = 0; row < graphicBuffer->getHeight(); row++) {
        for (int col = 0; col < graphicBuffer->getWidth(); col++) {
            int pixel = row * static_cast<int32_t>(graphicBuffer->getWidth()) + col;
            int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
            uint8_t* pixelColor = (uint8_t*)bufData + offset;
            const IComposerClient::Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
            ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
            ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
            ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
        }
    }

    status = graphicBuffer->unlock();
    ASSERT_EQ(::android::OK, status);
}

ReadbackBuffer::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) {
                               uint32_t width, uint32_t height, PixelFormat pixelFormat) {
    mDisplay = display;

    mComposerClient = client;
    mGralloc = gralloc;

    mPixelFormat = pixelFormat;
    mDataspace = dataspace;

    mWidth = width;
    mHeight = height;
    mPixelFormat = pixelFormat;
    mLayerCount = 1;
    mFormat = mPixelFormat;
    mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);

    mAccessRegion.top = 0;
    mAccessRegion.left = 0;
    mAccessRegion.width = width;
    mAccessRegion.height = height;
}

void ReadbackBuffer::setReadbackBuffer() {
    mBufferHandle.reset(new Gralloc::NativeHandleWrapper(
            mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
                               /*import*/ true, &mStride)));
    ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle->get(), mWidth, mHeight,
                                                  mLayerCount, mFormat, mUsage, mStride));
    ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle->get(), -1));
    mGraphicBuffer = sp<GraphicBuffer>::make(mWidth, mHeight,
                                             static_cast<::android::PixelFormat>(mPixelFormat),
                                             mLayerCount, mUsage, "ReadbackBuffer");
    ASSERT_NE(nullptr, mGraphicBuffer);
    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
    mComposerClient->setReadbackBuffer(mDisplay, mGraphicBuffer->handle, -1 /* fence */);
}

void ReadbackBuffer::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->get(), mUsage, mAccessRegion, fenceHandle);
    ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
    ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
                                        mPixelFormat);
    int32_t unlockFence = mGralloc->unlock(mBufferHandle->get());
    if (unlockFence != -1) {
        sync_wait(unlockFence, -1);
        close(unlockFence);
    }
    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, fenceHandle);
}

void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+1 −3
Original line number Diff line number Diff line
@@ -83,9 +83,7 @@ void TestRenderEngine::drawLayers() {
void TestRenderEngine::checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors) {
    void* bufferData;
    ASSERT_EQ(0, mGraphicBuffer->lock(mGraphicBuffer->getUsage(), &bufferData));
    ReadbackHelper::compareColorBuffers(expectedColors, bufferData, mGraphicBuffer->getStride(),
                                        mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
                                        mFormat);
    ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, -1 /* fence */);
    ASSERT_EQ(0, mGraphicBuffer->unlock());
}

+4 −2
Original line number Diff line number Diff line
@@ -78,7 +78,9 @@ class ComposerClient : public V2_1::vts::ComposerClient {
                                    PixelFormat format, Dataspace dataspace);
    void setPowerMode_2_2(Display display, IComposerClient::PowerMode mode);
    void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
    void getRequiredReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                             Dataspace* outDataspace);
    Error getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                      Dataspace* outDataspace);
    void getReadbackBufferFence(Display display, int32_t* outFence);

+24 −16
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ namespace composer {
namespace V2_2 {
namespace vts {

using android::GraphicBuffer;
using android::sp;
using android::hardware::hidl_handle;
using common::V1_1::BufferUsage;
using common::V1_1::Dataspace;
@@ -156,6 +158,13 @@ class ReadbackHelper {

    static int32_t GetBytesPerPixel(PixelFormat pixelFormat);

    static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
                                      IComposerClient::Color desiredColor, int* fillFence);

    static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
                                      const std::vector<IComposerClient::Color>& desiredColors,
                                      int* fillFence);

    static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
                           PixelFormat pixelFormat,
                           std::vector<IComposerClient::Color> desiredPixelColors);
@@ -166,40 +175,39 @@ class ReadbackHelper {
    static void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
                               IComposerClient::Rect area, IComposerClient::Color color);

    static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
                                  const Error error);

    static const std::vector<ColorMode> colorModes;
    static const std::vector<Dataspace> dataspaces;

    static void compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
                                    void* bufferData, const uint32_t stride, const uint32_t width,
                                    const uint32_t height, const PixelFormat pixelFormat);
    static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error);
    static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace);

    static void createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
                                     Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer);

    static void compareColorToBuffer(IComposerClient::Color expectedColors,
                                     const sp<GraphicBuffer>& graphicBuffer, int32_t fence);

    static void compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
                                      const sp<GraphicBuffer>& graphicBuffer, int32_t fence);
};

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);
    ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client, uint32_t width,
                   uint32_t height, PixelFormat pixelFormat);

    void setReadbackBuffer();

    void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors);

  protected:
    sp<GraphicBuffer> mGraphicBuffer;
    uint32_t mWidth;
    uint32_t mHeight;
    PixelFormat mPixelFormat;
    uint32_t mLayerCount;
    PixelFormat mFormat;
    uint64_t mUsage;
    AccessRegion mAccessRegion;
    uint32_t mStride;
    std::unique_ptr<Gralloc::NativeHandleWrapper> mBufferHandle = nullptr;
    PixelFormat mPixelFormat;
    Dataspace mDataspace;
    Display mDisplay;
    std::shared_ptr<Gralloc> mGralloc;
    std::shared_ptr<ComposerClient> mComposerClient;
};

Loading