diff options
| author | 2019-12-04 22:12:12 +0000 | |
|---|---|---|
| committer | 2019-12-04 22:12:12 +0000 | |
| commit | d3647642b3bdb231d713154d40425a83f68dc8d2 (patch) | |
| tree | 5654f37a114e2dadc1985611930b7517289297c9 | |
| parent | cace66c539fc5c2c3451fa5af5c6324ddcc4e384 (diff) | |
| parent | 45e4b3b9e1f2135d9959ec17dc4daf0b3cd5e1bd (diff) | |
Merge "Set the crop on the BLASt adapter"
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 10 | ||||
| -rw-r--r-- | libs/gui/include/gui/BLASTBufferQueue.h | 1 | ||||
| -rw-r--r-- | libs/gui/tests/BLASTBufferQueue_test.cpp | 136 |
3 files changed, 135 insertions, 12 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 06a5f06e31..29ea84e76d 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -19,6 +19,7 @@ #include <gui/BLASTBufferQueue.h> #include <gui/BufferItemConsumer.h> +#include <gui/GLConsumer.h> #include <chrono> @@ -131,13 +132,20 @@ void BLASTBufferQueue::processNextBufferLocked() { t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this)); t->setFrame(mSurfaceControl, {0, 0, (int32_t)buffer->getWidth(), (int32_t)buffer->getHeight()}); - t->setCrop(mSurfaceControl, {0, 0, (int32_t)buffer->getWidth(), (int32_t)buffer->getHeight()}); + t->setCrop(mSurfaceControl, computeCrop(mLastSubmittedBufferItem)); if (applyTransaction) { t->apply(); } } +Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { + if (item.mScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { + return GLConsumer::scaleDownCrop(item.mCrop, mWidth, mHeight); + } + return item.mCrop; +} + void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { std::lock_guard _lock{mMutex}; diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index f1758a220b..dd0b4709e5 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -62,6 +62,7 @@ private: BLASTBufferQueue(const BLASTBufferQueue& rhs); void processNextBufferLocked() REQUIRES(mMutex); + Rect computeCrop(const BufferItem& item); sp<SurfaceControl> mSurfaceControl; diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index 6ecdae5fd7..ae6c5cff0c 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -131,10 +131,10 @@ protected: producer = igbProducer; } - 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++) { + void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g, + uint8_t b) { + for (uint32_t row = rect.top; row < rect.bottom; row++) { + for (uint32_t col = rect.left; col < rect.right; col++) { uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col); *pixel = r; *(pixel + 1) = g; @@ -144,7 +144,7 @@ protected: } } - void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b) { + void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region) { const auto width = mScreenCaptureBuf->getWidth(); const auto height = mScreenCaptureBuf->getHeight(); const auto stride = mScreenCaptureBuf->getStride(); @@ -156,9 +156,16 @@ protected: 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)); + if (row >= region.top && row < region.bottom && col >= region.left && + col < region.right) { + EXPECT_EQ(r, *(pixel)); + EXPECT_EQ(g, *(pixel + 1)); + EXPECT_EQ(b, *(pixel + 2)); + } else { + EXPECT_EQ(0, *(pixel)); + EXPECT_EQ(0, *(pixel + 1)); + EXPECT_EQ(0, *(pixel + 2)); + } } } mScreenCaptureBuf->unlock(); @@ -225,7 +232,7 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { 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); + fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b); buf->unlock(); IGraphicBufferProducer::QueueBufferOutput qbOutput; @@ -236,7 +243,7 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { igbProducer->queueBuffer(slot, input, &qbOutput); ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint); - sleep(1); + adapter.waitForCallbacks(); // capture screen and verify that it is red bool capturedSecureLayers; @@ -245,7 +252,8 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(), mDisplayWidth, mDisplayHeight, /*useIdentityTransform*/ false)); - ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b)); + ASSERT_NO_FATAL_FAILURE( + checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); } TEST_F(BLASTBufferQueueTest, TripleBuffering) { @@ -286,4 +294,110 @@ TEST_F(BLASTBufferQueueTest, TripleBuffering) { } adapter.waitForCallbacks(); } + +TEST_F(BLASTBufferQueueTest, SetCrop_Item) { + uint8_t r = 255; + uint8_t g = 0; + uint8_t b = 0; + + BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); + sp<IGraphicBufferProducer> igbProducer; + setUpProducer(adapter, igbProducer); + 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, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b); + buf->unlock(); + + IGraphicBufferProducer::QueueBufferOutput qbOutput; + IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + Rect(mDisplayWidth, mDisplayHeight / 2), + NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, + Fence::NO_FENCE); + igbProducer->queueBuffer(slot, input, &qbOutput); + ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint); + + adapter.waitForCallbacks(); + // 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, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); +} + +TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { + uint8_t r = 255; + uint8_t g = 0; + uint8_t b = 0; + + int32_t bufferSideLength = + (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2; + int32_t finalCropSideLength = bufferSideLength / 2; + + auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceColor); + ASSERT_NE(nullptr, bg.get()); + Transaction t; + t.setLayerStack(bg, 0) + .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight)) + .setColor(bg, half3{0, 0, 0}) + .setLayer(bg, 0) + .apply(); + + BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength); + sp<IGraphicBufferProducer> igbProducer; + setUpProducer(adapter, igbProducer); + int slot; + sp<Fence> fence; + sp<GraphicBuffer> buf; + auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength, + 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, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0); + fillBuffer(bufData, + Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2, + buf->getHeight()), + buf->getStride(), r, g, b); + buf->unlock(); + + IGraphicBufferProducer::QueueBufferOutput qbOutput; + IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + Rect(bufferSideLength, finalCropSideLength), + NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0, + Fence::NO_FENCE); + igbProducer->queueBuffer(slot, input, &qbOutput); + ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint); + + adapter.waitForCallbacks(); + // 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, + {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength})); +} + } // namespace android |