Loading graphics/composer/2.2/utils/vts/ComposerVts.cpp +16 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading graphics/composer/2.2/utils/vts/ReadbackVts.cpp +113 −52 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "renderengine/ExternalTexture.h" #include "renderengine/impl/ExternalTexture.h" using ::android::status_t; namespace android { namespace hardware { namespace graphics { Loading Loading @@ -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) { Loading @@ -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; } } } Loading @@ -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; } Loading @@ -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) { Loading graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +1 −3 Original line number Diff line number Diff line Loading @@ -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()); } Loading graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h +4 −2 Original line number Diff line number Diff line Loading @@ -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); Loading graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +24 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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 Loading
graphics/composer/2.2/utils/vts/ComposerVts.cpp +16 −8 Original line number Diff line number Diff line Loading @@ -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) { Loading
graphics/composer/2.2/utils/vts/ReadbackVts.cpp +113 −52 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include "renderengine/ExternalTexture.h" #include "renderengine/impl/ExternalTexture.h" using ::android::status_t; namespace android { namespace hardware { namespace graphics { Loading Loading @@ -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) { Loading @@ -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; } } } Loading @@ -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; } Loading @@ -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) { Loading
graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +1 −3 Original line number Diff line number Diff line Loading @@ -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()); } Loading
graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h +4 −2 Original line number Diff line number Diff line Loading @@ -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); Loading
graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +24 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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