blob: b2d50482a5137adf6628909939ba7d9c606a2632 [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
Valerie Hauda3446e2019-10-14 15:49:22 -070021#include <android/hardware/graphics/common/1.2/types.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080022#include <gui/BufferQueueCore.h>
23#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080024#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070025#include <gui/IGraphicBufferProducer.h>
26#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080027#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070028#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070029#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050030#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070031#include <private/gui/ComposerService.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010032#include <ui/DisplayMode.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070033#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070034#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080035#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070036
37#include <gtest/gtest.h>
38
39using namespace std::chrono_literals;
40
41namespace android {
42
Valerie Hauc5011f92019-10-11 09:52:07 -070043using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070044using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070045
chaviwd7deef72021-10-06 11:53:40 -050046class CountProducerListener : public BnProducerListener {
47public:
48 void onBufferReleased() override {
49 std::scoped_lock<std::mutex> lock(mMutex);
50 mNumReleased++;
51 mReleaseCallback.notify_one();
52 }
53
54 void waitOnNumberReleased(int32_t expectedNumReleased) {
55 std::unique_lock<std::mutex> lock(mMutex);
56 while (mNumReleased < expectedNumReleased) {
57 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
58 std::cv_status::timeout)
59 << "did not receive release";
60 }
61 }
62
63private:
64 std::mutex mMutex;
65 std::condition_variable mReleaseCallback;
66 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
67};
68
chaviwf10b9042021-10-13 15:48:59 -050069class TestBLASTBufferQueue : public BLASTBufferQueue {
70public:
71 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
72 int height, int32_t format)
73 : BLASTBufferQueue(name, surface, width, height, format) {}
74
75 void transactionCommittedCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
76 const std::vector<SurfaceControlStats>& stats) override {
77 BLASTBufferQueue::transactionCommittedCallback(latchTime, presentFence, stats);
78
79 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
80
81 {
82 std::unique_lock lock{frameNumberMutex};
83 mLastTransactionCommittedFrameNumber = frameNumber;
84 mCommittedCV.notify_all();
85 }
86 }
87
88 void waitForCallback(int64_t frameNumber) {
89 std::unique_lock lock{frameNumberMutex};
90 // Wait until all but one of the submitted buffers have been released.
91 while (mLastTransactionCommittedFrameNumber < frameNumber) {
92 mCommittedCV.wait(lock);
93 }
94 }
95
96private:
97 std::mutex frameNumberMutex;
98 std::condition_variable mCommittedCV;
99 int64_t mLastTransactionCommittedFrameNumber = -1;
100};
101
Valerie Hauc5011f92019-10-11 09:52:07 -0700102class BLASTBufferQueueHelper {
103public:
104 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500105 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
106 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700107 }
108
109 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800110 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700111 }
112
113 void setNextTransaction(Transaction* next) {
114 mBlastBufferQueueAdapter->setNextTransaction(next);
115 }
116
Vishnu Nairea0de002020-11-17 17:42:37 -0800117 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700118
Vishnu Nairea0de002020-11-17 17:42:37 -0800119 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700120
Valerie Hauc5011f92019-10-11 09:52:07 -0700121 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700122
123 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
124 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
125 }
126
Valerie Hauc5011f92019-10-11 09:52:07 -0700127 const sp<SurfaceControl> getSurfaceControl() {
128 return mBlastBufferQueueAdapter->mSurfaceControl;
129 }
130
Vishnu Naira4fbca52021-07-07 16:52:34 -0700131 sp<Surface> getSurface() {
132 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
133 }
134
Valerie Haud3b90d22019-11-06 09:37:31 -0800135 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700136 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800137 // Wait until all but one of the submitted buffers have been released.
138 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800139 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
140 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700141 }
142
Vishnu Nair1506b182021-02-22 14:35:15 -0800143 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500144 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800145 }
146
Valerie Hauc5011f92019-10-11 09:52:07 -0700147private:
chaviwf10b9042021-10-13 15:48:59 -0500148 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700149};
150
151class BLASTBufferQueueTest : public ::testing::Test {
152public:
153protected:
154 BLASTBufferQueueTest() {
155 const ::testing::TestInfo* const testInfo =
156 ::testing::UnitTest::GetInstance()->current_test_info();
157 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
158 }
159
160 ~BLASTBufferQueueTest() {
161 const ::testing::TestInfo* const testInfo =
162 ::testing::UnitTest::GetInstance()->current_test_info();
163 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
164 }
165
166 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700167 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700168 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700169 mDisplayToken = mClient->getInternalDisplayToken();
170 ASSERT_NE(nullptr, mDisplayToken.get());
171 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700172 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700173 t.apply();
174 t.clear();
175
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100176 ui::DisplayMode mode;
177 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
178 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800179 mDisplayWidth = resolution.getWidth();
180 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700181
182 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
183 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
184 ISurfaceComposerClient::eFXSurfaceBufferState,
185 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700186 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700187 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700188 .show(mSurfaceControl)
189 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
190 .apply();
chaviwd2432892020-07-24 17:42:39 -0700191
192 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800193 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700194 }
195
chaviwd7deef72021-10-06 11:53:40 -0500196 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
197 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800198 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500199 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800200 }
201
chaviwd7deef72021-10-06 11:53:40 -0500202 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800203 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500204 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800205 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500206 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800207 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500208 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800209 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800210 }
211
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800212 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
213 uint8_t b) {
214 for (uint32_t row = rect.top; row < rect.bottom; row++) {
215 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700216 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
217 *pixel = r;
218 *(pixel + 1) = g;
219 *(pixel + 2) = b;
220 *(pixel + 3) = 255;
221 }
222 }
223 }
224
Valerie Hau5977fc82019-12-05 15:56:39 -0800225 void fillQuadrants(sp<GraphicBuffer>& buf) {
226 const auto bufWidth = buf->getWidth();
227 const auto bufHeight = buf->getHeight();
228 uint32_t* bufData;
229 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
230 reinterpret_cast<void**>(&bufData));
231 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
232 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
233 0, 0);
234 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
235 buf->getStride(), 0, 255, 0);
236 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
237 255);
238 buf->unlock();
239 }
240
241 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
242 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700243 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800244 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700245 const auto width = captureBuf->getWidth();
246 const auto height = captureBuf->getHeight();
247 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700248
249 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700250 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
251 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700252
253 for (uint32_t row = 0; row < height; row++) {
254 for (uint32_t col = 0; col < width; col++) {
255 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800256 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800257 bool inRegion;
258 if (!outsideRegion) {
259 inRegion = row >= region.top + border && row < region.bottom - border &&
260 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800261 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800262 inRegion = row >= region.top - border && row < region.bottom + border &&
263 col >= region.left - border && col < region.right + border;
264 }
265 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000266 ASSERT_GE(epsilon, abs(r - *(pixel)));
267 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
268 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800269 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000270 ASSERT_GE(epsilon, abs(r - *(pixel)));
271 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
272 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800273 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800274 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700275 }
276 }
chaviwd2432892020-07-24 17:42:39 -0700277 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700278 }
279
chaviw8ffc7b82020-08-18 11:25:37 -0700280 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
281 ScreenCaptureResults& captureResults) {
282 const auto sf = ComposerService::getComposerService();
283 SurfaceComposerClient::Transaction().apply(true);
284
285 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
286 status_t status = sf->captureDisplay(captureArgs, captureListener);
287 if (status != NO_ERROR) {
288 return status;
289 }
290 captureResults = captureListener->waitForResults();
291 return captureResults.result;
292 }
293
Vishnu Nair277142c2021-01-05 18:35:29 -0800294 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
295 nsecs_t presentTimeDelay) {
296 int slot;
297 sp<Fence> fence;
298 sp<GraphicBuffer> buf;
299 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
300 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
301 nullptr, nullptr);
302 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
303 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
304
305 uint32_t* bufData;
306 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
307 reinterpret_cast<void**>(&bufData));
308 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
309 buf->unlock();
310
311 IGraphicBufferProducer::QueueBufferOutput qbOutput;
312 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
313 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
314 Rect(mDisplayWidth, mDisplayHeight / 2),
315 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
316 Fence::NO_FENCE);
317 igbp->queueBuffer(slot, input, &qbOutput);
318 }
319
Valerie Hauc5011f92019-10-11 09:52:07 -0700320 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700321 sp<ISurfaceComposer> mComposer;
322
323 sp<IBinder> mDisplayToken;
324
Valerie Hauc5011f92019-10-11 09:52:07 -0700325 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700326
327 uint32_t mDisplayWidth;
328 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700329
330 DisplayCaptureArgs mCaptureArgs;
331 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500332 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700333};
334
335TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
336 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700337 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700338 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700339 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
340 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700341 ASSERT_EQ(nullptr, adapter.getNextTransaction());
342}
343
344TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700345 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700346 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700347 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
348 PIXEL_FORMAT_RGBA_8888);
349 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700350 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800351 sp<IGraphicBufferProducer> igbProducer;
352 setUpProducer(adapter, igbProducer);
353
354 int32_t width;
355 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
356 ASSERT_EQ(mDisplayWidth / 2, width);
357 int32_t height;
358 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
359 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700360}
361
362TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700363 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700364 Transaction next;
365 adapter.setNextTransaction(&next);
366 ASSERT_EQ(&next, adapter.getNextTransaction());
367}
Valerie Hauda3446e2019-10-14 15:49:22 -0700368
Valerie Haubf29e042020-02-06 11:40:38 -0800369TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800370 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
371 sp<IGraphicBufferProducer> igbProducer;
372 setUpProducer(adapter, igbProducer);
373
374 int slot;
375 sp<Fence> fence;
376 sp<GraphicBuffer> buf;
377 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
378 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
379 nullptr, nullptr);
380 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
381 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
382
383 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
384 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800385 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
386 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800387 Rect(mDisplayWidth, mDisplayHeight),
388 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
389 Fence::NO_FENCE);
390 igbProducer->queueBuffer(slot, input, &qbOutput);
391 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
392
393 adapter.waitForCallbacks();
394 ASSERT_GE(systemTime(), desiredPresentTime);
395}
396
Valerie Hauda3446e2019-10-14 15:49:22 -0700397TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
398 uint8_t r = 255;
399 uint8_t g = 0;
400 uint8_t b = 0;
401
402 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800403 sp<IGraphicBufferProducer> igbProducer;
404 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700405
406 int slot;
407 sp<Fence> fence;
408 sp<GraphicBuffer> buf;
409 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
410 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
411 nullptr, nullptr);
412 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
413 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
414
415 uint32_t* bufData;
416 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
417 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800418 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700419 buf->unlock();
420
Valerie Haud3b90d22019-11-06 09:37:31 -0800421 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800422 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
423 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700424 Rect(mDisplayWidth, mDisplayHeight),
425 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
426 Fence::NO_FENCE);
427 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800428 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700429
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800430 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700431
432 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700433 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800434 ASSERT_NO_FATAL_FAILURE(
435 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700436}
Valerie Haud3b90d22019-11-06 09:37:31 -0800437
438TEST_F(BLASTBufferQueueTest, TripleBuffering) {
439 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
440 sp<IGraphicBufferProducer> igbProducer;
441 setUpProducer(adapter, igbProducer);
442
443 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700444 int minUndequeuedBuffers = 0;
445 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
446 const auto bufferCount = minUndequeuedBuffers + 2;
447
448 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800449 int slot;
450 sp<Fence> fence;
451 sp<GraphicBuffer> buf;
452 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
453 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
454 nullptr, nullptr);
455 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
456 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
457 allocated.push_back({slot, fence});
458 }
459 for (int i = 0; i < allocated.size(); i++) {
460 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
461 }
462
Valerie Haua32c5522019-12-09 10:11:08 -0800463 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800464 int slot;
465 sp<Fence> fence;
466 sp<GraphicBuffer> buf;
467 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
468 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
469 nullptr, nullptr);
470 ASSERT_EQ(NO_ERROR, ret);
471 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800472 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
473 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800474 Rect(mDisplayWidth, mDisplayHeight),
475 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
476 Fence::NO_FENCE);
477 igbProducer->queueBuffer(slot, input, &qbOutput);
478 }
479 adapter.waitForCallbacks();
480}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800481
482TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
483 uint8_t r = 255;
484 uint8_t g = 0;
485 uint8_t b = 0;
486
487 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
488 sp<IGraphicBufferProducer> igbProducer;
489 setUpProducer(adapter, igbProducer);
490 int slot;
491 sp<Fence> fence;
492 sp<GraphicBuffer> buf;
493 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
494 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
495 nullptr, nullptr);
496 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
497 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
498
499 uint32_t* bufData;
500 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
501 reinterpret_cast<void**>(&bufData));
502 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
503 buf->unlock();
504
505 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800506 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
507 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800508 Rect(mDisplayWidth, mDisplayHeight / 2),
509 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
510 Fence::NO_FENCE);
511 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800512 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800513
514 adapter.waitForCallbacks();
515 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700516 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700517
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800518 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000519 checkScreenCapture(r, g, b,
520 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800521}
522
523TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
524 uint8_t r = 255;
525 uint8_t g = 0;
526 uint8_t b = 0;
527
528 int32_t bufferSideLength =
529 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
530 int32_t finalCropSideLength = bufferSideLength / 2;
531
532 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800533 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800534 ASSERT_NE(nullptr, bg.get());
535 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700536 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800537 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800538 .setColor(bg, half3{0, 0, 0})
539 .setLayer(bg, 0)
540 .apply();
541
542 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
543 sp<IGraphicBufferProducer> igbProducer;
544 setUpProducer(adapter, igbProducer);
545 int slot;
546 sp<Fence> fence;
547 sp<GraphicBuffer> buf;
548 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
549 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
550 nullptr, nullptr);
551 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
552 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
553
554 uint32_t* bufData;
555 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
556 reinterpret_cast<void**>(&bufData));
557 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
558 fillBuffer(bufData,
559 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
560 buf->getHeight()),
561 buf->getStride(), r, g, b);
562 buf->unlock();
563
564 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800565 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
566 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800567 Rect(bufferSideLength, finalCropSideLength),
568 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
569 Fence::NO_FENCE);
570 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800571 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800572
573 adapter.waitForCallbacks();
574 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700575 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700576 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
577 {10, 10, (int32_t)bufferSideLength - 10,
578 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800579 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700580 checkScreenCapture(0, 0, 0,
581 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
582 /*border*/ 0, /*outsideRegion*/ true));
583}
584
585TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
586 // add black background
587 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
588 ISurfaceComposerClient::eFXSurfaceEffect);
589 ASSERT_NE(nullptr, bg.get());
590 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700591 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700592 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
593 .setColor(bg, half3{0, 0, 0})
594 .setLayer(bg, 0)
595 .apply();
596
597 Rect windowSize(1000, 1000);
598 Rect bufferSize(windowSize);
599 Rect bufferCrop(200, 200, 700, 700);
600
601 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
602 sp<IGraphicBufferProducer> igbProducer;
603 setUpProducer(adapter, igbProducer);
604 int slot;
605 sp<Fence> fence;
606 sp<GraphicBuffer> buf;
607 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
608 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
609 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
610 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
611 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
612
613 uint32_t* bufData;
614 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
615 reinterpret_cast<void**>(&bufData));
616 // fill buffer with grey
617 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
618
619 // fill crop area with different colors so we can verify the cropped region has been scaled
620 // correctly.
621 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
622 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
623 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
624 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
625 buf->unlock();
626
627 IGraphicBufferProducer::QueueBufferOutput qbOutput;
628 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
629 HAL_DATASPACE_UNKNOWN,
630 bufferCrop /* Rect::INVALID_RECT */,
631 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
632 Fence::NO_FENCE);
633 igbProducer->queueBuffer(slot, input, &qbOutput);
634 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
635
636 adapter.waitForCallbacks();
637
638 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
639
640 // Verify cropped region is scaled correctly.
641 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
642 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
643 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
644 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
645 // Verify outside region is black.
646 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
647 {0, 0, (int32_t)windowSize.getWidth(),
648 (int32_t)windowSize.getHeight()},
649 /*border*/ 0, /*outsideRegion*/ true));
650}
651
652TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
653 // add black background
654 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
655 ISurfaceComposerClient::eFXSurfaceEffect);
656 ASSERT_NE(nullptr, bg.get());
657 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700659 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
660 .setColor(bg, half3{0, 0, 0})
661 .setLayer(bg, 0)
662 .apply();
663
664 Rect windowSize(1000, 1000);
665 Rect bufferSize(500, 500);
666 Rect bufferCrop(100, 100, 350, 350);
667
668 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
669 sp<IGraphicBufferProducer> igbProducer;
670 setUpProducer(adapter, igbProducer);
671 int slot;
672 sp<Fence> fence;
673 sp<GraphicBuffer> buf;
674 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
675 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
676 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
677 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
678 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
679
680 uint32_t* bufData;
681 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
682 reinterpret_cast<void**>(&bufData));
683 // fill buffer with grey
684 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
685
686 // fill crop area with different colors so we can verify the cropped region has been scaled
687 // correctly.
688 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
689 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
690 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
691 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
692 buf->unlock();
693
694 IGraphicBufferProducer::QueueBufferOutput qbOutput;
695 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
696 HAL_DATASPACE_UNKNOWN,
697 bufferCrop /* Rect::INVALID_RECT */,
698 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
699 Fence::NO_FENCE);
700 igbProducer->queueBuffer(slot, input, &qbOutput);
701 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
702
703 adapter.waitForCallbacks();
704
705 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
706 // Verify cropped region is scaled correctly.
707 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
708 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
709 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
710 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
711 // Verify outside region is black.
712 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
713 {0, 0, (int32_t)windowSize.getWidth(),
714 (int32_t)windowSize.getHeight()},
715 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800716}
717
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700718// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
719// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
720TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
721 uint8_t r = 255;
722 uint8_t g = 0;
723 uint8_t b = 0;
724
725 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
726 sp<IGraphicBufferProducer> igbProducer;
727 setUpProducer(adapter, igbProducer);
728 {
729 int slot;
730 sp<Fence> fence;
731 sp<GraphicBuffer> buf;
732 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
733 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
734 nullptr, nullptr);
735 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
736 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
737
738 uint32_t* bufData;
739 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
740 reinterpret_cast<void**>(&bufData));
741 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
742 buf->unlock();
743
744 IGraphicBufferProducer::QueueBufferOutput qbOutput;
745 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
746 HAL_DATASPACE_UNKNOWN, {},
747 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
748 Fence::NO_FENCE);
749 igbProducer->queueBuffer(slot, input, &qbOutput);
750 adapter.waitForCallbacks();
751 }
752 // capture screen and verify that it is red
753 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
754
755 ASSERT_NO_FATAL_FAILURE(
756 checkScreenCapture(r, g, b,
757 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
758
759 // update the size to half the display and dequeue a buffer quarter of the display.
760 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
761
762 {
763 int slot;
764 sp<Fence> fence;
765 sp<GraphicBuffer> buf;
766 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
767 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
768 nullptr, nullptr);
769 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
770 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
771
772 uint32_t* bufData;
773 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
774 reinterpret_cast<void**>(&bufData));
775 g = 255;
776 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
777 buf->unlock();
778
779 IGraphicBufferProducer::QueueBufferOutput qbOutput;
780 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
781 HAL_DATASPACE_UNKNOWN, {},
782 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
783 0, Fence::NO_FENCE);
784 igbProducer->queueBuffer(slot, input, &qbOutput);
785 adapter.waitForCallbacks();
786 }
787 // capture screen and verify that it is red
788 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
789 // verify we still scale the buffer to the new size (half the screen height)
790 ASSERT_NO_FATAL_FAILURE(
791 checkScreenCapture(r, g, b,
792 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
793}
794
chaviwd7deef72021-10-06 11:53:40 -0500795TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
796 uint8_t r = 255;
797 uint8_t g = 0;
798 uint8_t b = 0;
799
800 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
801
802 sp<IGraphicBufferProducer> igbProducer;
803 setUpProducer(adapter, igbProducer);
804
805 Transaction next;
806 adapter.setNextTransaction(&next);
807 queueBuffer(igbProducer, 0, 255, 0, 0);
808
809 // queue non sync buffer, so this one should get blocked
810 // Add a present delay to allow the first screenshot to get taken.
811 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
812 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
813
814 CallbackHelper transactionCallback;
815 next.addTransactionCompletedCallback(transactionCallback.function,
816 transactionCallback.getContext())
817 .apply();
818
819 CallbackData callbackData;
820 transactionCallback.getCallbackData(&callbackData);
821
822 // capture screen and verify that it is red
823 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
824 ASSERT_NO_FATAL_FAILURE(
825 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
826
827 mProducerListener->waitOnNumberReleased(1);
828 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
829 ASSERT_NO_FATAL_FAILURE(
830 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
831}
832
833TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
834 uint8_t r = 255;
835 uint8_t g = 0;
836 uint8_t b = 0;
837
838 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
839
840 sp<IGraphicBufferProducer> igbProducer;
841 setUpProducer(adapter, igbProducer);
842
843 Transaction mainTransaction;
844
845 Transaction next;
846 adapter.setNextTransaction(&next);
847 queueBuffer(igbProducer, 0, 255, 0, 0);
848
849 mainTransaction.merge(std::move(next));
850
851 adapter.setNextTransaction(&next);
852 queueBuffer(igbProducer, r, g, b, 0);
853
854 mainTransaction.merge(std::move(next));
855 // Expect 1 buffer to be released even before sending to SurfaceFlinger
856 mProducerListener->waitOnNumberReleased(1);
857
858 CallbackHelper transactionCallback;
859 mainTransaction
860 .addTransactionCompletedCallback(transactionCallback.function,
861 transactionCallback.getContext())
862 .apply();
863
864 CallbackData callbackData;
865 transactionCallback.getCallbackData(&callbackData);
866
867 // capture screen and verify that it is red
868 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
869 ASSERT_NO_FATAL_FAILURE(
870 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
871}
872
873TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
874 uint8_t r = 255;
875 uint8_t g = 0;
876 uint8_t b = 0;
877
878 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
879
880 sp<IGraphicBufferProducer> igbProducer;
881 setUpProducer(adapter, igbProducer);
882
883 Transaction mainTransaction;
884
885 Transaction next;
886 // queue a sync transaction
887 adapter.setNextTransaction(&next);
888 queueBuffer(igbProducer, 0, 255, 0, 0);
889
890 mainTransaction.merge(std::move(next));
891
892 // queue another buffer without setting next transaction
893 queueBuffer(igbProducer, 0, 0, 255, 0);
894
895 // queue another sync transaction
896 adapter.setNextTransaction(&next);
897 queueBuffer(igbProducer, r, g, b, 0);
898 // Expect 1 buffer to be released because the non sync transaction should merge
899 // with the sync
900 mProducerListener->waitOnNumberReleased(1);
901
902 mainTransaction.merge(std::move(next));
903 // Expect 2 buffers to be released due to merging the two syncs.
904 mProducerListener->waitOnNumberReleased(2);
905
906 CallbackHelper transactionCallback;
907 mainTransaction
908 .addTransactionCompletedCallback(transactionCallback.function,
909 transactionCallback.getContext())
910 .apply();
911
912 CallbackData callbackData;
913 transactionCallback.getCallbackData(&callbackData);
914
915 // capture screen and verify that it is red
916 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
917 ASSERT_NO_FATAL_FAILURE(
918 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
919}
920
921TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
922 uint8_t r = 255;
923 uint8_t g = 0;
924 uint8_t b = 0;
925
926 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
927
928 sp<IGraphicBufferProducer> igbProducer;
929 setUpProducer(adapter, igbProducer, 3);
930
931 Transaction mainTransaction;
932
933 Transaction next;
934 // queue a sync transaction
935 adapter.setNextTransaction(&next);
936 queueBuffer(igbProducer, 0, 255, 0, 0);
937
938 mainTransaction.merge(std::move(next));
939
940 // queue a few buffers without setting next transaction
941 queueBuffer(igbProducer, 0, 0, 255, 0);
942 queueBuffer(igbProducer, 0, 0, 255, 0);
943 queueBuffer(igbProducer, 0, 0, 255, 0);
944
945 // queue another sync transaction
946 adapter.setNextTransaction(&next);
947 queueBuffer(igbProducer, r, g, b, 0);
948 // Expect 3 buffers to be released because the non sync transactions should merge
949 // with the sync
950 mProducerListener->waitOnNumberReleased(3);
951
952 mainTransaction.merge(std::move(next));
953 // Expect 4 buffers to be released due to merging the two syncs.
954 mProducerListener->waitOnNumberReleased(4);
955
956 CallbackHelper transactionCallback;
957 mainTransaction
958 .addTransactionCompletedCallback(transactionCallback.function,
959 transactionCallback.getContext())
960 .apply();
961
962 CallbackData callbackData;
963 transactionCallback.getCallbackData(&callbackData);
964
965 // capture screen and verify that it is red
966 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
967 ASSERT_NO_FATAL_FAILURE(
968 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
969}
970
971// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
972// continue processing is for a release callback from SurfaceFlinger.
973// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
974// continue acquiring buffers.
975TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
976 uint8_t r = 255;
977 uint8_t g = 0;
978 uint8_t b = 0;
979
980 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
981
982 sp<IGraphicBufferProducer> igbProducer;
983 setUpProducer(adapter, igbProducer, 4);
984
985 Transaction mainTransaction;
986
987 // Send a buffer to SF
988 queueBuffer(igbProducer, 0, 255, 0, 0);
989
990 Transaction next;
991 // queue a sync transaction
992 adapter.setNextTransaction(&next);
993 queueBuffer(igbProducer, 0, 255, 0, 0);
994
995 mainTransaction.merge(std::move(next));
996
997 // queue a few buffers without setting next transaction
998 queueBuffer(igbProducer, 0, 0, 255, 0);
999 queueBuffer(igbProducer, 0, 0, 255, 0);
1000 queueBuffer(igbProducer, 0, 0, 255, 0);
1001
1002 // apply the first synced buffer to ensure we have to wait on SF
1003 mainTransaction.apply();
1004
1005 // queue another sync transaction
1006 adapter.setNextTransaction(&next);
1007 queueBuffer(igbProducer, r, g, b, 0);
1008 // Expect 2 buffers to be released because the non sync transactions should merge
1009 // with the sync
1010 mProducerListener->waitOnNumberReleased(3);
1011
1012 mainTransaction.merge(std::move(next));
1013
1014 CallbackHelper transactionCallback;
1015 mainTransaction
1016 .addTransactionCompletedCallback(transactionCallback.function,
1017 transactionCallback.getContext())
1018 .apply();
1019
1020 CallbackData callbackData;
1021 transactionCallback.getCallbackData(&callbackData);
1022
1023 // capture screen and verify that it is red
1024 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1025 ASSERT_NO_FATAL_FAILURE(
1026 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1027}
1028
Vishnu Nair89496122020-12-14 17:14:53 -08001029class TestProducerListener : public BnProducerListener {
1030public:
1031 sp<IGraphicBufferProducer> mIgbp;
1032 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1033 void onBufferReleased() override {
1034 sp<GraphicBuffer> buffer;
1035 sp<Fence> fence;
1036 mIgbp->detachNextBuffer(&buffer, &fence);
1037 }
1038};
1039
1040TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1041 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1042 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1043 ASSERT_NE(nullptr, igbProducer.get());
1044 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1045 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1046 ASSERT_EQ(NO_ERROR,
1047 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1048 false, &qbOutput));
1049 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1050 for (int i = 0; i < 3; i++) {
1051 int slot;
1052 sp<Fence> fence;
1053 sp<GraphicBuffer> buf;
1054 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1055 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1056 nullptr, nullptr);
1057 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1058 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1059 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001060 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1061 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001062 Rect(mDisplayWidth, mDisplayHeight),
1063 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1064 Fence::NO_FENCE);
1065 igbProducer->queueBuffer(slot, input, &qbOutput);
1066 }
1067 adapter.waitForCallbacks();
1068}
1069
Vishnu Nair17dde612020-12-28 11:39:59 -08001070TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1071 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1072
1073 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1074 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1075 int queuesToNativeWindow = 0;
1076 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1077 &queuesToNativeWindow);
1078 ASSERT_EQ(NO_ERROR, err);
1079 ASSERT_EQ(queuesToNativeWindow, 1);
1080}
1081
Vishnu Nair083efd32021-02-12 09:32:30 -08001082// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1083// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001084TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1085 sp<SurfaceControl> bgSurface =
1086 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1087 ISurfaceComposerClient::eFXSurfaceBufferState);
1088 ASSERT_NE(nullptr, bgSurface.get());
1089 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001090 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001091 .show(bgSurface)
1092 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001093 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1094 .apply();
1095
1096 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1097 sp<IGraphicBufferProducer> slowIgbProducer;
1098 setUpProducer(slowAdapter, slowIgbProducer);
1099 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001100 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001101
1102 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1103 sp<IGraphicBufferProducer> fastIgbProducer;
1104 setUpProducer(fastAdapter, fastIgbProducer);
1105 uint8_t r = 255;
1106 uint8_t g = 0;
1107 uint8_t b = 0;
1108 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1109 fastAdapter.waitForCallbacks();
1110
1111 // capture screen and verify that it is red
1112 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1113
1114 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001115 checkScreenCapture(r, g, b,
1116 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001117}
1118
Vishnu Naira4fbca52021-07-07 16:52:34 -07001119TEST_F(BLASTBufferQueueTest, TransformHint) {
1120 // Transform hint is provided to BBQ via the surface control passed by WM
1121 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1122
1123 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1124 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1125 ASSERT_NE(nullptr, igbProducer.get());
1126 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1127 sp<Surface> surface = adapter.getSurface();
1128
1129 // Before connecting to the surface, we do not get a valid transform hint
1130 int transformHint;
1131 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1132 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1133
1134 ASSERT_EQ(NO_ERROR,
1135 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1136
1137 // After connecting to the surface, we should get the correct hint.
1138 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1139 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1140
1141 ANativeWindow_Buffer buffer;
1142 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1143
1144 // Transform hint is updated via callbacks or surface control updates
1145 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1146 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1147
1148 // The hint does not change and matches the value used when dequeueing the buffer.
1149 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1150 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1151
1152 surface->unlockAndPost();
1153
1154 // After queuing the buffer, we get the updated transform hint
1155 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1156 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1157
1158 adapter.waitForCallbacks();
1159}
1160
Valerie Hau5977fc82019-12-05 15:56:39 -08001161class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1162public:
1163 void test(uint32_t tr) {
1164 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1165 sp<IGraphicBufferProducer> igbProducer;
1166 setUpProducer(adapter, igbProducer);
1167
1168 auto bufWidth = mDisplayWidth;
1169 auto bufHeight = mDisplayHeight;
1170 int slot;
1171 sp<Fence> fence;
1172 sp<GraphicBuffer> buf;
1173
1174 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1175 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1176 nullptr, nullptr);
1177 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1178 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1179
1180 fillQuadrants(buf);
1181
1182 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001183 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1184 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001185 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001186 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1187 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001188 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001189 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001190
1191 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001192 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001193
Valerie Hau5977fc82019-12-05 15:56:39 -08001194 switch (tr) {
1195 case ui::Transform::ROT_0:
1196 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1197 {0, 0, (int32_t)mDisplayWidth / 2,
1198 (int32_t)mDisplayHeight / 2},
1199 1));
1200 ASSERT_NO_FATAL_FAILURE(
1201 checkScreenCapture(255, 0, 0,
1202 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1203 (int32_t)mDisplayHeight / 2},
1204 1));
1205 ASSERT_NO_FATAL_FAILURE(
1206 checkScreenCapture(0, 255, 0,
1207 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1208 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1209 1));
1210 ASSERT_NO_FATAL_FAILURE(
1211 checkScreenCapture(0, 0, 255,
1212 {0, (int32_t)mDisplayHeight / 2,
1213 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1214 1));
1215 break;
1216 case ui::Transform::FLIP_H:
1217 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1218 {0, 0, (int32_t)mDisplayWidth / 2,
1219 (int32_t)mDisplayHeight / 2},
1220 1));
1221 ASSERT_NO_FATAL_FAILURE(
1222 checkScreenCapture(0, 0, 0,
1223 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1224 (int32_t)mDisplayHeight / 2},
1225 1));
1226 ASSERT_NO_FATAL_FAILURE(
1227 checkScreenCapture(0, 0, 255,
1228 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1229 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1230 1));
1231 ASSERT_NO_FATAL_FAILURE(
1232 checkScreenCapture(0, 255, 0,
1233 {0, (int32_t)mDisplayHeight / 2,
1234 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1235 1));
1236 break;
1237 case ui::Transform::FLIP_V:
1238 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1239 {0, 0, (int32_t)mDisplayWidth / 2,
1240 (int32_t)mDisplayHeight / 2},
1241 1));
1242 ASSERT_NO_FATAL_FAILURE(
1243 checkScreenCapture(0, 255, 0,
1244 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1245 (int32_t)mDisplayHeight / 2},
1246 1));
1247 ASSERT_NO_FATAL_FAILURE(
1248 checkScreenCapture(255, 0, 0,
1249 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1250 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1251 1));
1252 ASSERT_NO_FATAL_FAILURE(
1253 checkScreenCapture(0, 0, 0,
1254 {0, (int32_t)mDisplayHeight / 2,
1255 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1256 1));
1257 break;
1258 case ui::Transform::ROT_90:
1259 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1260 {0, 0, (int32_t)mDisplayWidth / 2,
1261 (int32_t)mDisplayHeight / 2},
1262 1));
1263 ASSERT_NO_FATAL_FAILURE(
1264 checkScreenCapture(0, 0, 0,
1265 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1266 (int32_t)mDisplayHeight / 2},
1267 1));
1268 ASSERT_NO_FATAL_FAILURE(
1269 checkScreenCapture(255, 0, 0,
1270 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1271 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1272 1));
1273 ASSERT_NO_FATAL_FAILURE(
1274 checkScreenCapture(0, 255, 0,
1275 {0, (int32_t)mDisplayHeight / 2,
1276 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1277 1));
1278 break;
1279 case ui::Transform::ROT_180:
1280 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1281 {0, 0, (int32_t)mDisplayWidth / 2,
1282 (int32_t)mDisplayHeight / 2},
1283 1));
1284 ASSERT_NO_FATAL_FAILURE(
1285 checkScreenCapture(0, 0, 255,
1286 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1287 (int32_t)mDisplayHeight / 2},
1288 1));
1289 ASSERT_NO_FATAL_FAILURE(
1290 checkScreenCapture(0, 0, 0,
1291 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1292 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1293 1));
1294 ASSERT_NO_FATAL_FAILURE(
1295 checkScreenCapture(255, 0, 0,
1296 {0, (int32_t)mDisplayHeight / 2,
1297 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1298 1));
1299 break;
1300 case ui::Transform::ROT_270:
1301 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1302 {0, 0, (int32_t)mDisplayWidth / 2,
1303 (int32_t)mDisplayHeight / 2},
1304 1));
1305 ASSERT_NO_FATAL_FAILURE(
1306 checkScreenCapture(0, 255, 0,
1307 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1308 (int32_t)mDisplayHeight / 2},
1309 1));
1310 ASSERT_NO_FATAL_FAILURE(
1311 checkScreenCapture(0, 0, 255,
1312 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1313 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1314 1));
1315 ASSERT_NO_FATAL_FAILURE(
1316 checkScreenCapture(0, 0, 0,
1317 {0, (int32_t)mDisplayHeight / 2,
1318 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1319 1));
1320 }
1321 }
1322};
1323
1324TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1325 test(ui::Transform::ROT_0);
1326}
1327
1328TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1329 test(ui::Transform::FLIP_H);
1330}
1331
1332TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1333 test(ui::Transform::FLIP_V);
1334}
1335
1336TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1337 test(ui::Transform::ROT_90);
1338}
1339
1340TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1341 test(ui::Transform::ROT_180);
1342}
1343
1344TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1345 test(ui::Transform::ROT_270);
1346}
Valerie Hau871d6352020-01-29 08:44:02 -08001347
1348class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1349public:
1350 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001351 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001352 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001353 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001354 int slot;
1355 sp<Fence> fence;
1356 sp<GraphicBuffer> buf;
1357 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1358 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1359 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001360 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1361 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1362 }
Valerie Hau871d6352020-01-29 08:44:02 -08001363
Vishnu Nairde66dc72021-06-17 17:54:41 -07001364 *outRequestedPresentTime = requestedPresentTime;
1365 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1366 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001367 Rect(mDisplayWidth, mDisplayHeight),
1368 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1369 Fence::NO_FENCE, /*sticky*/ 0,
1370 getFrameTimestamps);
1371 if (postedTime) *postedTime = systemTime();
1372 igbProducer->queueBuffer(slot, input, qbOutput);
1373 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001374 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001375};
1376
1377TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1378 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1379 sp<IGraphicBufferProducer> igbProducer;
1380 ProducerFrameEventHistory history;
1381 setUpProducer(adapter, igbProducer);
1382
1383 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1384 nsecs_t requestedPresentTimeA = 0;
1385 nsecs_t postedTimeA = 0;
1386 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1387 history.applyDelta(qbOutput.frameTimestamps);
1388
1389 FrameEvents* events = nullptr;
1390 events = history.getFrame(1);
1391 ASSERT_NE(nullptr, events);
1392 ASSERT_EQ(1, events->frameNumber);
1393 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1394 ASSERT_GE(events->postedTime, postedTimeA);
1395
Vishnu Nair1506b182021-02-22 14:35:15 -08001396 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001397
1398 // queue another buffer so we query for frame event deltas
1399 nsecs_t requestedPresentTimeB = 0;
1400 nsecs_t postedTimeB = 0;
1401 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1402 history.applyDelta(qbOutput.frameTimestamps);
1403 events = history.getFrame(1);
1404 ASSERT_NE(nullptr, events);
1405
1406 // frame number, requestedPresentTime, and postTime should not have changed
1407 ASSERT_EQ(1, events->frameNumber);
1408 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1409 ASSERT_GE(events->postedTime, postedTimeA);
1410
1411 ASSERT_GE(events->latchTime, postedTimeA);
1412 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1413 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1414 ASSERT_NE(nullptr, events->displayPresentFence);
1415 ASSERT_NE(nullptr, events->releaseFence);
1416
1417 // we should also have gotten the initial values for the next frame
1418 events = history.getFrame(2);
1419 ASSERT_NE(nullptr, events);
1420 ASSERT_EQ(2, events->frameNumber);
1421 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1422 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001423
1424 // wait for any callbacks that have not been received
1425 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001426}
Vishnu Nair083efd32021-02-12 09:32:30 -08001427
Vishnu Nair083efd32021-02-12 09:32:30 -08001428TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1429 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1430 sp<IGraphicBufferProducer> igbProducer;
1431 setUpProducer(adapter, igbProducer);
1432
1433 ProducerFrameEventHistory history;
1434 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1435 nsecs_t requestedPresentTimeA = 0;
1436 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001437 // Present the frame sometime in the future so we can add two frames to the queue so the older
1438 // one will be dropped.
1439 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001440 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001441 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001442 history.applyDelta(qbOutput.frameTimestamps);
1443
1444 FrameEvents* events = nullptr;
1445 events = history.getFrame(1);
1446 ASSERT_NE(nullptr, events);
1447 ASSERT_EQ(1, events->frameNumber);
1448 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1449 ASSERT_GE(events->postedTime, postedTimeA);
1450
1451 // queue another buffer so the first can be dropped
1452 nsecs_t requestedPresentTimeB = 0;
1453 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001454 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1455 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1456 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001457 history.applyDelta(qbOutput.frameTimestamps);
1458 events = history.getFrame(1);
1459 ASSERT_NE(nullptr, events);
1460
1461 // frame number, requestedPresentTime, and postTime should not have changed
1462 ASSERT_EQ(1, events->frameNumber);
1463 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1464 ASSERT_GE(events->postedTime, postedTimeA);
1465
Vishnu Nairde66dc72021-06-17 17:54:41 -07001466 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001467 ASSERT_FALSE(events->hasLatchInfo());
1468 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001469 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1470 ASSERT_FALSE(events->hasDisplayPresentInfo());
1471 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001472
Vishnu Nairde66dc72021-06-17 17:54:41 -07001473 // wait for the last transaction to be completed.
1474 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001475
Vishnu Nairde66dc72021-06-17 17:54:41 -07001476 // queue another buffer so we query for frame event deltas
1477 nsecs_t requestedPresentTimeC = 0;
1478 nsecs_t postedTimeC = 0;
1479 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1480 history.applyDelta(qbOutput.frameTimestamps);
1481
1482 // frame number, requestedPresentTime, and postTime should not have changed
1483 ASSERT_EQ(1, events->frameNumber);
1484 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1485 ASSERT_GE(events->postedTime, postedTimeA);
1486
1487 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1488 ASSERT_FALSE(events->hasLatchInfo());
1489 ASSERT_FALSE(events->hasDequeueReadyInfo());
1490 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1491 ASSERT_FALSE(events->hasDisplayPresentInfo());
1492 ASSERT_FALSE(events->hasReleaseInfo());
1493
1494 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001495 events = history.getFrame(2);
1496 ASSERT_NE(nullptr, events);
1497 ASSERT_EQ(2, events->frameNumber);
1498 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1499 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001500 ASSERT_GE(events->latchTime, postedTimeB);
1501 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1502 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1503 ASSERT_NE(nullptr, events->displayPresentFence);
1504 ASSERT_NE(nullptr, events->releaseFence);
1505
1506 // wait for any callbacks that have not been received
1507 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001508}
1509
Vishnu Nair9a69a042021-06-18 13:19:49 -07001510TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1511 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1512 sp<IGraphicBufferProducer> igbProducer;
1513 ProducerFrameEventHistory history;
1514 setUpProducer(adapter, igbProducer);
1515
1516 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1517 nsecs_t requestedPresentTimeA = 0;
1518 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001519 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1520 history.applyDelta(qbOutput.frameTimestamps);
1521 adapter.waitForCallback(1);
1522
1523 // queue another buffer so we query for frame event deltas
1524 nsecs_t requestedPresentTimeB = 0;
1525 nsecs_t postedTimeB = 0;
1526 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1527 history.applyDelta(qbOutput.frameTimestamps);
1528
1529 // check for a valid compositor deadline
1530 ASSERT_NE(0, history.getReportedCompositeDeadline());
1531
1532 // wait for any callbacks that have not been received
1533 adapter.waitForCallbacks();
1534}
1535
Valerie Hauc5011f92019-10-11 09:52:07 -07001536} // namespace android