blob: 8e4898d680ab074a69338793a6da311cdaa48db7 [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
Valerie Hauc5011f92019-10-11 09:52:07 -070069class BLASTBufferQueueHelper {
70public:
71 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -080072 mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height,
73 PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -070074 }
75
76 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -080077 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -070078 }
79
80 void setNextTransaction(Transaction* next) {
81 mBlastBufferQueueAdapter->setNextTransaction(next);
82 }
83
Vishnu Nairea0de002020-11-17 17:42:37 -080084 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -070085
Vishnu Nairea0de002020-11-17 17:42:37 -080086 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -070087
Valerie Hauc5011f92019-10-11 09:52:07 -070088 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -070089
90 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
91 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
92 }
93
Valerie Hauc5011f92019-10-11 09:52:07 -070094 const sp<SurfaceControl> getSurfaceControl() {
95 return mBlastBufferQueueAdapter->mSurfaceControl;
96 }
97
Vishnu Naira4fbca52021-07-07 16:52:34 -070098 sp<Surface> getSurface() {
99 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
100 }
101
Valerie Haud3b90d22019-11-06 09:37:31 -0800102 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700103 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800104 // Wait until all but one of the submitted buffers have been released.
105 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800106 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
107 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700108 }
109
Vishnu Nair1506b182021-02-22 14:35:15 -0800110 void setTransactionCompleteCallback(int64_t frameNumber) {
111 mBlastBufferQueueAdapter->setTransactionCompleteCallback(frameNumber, [&](int64_t frame) {
112 std::unique_lock lock{mMutex};
113 mLastTransactionCompleteFrameNumber = frame;
114 mCallbackCV.notify_all();
115 });
116 }
117
118 void waitForCallback(int64_t frameNumber) {
119 std::unique_lock lock{mMutex};
120 // Wait until all but one of the submitted buffers have been released.
121 while (mLastTransactionCompleteFrameNumber < frameNumber) {
122 mCallbackCV.wait(lock);
123 }
124 }
125
Valerie Hauc5011f92019-10-11 09:52:07 -0700126private:
127 sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
Vishnu Nair1506b182021-02-22 14:35:15 -0800128
129 std::mutex mMutex;
130 std::condition_variable mCallbackCV;
131 int64_t mLastTransactionCompleteFrameNumber = -1;
Valerie Hauc5011f92019-10-11 09:52:07 -0700132};
133
134class BLASTBufferQueueTest : public ::testing::Test {
135public:
136protected:
137 BLASTBufferQueueTest() {
138 const ::testing::TestInfo* const testInfo =
139 ::testing::UnitTest::GetInstance()->current_test_info();
140 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
141 }
142
143 ~BLASTBufferQueueTest() {
144 const ::testing::TestInfo* const testInfo =
145 ::testing::UnitTest::GetInstance()->current_test_info();
146 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
147 }
148
149 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700150 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700151 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700152 mDisplayToken = mClient->getInternalDisplayToken();
153 ASSERT_NE(nullptr, mDisplayToken.get());
154 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700155 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700156 t.apply();
157 t.clear();
158
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100159 ui::DisplayMode mode;
160 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
161 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800162 mDisplayWidth = resolution.getWidth();
163 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700164
165 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
166 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
167 ISurfaceComposerClient::eFXSurfaceBufferState,
168 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700169 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700170 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700171 .show(mSurfaceControl)
172 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
173 .apply();
chaviwd2432892020-07-24 17:42:39 -0700174
175 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800176 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700177 }
178
chaviwd7deef72021-10-06 11:53:40 -0500179 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
180 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800181 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500182 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800183 }
184
chaviwd7deef72021-10-06 11:53:40 -0500185 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800186 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500187 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800188 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500189 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800190 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500191 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800192 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800193 }
194
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800195 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
196 uint8_t b) {
197 for (uint32_t row = rect.top; row < rect.bottom; row++) {
198 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700199 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
200 *pixel = r;
201 *(pixel + 1) = g;
202 *(pixel + 2) = b;
203 *(pixel + 3) = 255;
204 }
205 }
206 }
207
Valerie Hau5977fc82019-12-05 15:56:39 -0800208 void fillQuadrants(sp<GraphicBuffer>& buf) {
209 const auto bufWidth = buf->getWidth();
210 const auto bufHeight = buf->getHeight();
211 uint32_t* bufData;
212 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
213 reinterpret_cast<void**>(&bufData));
214 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
215 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
216 0, 0);
217 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
218 buf->getStride(), 0, 255, 0);
219 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
220 255);
221 buf->unlock();
222 }
223
224 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
225 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700226 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800227 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700228 const auto width = captureBuf->getWidth();
229 const auto height = captureBuf->getHeight();
230 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700231
232 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700233 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
234 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700235
236 for (uint32_t row = 0; row < height; row++) {
237 for (uint32_t col = 0; col < width; col++) {
238 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800239 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800240 bool inRegion;
241 if (!outsideRegion) {
242 inRegion = row >= region.top + border && row < region.bottom - border &&
243 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800244 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800245 inRegion = row >= region.top - border && row < region.bottom + border &&
246 col >= region.left - border && col < region.right + border;
247 }
248 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000249 ASSERT_GE(epsilon, abs(r - *(pixel)));
250 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
251 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800252 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000253 ASSERT_GE(epsilon, abs(r - *(pixel)));
254 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
255 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800256 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800257 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700258 }
259 }
chaviwd2432892020-07-24 17:42:39 -0700260 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700261 }
262
chaviw8ffc7b82020-08-18 11:25:37 -0700263 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
264 ScreenCaptureResults& captureResults) {
265 const auto sf = ComposerService::getComposerService();
266 SurfaceComposerClient::Transaction().apply(true);
267
268 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
269 status_t status = sf->captureDisplay(captureArgs, captureListener);
270 if (status != NO_ERROR) {
271 return status;
272 }
273 captureResults = captureListener->waitForResults();
274 return captureResults.result;
275 }
276
Vishnu Nair277142c2021-01-05 18:35:29 -0800277 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
278 nsecs_t presentTimeDelay) {
279 int slot;
280 sp<Fence> fence;
281 sp<GraphicBuffer> buf;
282 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
283 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
284 nullptr, nullptr);
285 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
286 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
287
288 uint32_t* bufData;
289 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
290 reinterpret_cast<void**>(&bufData));
291 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
292 buf->unlock();
293
294 IGraphicBufferProducer::QueueBufferOutput qbOutput;
295 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
296 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
297 Rect(mDisplayWidth, mDisplayHeight / 2),
298 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
299 Fence::NO_FENCE);
300 igbp->queueBuffer(slot, input, &qbOutput);
301 }
302
Valerie Hauc5011f92019-10-11 09:52:07 -0700303 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700304 sp<ISurfaceComposer> mComposer;
305
306 sp<IBinder> mDisplayToken;
307
Valerie Hauc5011f92019-10-11 09:52:07 -0700308 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700309
310 uint32_t mDisplayWidth;
311 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700312
313 DisplayCaptureArgs mCaptureArgs;
314 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500315 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700316};
317
318TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
319 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700320 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700321 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700322 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
323 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700324 ASSERT_EQ(nullptr, adapter.getNextTransaction());
325}
326
327TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700328 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700329 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700330 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
331 PIXEL_FORMAT_RGBA_8888);
332 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700333 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800334 sp<IGraphicBufferProducer> igbProducer;
335 setUpProducer(adapter, igbProducer);
336
337 int32_t width;
338 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
339 ASSERT_EQ(mDisplayWidth / 2, width);
340 int32_t height;
341 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
342 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700343}
344
345TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700346 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700347 Transaction next;
348 adapter.setNextTransaction(&next);
349 ASSERT_EQ(&next, adapter.getNextTransaction());
350}
Valerie Hauda3446e2019-10-14 15:49:22 -0700351
Valerie Haubf29e042020-02-06 11:40:38 -0800352TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800353 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
354 sp<IGraphicBufferProducer> igbProducer;
355 setUpProducer(adapter, igbProducer);
356
357 int slot;
358 sp<Fence> fence;
359 sp<GraphicBuffer> buf;
360 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
361 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
362 nullptr, nullptr);
363 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
364 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
365
366 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
367 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800368 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
369 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800370 Rect(mDisplayWidth, mDisplayHeight),
371 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
372 Fence::NO_FENCE);
373 igbProducer->queueBuffer(slot, input, &qbOutput);
374 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
375
376 adapter.waitForCallbacks();
377 ASSERT_GE(systemTime(), desiredPresentTime);
378}
379
Valerie Hauda3446e2019-10-14 15:49:22 -0700380TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
381 uint8_t r = 255;
382 uint8_t g = 0;
383 uint8_t b = 0;
384
385 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800386 sp<IGraphicBufferProducer> igbProducer;
387 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700388
389 int slot;
390 sp<Fence> fence;
391 sp<GraphicBuffer> buf;
392 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
393 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
394 nullptr, nullptr);
395 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
396 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
397
398 uint32_t* bufData;
399 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
400 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800401 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700402 buf->unlock();
403
Valerie Haud3b90d22019-11-06 09:37:31 -0800404 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800405 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
406 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700407 Rect(mDisplayWidth, mDisplayHeight),
408 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
409 Fence::NO_FENCE);
410 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800411 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700412
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800413 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700414
415 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700416 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800417 ASSERT_NO_FATAL_FAILURE(
418 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700419}
Valerie Haud3b90d22019-11-06 09:37:31 -0800420
421TEST_F(BLASTBufferQueueTest, TripleBuffering) {
422 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
423 sp<IGraphicBufferProducer> igbProducer;
424 setUpProducer(adapter, igbProducer);
425
426 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700427 int minUndequeuedBuffers = 0;
428 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
429 const auto bufferCount = minUndequeuedBuffers + 2;
430
431 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800432 int slot;
433 sp<Fence> fence;
434 sp<GraphicBuffer> buf;
435 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
436 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
437 nullptr, nullptr);
438 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
439 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
440 allocated.push_back({slot, fence});
441 }
442 for (int i = 0; i < allocated.size(); i++) {
443 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
444 }
445
Valerie Haua32c5522019-12-09 10:11:08 -0800446 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800447 int slot;
448 sp<Fence> fence;
449 sp<GraphicBuffer> buf;
450 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
451 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
452 nullptr, nullptr);
453 ASSERT_EQ(NO_ERROR, ret);
454 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800455 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
456 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800457 Rect(mDisplayWidth, mDisplayHeight),
458 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
459 Fence::NO_FENCE);
460 igbProducer->queueBuffer(slot, input, &qbOutput);
461 }
462 adapter.waitForCallbacks();
463}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800464
465TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
466 uint8_t r = 255;
467 uint8_t g = 0;
468 uint8_t b = 0;
469
470 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
471 sp<IGraphicBufferProducer> igbProducer;
472 setUpProducer(adapter, igbProducer);
473 int slot;
474 sp<Fence> fence;
475 sp<GraphicBuffer> buf;
476 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
477 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
478 nullptr, nullptr);
479 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
480 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
481
482 uint32_t* bufData;
483 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
484 reinterpret_cast<void**>(&bufData));
485 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
486 buf->unlock();
487
488 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800489 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
490 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800491 Rect(mDisplayWidth, mDisplayHeight / 2),
492 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
493 Fence::NO_FENCE);
494 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800495 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800496
497 adapter.waitForCallbacks();
498 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700499 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700500
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800501 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000502 checkScreenCapture(r, g, b,
503 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800504}
505
506TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
507 uint8_t r = 255;
508 uint8_t g = 0;
509 uint8_t b = 0;
510
511 int32_t bufferSideLength =
512 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
513 int32_t finalCropSideLength = bufferSideLength / 2;
514
515 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800516 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800517 ASSERT_NE(nullptr, bg.get());
518 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700519 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800520 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800521 .setColor(bg, half3{0, 0, 0})
522 .setLayer(bg, 0)
523 .apply();
524
525 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
526 sp<IGraphicBufferProducer> igbProducer;
527 setUpProducer(adapter, igbProducer);
528 int slot;
529 sp<Fence> fence;
530 sp<GraphicBuffer> buf;
531 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
532 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
533 nullptr, nullptr);
534 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
535 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
536
537 uint32_t* bufData;
538 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
539 reinterpret_cast<void**>(&bufData));
540 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
541 fillBuffer(bufData,
542 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
543 buf->getHeight()),
544 buf->getStride(), r, g, b);
545 buf->unlock();
546
547 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800548 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
549 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800550 Rect(bufferSideLength, finalCropSideLength),
551 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
552 Fence::NO_FENCE);
553 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800554 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800555
556 adapter.waitForCallbacks();
557 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700558 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700559 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
560 {10, 10, (int32_t)bufferSideLength - 10,
561 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800562 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700563 checkScreenCapture(0, 0, 0,
564 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
565 /*border*/ 0, /*outsideRegion*/ true));
566}
567
568TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
569 // add black background
570 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
571 ISurfaceComposerClient::eFXSurfaceEffect);
572 ASSERT_NE(nullptr, bg.get());
573 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700574 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700575 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
576 .setColor(bg, half3{0, 0, 0})
577 .setLayer(bg, 0)
578 .apply();
579
580 Rect windowSize(1000, 1000);
581 Rect bufferSize(windowSize);
582 Rect bufferCrop(200, 200, 700, 700);
583
584 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
585 sp<IGraphicBufferProducer> igbProducer;
586 setUpProducer(adapter, igbProducer);
587 int slot;
588 sp<Fence> fence;
589 sp<GraphicBuffer> buf;
590 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
591 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
592 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
593 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
594 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
595
596 uint32_t* bufData;
597 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
598 reinterpret_cast<void**>(&bufData));
599 // fill buffer with grey
600 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
601
602 // fill crop area with different colors so we can verify the cropped region has been scaled
603 // correctly.
604 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
605 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
606 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
607 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
608 buf->unlock();
609
610 IGraphicBufferProducer::QueueBufferOutput qbOutput;
611 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
612 HAL_DATASPACE_UNKNOWN,
613 bufferCrop /* Rect::INVALID_RECT */,
614 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
615 Fence::NO_FENCE);
616 igbProducer->queueBuffer(slot, input, &qbOutput);
617 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
618
619 adapter.waitForCallbacks();
620
621 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
622
623 // Verify cropped region is scaled correctly.
624 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
625 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
626 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
627 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
628 // Verify outside region is black.
629 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
630 {0, 0, (int32_t)windowSize.getWidth(),
631 (int32_t)windowSize.getHeight()},
632 /*border*/ 0, /*outsideRegion*/ true));
633}
634
635TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
636 // add black background
637 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
638 ISurfaceComposerClient::eFXSurfaceEffect);
639 ASSERT_NE(nullptr, bg.get());
640 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700642 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
643 .setColor(bg, half3{0, 0, 0})
644 .setLayer(bg, 0)
645 .apply();
646
647 Rect windowSize(1000, 1000);
648 Rect bufferSize(500, 500);
649 Rect bufferCrop(100, 100, 350, 350);
650
651 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
652 sp<IGraphicBufferProducer> igbProducer;
653 setUpProducer(adapter, igbProducer);
654 int slot;
655 sp<Fence> fence;
656 sp<GraphicBuffer> buf;
657 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
658 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
659 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
660 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
661 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
662
663 uint32_t* bufData;
664 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
665 reinterpret_cast<void**>(&bufData));
666 // fill buffer with grey
667 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
668
669 // fill crop area with different colors so we can verify the cropped region has been scaled
670 // correctly.
671 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
672 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
673 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
674 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
675 buf->unlock();
676
677 IGraphicBufferProducer::QueueBufferOutput qbOutput;
678 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
679 HAL_DATASPACE_UNKNOWN,
680 bufferCrop /* Rect::INVALID_RECT */,
681 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
682 Fence::NO_FENCE);
683 igbProducer->queueBuffer(slot, input, &qbOutput);
684 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
685
686 adapter.waitForCallbacks();
687
688 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
689 // Verify cropped region is scaled correctly.
690 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
691 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
692 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
693 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
694 // Verify outside region is black.
695 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
696 {0, 0, (int32_t)windowSize.getWidth(),
697 (int32_t)windowSize.getHeight()},
698 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800699}
700
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700701// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
702// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
703TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
704 uint8_t r = 255;
705 uint8_t g = 0;
706 uint8_t b = 0;
707
708 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
709 sp<IGraphicBufferProducer> igbProducer;
710 setUpProducer(adapter, igbProducer);
711 {
712 int slot;
713 sp<Fence> fence;
714 sp<GraphicBuffer> buf;
715 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
716 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
717 nullptr, nullptr);
718 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
719 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
720
721 uint32_t* bufData;
722 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
723 reinterpret_cast<void**>(&bufData));
724 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
725 buf->unlock();
726
727 IGraphicBufferProducer::QueueBufferOutput qbOutput;
728 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
729 HAL_DATASPACE_UNKNOWN, {},
730 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
731 Fence::NO_FENCE);
732 igbProducer->queueBuffer(slot, input, &qbOutput);
733 adapter.waitForCallbacks();
734 }
735 // capture screen and verify that it is red
736 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
737
738 ASSERT_NO_FATAL_FAILURE(
739 checkScreenCapture(r, g, b,
740 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
741
742 // update the size to half the display and dequeue a buffer quarter of the display.
743 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
744
745 {
746 int slot;
747 sp<Fence> fence;
748 sp<GraphicBuffer> buf;
749 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
750 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
751 nullptr, nullptr);
752 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
753 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
754
755 uint32_t* bufData;
756 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
757 reinterpret_cast<void**>(&bufData));
758 g = 255;
759 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
760 buf->unlock();
761
762 IGraphicBufferProducer::QueueBufferOutput qbOutput;
763 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
764 HAL_DATASPACE_UNKNOWN, {},
765 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
766 0, Fence::NO_FENCE);
767 igbProducer->queueBuffer(slot, input, &qbOutput);
768 adapter.waitForCallbacks();
769 }
770 // capture screen and verify that it is red
771 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
772 // verify we still scale the buffer to the new size (half the screen height)
773 ASSERT_NO_FATAL_FAILURE(
774 checkScreenCapture(r, g, b,
775 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
776}
777
chaviwd7deef72021-10-06 11:53:40 -0500778TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
779 uint8_t r = 255;
780 uint8_t g = 0;
781 uint8_t b = 0;
782
783 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
784
785 sp<IGraphicBufferProducer> igbProducer;
786 setUpProducer(adapter, igbProducer);
787
788 Transaction next;
789 adapter.setNextTransaction(&next);
790 queueBuffer(igbProducer, 0, 255, 0, 0);
791
792 // queue non sync buffer, so this one should get blocked
793 // Add a present delay to allow the first screenshot to get taken.
794 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
795 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
796
797 CallbackHelper transactionCallback;
798 next.addTransactionCompletedCallback(transactionCallback.function,
799 transactionCallback.getContext())
800 .apply();
801
802 CallbackData callbackData;
803 transactionCallback.getCallbackData(&callbackData);
804
805 // capture screen and verify that it is red
806 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
807 ASSERT_NO_FATAL_FAILURE(
808 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
809
810 mProducerListener->waitOnNumberReleased(1);
811 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
812 ASSERT_NO_FATAL_FAILURE(
813 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
814}
815
816TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
817 uint8_t r = 255;
818 uint8_t g = 0;
819 uint8_t b = 0;
820
821 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
822
823 sp<IGraphicBufferProducer> igbProducer;
824 setUpProducer(adapter, igbProducer);
825
826 Transaction mainTransaction;
827
828 Transaction next;
829 adapter.setNextTransaction(&next);
830 queueBuffer(igbProducer, 0, 255, 0, 0);
831
832 mainTransaction.merge(std::move(next));
833
834 adapter.setNextTransaction(&next);
835 queueBuffer(igbProducer, r, g, b, 0);
836
837 mainTransaction.merge(std::move(next));
838 // Expect 1 buffer to be released even before sending to SurfaceFlinger
839 mProducerListener->waitOnNumberReleased(1);
840
841 CallbackHelper transactionCallback;
842 mainTransaction
843 .addTransactionCompletedCallback(transactionCallback.function,
844 transactionCallback.getContext())
845 .apply();
846
847 CallbackData callbackData;
848 transactionCallback.getCallbackData(&callbackData);
849
850 // capture screen and verify that it is red
851 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
852 ASSERT_NO_FATAL_FAILURE(
853 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
854}
855
856TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
857 uint8_t r = 255;
858 uint8_t g = 0;
859 uint8_t b = 0;
860
861 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
862
863 sp<IGraphicBufferProducer> igbProducer;
864 setUpProducer(adapter, igbProducer);
865
866 Transaction mainTransaction;
867
868 Transaction next;
869 // queue a sync transaction
870 adapter.setNextTransaction(&next);
871 queueBuffer(igbProducer, 0, 255, 0, 0);
872
873 mainTransaction.merge(std::move(next));
874
875 // queue another buffer without setting next transaction
876 queueBuffer(igbProducer, 0, 0, 255, 0);
877
878 // queue another sync transaction
879 adapter.setNextTransaction(&next);
880 queueBuffer(igbProducer, r, g, b, 0);
881 // Expect 1 buffer to be released because the non sync transaction should merge
882 // with the sync
883 mProducerListener->waitOnNumberReleased(1);
884
885 mainTransaction.merge(std::move(next));
886 // Expect 2 buffers to be released due to merging the two syncs.
887 mProducerListener->waitOnNumberReleased(2);
888
889 CallbackHelper transactionCallback;
890 mainTransaction
891 .addTransactionCompletedCallback(transactionCallback.function,
892 transactionCallback.getContext())
893 .apply();
894
895 CallbackData callbackData;
896 transactionCallback.getCallbackData(&callbackData);
897
898 // capture screen and verify that it is red
899 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
900 ASSERT_NO_FATAL_FAILURE(
901 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
902}
903
904TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
905 uint8_t r = 255;
906 uint8_t g = 0;
907 uint8_t b = 0;
908
909 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
910
911 sp<IGraphicBufferProducer> igbProducer;
912 setUpProducer(adapter, igbProducer, 3);
913
914 Transaction mainTransaction;
915
916 Transaction next;
917 // queue a sync transaction
918 adapter.setNextTransaction(&next);
919 queueBuffer(igbProducer, 0, 255, 0, 0);
920
921 mainTransaction.merge(std::move(next));
922
923 // queue a few buffers without setting next transaction
924 queueBuffer(igbProducer, 0, 0, 255, 0);
925 queueBuffer(igbProducer, 0, 0, 255, 0);
926 queueBuffer(igbProducer, 0, 0, 255, 0);
927
928 // queue another sync transaction
929 adapter.setNextTransaction(&next);
930 queueBuffer(igbProducer, r, g, b, 0);
931 // Expect 3 buffers to be released because the non sync transactions should merge
932 // with the sync
933 mProducerListener->waitOnNumberReleased(3);
934
935 mainTransaction.merge(std::move(next));
936 // Expect 4 buffers to be released due to merging the two syncs.
937 mProducerListener->waitOnNumberReleased(4);
938
939 CallbackHelper transactionCallback;
940 mainTransaction
941 .addTransactionCompletedCallback(transactionCallback.function,
942 transactionCallback.getContext())
943 .apply();
944
945 CallbackData callbackData;
946 transactionCallback.getCallbackData(&callbackData);
947
948 // capture screen and verify that it is red
949 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
950 ASSERT_NO_FATAL_FAILURE(
951 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
952}
953
954// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
955// continue processing is for a release callback from SurfaceFlinger.
956// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
957// continue acquiring buffers.
958TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
959 uint8_t r = 255;
960 uint8_t g = 0;
961 uint8_t b = 0;
962
963 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
964
965 sp<IGraphicBufferProducer> igbProducer;
966 setUpProducer(adapter, igbProducer, 4);
967
968 Transaction mainTransaction;
969
970 // Send a buffer to SF
971 queueBuffer(igbProducer, 0, 255, 0, 0);
972
973 Transaction next;
974 // queue a sync transaction
975 adapter.setNextTransaction(&next);
976 queueBuffer(igbProducer, 0, 255, 0, 0);
977
978 mainTransaction.merge(std::move(next));
979
980 // queue a few buffers without setting next transaction
981 queueBuffer(igbProducer, 0, 0, 255, 0);
982 queueBuffer(igbProducer, 0, 0, 255, 0);
983 queueBuffer(igbProducer, 0, 0, 255, 0);
984
985 // apply the first synced buffer to ensure we have to wait on SF
986 mainTransaction.apply();
987
988 // queue another sync transaction
989 adapter.setNextTransaction(&next);
990 queueBuffer(igbProducer, r, g, b, 0);
991 // Expect 2 buffers to be released because the non sync transactions should merge
992 // with the sync
993 mProducerListener->waitOnNumberReleased(3);
994
995 mainTransaction.merge(std::move(next));
996
997 CallbackHelper transactionCallback;
998 mainTransaction
999 .addTransactionCompletedCallback(transactionCallback.function,
1000 transactionCallback.getContext())
1001 .apply();
1002
1003 CallbackData callbackData;
1004 transactionCallback.getCallbackData(&callbackData);
1005
1006 // capture screen and verify that it is red
1007 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1008 ASSERT_NO_FATAL_FAILURE(
1009 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1010}
1011
Vishnu Nair89496122020-12-14 17:14:53 -08001012class TestProducerListener : public BnProducerListener {
1013public:
1014 sp<IGraphicBufferProducer> mIgbp;
1015 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1016 void onBufferReleased() override {
1017 sp<GraphicBuffer> buffer;
1018 sp<Fence> fence;
1019 mIgbp->detachNextBuffer(&buffer, &fence);
1020 }
1021};
1022
1023TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1024 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1025 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1026 ASSERT_NE(nullptr, igbProducer.get());
1027 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1028 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1029 ASSERT_EQ(NO_ERROR,
1030 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1031 false, &qbOutput));
1032 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1033 for (int i = 0; i < 3; i++) {
1034 int slot;
1035 sp<Fence> fence;
1036 sp<GraphicBuffer> buf;
1037 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1038 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1039 nullptr, nullptr);
1040 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1041 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1042 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001043 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1044 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001045 Rect(mDisplayWidth, mDisplayHeight),
1046 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1047 Fence::NO_FENCE);
1048 igbProducer->queueBuffer(slot, input, &qbOutput);
1049 }
1050 adapter.waitForCallbacks();
1051}
1052
Vishnu Nair17dde612020-12-28 11:39:59 -08001053TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1054 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1055
1056 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1057 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1058 int queuesToNativeWindow = 0;
1059 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1060 &queuesToNativeWindow);
1061 ASSERT_EQ(NO_ERROR, err);
1062 ASSERT_EQ(queuesToNativeWindow, 1);
1063}
1064
Vishnu Nair083efd32021-02-12 09:32:30 -08001065// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1066// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001067TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1068 sp<SurfaceControl> bgSurface =
1069 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1070 ISurfaceComposerClient::eFXSurfaceBufferState);
1071 ASSERT_NE(nullptr, bgSurface.get());
1072 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001073 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001074 .show(bgSurface)
1075 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001076 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1077 .apply();
1078
1079 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1080 sp<IGraphicBufferProducer> slowIgbProducer;
1081 setUpProducer(slowAdapter, slowIgbProducer);
1082 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001083 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001084
1085 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1086 sp<IGraphicBufferProducer> fastIgbProducer;
1087 setUpProducer(fastAdapter, fastIgbProducer);
1088 uint8_t r = 255;
1089 uint8_t g = 0;
1090 uint8_t b = 0;
1091 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1092 fastAdapter.waitForCallbacks();
1093
1094 // capture screen and verify that it is red
1095 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1096
1097 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001098 checkScreenCapture(r, g, b,
1099 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001100}
1101
Vishnu Naira4fbca52021-07-07 16:52:34 -07001102TEST_F(BLASTBufferQueueTest, TransformHint) {
1103 // Transform hint is provided to BBQ via the surface control passed by WM
1104 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1105
1106 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1107 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1108 ASSERT_NE(nullptr, igbProducer.get());
1109 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1110 sp<Surface> surface = adapter.getSurface();
1111
1112 // Before connecting to the surface, we do not get a valid transform hint
1113 int transformHint;
1114 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1115 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1116
1117 ASSERT_EQ(NO_ERROR,
1118 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1119
1120 // After connecting to the surface, we should get the correct hint.
1121 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1122 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1123
1124 ANativeWindow_Buffer buffer;
1125 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1126
1127 // Transform hint is updated via callbacks or surface control updates
1128 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1129 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1130
1131 // The hint does not change and matches the value used when dequeueing the buffer.
1132 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1133 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1134
1135 surface->unlockAndPost();
1136
1137 // After queuing the buffer, we get the updated transform hint
1138 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1139 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1140
1141 adapter.waitForCallbacks();
1142}
1143
Valerie Hau5977fc82019-12-05 15:56:39 -08001144class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1145public:
1146 void test(uint32_t tr) {
1147 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1148 sp<IGraphicBufferProducer> igbProducer;
1149 setUpProducer(adapter, igbProducer);
1150
1151 auto bufWidth = mDisplayWidth;
1152 auto bufHeight = mDisplayHeight;
1153 int slot;
1154 sp<Fence> fence;
1155 sp<GraphicBuffer> buf;
1156
1157 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1158 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1159 nullptr, nullptr);
1160 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1161 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1162
1163 fillQuadrants(buf);
1164
1165 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001166 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1167 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001168 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001169 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1170 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001171 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001172 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001173
1174 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001175 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001176
Valerie Hau5977fc82019-12-05 15:56:39 -08001177 switch (tr) {
1178 case ui::Transform::ROT_0:
1179 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1180 {0, 0, (int32_t)mDisplayWidth / 2,
1181 (int32_t)mDisplayHeight / 2},
1182 1));
1183 ASSERT_NO_FATAL_FAILURE(
1184 checkScreenCapture(255, 0, 0,
1185 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1186 (int32_t)mDisplayHeight / 2},
1187 1));
1188 ASSERT_NO_FATAL_FAILURE(
1189 checkScreenCapture(0, 255, 0,
1190 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1191 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1192 1));
1193 ASSERT_NO_FATAL_FAILURE(
1194 checkScreenCapture(0, 0, 255,
1195 {0, (int32_t)mDisplayHeight / 2,
1196 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1197 1));
1198 break;
1199 case ui::Transform::FLIP_H:
1200 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1201 {0, 0, (int32_t)mDisplayWidth / 2,
1202 (int32_t)mDisplayHeight / 2},
1203 1));
1204 ASSERT_NO_FATAL_FAILURE(
1205 checkScreenCapture(0, 0, 0,
1206 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1207 (int32_t)mDisplayHeight / 2},
1208 1));
1209 ASSERT_NO_FATAL_FAILURE(
1210 checkScreenCapture(0, 0, 255,
1211 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1212 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1213 1));
1214 ASSERT_NO_FATAL_FAILURE(
1215 checkScreenCapture(0, 255, 0,
1216 {0, (int32_t)mDisplayHeight / 2,
1217 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1218 1));
1219 break;
1220 case ui::Transform::FLIP_V:
1221 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1222 {0, 0, (int32_t)mDisplayWidth / 2,
1223 (int32_t)mDisplayHeight / 2},
1224 1));
1225 ASSERT_NO_FATAL_FAILURE(
1226 checkScreenCapture(0, 255, 0,
1227 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1228 (int32_t)mDisplayHeight / 2},
1229 1));
1230 ASSERT_NO_FATAL_FAILURE(
1231 checkScreenCapture(255, 0, 0,
1232 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1233 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1234 1));
1235 ASSERT_NO_FATAL_FAILURE(
1236 checkScreenCapture(0, 0, 0,
1237 {0, (int32_t)mDisplayHeight / 2,
1238 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1239 1));
1240 break;
1241 case ui::Transform::ROT_90:
1242 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1243 {0, 0, (int32_t)mDisplayWidth / 2,
1244 (int32_t)mDisplayHeight / 2},
1245 1));
1246 ASSERT_NO_FATAL_FAILURE(
1247 checkScreenCapture(0, 0, 0,
1248 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1249 (int32_t)mDisplayHeight / 2},
1250 1));
1251 ASSERT_NO_FATAL_FAILURE(
1252 checkScreenCapture(255, 0, 0,
1253 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1254 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1255 1));
1256 ASSERT_NO_FATAL_FAILURE(
1257 checkScreenCapture(0, 255, 0,
1258 {0, (int32_t)mDisplayHeight / 2,
1259 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1260 1));
1261 break;
1262 case ui::Transform::ROT_180:
1263 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1264 {0, 0, (int32_t)mDisplayWidth / 2,
1265 (int32_t)mDisplayHeight / 2},
1266 1));
1267 ASSERT_NO_FATAL_FAILURE(
1268 checkScreenCapture(0, 0, 255,
1269 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1270 (int32_t)mDisplayHeight / 2},
1271 1));
1272 ASSERT_NO_FATAL_FAILURE(
1273 checkScreenCapture(0, 0, 0,
1274 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1275 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1276 1));
1277 ASSERT_NO_FATAL_FAILURE(
1278 checkScreenCapture(255, 0, 0,
1279 {0, (int32_t)mDisplayHeight / 2,
1280 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1281 1));
1282 break;
1283 case ui::Transform::ROT_270:
1284 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1285 {0, 0, (int32_t)mDisplayWidth / 2,
1286 (int32_t)mDisplayHeight / 2},
1287 1));
1288 ASSERT_NO_FATAL_FAILURE(
1289 checkScreenCapture(0, 255, 0,
1290 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1291 (int32_t)mDisplayHeight / 2},
1292 1));
1293 ASSERT_NO_FATAL_FAILURE(
1294 checkScreenCapture(0, 0, 255,
1295 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1296 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1297 1));
1298 ASSERT_NO_FATAL_FAILURE(
1299 checkScreenCapture(0, 0, 0,
1300 {0, (int32_t)mDisplayHeight / 2,
1301 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1302 1));
1303 }
1304 }
1305};
1306
1307TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1308 test(ui::Transform::ROT_0);
1309}
1310
1311TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1312 test(ui::Transform::FLIP_H);
1313}
1314
1315TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1316 test(ui::Transform::FLIP_V);
1317}
1318
1319TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1320 test(ui::Transform::ROT_90);
1321}
1322
1323TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1324 test(ui::Transform::ROT_180);
1325}
1326
1327TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1328 test(ui::Transform::ROT_270);
1329}
Valerie Hau871d6352020-01-29 08:44:02 -08001330
1331class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1332public:
1333 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001334 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001335 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001336 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001337 int slot;
1338 sp<Fence> fence;
1339 sp<GraphicBuffer> buf;
1340 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1341 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1342 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001343 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1344 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1345 }
Valerie Hau871d6352020-01-29 08:44:02 -08001346
Vishnu Nairde66dc72021-06-17 17:54:41 -07001347 *outRequestedPresentTime = requestedPresentTime;
1348 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1349 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001350 Rect(mDisplayWidth, mDisplayHeight),
1351 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1352 Fence::NO_FENCE, /*sticky*/ 0,
1353 getFrameTimestamps);
1354 if (postedTime) *postedTime = systemTime();
1355 igbProducer->queueBuffer(slot, input, qbOutput);
1356 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001357 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001358};
1359
1360TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1361 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1362 sp<IGraphicBufferProducer> igbProducer;
1363 ProducerFrameEventHistory history;
1364 setUpProducer(adapter, igbProducer);
1365
1366 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1367 nsecs_t requestedPresentTimeA = 0;
1368 nsecs_t postedTimeA = 0;
Vishnu Nair1506b182021-02-22 14:35:15 -08001369 adapter.setTransactionCompleteCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001370 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1371 history.applyDelta(qbOutput.frameTimestamps);
1372
1373 FrameEvents* events = nullptr;
1374 events = history.getFrame(1);
1375 ASSERT_NE(nullptr, events);
1376 ASSERT_EQ(1, events->frameNumber);
1377 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1378 ASSERT_GE(events->postedTime, postedTimeA);
1379
Vishnu Nair1506b182021-02-22 14:35:15 -08001380 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001381
1382 // queue another buffer so we query for frame event deltas
1383 nsecs_t requestedPresentTimeB = 0;
1384 nsecs_t postedTimeB = 0;
1385 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1386 history.applyDelta(qbOutput.frameTimestamps);
1387 events = history.getFrame(1);
1388 ASSERT_NE(nullptr, events);
1389
1390 // frame number, requestedPresentTime, and postTime should not have changed
1391 ASSERT_EQ(1, events->frameNumber);
1392 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1393 ASSERT_GE(events->postedTime, postedTimeA);
1394
1395 ASSERT_GE(events->latchTime, postedTimeA);
1396 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1397 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1398 ASSERT_NE(nullptr, events->displayPresentFence);
1399 ASSERT_NE(nullptr, events->releaseFence);
1400
1401 // we should also have gotten the initial values for the next frame
1402 events = history.getFrame(2);
1403 ASSERT_NE(nullptr, events);
1404 ASSERT_EQ(2, events->frameNumber);
1405 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1406 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001407
1408 // wait for any callbacks that have not been received
1409 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001410}
Vishnu Nair083efd32021-02-12 09:32:30 -08001411
Vishnu Nair083efd32021-02-12 09:32:30 -08001412TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1413 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1414 sp<IGraphicBufferProducer> igbProducer;
1415 setUpProducer(adapter, igbProducer);
1416
1417 ProducerFrameEventHistory history;
1418 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1419 nsecs_t requestedPresentTimeA = 0;
1420 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001421 // Present the frame sometime in the future so we can add two frames to the queue so the older
1422 // one will be dropped.
1423 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001424 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001425 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001426 history.applyDelta(qbOutput.frameTimestamps);
1427
1428 FrameEvents* events = nullptr;
1429 events = history.getFrame(1);
1430 ASSERT_NE(nullptr, events);
1431 ASSERT_EQ(1, events->frameNumber);
1432 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1433 ASSERT_GE(events->postedTime, postedTimeA);
1434
1435 // queue another buffer so the first can be dropped
1436 nsecs_t requestedPresentTimeB = 0;
1437 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001438 adapter.setTransactionCompleteCallback(2);
1439 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1440 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1441 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001442 history.applyDelta(qbOutput.frameTimestamps);
1443 events = history.getFrame(1);
1444 ASSERT_NE(nullptr, events);
1445
1446 // frame number, requestedPresentTime, and postTime should not have changed
1447 ASSERT_EQ(1, events->frameNumber);
1448 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1449 ASSERT_GE(events->postedTime, postedTimeA);
1450
Vishnu Nairde66dc72021-06-17 17:54:41 -07001451 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001452 ASSERT_FALSE(events->hasLatchInfo());
1453 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001454 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1455 ASSERT_FALSE(events->hasDisplayPresentInfo());
1456 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001457
Vishnu Nairde66dc72021-06-17 17:54:41 -07001458 // wait for the last transaction to be completed.
1459 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001460
Vishnu Nairde66dc72021-06-17 17:54:41 -07001461 // queue another buffer so we query for frame event deltas
1462 nsecs_t requestedPresentTimeC = 0;
1463 nsecs_t postedTimeC = 0;
1464 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1465 history.applyDelta(qbOutput.frameTimestamps);
1466
1467 // frame number, requestedPresentTime, and postTime should not have changed
1468 ASSERT_EQ(1, events->frameNumber);
1469 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1470 ASSERT_GE(events->postedTime, postedTimeA);
1471
1472 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1473 ASSERT_FALSE(events->hasLatchInfo());
1474 ASSERT_FALSE(events->hasDequeueReadyInfo());
1475 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1476 ASSERT_FALSE(events->hasDisplayPresentInfo());
1477 ASSERT_FALSE(events->hasReleaseInfo());
1478
1479 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001480 events = history.getFrame(2);
1481 ASSERT_NE(nullptr, events);
1482 ASSERT_EQ(2, events->frameNumber);
1483 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1484 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001485 ASSERT_GE(events->latchTime, postedTimeB);
1486 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1487 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1488 ASSERT_NE(nullptr, events->displayPresentFence);
1489 ASSERT_NE(nullptr, events->releaseFence);
1490
1491 // wait for any callbacks that have not been received
1492 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001493}
1494
Vishnu Nair9a69a042021-06-18 13:19:49 -07001495TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1496 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1497 sp<IGraphicBufferProducer> igbProducer;
1498 ProducerFrameEventHistory history;
1499 setUpProducer(adapter, igbProducer);
1500
1501 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1502 nsecs_t requestedPresentTimeA = 0;
1503 nsecs_t postedTimeA = 0;
1504 adapter.setTransactionCompleteCallback(1);
1505 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1506 history.applyDelta(qbOutput.frameTimestamps);
1507 adapter.waitForCallback(1);
1508
1509 // queue another buffer so we query for frame event deltas
1510 nsecs_t requestedPresentTimeB = 0;
1511 nsecs_t postedTimeB = 0;
1512 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1513 history.applyDelta(qbOutput.frameTimestamps);
1514
1515 // check for a valid compositor deadline
1516 ASSERT_NE(0, history.getReportedCompositeDeadline());
1517
1518 // wait for any callbacks that have not been received
1519 adapter.waitForCallbacks();
1520}
1521
Valerie Hauc5011f92019-10-11 09:52:07 -07001522} // namespace android