blob: 6852589e32ae703124f5abc1aae4e8ed649a5dd2 [file] [log] [blame]
Valerie Hauc5011f92019-10-11 09:52:07 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BLASTBufferQueue_test"
18
19#include <gui/BLASTBufferQueue.h>
20
Vishnu Nair2e8ae852024-03-30 00:02:30 +000021#include <android-base/thread_annotations.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070022#include <android/hardware/graphics/common/1.2/types.h>
Huihong Luo3bdef862022-03-03 11:57:19 -080023#include <gui/AidlStatusUtil.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080024#include <gui/BufferQueueCore.h>
25#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080026#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070027#include <gui/IGraphicBufferProducer.h>
28#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080029#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070030#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070031#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050032#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070033#include <private/gui/ComposerService.h>
Huihong Luo9e84f332021-12-16 14:33:46 -080034#include <private/gui/ComposerServiceAIDL.h>
Melody Hsub9578222023-10-02 23:09:36 +000035#include <tests/utils/ScreenshotUtils.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010036#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070037#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070038#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070039#include <ui/GraphicTypes.h>
Melody Hsub9578222023-10-02 23:09:36 +000040#include <ui/Rect.h>
41#include <ui/Size.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080042#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070043
44#include <gtest/gtest.h>
45
Alec Mouri21d94322023-10-17 19:51:39 +000046#include <com_android_graphics_libgui_flags.h>
47
Valerie Hauc5011f92019-10-11 09:52:07 -070048using namespace std::chrono_literals;
49
50namespace android {
Alec Mouri21d94322023-10-17 19:51:39 +000051using namespace com::android::graphics::libgui;
Valerie Hauc5011f92019-10-11 09:52:07 -070052
Valerie Hauc5011f92019-10-11 09:52:07 -070053using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070054using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070055
chaviwd7deef72021-10-06 11:53:40 -050056class CountProducerListener : public BnProducerListener {
57public:
58 void onBufferReleased() override {
59 std::scoped_lock<std::mutex> lock(mMutex);
60 mNumReleased++;
61 mReleaseCallback.notify_one();
62 }
63
64 void waitOnNumberReleased(int32_t expectedNumReleased) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +000065 std::unique_lock lock{mMutex};
66 base::ScopedLockAssertion assumeLocked(mMutex);
chaviwd7deef72021-10-06 11:53:40 -050067 while (mNumReleased < expectedNumReleased) {
68 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
69 std::cv_status::timeout)
70 << "did not receive release";
71 }
72 }
73
74private:
75 std::mutex mMutex;
76 std::condition_variable mReleaseCallback;
77 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
78};
79
chaviwf10b9042021-10-13 15:48:59 -050080class TestBLASTBufferQueue : public BLASTBufferQueue {
81public:
82 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
83 int height, int32_t format)
84 : BLASTBufferQueue(name, surface, width, height, format) {}
85
chaviw6b9ffea2021-11-08 09:25:48 -060086 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
87 const std::vector<SurfaceControlStats>& stats) override {
88 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050089 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
90
91 {
92 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060093 mLastTransactionFrameNumber = frameNumber;
94 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050095 }
96 }
97
98 void waitForCallback(int64_t frameNumber) {
99 std::unique_lock lock{frameNumberMutex};
100 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -0600101 while (mLastTransactionFrameNumber < frameNumber) {
102 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -0500103 }
104 }
105
106private:
107 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600108 std::condition_variable mWaitForCallbackCV;
109 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500110};
111
Valerie Hauc5011f92019-10-11 09:52:07 -0700112class BLASTBufferQueueHelper {
113public:
114 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500115 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
116 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700117 }
118
119 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800120 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700121 }
122
Tianhao Yao4861b102022-02-03 20:18:35 +0000123 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
124 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
125 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
126 }
127
Chavi Weingartenc398c012023-04-12 17:26:02 +0000128 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000129 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000130 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000131 }
132
133 void stopContinuousSyncTransaction() {
134 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700135 }
136
Chavi Weingartenc398c012023-04-12 17:26:02 +0000137 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
138
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000139 int getWidth() {
140 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
141 return mBlastBufferQueueAdapter->mSize.width;
142 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700143
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000144 int getHeight() {
145 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
146 return mBlastBufferQueueAdapter->mSize.height;
147 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700148
Tianhao Yao4861b102022-02-03 20:18:35 +0000149 std::function<void(Transaction*)> getTransactionReadyCallback() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000150 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Tianhao Yao4861b102022-02-03 20:18:35 +0000151 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
152 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700153
154 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
155 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
156 }
157
Valerie Hauc5011f92019-10-11 09:52:07 -0700158 const sp<SurfaceControl> getSurfaceControl() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000159 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Valerie Hauc5011f92019-10-11 09:52:07 -0700160 return mBlastBufferQueueAdapter->mSurfaceControl;
161 }
162
Vishnu Naira4fbca52021-07-07 16:52:34 -0700163 sp<Surface> getSurface() {
164 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
165 }
166
Valerie Haud3b90d22019-11-06 09:37:31 -0800167 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700168 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000169 base::ScopedLockAssertion assumeLocked(mBlastBufferQueueAdapter->mMutex);
Vishnu Nair1506b182021-02-22 14:35:15 -0800170 // Wait until all but one of the submitted buffers have been released.
171 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800172 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
173 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700174 }
175
Vishnu Nair1506b182021-02-22 14:35:15 -0800176 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500177 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800178 }
179
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000180 void validateNumFramesSubmitted(size_t numFramesSubmitted) {
181 std::scoped_lock lock{mBlastBufferQueueAdapter->mMutex};
chaviw0acd33a2021-11-02 11:55:37 -0500182 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
183 }
184
chaviwc1cf4022022-06-03 13:32:33 -0500185 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
186 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
187 }
188
Valerie Hauc5011f92019-10-11 09:52:07 -0700189private:
chaviwf10b9042021-10-13 15:48:59 -0500190 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700191};
192
193class BLASTBufferQueueTest : public ::testing::Test {
194public:
195protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700196 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700197 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700198 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700199 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
200 ASSERT_FALSE(ids.empty());
201 // display 0 is picked as this test is not much display depedent
202 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700203 ASSERT_NE(nullptr, mDisplayToken.get());
204 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700205 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700206 t.apply();
207 t.clear();
208
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700209 ui::DisplayState displayState;
210 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
211 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800212 mDisplayWidth = resolution.getWidth();
213 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000214 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000215 static_cast<int32_t>(displayState.orientation));
Valerie Hauda3446e2019-10-14 15:49:22 -0700216
Melody Hsub9578222023-10-02 23:09:36 +0000217 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
218 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
219 ISurfaceComposerClient::eFXSurfaceBufferState,
220 /*parent*/ nullptr);
221
222 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
223 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
224 .show(mRootSurfaceControl)
225 .apply();
226
Valerie Hauda3446e2019-10-14 15:49:22 -0700227 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
228 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
229 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000230 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700231
Melody Hsub9578222023-10-02 23:09:36 +0000232 mCaptureArgs.sourceCrop = Rect(ui::Size(mDisplayWidth, mDisplayHeight));
233 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700234 }
235
chaviwd7deef72021-10-06 11:53:40 -0500236 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
237 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800238 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500239 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800240 }
241
chaviwd7deef72021-10-06 11:53:40 -0500242 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800243 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500244 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800245 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500246 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800247 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500248 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800249 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800250 }
251
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800252 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
253 uint8_t b) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000254 for (int32_t row = rect.top; row < rect.bottom; row++) {
255 for (int32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700256 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
257 *pixel = r;
258 *(pixel + 1) = g;
259 *(pixel + 2) = b;
260 *(pixel + 3) = 255;
261 }
262 }
263 }
264
Valerie Hau5977fc82019-12-05 15:56:39 -0800265 void fillQuadrants(sp<GraphicBuffer>& buf) {
266 const auto bufWidth = buf->getWidth();
267 const auto bufHeight = buf->getHeight();
268 uint32_t* bufData;
269 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
270 reinterpret_cast<void**>(&bufData));
271 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
272 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
273 0, 0);
274 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
275 buf->getStride(), 0, 255, 0);
276 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
277 255);
278 buf->unlock();
279 }
280
281 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
282 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700283 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800284 const auto epsilon = 3;
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000285 const int32_t width = static_cast<int32_t>(captureBuf->getWidth());
286 const int32_t height = static_cast<int32_t>(captureBuf->getHeight());
chaviwd2432892020-07-24 17:42:39 -0700287 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700288
289 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700290 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
291 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700292
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000293 for (int32_t row = 0; row < height; row++) {
294 for (int32_t col = 0; col < width; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700295 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800296 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800297 bool inRegion;
298 if (!outsideRegion) {
299 inRegion = row >= region.top + border && row < region.bottom - border &&
300 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800301 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800302 inRegion = row >= region.top - border && row < region.bottom + border &&
303 col >= region.left - border && col < region.right + border;
304 }
305 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000306 ASSERT_GE(epsilon, abs(r - *(pixel)));
307 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
308 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800309 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000310 ASSERT_GE(epsilon, abs(r - *(pixel)));
311 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
312 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800313 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800314 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700315 }
316 }
chaviwd2432892020-07-24 17:42:39 -0700317 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700318 }
319
Vishnu Nair277142c2021-01-05 18:35:29 -0800320 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
321 nsecs_t presentTimeDelay) {
322 int slot;
323 sp<Fence> fence;
324 sp<GraphicBuffer> buf;
325 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
326 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
327 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500328 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800329 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
330
331 uint32_t* bufData;
332 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
333 reinterpret_cast<void**>(&bufData));
334 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
335 buf->unlock();
336
337 IGraphicBufferProducer::QueueBufferOutput qbOutput;
338 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
339 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
340 Rect(mDisplayWidth, mDisplayHeight / 2),
341 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
342 Fence::NO_FENCE);
343 igbp->queueBuffer(slot, input, &qbOutput);
344 }
345
Valerie Hauc5011f92019-10-11 09:52:07 -0700346 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700347 sp<ISurfaceComposer> mComposer;
348
349 sp<IBinder> mDisplayToken;
350
Valerie Hauc5011f92019-10-11 09:52:07 -0700351 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000352 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700353
354 uint32_t mDisplayWidth;
355 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700356
Melody Hsub9578222023-10-02 23:09:36 +0000357 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700358 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500359 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700360};
361
362TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
363 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700364 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700365 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000366 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth), adapter.getWidth());
367 ASSERT_EQ(static_cast<int32_t>(mDisplayHeight), adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000368 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700369}
370
371TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700372 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700373 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700374 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
Melody Hsub9578222023-10-02 23:09:36 +0000375 PIXEL_FORMAT_RGBA_8888,
376 ISurfaceComposerClient::eFXSurfaceBufferState,
377 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700378 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700379 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800380 sp<IGraphicBufferProducer> igbProducer;
381 setUpProducer(adapter, igbProducer);
382
383 int32_t width;
384 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000385 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth) / 2, width);
Vishnu Nairea0de002020-11-17 17:42:37 -0800386 int32_t height;
387 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000388 ASSERT_EQ(static_cast<int32_t>(mDisplayHeight) / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700389}
390
Tianhao Yao4861b102022-02-03 20:18:35 +0000391TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700392 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000393 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
394 auto callback = [](Transaction*) {};
395 adapter.syncNextTransaction(callback);
396 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700397}
Valerie Hauda3446e2019-10-14 15:49:22 -0700398
Valerie Haubf29e042020-02-06 11:40:38 -0800399TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800400 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
401 sp<IGraphicBufferProducer> igbProducer;
402 setUpProducer(adapter, igbProducer);
403
404 int slot;
405 sp<Fence> fence;
406 sp<GraphicBuffer> buf;
407 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
408 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
409 nullptr, nullptr);
410 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
411 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
412
413 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
414 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800415 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
416 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800417 Rect(mDisplayWidth, mDisplayHeight),
418 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
419 Fence::NO_FENCE);
420 igbProducer->queueBuffer(slot, input, &qbOutput);
421 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
422
423 adapter.waitForCallbacks();
424 ASSERT_GE(systemTime(), desiredPresentTime);
425}
426
Valerie Hauda3446e2019-10-14 15:49:22 -0700427TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
428 uint8_t r = 255;
429 uint8_t g = 0;
430 uint8_t b = 0;
431
432 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800433 sp<IGraphicBufferProducer> igbProducer;
434 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700435
436 int slot;
437 sp<Fence> fence;
438 sp<GraphicBuffer> buf;
439 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
440 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
441 nullptr, nullptr);
442 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
443 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
444
445 uint32_t* bufData;
446 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
447 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800448 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700449 buf->unlock();
450
Valerie Haud3b90d22019-11-06 09:37:31 -0800451 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800452 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
453 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700454 Rect(mDisplayWidth, mDisplayHeight),
455 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
456 Fence::NO_FENCE);
457 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800458 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700459
Patrick Williams0eb09c62023-07-28 11:24:35 -0500460 // ensure the buffer queue transaction has been committed
461 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700462
463 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000464 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800465 ASSERT_NO_FATAL_FAILURE(
466 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700467}
Valerie Haud3b90d22019-11-06 09:37:31 -0800468
469TEST_F(BLASTBufferQueueTest, TripleBuffering) {
470 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
471 sp<IGraphicBufferProducer> igbProducer;
472 setUpProducer(adapter, igbProducer);
473
474 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700475 int minUndequeuedBuffers = 0;
476 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
477 const auto bufferCount = minUndequeuedBuffers + 2;
478
479 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800480 int slot;
481 sp<Fence> fence;
482 sp<GraphicBuffer> buf;
483 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
484 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
485 nullptr, nullptr);
486 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
487 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
488 allocated.push_back({slot, fence});
489 }
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700490 for (size_t i = 0; i < allocated.size(); i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800491 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
492 }
493
Valerie Haua32c5522019-12-09 10:11:08 -0800494 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800495 int slot;
496 sp<Fence> fence;
497 sp<GraphicBuffer> buf;
498 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
499 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
500 nullptr, nullptr);
501 ASSERT_EQ(NO_ERROR, ret);
502 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800503 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
504 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800505 Rect(mDisplayWidth, mDisplayHeight),
506 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
507 Fence::NO_FENCE);
508 igbProducer->queueBuffer(slot, input, &qbOutput);
509 }
510 adapter.waitForCallbacks();
511}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800512
513TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
514 uint8_t r = 255;
515 uint8_t g = 0;
516 uint8_t b = 0;
517
518 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
519 sp<IGraphicBufferProducer> igbProducer;
520 setUpProducer(adapter, igbProducer);
521 int slot;
522 sp<Fence> fence;
523 sp<GraphicBuffer> buf;
524 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
525 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
526 nullptr, nullptr);
527 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
528 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
529
530 uint32_t* bufData;
531 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
532 reinterpret_cast<void**>(&bufData));
533 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
534 buf->unlock();
535
536 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800537 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
538 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800539 Rect(mDisplayWidth, mDisplayHeight / 2),
540 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
541 Fence::NO_FENCE);
542 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800543 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800544
Patrick Williams0eb09c62023-07-28 11:24:35 -0500545 // ensure the buffer queue transaction has been committed
546 Transaction().apply(true /* synchronous */);
547
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800548 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000549 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700550
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800551 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000552 checkScreenCapture(r, g, b,
553 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800554}
555
556TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
557 uint8_t r = 255;
558 uint8_t g = 0;
559 uint8_t b = 0;
560
561 int32_t bufferSideLength =
562 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
563 int32_t finalCropSideLength = bufferSideLength / 2;
564
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800565 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
566 sp<IGraphicBufferProducer> igbProducer;
567 setUpProducer(adapter, igbProducer);
568 int slot;
569 sp<Fence> fence;
570 sp<GraphicBuffer> buf;
571 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
572 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
573 nullptr, nullptr);
574 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
575 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
576
577 uint32_t* bufData;
578 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
579 reinterpret_cast<void**>(&bufData));
580 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
581 fillBuffer(bufData,
582 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
583 buf->getHeight()),
584 buf->getStride(), r, g, b);
585 buf->unlock();
586
587 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800588 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
589 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800590 Rect(bufferSideLength, finalCropSideLength),
591 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
592 Fence::NO_FENCE);
593 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800594 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800595
Patrick Williams0eb09c62023-07-28 11:24:35 -0500596 // ensure the buffer queue transaction has been committed
597 Transaction().apply(true /* synchronous */);
598
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800599 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000600 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700601 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
602 {10, 10, (int32_t)bufferSideLength - 10,
603 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800604 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700605 checkScreenCapture(0, 0, 0,
606 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
607 /*border*/ 0, /*outsideRegion*/ true));
608}
609
610TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700611 Rect windowSize(1000, 1000);
612 Rect bufferSize(windowSize);
613 Rect bufferCrop(200, 200, 700, 700);
614
615 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
616 sp<IGraphicBufferProducer> igbProducer;
617 setUpProducer(adapter, igbProducer);
618 int slot;
619 sp<Fence> fence;
620 sp<GraphicBuffer> buf;
621 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
622 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
623 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
624 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
625 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
626
627 uint32_t* bufData;
628 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
629 reinterpret_cast<void**>(&bufData));
630 // fill buffer with grey
631 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
632
633 // fill crop area with different colors so we can verify the cropped region has been scaled
634 // correctly.
635 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
636 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
637 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
638 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
639 buf->unlock();
640
641 IGraphicBufferProducer::QueueBufferOutput qbOutput;
642 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
643 HAL_DATASPACE_UNKNOWN,
644 bufferCrop /* Rect::INVALID_RECT */,
645 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
646 Fence::NO_FENCE);
647 igbProducer->queueBuffer(slot, input, &qbOutput);
648 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
649
Patrick Williams0eb09c62023-07-28 11:24:35 -0500650 // ensure the buffer queue transaction has been committed
651 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700652
Melody Hsub9578222023-10-02 23:09:36 +0000653 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700654
655 // Verify cropped region is scaled correctly.
656 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
657 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
658 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
659 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
660 // Verify outside region is black.
661 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
662 {0, 0, (int32_t)windowSize.getWidth(),
663 (int32_t)windowSize.getHeight()},
664 /*border*/ 0, /*outsideRegion*/ true));
665}
666
667TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700668 Rect windowSize(1000, 1000);
669 Rect bufferSize(500, 500);
670 Rect bufferCrop(100, 100, 350, 350);
671
672 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
673 sp<IGraphicBufferProducer> igbProducer;
674 setUpProducer(adapter, igbProducer);
675 int slot;
676 sp<Fence> fence;
677 sp<GraphicBuffer> buf;
678 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
679 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
680 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
681 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
682 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
683
684 uint32_t* bufData;
685 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
686 reinterpret_cast<void**>(&bufData));
687 // fill buffer with grey
688 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
689
690 // fill crop area with different colors so we can verify the cropped region has been scaled
691 // correctly.
692 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
693 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
694 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
695 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
696 buf->unlock();
697
698 IGraphicBufferProducer::QueueBufferOutput qbOutput;
699 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
700 HAL_DATASPACE_UNKNOWN,
701 bufferCrop /* Rect::INVALID_RECT */,
702 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
703 Fence::NO_FENCE);
704 igbProducer->queueBuffer(slot, input, &qbOutput);
705 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
706
Patrick Williams0eb09c62023-07-28 11:24:35 -0500707 // ensure the buffer queue transaction has been committed
708 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700709
Melody Hsub9578222023-10-02 23:09:36 +0000710 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700711 // Verify cropped region is scaled correctly.
712 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
713 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
714 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
715 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
716 // Verify outside region is black.
717 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
718 {0, 0, (int32_t)windowSize.getWidth(),
719 (int32_t)windowSize.getHeight()},
720 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800721}
722
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700723// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
724// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
725TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
726 uint8_t r = 255;
727 uint8_t g = 0;
728 uint8_t b = 0;
729
730 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
731 sp<IGraphicBufferProducer> igbProducer;
732 setUpProducer(adapter, igbProducer);
733 {
734 int slot;
735 sp<Fence> fence;
736 sp<GraphicBuffer> buf;
737 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
738 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
739 nullptr, nullptr);
740 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
741 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
742
743 uint32_t* bufData;
744 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
745 reinterpret_cast<void**>(&bufData));
746 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
747 buf->unlock();
748
749 IGraphicBufferProducer::QueueBufferOutput qbOutput;
750 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
751 HAL_DATASPACE_UNKNOWN, {},
752 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
753 Fence::NO_FENCE);
754 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500755
756 // ensure the buffer queue transaction has been committed
757 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700758 }
759 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000760 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700761
762 ASSERT_NO_FATAL_FAILURE(
763 checkScreenCapture(r, g, b,
764 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
765
766 // update the size to half the display and dequeue a buffer quarter of the display.
767 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
768
769 {
770 int slot;
771 sp<Fence> fence;
772 sp<GraphicBuffer> buf;
773 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
774 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
775 nullptr, nullptr);
776 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
777 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
778
779 uint32_t* bufData;
780 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
781 reinterpret_cast<void**>(&bufData));
782 g = 255;
783 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
784 buf->unlock();
785
786 IGraphicBufferProducer::QueueBufferOutput qbOutput;
787 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
788 HAL_DATASPACE_UNKNOWN, {},
789 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
790 0, Fence::NO_FENCE);
791 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500792 // ensure the buffer queue transaction has been committed
793 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700794 }
795 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000796 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700797 // verify we still scale the buffer to the new size (half the screen height)
798 ASSERT_NO_FATAL_FAILURE(
799 checkScreenCapture(r, g, b,
800 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
801}
802
chaviwd7deef72021-10-06 11:53:40 -0500803TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
804 uint8_t r = 255;
805 uint8_t g = 0;
806 uint8_t b = 0;
807
808 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
809
810 sp<IGraphicBufferProducer> igbProducer;
811 setUpProducer(adapter, igbProducer);
812
chaviwa1c4c822021-11-10 18:11:58 -0600813 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000814 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500815 queueBuffer(igbProducer, 0, 255, 0, 0);
816
817 // queue non sync buffer, so this one should get blocked
818 // Add a present delay to allow the first screenshot to get taken.
819 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
820 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
821
822 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600823 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500824 transactionCallback.getContext())
825 .apply();
826
827 CallbackData callbackData;
828 transactionCallback.getCallbackData(&callbackData);
829
chaviw0acd33a2021-11-02 11:55:37 -0500830 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000831 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500832 ASSERT_NO_FATAL_FAILURE(
833 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
834
835 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000836 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500837 ASSERT_NO_FATAL_FAILURE(
838 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
839}
840
841TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
842 uint8_t r = 255;
843 uint8_t g = 0;
844 uint8_t b = 0;
845
846 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
847
848 sp<IGraphicBufferProducer> igbProducer;
849 setUpProducer(adapter, igbProducer);
850
851 Transaction mainTransaction;
852
chaviwa1c4c822021-11-10 18:11:58 -0600853 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000854 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500855 queueBuffer(igbProducer, 0, 255, 0, 0);
856
chaviwa1c4c822021-11-10 18:11:58 -0600857 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500858
Tianhao Yao4861b102022-02-03 20:18:35 +0000859 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500860 queueBuffer(igbProducer, r, g, b, 0);
861
chaviwa1c4c822021-11-10 18:11:58 -0600862 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500863 // Expect 1 buffer to be released even before sending to SurfaceFlinger
864 mProducerListener->waitOnNumberReleased(1);
865
866 CallbackHelper transactionCallback;
867 mainTransaction
868 .addTransactionCompletedCallback(transactionCallback.function,
869 transactionCallback.getContext())
870 .apply();
871
872 CallbackData callbackData;
873 transactionCallback.getCallbackData(&callbackData);
874
875 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000876 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500877 ASSERT_NO_FATAL_FAILURE(
878 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
879}
880
881TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
882 uint8_t r = 255;
883 uint8_t g = 0;
884 uint8_t b = 0;
885
886 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
887
888 sp<IGraphicBufferProducer> igbProducer;
889 setUpProducer(adapter, igbProducer);
890
891 Transaction mainTransaction;
892
chaviwa1c4c822021-11-10 18:11:58 -0600893 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500894 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000895 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500896 queueBuffer(igbProducer, 0, 255, 0, 0);
897
chaviwa1c4c822021-11-10 18:11:58 -0600898 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500899
chaviwa1c4c822021-11-10 18:11:58 -0600900 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500901 queueBuffer(igbProducer, 0, 0, 255, 0);
902
903 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000904 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500905 queueBuffer(igbProducer, r, g, b, 0);
906 // Expect 1 buffer to be released because the non sync transaction should merge
907 // with the sync
908 mProducerListener->waitOnNumberReleased(1);
909
chaviwa1c4c822021-11-10 18:11:58 -0600910 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500911 // Expect 2 buffers to be released due to merging the two syncs.
912 mProducerListener->waitOnNumberReleased(2);
913
914 CallbackHelper transactionCallback;
915 mainTransaction
916 .addTransactionCompletedCallback(transactionCallback.function,
917 transactionCallback.getContext())
918 .apply();
919
920 CallbackData callbackData;
921 transactionCallback.getCallbackData(&callbackData);
922
923 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000924 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500925 ASSERT_NO_FATAL_FAILURE(
926 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
927}
928
929TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
930 uint8_t r = 255;
931 uint8_t g = 0;
932 uint8_t b = 0;
933
934 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
935
936 sp<IGraphicBufferProducer> igbProducer;
937 setUpProducer(adapter, igbProducer, 3);
938
939 Transaction mainTransaction;
940
chaviwa1c4c822021-11-10 18:11:58 -0600941 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500942 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000943 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500944 queueBuffer(igbProducer, 0, 255, 0, 0);
945
chaviwa1c4c822021-11-10 18:11:58 -0600946 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500947
chaviwa1c4c822021-11-10 18:11:58 -0600948 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500949 queueBuffer(igbProducer, 0, 0, 255, 0);
950 queueBuffer(igbProducer, 0, 0, 255, 0);
951 queueBuffer(igbProducer, 0, 0, 255, 0);
952
953 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000954 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500955 queueBuffer(igbProducer, r, g, b, 0);
956 // Expect 3 buffers to be released because the non sync transactions should merge
957 // with the sync
958 mProducerListener->waitOnNumberReleased(3);
959
chaviwa1c4c822021-11-10 18:11:58 -0600960 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500961 // Expect 4 buffers to be released due to merging the two syncs.
962 mProducerListener->waitOnNumberReleased(4);
963
964 CallbackHelper transactionCallback;
965 mainTransaction
966 .addTransactionCompletedCallback(transactionCallback.function,
967 transactionCallback.getContext())
968 .apply();
969
970 CallbackData callbackData;
971 transactionCallback.getCallbackData(&callbackData);
972
973 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000974 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500975 ASSERT_NO_FATAL_FAILURE(
976 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
977}
978
979// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
980// continue processing is for a release callback from SurfaceFlinger.
981// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
982// continue acquiring buffers.
983TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
984 uint8_t r = 255;
985 uint8_t g = 0;
986 uint8_t b = 0;
987
988 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
989
990 sp<IGraphicBufferProducer> igbProducer;
991 setUpProducer(adapter, igbProducer, 4);
992
993 Transaction mainTransaction;
994
995 // Send a buffer to SF
996 queueBuffer(igbProducer, 0, 255, 0, 0);
997
chaviwa1c4c822021-11-10 18:11:58 -0600998 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500999 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001000 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001001 queueBuffer(igbProducer, 0, 255, 0, 0);
1002
chaviwa1c4c822021-11-10 18:11:58 -06001003 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001004
chaviwa1c4c822021-11-10 18:11:58 -06001005 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001006 queueBuffer(igbProducer, 0, 0, 255, 0);
1007 queueBuffer(igbProducer, 0, 0, 255, 0);
1008 queueBuffer(igbProducer, 0, 0, 255, 0);
1009
1010 // apply the first synced buffer to ensure we have to wait on SF
1011 mainTransaction.apply();
1012
1013 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001014 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001015 queueBuffer(igbProducer, r, g, b, 0);
1016 // Expect 2 buffers to be released because the non sync transactions should merge
1017 // with the sync
1018 mProducerListener->waitOnNumberReleased(3);
1019
chaviwa1c4c822021-11-10 18:11:58 -06001020 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001021
1022 CallbackHelper transactionCallback;
1023 mainTransaction
1024 .addTransactionCompletedCallback(transactionCallback.function,
1025 transactionCallback.getContext())
1026 .apply();
1027
1028 CallbackData callbackData;
1029 transactionCallback.getCallbackData(&callbackData);
1030
1031 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001032 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001033 ASSERT_NO_FATAL_FAILURE(
1034 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1035}
1036
Tianhao Yao4861b102022-02-03 20:18:35 +00001037TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001038 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1039
1040 sp<IGraphicBufferProducer> igbProducer;
1041 setUpProducer(adapter, igbProducer);
1042
1043 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001044 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001045 queueBuffer(igbProducer, 0, 255, 0, 0);
1046 queueBuffer(igbProducer, 0, 0, 255, 0);
1047 // There should only be one frame submitted since the first frame will be released.
1048 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001049 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001050
1051 // queue non sync buffer, so this one should get blocked
1052 // Add a present delay to allow the first screenshot to get taken.
1053 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1054 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1055
1056 CallbackHelper transactionCallback;
1057 next.addTransactionCompletedCallback(transactionCallback.function,
1058 transactionCallback.getContext())
1059 .apply();
1060
1061 CallbackData callbackData;
1062 transactionCallback.getCallbackData(&callbackData);
1063
1064 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001065 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001066 ASSERT_NO_FATAL_FAILURE(
1067 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1068
1069 mProducerListener->waitOnNumberReleased(2);
1070 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001071 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001072 ASSERT_NO_FATAL_FAILURE(
1073 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1074}
1075
chaviw3b4bdcf2022-03-17 09:27:03 -05001076TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1077 std::mutex mutex;
1078 std::condition_variable callbackReceivedCv;
1079 bool receivedCallback = false;
1080
1081 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1082 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1083 auto callback = [&](Transaction*) {
1084 std::unique_lock<std::mutex> lock(mutex);
1085 receivedCallback = true;
1086 callbackReceivedCv.notify_one();
1087 };
1088 adapter.syncNextTransaction(callback);
1089 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1090
1091 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001092 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1093
1094 sp<IGraphicBufferProducer> igbProducer;
1095 setUpProducer(adapter, igbProducer);
1096 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001097
1098 std::unique_lock<std::mutex> lock(mutex);
1099 if (!receivedCallback) {
1100 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1101 std::cv_status::timeout)
1102 << "did not receive callback";
1103 }
1104
1105 ASSERT_TRUE(receivedCallback);
1106}
1107
Chavi Weingartenc398c012023-04-12 17:26:02 +00001108TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1109 std::mutex mutex;
1110 std::condition_variable callbackReceivedCv;
1111 bool receivedCallback = false;
1112
1113 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1114 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1115 auto callback = [&](Transaction*) {
1116 std::unique_lock<std::mutex> lock(mutex);
1117 receivedCallback = true;
1118 callbackReceivedCv.notify_one();
1119 };
1120 adapter.syncNextTransaction(callback);
1121 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1122
1123 adapter.clearSyncTransaction();
1124
1125 sp<IGraphicBufferProducer> igbProducer;
1126 setUpProducer(adapter, igbProducer);
1127 queueBuffer(igbProducer, 0, 255, 0, 0);
1128
1129 std::unique_lock<std::mutex> lock(mutex);
1130 if (!receivedCallback) {
1131 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1132 std::cv_status::timeout)
1133 << "did not receive callback";
1134 }
1135
1136 ASSERT_FALSE(receivedCallback);
1137}
1138
chaviwc1cf4022022-06-03 13:32:33 -05001139TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1140 uint8_t r = 255;
1141 uint8_t g = 0;
1142 uint8_t b = 0;
1143
1144 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1145
1146 sp<IGraphicBufferProducer> igbProducer;
1147 setUpProducer(adapter, igbProducer);
1148
1149 Transaction sync;
1150 adapter.setSyncTransaction(sync);
1151 queueBuffer(igbProducer, 0, 255, 0, 0);
1152
1153 // Merge a transaction that has a complete callback into the next frame so we can get notified
1154 // when to take a screenshot
1155 CallbackHelper transactionCallback;
1156 Transaction t;
1157 t.addTransactionCompletedCallback(transactionCallback.function,
1158 transactionCallback.getContext());
1159 adapter.mergeWithNextTransaction(&t, 2);
1160 queueBuffer(igbProducer, r, g, b, 0);
1161
1162 // Drop the buffer, but ensure the next one continues to get processed.
1163 sync.setBuffer(mSurfaceControl, nullptr);
1164
1165 CallbackData callbackData;
1166 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001167 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001168 ASSERT_NO_FATAL_FAILURE(
1169 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001170 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001171}
1172
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001173// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1174// until the old surface control is destroyed. This is not necessarily a bug but to document a
1175// limitation with the update API and to test any changes to make the api more robust. The current
1176// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1177TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1178 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1179 std::vector<sp<SurfaceControl>> surfaceControls;
1180 sp<IGraphicBufferProducer> igbProducer;
1181 for (int i = 0; i < 10; i++) {
1182 sp<SurfaceControl> sc =
1183 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1184 PIXEL_FORMAT_RGBA_8888,
1185 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001186 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001187 Transaction()
1188 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1189 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1190 .show(mSurfaceControl)
1191 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1192 .apply(true);
1193 surfaceControls.push_back(sc);
1194 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1195
1196 setUpProducer(adapter, igbProducer);
1197 Transaction next;
1198 queueBuffer(igbProducer, 0, 255, 0, 0);
1199 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001200 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001201 queueBuffer(igbProducer, 255, 0, 0, 0);
1202
1203 CallbackHelper transactionCallback;
1204 next.addTransactionCompletedCallback(transactionCallback.function,
1205 transactionCallback.getContext())
1206 .apply();
1207
1208 CallbackData callbackData;
1209 transactionCallback.getCallbackData(&callbackData);
1210 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001211 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001212 ASSERT_NO_FATAL_FAILURE(
1213 checkScreenCapture(255, 0, 0,
1214 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1215 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1216 }
1217}
1218
1219// See DISABLED_DisconnectProducerTest
1220TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1221 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1222 std::vector<sp<SurfaceControl>> surfaceControls;
1223 sp<IGraphicBufferProducer> igbProducer;
1224 for (int i = 0; i < 10; i++) {
1225 sp<SurfaceControl> sc =
1226 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1227 PIXEL_FORMAT_RGBA_8888,
1228 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001229 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001230 Transaction()
1231 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1232 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1233 .show(mSurfaceControl)
1234 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1235 .apply(true);
1236 surfaceControls.push_back(sc);
1237 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1238 setUpProducer(adapter, igbProducer);
1239
1240 Transaction next;
1241 queueBuffer(igbProducer, 0, 255, 0, 0);
1242 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001243 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001244 queueBuffer(igbProducer, 255, 0, 0, 0);
1245
1246 CallbackHelper transactionCallback;
1247 next.addTransactionCompletedCallback(transactionCallback.function,
1248 transactionCallback.getContext())
1249 .apply();
1250
1251 CallbackData callbackData;
1252 transactionCallback.getCallbackData(&callbackData);
1253 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001254 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001255 ASSERT_NO_FATAL_FAILURE(
1256 checkScreenCapture(255, 0, 0,
1257 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1258 }
1259}
1260
Vishnu Nair89496122020-12-14 17:14:53 -08001261class TestProducerListener : public BnProducerListener {
1262public:
1263 sp<IGraphicBufferProducer> mIgbp;
1264 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1265 void onBufferReleased() override {
1266 sp<GraphicBuffer> buffer;
1267 sp<Fence> fence;
1268 mIgbp->detachNextBuffer(&buffer, &fence);
1269 }
1270};
1271
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001272class TestSurfaceListener : public SurfaceListener {
1273public:
1274 sp<IGraphicBufferProducer> mIgbp;
1275 TestSurfaceListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1276 void onBufferReleased() override {
1277 sp<GraphicBuffer> buffer;
1278 sp<Fence> fence;
1279 mIgbp->detachNextBuffer(&buffer, &fence);
1280 }
1281 bool needsReleaseNotify() override { return true; }
1282 void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
1283 void onBufferDetached(int /*slot*/) {}
1284};
1285
Vishnu Nair89496122020-12-14 17:14:53 -08001286TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1287 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1288 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1289 ASSERT_NE(nullptr, igbProducer.get());
1290 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1291 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1292 ASSERT_EQ(NO_ERROR,
1293 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1294 false, &qbOutput));
1295 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1296 for (int i = 0; i < 3; i++) {
1297 int slot;
1298 sp<Fence> fence;
1299 sp<GraphicBuffer> buf;
1300 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1301 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1302 nullptr, nullptr);
1303 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1304 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1305 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001306 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1307 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001308 Rect(mDisplayWidth, mDisplayHeight),
1309 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1310 Fence::NO_FENCE);
1311 igbProducer->queueBuffer(slot, input, &qbOutput);
1312 }
1313 adapter.waitForCallbacks();
1314}
1315
Vishnu Nair17dde612020-12-28 11:39:59 -08001316TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1317 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1318
1319 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1320 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1321 int queuesToNativeWindow = 0;
1322 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1323 &queuesToNativeWindow);
1324 ASSERT_EQ(NO_ERROR, err);
1325 ASSERT_EQ(queuesToNativeWindow, 1);
1326}
1327
Vishnu Naira4fbca52021-07-07 16:52:34 -07001328TEST_F(BLASTBufferQueueTest, TransformHint) {
1329 // Transform hint is provided to BBQ via the surface control passed by WM
1330 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1331
1332 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1333 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1334 ASSERT_NE(nullptr, igbProducer.get());
1335 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1336 sp<Surface> surface = adapter.getSurface();
1337
1338 // Before connecting to the surface, we do not get a valid transform hint
1339 int transformHint;
1340 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001341 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001342
1343 ASSERT_EQ(NO_ERROR,
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001344 surface->connect(NATIVE_WINDOW_API_CPU, new TestSurfaceListener(igbProducer)));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001345
1346 // After connecting to the surface, we should get the correct hint.
1347 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001348 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001349
1350 ANativeWindow_Buffer buffer;
1351 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1352
1353 // Transform hint is updated via callbacks or surface control updates
1354 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1355 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1356
1357 // The hint does not change and matches the value used when dequeueing the buffer.
1358 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001359 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001360
1361 surface->unlockAndPost();
1362
1363 // After queuing the buffer, we get the updated transform hint
1364 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001365 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001366
1367 adapter.waitForCallbacks();
1368}
1369
Valerie Hau5977fc82019-12-05 15:56:39 -08001370class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1371public:
1372 void test(uint32_t tr) {
1373 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1374 sp<IGraphicBufferProducer> igbProducer;
1375 setUpProducer(adapter, igbProducer);
1376
1377 auto bufWidth = mDisplayWidth;
1378 auto bufHeight = mDisplayHeight;
1379 int slot;
1380 sp<Fence> fence;
1381 sp<GraphicBuffer> buf;
1382
1383 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1384 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1385 nullptr, nullptr);
1386 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1387 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1388
1389 fillQuadrants(buf);
1390
1391 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001392 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1393 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001394 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001395 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1396 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001397 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001398 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001399
Patrick Williams0eb09c62023-07-28 11:24:35 -05001400 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001401 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001402
Valerie Hau5977fc82019-12-05 15:56:39 -08001403 switch (tr) {
1404 case ui::Transform::ROT_0:
1405 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1406 {0, 0, (int32_t)mDisplayWidth / 2,
1407 (int32_t)mDisplayHeight / 2},
1408 1));
1409 ASSERT_NO_FATAL_FAILURE(
1410 checkScreenCapture(255, 0, 0,
1411 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1412 (int32_t)mDisplayHeight / 2},
1413 1));
1414 ASSERT_NO_FATAL_FAILURE(
1415 checkScreenCapture(0, 255, 0,
1416 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1417 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1418 1));
1419 ASSERT_NO_FATAL_FAILURE(
1420 checkScreenCapture(0, 0, 255,
1421 {0, (int32_t)mDisplayHeight / 2,
1422 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1423 1));
1424 break;
1425 case ui::Transform::FLIP_H:
1426 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1427 {0, 0, (int32_t)mDisplayWidth / 2,
1428 (int32_t)mDisplayHeight / 2},
1429 1));
1430 ASSERT_NO_FATAL_FAILURE(
1431 checkScreenCapture(0, 0, 0,
1432 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1433 (int32_t)mDisplayHeight / 2},
1434 1));
1435 ASSERT_NO_FATAL_FAILURE(
1436 checkScreenCapture(0, 0, 255,
1437 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1438 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1439 1));
1440 ASSERT_NO_FATAL_FAILURE(
1441 checkScreenCapture(0, 255, 0,
1442 {0, (int32_t)mDisplayHeight / 2,
1443 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1444 1));
1445 break;
1446 case ui::Transform::FLIP_V:
1447 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1448 {0, 0, (int32_t)mDisplayWidth / 2,
1449 (int32_t)mDisplayHeight / 2},
1450 1));
1451 ASSERT_NO_FATAL_FAILURE(
1452 checkScreenCapture(0, 255, 0,
1453 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1454 (int32_t)mDisplayHeight / 2},
1455 1));
1456 ASSERT_NO_FATAL_FAILURE(
1457 checkScreenCapture(255, 0, 0,
1458 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1459 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1460 1));
1461 ASSERT_NO_FATAL_FAILURE(
1462 checkScreenCapture(0, 0, 0,
1463 {0, (int32_t)mDisplayHeight / 2,
1464 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1465 1));
1466 break;
1467 case ui::Transform::ROT_90:
1468 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1469 {0, 0, (int32_t)mDisplayWidth / 2,
1470 (int32_t)mDisplayHeight / 2},
1471 1));
1472 ASSERT_NO_FATAL_FAILURE(
1473 checkScreenCapture(0, 0, 0,
1474 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1475 (int32_t)mDisplayHeight / 2},
1476 1));
1477 ASSERT_NO_FATAL_FAILURE(
1478 checkScreenCapture(255, 0, 0,
1479 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1480 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1481 1));
1482 ASSERT_NO_FATAL_FAILURE(
1483 checkScreenCapture(0, 255, 0,
1484 {0, (int32_t)mDisplayHeight / 2,
1485 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1486 1));
1487 break;
1488 case ui::Transform::ROT_180:
1489 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1490 {0, 0, (int32_t)mDisplayWidth / 2,
1491 (int32_t)mDisplayHeight / 2},
1492 1));
1493 ASSERT_NO_FATAL_FAILURE(
1494 checkScreenCapture(0, 0, 255,
1495 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1496 (int32_t)mDisplayHeight / 2},
1497 1));
1498 ASSERT_NO_FATAL_FAILURE(
1499 checkScreenCapture(0, 0, 0,
1500 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1501 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1502 1));
1503 ASSERT_NO_FATAL_FAILURE(
1504 checkScreenCapture(255, 0, 0,
1505 {0, (int32_t)mDisplayHeight / 2,
1506 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1507 1));
1508 break;
1509 case ui::Transform::ROT_270:
1510 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1511 {0, 0, (int32_t)mDisplayWidth / 2,
1512 (int32_t)mDisplayHeight / 2},
1513 1));
1514 ASSERT_NO_FATAL_FAILURE(
1515 checkScreenCapture(0, 255, 0,
1516 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1517 (int32_t)mDisplayHeight / 2},
1518 1));
1519 ASSERT_NO_FATAL_FAILURE(
1520 checkScreenCapture(0, 0, 255,
1521 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1522 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1523 1));
1524 ASSERT_NO_FATAL_FAILURE(
1525 checkScreenCapture(0, 0, 0,
1526 {0, (int32_t)mDisplayHeight / 2,
1527 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1528 1));
1529 }
1530 }
1531};
1532
1533TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1534 test(ui::Transform::ROT_0);
1535}
1536
1537TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1538 test(ui::Transform::FLIP_H);
1539}
1540
1541TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1542 test(ui::Transform::FLIP_V);
1543}
1544
1545TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1546 test(ui::Transform::ROT_90);
1547}
1548
1549TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1550 test(ui::Transform::ROT_180);
1551}
1552
1553TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1554 test(ui::Transform::ROT_270);
1555}
Valerie Hau871d6352020-01-29 08:44:02 -08001556
1557class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1558public:
1559 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001560 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001561 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001562 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001563 int slot;
1564 sp<Fence> fence;
1565 sp<GraphicBuffer> buf;
1566 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1567 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1568 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001569 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1570 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1571 }
Valerie Hau871d6352020-01-29 08:44:02 -08001572
Vishnu Nairde66dc72021-06-17 17:54:41 -07001573 *outRequestedPresentTime = requestedPresentTime;
1574 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1575 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001576 Rect(mDisplayWidth, mDisplayHeight),
1577 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1578 Fence::NO_FENCE, /*sticky*/ 0,
1579 getFrameTimestamps);
1580 if (postedTime) *postedTime = systemTime();
1581 igbProducer->queueBuffer(slot, input, qbOutput);
1582 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001583 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001584};
1585
1586TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1587 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1588 sp<IGraphicBufferProducer> igbProducer;
1589 ProducerFrameEventHistory history;
1590 setUpProducer(adapter, igbProducer);
1591
1592 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1593 nsecs_t requestedPresentTimeA = 0;
1594 nsecs_t postedTimeA = 0;
1595 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1596 history.applyDelta(qbOutput.frameTimestamps);
1597
1598 FrameEvents* events = nullptr;
1599 events = history.getFrame(1);
1600 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001601 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001602 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1603 ASSERT_GE(events->postedTime, postedTimeA);
1604
Vishnu Nair1506b182021-02-22 14:35:15 -08001605 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001606
1607 // queue another buffer so we query for frame event deltas
1608 nsecs_t requestedPresentTimeB = 0;
1609 nsecs_t postedTimeB = 0;
1610 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1611 history.applyDelta(qbOutput.frameTimestamps);
Alec Mouri21d94322023-10-17 19:51:39 +00001612
1613 adapter.waitForCallback(2);
1614
Valerie Hau871d6352020-01-29 08:44:02 -08001615 events = history.getFrame(1);
1616 ASSERT_NE(nullptr, events);
1617
1618 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001619 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001620 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1621 ASSERT_GE(events->postedTime, postedTimeA);
1622
1623 ASSERT_GE(events->latchTime, postedTimeA);
Alec Mouri21d94322023-10-17 19:51:39 +00001624 if (flags::frametimestamps_previousrelease()) {
1625 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1626 }
Valerie Hau871d6352020-01-29 08:44:02 -08001627 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1628 ASSERT_NE(nullptr, events->displayPresentFence);
1629 ASSERT_NE(nullptr, events->releaseFence);
1630
1631 // we should also have gotten the initial values for the next frame
1632 events = history.getFrame(2);
1633 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001634 ASSERT_EQ(2u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001635 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1636 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001637
Alec Mouri21d94322023-10-17 19:51:39 +00001638 // Now do the same as above with a third buffer, so that timings related to
1639 // buffer releases make it back to the first frame.
1640 nsecs_t requestedPresentTimeC = 0;
1641 nsecs_t postedTimeC = 0;
1642 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1643 history.applyDelta(qbOutput.frameTimestamps);
1644
1645 adapter.waitForCallback(3);
1646
1647 // Check the first frame...
1648 events = history.getFrame(1);
1649 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001650 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001651 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1652 ASSERT_GE(events->postedTime, postedTimeA);
1653 ASSERT_GE(events->latchTime, postedTimeA);
1654 // Now dequeueReadyTime is valid, because the release timings finally
1655 // propaged to queueBuffer()
1656 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1657 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1658 ASSERT_NE(nullptr, events->displayPresentFence);
1659 ASSERT_NE(nullptr, events->releaseFence);
1660
1661 // ...and the second
1662 events = history.getFrame(2);
1663 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001664 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001665 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1666 ASSERT_GE(events->postedTime, postedTimeB);
1667 ASSERT_GE(events->latchTime, postedTimeB);
1668 if (flags::frametimestamps_previousrelease()) {
1669 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1670 }
1671 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1672 ASSERT_NE(nullptr, events->displayPresentFence);
1673 ASSERT_NE(nullptr, events->releaseFence);
1674
1675 // ...and finally the third!
1676 events = history.getFrame(3);
1677 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001678 ASSERT_EQ(3u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001679 ASSERT_EQ(requestedPresentTimeC, events->requestedPresentTime);
1680 ASSERT_GE(events->postedTime, postedTimeC);
1681
Valerie Hau78491e92020-04-15 13:10:56 -07001682 // wait for any callbacks that have not been received
1683 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001684}
Vishnu Nair083efd32021-02-12 09:32:30 -08001685
Vishnu Nair083efd32021-02-12 09:32:30 -08001686TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1687 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1688 sp<IGraphicBufferProducer> igbProducer;
1689 setUpProducer(adapter, igbProducer);
1690
1691 ProducerFrameEventHistory history;
1692 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1693 nsecs_t requestedPresentTimeA = 0;
1694 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001695 // Present the frame sometime in the future so we can add two frames to the queue so the older
1696 // one will be dropped.
1697 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001698 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001699 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001700 history.applyDelta(qbOutput.frameTimestamps);
1701
1702 FrameEvents* events = nullptr;
1703 events = history.getFrame(1);
1704 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001705 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001706 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1707 ASSERT_GE(events->postedTime, postedTimeA);
1708
1709 // queue another buffer so the first can be dropped
1710 nsecs_t requestedPresentTimeB = 0;
1711 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001712 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1713 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1714 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001715 history.applyDelta(qbOutput.frameTimestamps);
1716 events = history.getFrame(1);
1717 ASSERT_NE(nullptr, events);
1718
1719 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001720 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001721 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1722 ASSERT_GE(events->postedTime, postedTimeA);
1723
Vishnu Nairde66dc72021-06-17 17:54:41 -07001724 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001725 ASSERT_FALSE(events->hasLatchInfo());
1726 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001727 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1728 ASSERT_FALSE(events->hasDisplayPresentInfo());
1729 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001730
Vishnu Nairde66dc72021-06-17 17:54:41 -07001731 // wait for the last transaction to be completed.
1732 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001733
Vishnu Nairde66dc72021-06-17 17:54:41 -07001734 // queue another buffer so we query for frame event deltas
1735 nsecs_t requestedPresentTimeC = 0;
1736 nsecs_t postedTimeC = 0;
1737 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1738 history.applyDelta(qbOutput.frameTimestamps);
1739
Alec Mouri21d94322023-10-17 19:51:39 +00001740 adapter.waitForCallback(3);
1741
Vishnu Nairde66dc72021-06-17 17:54:41 -07001742 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001743 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001744 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1745 ASSERT_GE(events->postedTime, postedTimeA);
1746
1747 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1748 ASSERT_FALSE(events->hasLatchInfo());
1749 ASSERT_FALSE(events->hasDequeueReadyInfo());
1750 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1751 ASSERT_FALSE(events->hasDisplayPresentInfo());
1752 ASSERT_FALSE(events->hasReleaseInfo());
1753
1754 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001755 events = history.getFrame(2);
1756 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001757 ASSERT_EQ(2u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001758 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1759 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001760 ASSERT_GE(events->latchTime, postedTimeB);
Alec Mouri21d94322023-10-17 19:51:39 +00001761
1762 if (flags::frametimestamps_previousrelease()) {
1763 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1764 }
1765 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1766 ASSERT_NE(nullptr, events->displayPresentFence);
1767 ASSERT_NE(nullptr, events->releaseFence);
1768
1769 // Queue another buffer to check for timestamps that came late
1770 nsecs_t requestedPresentTimeD = 0;
1771 nsecs_t postedTimeD = 0;
1772 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeD, &postedTimeD, &qbOutput, true);
1773 history.applyDelta(qbOutput.frameTimestamps);
1774
1775 adapter.waitForCallback(4);
1776
1777 // frame number, requestedPresentTime, and postTime should not have changed
1778 events = history.getFrame(1);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001779 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001780 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1781 ASSERT_GE(events->postedTime, postedTimeA);
1782
1783 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1784 ASSERT_FALSE(events->hasLatchInfo());
1785 ASSERT_FALSE(events->hasDequeueReadyInfo());
1786 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1787 ASSERT_FALSE(events->hasDisplayPresentInfo());
1788 ASSERT_FALSE(events->hasReleaseInfo());
1789
1790 // we should also have gotten values for the presented frame
1791 events = history.getFrame(2);
1792 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001793 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001794 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1795 ASSERT_GE(events->postedTime, postedTimeB);
1796 ASSERT_GE(events->latchTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001797 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1798 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1799 ASSERT_NE(nullptr, events->displayPresentFence);
1800 ASSERT_NE(nullptr, events->releaseFence);
1801
1802 // wait for any callbacks that have not been received
1803 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001804}
1805
Vishnu Nair9a69a042021-06-18 13:19:49 -07001806TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1807 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1808 sp<IGraphicBufferProducer> igbProducer;
1809 ProducerFrameEventHistory history;
1810 setUpProducer(adapter, igbProducer);
1811
1812 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1813 nsecs_t requestedPresentTimeA = 0;
1814 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001815 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1816 history.applyDelta(qbOutput.frameTimestamps);
1817 adapter.waitForCallback(1);
1818
1819 // queue another buffer so we query for frame event deltas
1820 nsecs_t requestedPresentTimeB = 0;
1821 nsecs_t postedTimeB = 0;
1822 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1823 history.applyDelta(qbOutput.frameTimestamps);
1824
1825 // check for a valid compositor deadline
1826 ASSERT_NE(0, history.getReportedCompositeDeadline());
1827
1828 // wait for any callbacks that have not been received
1829 adapter.waitForCallbacks();
1830}
1831
Valerie Hauc5011f92019-10-11 09:52:07 -07001832} // namespace android