diff options
| author | 2019-10-14 15:49:22 -0700 | |
|---|---|---|
| committer | 2019-10-16 10:20:50 -0700 | |
| commit | da3446eb26f8922fa373f15f64dd5e65b4230e55 (patch) | |
| tree | 96edf4ea08e34950a4d9aa8ad0f587b728c5a9df | |
| parent | e676761dc5600be49bac302cd416c4a168f86f8f (diff) | |
Adding onFrameAvailable test for BLASTBufferQueue
Bug: 142546708
Test: build, boot, libgui_test
Change-Id: I92a03e777334b7b4729338c7e3a75dad1db8b613
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 2 | ||||
| -rw-r--r-- | libs/gui/tests/BLASTBufferQueue_test.cpp | 156 |
2 files changed, 142 insertions, 16 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 3a369cdd43..9a5017577d 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -64,7 +64,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence : Fence::NO_FENCE); mNextCallbackBufferItem = BufferItem(); } - mDequeueWaitCV.notify_one(); + mDequeueWaitCV.notify_all(); decStrong((void*)transactionCallbackThunk); } diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index a5f115e462..db1ac249b5 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -18,8 +18,14 @@ #include <gui/BLASTBufferQueue.h> +#include <android/hardware/graphics/common/1.2/types.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> #include <gui/SurfaceComposerClient.h> +#include <private/gui/ComposerService.h> +#include <ui/DisplayInfo.h> #include <ui/GraphicBuffer.h> +#include <ui/GraphicTypes.h> #include <gtest/gtest.h> @@ -27,10 +33,8 @@ using namespace std::chrono_literals; namespace android { -const int DEFAULT_WIDTH = 100; -const int DEFAULT_HEIGHT = 100; - using Transaction = SurfaceComposerClient::Transaction; +using android::hardware::graphics::common::V1_2::BufferUsage; class BLASTBufferQueueHelper { public: @@ -47,12 +51,24 @@ public: } int getWidth() { return mBlastBufferQueueAdapter->mWidth; } + int getHeight() { return mBlastBufferQueueAdapter->mHeight; } + Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; } + + sp<IGraphicBufferProducer> getIGraphicBufferProducer() { + return mBlastBufferQueueAdapter->getIGraphicBufferProducer(); + } + const sp<SurfaceControl> getSurfaceControl() { return mBlastBufferQueueAdapter->mSurfaceControl; } + void waitForCallback() { + std::unique_lock lock{mBlastBufferQueueAdapter->mMutex}; + mBlastBufferQueueAdapter->mDequeueWaitCV.wait_for(lock, 1s); + } + private: sp<BLASTBufferQueue> mBlastBufferQueueAdapter; }; @@ -73,39 +89,149 @@ protected: } void SetUp() { + mComposer = ComposerService::getComposerService(); mClient = new SurfaceComposerClient(); - mSurfaceControl = mClient->createSurface(String8("TestSurface"), DEFAULT_WIDTH, - DEFAULT_HEIGHT, PIXEL_FORMAT_RGBA_8888); + mDisplayToken = mClient->getInternalDisplayToken(); + ASSERT_NE(nullptr, mDisplayToken.get()); + Transaction t; + t.setDisplayLayerStack(mDisplayToken, 0); + t.apply(); + t.clear(); + + DisplayInfo info; + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplayToken, &info)); + mDisplayWidth = info.w; + mDisplayHeight = info.h; + + mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth, + mDisplayHeight, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceBufferState, + /*parent*/ nullptr); + t.setLayerStack(mSurfaceControl, 0) + .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max()) + .setFrame(mSurfaceControl, Rect(0, 0, mDisplayWidth, mDisplayHeight)) + .show(mSurfaceControl) + .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB) + .apply(); + } + + void fillBuffer(uint32_t* bufData, uint32_t width, uint32_t height, uint32_t stride, uint8_t r, + uint8_t g, uint8_t b) { + for (uint32_t row = 0; row < height; row++) { + for (uint32_t col = 0; col < width; col++) { + uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col); + *pixel = r; + *(pixel + 1) = g; + *(pixel + 2) = b; + *(pixel + 3) = 255; + } + } + } + + void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b) { + const auto width = mScreenCaptureBuf->getWidth(); + const auto height = mScreenCaptureBuf->getHeight(); + const auto stride = mScreenCaptureBuf->getStride(); + + uint32_t* bufData; + mScreenCaptureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN), + reinterpret_cast<void**>(&bufData)); + + for (uint32_t row = 0; row < height; row++) { + for (uint32_t col = 0; col < width; col++) { + uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col); + EXPECT_EQ(r, *(pixel)); + EXPECT_EQ(g, *(pixel + 1)); + EXPECT_EQ(b, *(pixel + 2)); + } + } + mScreenCaptureBuf->unlock(); + ASSERT_EQ(false, ::testing::Test::HasFailure()); } sp<SurfaceComposerClient> mClient; + sp<ISurfaceComposer> mComposer; + + sp<IBinder> mDisplayToken; + sp<SurfaceControl> mSurfaceControl; + sp<GraphicBuffer> mScreenCaptureBuf; + + uint32_t mDisplayWidth; + uint32_t mDisplayHeight; }; TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) { // create BLASTBufferQueue adapter associated with this surface - BLASTBufferQueueHelper adapter(mSurfaceControl, DEFAULT_WIDTH, DEFAULT_HEIGHT); + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl()); - ASSERT_EQ(DEFAULT_WIDTH, adapter.getWidth()); - ASSERT_EQ(DEFAULT_HEIGHT, adapter.getHeight()); + ASSERT_EQ(mDisplayWidth, adapter.getWidth()); + ASSERT_EQ(mDisplayHeight, adapter.getHeight()); ASSERT_EQ(nullptr, adapter.getNextTransaction()); } TEST_F(BLASTBufferQueueTest, Update) { - BLASTBufferQueueHelper adapter(mSurfaceControl, DEFAULT_WIDTH, DEFAULT_HEIGHT); + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); sp<SurfaceControl> updateSurface = - mClient->createSurface(String8("UpdateTest"), DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2, - PIXEL_FORMAT_RGB_888); - adapter.update(updateSurface, DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2); + mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2, + PIXEL_FORMAT_RGBA_8888); + adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2); ASSERT_EQ(updateSurface, adapter.getSurfaceControl()); - ASSERT_EQ(DEFAULT_WIDTH / 2, adapter.getWidth()); - ASSERT_EQ(DEFAULT_HEIGHT / 2, adapter.getHeight()); + ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth()); + ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight()); } TEST_F(BLASTBufferQueueTest, SetNextTransaction) { - BLASTBufferQueueHelper adapter(mSurfaceControl, DEFAULT_WIDTH, DEFAULT_HEIGHT); + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); Transaction next; adapter.setNextTransaction(&next); ASSERT_EQ(&next, adapter.getNextTransaction()); } + +TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { + uint8_t r = 255; + uint8_t g = 0; + uint8_t b = 0; + + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); + auto igbProducer = adapter.getIGraphicBufferProducer(); + ASSERT_NE(nullptr, igbProducer.get()); + IGraphicBufferProducer::QueueBufferOutput qbOutput; + ASSERT_EQ(NO_ERROR, + igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, + &qbOutput)); + ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(3)); + + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buf; + auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight, + PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN, + nullptr, nullptr); + ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret); + ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf)); + + uint32_t* bufData; + buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN), + reinterpret_cast<void**>(&bufData)); + fillBuffer(bufData, buf->getWidth(), buf->getHeight(), buf->getStride(), r, g, b); + buf->unlock(); + + IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + Rect(mDisplayWidth, mDisplayHeight), + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, + Fence::NO_FENCE); + igbProducer->queueBuffer(slot, input, &qbOutput); + + adapter.waitForCallback(); + + // capture screen and verify that it is red + bool capturedSecureLayers; + ASSERT_EQ(NO_ERROR, + mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers, + ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), + mDisplayWidth, mDisplayHeight, + /*useIdentityTransform*/ false)); + ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b)); +} } // namespace android |