blob: b993289e6a98b0d47370dd2ea04c7806e9219d88 [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>
Huihong Luo9e84f332021-12-16 14:33:46 -080032#include <private/gui/ComposerServiceAIDL.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010033#include <ui/DisplayMode.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070034#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070035#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080036#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070037
38#include <gtest/gtest.h>
39
40using namespace std::chrono_literals;
41
42namespace android {
43
Valerie Hauc5011f92019-10-11 09:52:07 -070044using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070045using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070046
chaviwd7deef72021-10-06 11:53:40 -050047class CountProducerListener : public BnProducerListener {
48public:
49 void onBufferReleased() override {
50 std::scoped_lock<std::mutex> lock(mMutex);
51 mNumReleased++;
52 mReleaseCallback.notify_one();
53 }
54
55 void waitOnNumberReleased(int32_t expectedNumReleased) {
56 std::unique_lock<std::mutex> lock(mMutex);
57 while (mNumReleased < expectedNumReleased) {
58 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
59 std::cv_status::timeout)
60 << "did not receive release";
61 }
62 }
63
64private:
65 std::mutex mMutex;
66 std::condition_variable mReleaseCallback;
67 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
68};
69
chaviwf10b9042021-10-13 15:48:59 -050070class TestBLASTBufferQueue : public BLASTBufferQueue {
71public:
72 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
73 int height, int32_t format)
74 : BLASTBufferQueue(name, surface, width, height, format) {}
75
chaviw6b9ffea2021-11-08 09:25:48 -060076 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
77 const std::vector<SurfaceControlStats>& stats) override {
78 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050079 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
80
81 {
82 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060083 mLastTransactionFrameNumber = frameNumber;
84 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050085 }
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.
chaviw6b9ffea2021-11-08 09:25:48 -060091 while (mLastTransactionFrameNumber < frameNumber) {
92 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -050093 }
94 }
95
96private:
97 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -060098 std::condition_variable mWaitForCallbackCV;
99 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500100};
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
Tianhao Yao4861b102022-02-03 20:18:35 +0000113 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
114 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
115 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
116 }
117
118 void syncNextTransaction(std::function<void(Transaction*)> callback,
119 bool acquireSingleBuffer = true) {
120 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
121 }
122
123 void stopContinuousSyncTransaction() {
124 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700125 }
126
Vishnu Nairea0de002020-11-17 17:42:37 -0800127 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700128
Vishnu Nairea0de002020-11-17 17:42:37 -0800129 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700130
Tianhao Yao4861b102022-02-03 20:18:35 +0000131 std::function<void(Transaction*)> getTransactionReadyCallback() {
132 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
133 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700134
135 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
136 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
137 }
138
Valerie Hauc5011f92019-10-11 09:52:07 -0700139 const sp<SurfaceControl> getSurfaceControl() {
140 return mBlastBufferQueueAdapter->mSurfaceControl;
141 }
142
Vishnu Naira4fbca52021-07-07 16:52:34 -0700143 sp<Surface> getSurface() {
144 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
145 }
146
Valerie Haud3b90d22019-11-06 09:37:31 -0800147 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700148 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800149 // Wait until all but one of the submitted buffers have been released.
150 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800151 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
152 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700153 }
154
Vishnu Nair1506b182021-02-22 14:35:15 -0800155 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500156 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800157 }
158
chaviw0acd33a2021-11-02 11:55:37 -0500159 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
160 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
161 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
162 }
163
chaviwc1cf4022022-06-03 13:32:33 -0500164 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
165 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
166 }
167
Valerie Hauc5011f92019-10-11 09:52:07 -0700168private:
chaviwf10b9042021-10-13 15:48:59 -0500169 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700170};
171
172class BLASTBufferQueueTest : public ::testing::Test {
173public:
174protected:
175 BLASTBufferQueueTest() {
176 const ::testing::TestInfo* const testInfo =
177 ::testing::UnitTest::GetInstance()->current_test_info();
178 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
179 }
180
181 ~BLASTBufferQueueTest() {
182 const ::testing::TestInfo* const testInfo =
183 ::testing::UnitTest::GetInstance()->current_test_info();
184 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
185 }
186
187 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700188 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700189 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700190 mDisplayToken = mClient->getInternalDisplayToken();
191 ASSERT_NE(nullptr, mDisplayToken.get());
192 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700193 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700194 t.apply();
195 t.clear();
196
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100197 ui::DisplayMode mode;
198 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
199 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800200 mDisplayWidth = resolution.getWidth();
201 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700202
203 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
204 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
205 ISurfaceComposerClient::eFXSurfaceBufferState,
206 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700207 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700208 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700209 .show(mSurfaceControl)
210 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
211 .apply();
chaviwd2432892020-07-24 17:42:39 -0700212
213 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800214 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700215 }
216
chaviwd7deef72021-10-06 11:53:40 -0500217 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
218 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800219 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500220 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800221 }
222
chaviwd7deef72021-10-06 11:53:40 -0500223 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800224 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500225 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800226 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500227 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800228 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500229 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800230 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800231 }
232
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800233 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
234 uint8_t b) {
235 for (uint32_t row = rect.top; row < rect.bottom; row++) {
236 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700237 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
238 *pixel = r;
239 *(pixel + 1) = g;
240 *(pixel + 2) = b;
241 *(pixel + 3) = 255;
242 }
243 }
244 }
245
Valerie Hau5977fc82019-12-05 15:56:39 -0800246 void fillQuadrants(sp<GraphicBuffer>& buf) {
247 const auto bufWidth = buf->getWidth();
248 const auto bufHeight = buf->getHeight();
249 uint32_t* bufData;
250 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
251 reinterpret_cast<void**>(&bufData));
252 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
253 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
254 0, 0);
255 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
256 buf->getStride(), 0, 255, 0);
257 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
258 255);
259 buf->unlock();
260 }
261
262 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
263 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700264 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800265 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700266 const auto width = captureBuf->getWidth();
267 const auto height = captureBuf->getHeight();
268 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700269
270 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700271 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
272 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700273
274 for (uint32_t row = 0; row < height; row++) {
275 for (uint32_t col = 0; col < width; col++) {
276 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800277 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800278 bool inRegion;
279 if (!outsideRegion) {
280 inRegion = row >= region.top + border && row < region.bottom - border &&
281 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800282 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800283 inRegion = row >= region.top - border && row < region.bottom + border &&
284 col >= region.left - border && col < region.right + border;
285 }
286 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000287 ASSERT_GE(epsilon, abs(r - *(pixel)));
288 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
289 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800290 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000291 ASSERT_GE(epsilon, abs(r - *(pixel)));
292 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
293 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800294 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800295 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700296 }
297 }
chaviwd2432892020-07-24 17:42:39 -0700298 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700299 }
300
chaviw8ffc7b82020-08-18 11:25:37 -0700301 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
302 ScreenCaptureResults& captureResults) {
Huihong Luo9e84f332021-12-16 14:33:46 -0800303 const auto sf = ComposerServiceAIDL::getComposerService();
chaviw8ffc7b82020-08-18 11:25:37 -0700304 SurfaceComposerClient::Transaction().apply(true);
305
306 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
Huihong Luo9e84f332021-12-16 14:33:46 -0800307 binder::Status status = sf->captureDisplay(captureArgs, captureListener);
308 if (status.transactionError() != NO_ERROR) {
309 return status.transactionError();
chaviw8ffc7b82020-08-18 11:25:37 -0700310 }
311 captureResults = captureListener->waitForResults();
312 return captureResults.result;
313 }
314
Vishnu Nair277142c2021-01-05 18:35:29 -0800315 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
316 nsecs_t presentTimeDelay) {
317 int slot;
318 sp<Fence> fence;
319 sp<GraphicBuffer> buf;
320 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
321 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
322 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500323 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800324 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
325
326 uint32_t* bufData;
327 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
328 reinterpret_cast<void**>(&bufData));
329 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
330 buf->unlock();
331
332 IGraphicBufferProducer::QueueBufferOutput qbOutput;
333 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
334 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
335 Rect(mDisplayWidth, mDisplayHeight / 2),
336 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
337 Fence::NO_FENCE);
338 igbp->queueBuffer(slot, input, &qbOutput);
339 }
340
Valerie Hauc5011f92019-10-11 09:52:07 -0700341 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700342 sp<ISurfaceComposer> mComposer;
343
344 sp<IBinder> mDisplayToken;
345
Valerie Hauc5011f92019-10-11 09:52:07 -0700346 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700347
348 uint32_t mDisplayWidth;
349 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700350
351 DisplayCaptureArgs mCaptureArgs;
352 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500353 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700354};
355
356TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
357 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700358 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700359 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700360 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
361 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000362 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700363}
364
365TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700366 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700367 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700368 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
369 PIXEL_FORMAT_RGBA_8888);
370 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700371 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800372 sp<IGraphicBufferProducer> igbProducer;
373 setUpProducer(adapter, igbProducer);
374
375 int32_t width;
376 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
377 ASSERT_EQ(mDisplayWidth / 2, width);
378 int32_t height;
379 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
380 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700381}
382
Tianhao Yao4861b102022-02-03 20:18:35 +0000383TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700384 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000385 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
386 auto callback = [](Transaction*) {};
387 adapter.syncNextTransaction(callback);
388 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700389}
Valerie Hauda3446e2019-10-14 15:49:22 -0700390
Valerie Haubf29e042020-02-06 11:40:38 -0800391TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800392 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
393 sp<IGraphicBufferProducer> igbProducer;
394 setUpProducer(adapter, igbProducer);
395
396 int slot;
397 sp<Fence> fence;
398 sp<GraphicBuffer> buf;
399 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
400 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
401 nullptr, nullptr);
402 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
403 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
404
405 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
406 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800407 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
408 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800409 Rect(mDisplayWidth, mDisplayHeight),
410 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
411 Fence::NO_FENCE);
412 igbProducer->queueBuffer(slot, input, &qbOutput);
413 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
414
415 adapter.waitForCallbacks();
416 ASSERT_GE(systemTime(), desiredPresentTime);
417}
418
Valerie Hauda3446e2019-10-14 15:49:22 -0700419TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
420 uint8_t r = 255;
421 uint8_t g = 0;
422 uint8_t b = 0;
423
424 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800425 sp<IGraphicBufferProducer> igbProducer;
426 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700427
428 int slot;
429 sp<Fence> fence;
430 sp<GraphicBuffer> buf;
431 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
432 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
433 nullptr, nullptr);
434 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
435 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
436
437 uint32_t* bufData;
438 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
439 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800440 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700441 buf->unlock();
442
Valerie Haud3b90d22019-11-06 09:37:31 -0800443 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800444 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
445 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700446 Rect(mDisplayWidth, mDisplayHeight),
447 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
448 Fence::NO_FENCE);
449 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800450 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700451
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800452 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700453
454 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700455 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800456 ASSERT_NO_FATAL_FAILURE(
457 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700458}
Valerie Haud3b90d22019-11-06 09:37:31 -0800459
460TEST_F(BLASTBufferQueueTest, TripleBuffering) {
461 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
462 sp<IGraphicBufferProducer> igbProducer;
463 setUpProducer(adapter, igbProducer);
464
465 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700466 int minUndequeuedBuffers = 0;
467 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
468 const auto bufferCount = minUndequeuedBuffers + 2;
469
470 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800471 int slot;
472 sp<Fence> fence;
473 sp<GraphicBuffer> buf;
474 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
475 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
476 nullptr, nullptr);
477 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
478 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
479 allocated.push_back({slot, fence});
480 }
481 for (int i = 0; i < allocated.size(); i++) {
482 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
483 }
484
Valerie Haua32c5522019-12-09 10:11:08 -0800485 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800486 int slot;
487 sp<Fence> fence;
488 sp<GraphicBuffer> buf;
489 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
490 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
491 nullptr, nullptr);
492 ASSERT_EQ(NO_ERROR, ret);
493 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800494 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
495 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800496 Rect(mDisplayWidth, mDisplayHeight),
497 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
498 Fence::NO_FENCE);
499 igbProducer->queueBuffer(slot, input, &qbOutput);
500 }
501 adapter.waitForCallbacks();
502}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800503
504TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
505 uint8_t r = 255;
506 uint8_t g = 0;
507 uint8_t b = 0;
508
509 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
510 sp<IGraphicBufferProducer> igbProducer;
511 setUpProducer(adapter, igbProducer);
512 int slot;
513 sp<Fence> fence;
514 sp<GraphicBuffer> buf;
515 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
516 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
517 nullptr, nullptr);
518 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
519 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
520
521 uint32_t* bufData;
522 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
523 reinterpret_cast<void**>(&bufData));
524 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
525 buf->unlock();
526
527 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800528 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
529 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800530 Rect(mDisplayWidth, mDisplayHeight / 2),
531 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
532 Fence::NO_FENCE);
533 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800534 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800535
536 adapter.waitForCallbacks();
537 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700538 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700539
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800540 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000541 checkScreenCapture(r, g, b,
542 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800543}
544
545TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
546 uint8_t r = 255;
547 uint8_t g = 0;
548 uint8_t b = 0;
549
550 int32_t bufferSideLength =
551 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
552 int32_t finalCropSideLength = bufferSideLength / 2;
553
554 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800555 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800556 ASSERT_NE(nullptr, bg.get());
557 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700558 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800559 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800560 .setColor(bg, half3{0, 0, 0})
561 .setLayer(bg, 0)
562 .apply();
563
564 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
565 sp<IGraphicBufferProducer> igbProducer;
566 setUpProducer(adapter, igbProducer);
567 int slot;
568 sp<Fence> fence;
569 sp<GraphicBuffer> buf;
570 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
571 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
572 nullptr, nullptr);
573 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
574 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
575
576 uint32_t* bufData;
577 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
578 reinterpret_cast<void**>(&bufData));
579 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
580 fillBuffer(bufData,
581 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
582 buf->getHeight()),
583 buf->getStride(), r, g, b);
584 buf->unlock();
585
586 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800587 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
588 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800589 Rect(bufferSideLength, finalCropSideLength),
590 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
591 Fence::NO_FENCE);
592 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800593 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800594
595 adapter.waitForCallbacks();
596 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700597 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700598 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
599 {10, 10, (int32_t)bufferSideLength - 10,
600 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800601 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700602 checkScreenCapture(0, 0, 0,
603 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
604 /*border*/ 0, /*outsideRegion*/ true));
605}
606
607TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
608 // add black background
609 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
610 ISurfaceComposerClient::eFXSurfaceEffect);
611 ASSERT_NE(nullptr, bg.get());
612 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700613 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700614 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
615 .setColor(bg, half3{0, 0, 0})
616 .setLayer(bg, 0)
617 .apply();
618
619 Rect windowSize(1000, 1000);
620 Rect bufferSize(windowSize);
621 Rect bufferCrop(200, 200, 700, 700);
622
623 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
624 sp<IGraphicBufferProducer> igbProducer;
625 setUpProducer(adapter, igbProducer);
626 int slot;
627 sp<Fence> fence;
628 sp<GraphicBuffer> buf;
629 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
630 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
631 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
632 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
633 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
634
635 uint32_t* bufData;
636 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
637 reinterpret_cast<void**>(&bufData));
638 // fill buffer with grey
639 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
640
641 // fill crop area with different colors so we can verify the cropped region has been scaled
642 // correctly.
643 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
644 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
645 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
646 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
647 buf->unlock();
648
649 IGraphicBufferProducer::QueueBufferOutput qbOutput;
650 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
651 HAL_DATASPACE_UNKNOWN,
652 bufferCrop /* Rect::INVALID_RECT */,
653 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
654 Fence::NO_FENCE);
655 igbProducer->queueBuffer(slot, input, &qbOutput);
656 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
657
658 adapter.waitForCallbacks();
659
660 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
661
662 // Verify cropped region is scaled correctly.
663 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
664 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
665 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
666 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
667 // Verify outside region is black.
668 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
669 {0, 0, (int32_t)windowSize.getWidth(),
670 (int32_t)windowSize.getHeight()},
671 /*border*/ 0, /*outsideRegion*/ true));
672}
673
674TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
675 // add black background
676 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
677 ISurfaceComposerClient::eFXSurfaceEffect);
678 ASSERT_NE(nullptr, bg.get());
679 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700681 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
682 .setColor(bg, half3{0, 0, 0})
683 .setLayer(bg, 0)
684 .apply();
685
686 Rect windowSize(1000, 1000);
687 Rect bufferSize(500, 500);
688 Rect bufferCrop(100, 100, 350, 350);
689
690 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
691 sp<IGraphicBufferProducer> igbProducer;
692 setUpProducer(adapter, igbProducer);
693 int slot;
694 sp<Fence> fence;
695 sp<GraphicBuffer> buf;
696 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
697 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
698 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
699 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
700 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
701
702 uint32_t* bufData;
703 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
704 reinterpret_cast<void**>(&bufData));
705 // fill buffer with grey
706 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
707
708 // fill crop area with different colors so we can verify the cropped region has been scaled
709 // correctly.
710 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
711 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
712 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
713 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
714 buf->unlock();
715
716 IGraphicBufferProducer::QueueBufferOutput qbOutput;
717 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
718 HAL_DATASPACE_UNKNOWN,
719 bufferCrop /* Rect::INVALID_RECT */,
720 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
721 Fence::NO_FENCE);
722 igbProducer->queueBuffer(slot, input, &qbOutput);
723 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
724
725 adapter.waitForCallbacks();
726
727 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
728 // Verify cropped region is scaled correctly.
729 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
730 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
731 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
732 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
733 // Verify outside region is black.
734 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
735 {0, 0, (int32_t)windowSize.getWidth(),
736 (int32_t)windowSize.getHeight()},
737 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800738}
739
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700740// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
741// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
742TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
743 uint8_t r = 255;
744 uint8_t g = 0;
745 uint8_t b = 0;
746
747 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
748 sp<IGraphicBufferProducer> igbProducer;
749 setUpProducer(adapter, igbProducer);
750 {
751 int slot;
752 sp<Fence> fence;
753 sp<GraphicBuffer> buf;
754 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
755 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
756 nullptr, nullptr);
757 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
758 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
759
760 uint32_t* bufData;
761 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
762 reinterpret_cast<void**>(&bufData));
763 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
764 buf->unlock();
765
766 IGraphicBufferProducer::QueueBufferOutput qbOutput;
767 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
768 HAL_DATASPACE_UNKNOWN, {},
769 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
770 Fence::NO_FENCE);
771 igbProducer->queueBuffer(slot, input, &qbOutput);
772 adapter.waitForCallbacks();
773 }
774 // capture screen and verify that it is red
775 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
776
777 ASSERT_NO_FATAL_FAILURE(
778 checkScreenCapture(r, g, b,
779 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
780
781 // update the size to half the display and dequeue a buffer quarter of the display.
782 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
783
784 {
785 int slot;
786 sp<Fence> fence;
787 sp<GraphicBuffer> buf;
788 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
789 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
790 nullptr, nullptr);
791 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
792 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
793
794 uint32_t* bufData;
795 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
796 reinterpret_cast<void**>(&bufData));
797 g = 255;
798 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
799 buf->unlock();
800
801 IGraphicBufferProducer::QueueBufferOutput qbOutput;
802 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
803 HAL_DATASPACE_UNKNOWN, {},
804 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
805 0, Fence::NO_FENCE);
806 igbProducer->queueBuffer(slot, input, &qbOutput);
807 adapter.waitForCallbacks();
808 }
809 // capture screen and verify that it is red
810 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
811 // verify we still scale the buffer to the new size (half the screen height)
812 ASSERT_NO_FATAL_FAILURE(
813 checkScreenCapture(r, g, b,
814 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
815}
816
chaviwd7deef72021-10-06 11:53:40 -0500817TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
818 uint8_t r = 255;
819 uint8_t g = 0;
820 uint8_t b = 0;
821
822 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
823
824 sp<IGraphicBufferProducer> igbProducer;
825 setUpProducer(adapter, igbProducer);
826
chaviwa1c4c822021-11-10 18:11:58 -0600827 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000828 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500829 queueBuffer(igbProducer, 0, 255, 0, 0);
830
831 // queue non sync buffer, so this one should get blocked
832 // Add a present delay to allow the first screenshot to get taken.
833 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
834 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
835
836 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600837 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500838 transactionCallback.getContext())
839 .apply();
840
841 CallbackData callbackData;
842 transactionCallback.getCallbackData(&callbackData);
843
chaviw0acd33a2021-11-02 11:55:37 -0500844 // capture screen and verify that it is green
chaviwd7deef72021-10-06 11:53:40 -0500845 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
846 ASSERT_NO_FATAL_FAILURE(
847 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
848
849 mProducerListener->waitOnNumberReleased(1);
850 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
851 ASSERT_NO_FATAL_FAILURE(
852 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
853}
854
855TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
856 uint8_t r = 255;
857 uint8_t g = 0;
858 uint8_t b = 0;
859
860 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
861
862 sp<IGraphicBufferProducer> igbProducer;
863 setUpProducer(adapter, igbProducer);
864
865 Transaction mainTransaction;
866
chaviwa1c4c822021-11-10 18:11:58 -0600867 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000868 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500869 queueBuffer(igbProducer, 0, 255, 0, 0);
870
chaviwa1c4c822021-11-10 18:11:58 -0600871 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500872
Tianhao Yao4861b102022-02-03 20:18:35 +0000873 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500874 queueBuffer(igbProducer, r, g, b, 0);
875
chaviwa1c4c822021-11-10 18:11:58 -0600876 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500877 // Expect 1 buffer to be released even before sending to SurfaceFlinger
878 mProducerListener->waitOnNumberReleased(1);
879
880 CallbackHelper transactionCallback;
881 mainTransaction
882 .addTransactionCompletedCallback(transactionCallback.function,
883 transactionCallback.getContext())
884 .apply();
885
886 CallbackData callbackData;
887 transactionCallback.getCallbackData(&callbackData);
888
889 // capture screen and verify that it is red
890 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
891 ASSERT_NO_FATAL_FAILURE(
892 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
893}
894
895TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
896 uint8_t r = 255;
897 uint8_t g = 0;
898 uint8_t b = 0;
899
900 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
901
902 sp<IGraphicBufferProducer> igbProducer;
903 setUpProducer(adapter, igbProducer);
904
905 Transaction mainTransaction;
906
chaviwa1c4c822021-11-10 18:11:58 -0600907 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500908 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000909 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500910 queueBuffer(igbProducer, 0, 255, 0, 0);
911
chaviwa1c4c822021-11-10 18:11:58 -0600912 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500913
chaviwa1c4c822021-11-10 18:11:58 -0600914 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500915 queueBuffer(igbProducer, 0, 0, 255, 0);
916
917 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000918 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500919 queueBuffer(igbProducer, r, g, b, 0);
920 // Expect 1 buffer to be released because the non sync transaction should merge
921 // with the sync
922 mProducerListener->waitOnNumberReleased(1);
923
chaviwa1c4c822021-11-10 18:11:58 -0600924 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500925 // Expect 2 buffers to be released due to merging the two syncs.
926 mProducerListener->waitOnNumberReleased(2);
927
928 CallbackHelper transactionCallback;
929 mainTransaction
930 .addTransactionCompletedCallback(transactionCallback.function,
931 transactionCallback.getContext())
932 .apply();
933
934 CallbackData callbackData;
935 transactionCallback.getCallbackData(&callbackData);
936
937 // capture screen and verify that it is red
938 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
939 ASSERT_NO_FATAL_FAILURE(
940 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
941}
942
943TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
944 uint8_t r = 255;
945 uint8_t g = 0;
946 uint8_t b = 0;
947
948 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
949
950 sp<IGraphicBufferProducer> igbProducer;
951 setUpProducer(adapter, igbProducer, 3);
952
953 Transaction mainTransaction;
954
chaviwa1c4c822021-11-10 18:11:58 -0600955 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500956 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000957 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500958 queueBuffer(igbProducer, 0, 255, 0, 0);
959
chaviwa1c4c822021-11-10 18:11:58 -0600960 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500961
chaviwa1c4c822021-11-10 18:11:58 -0600962 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500963 queueBuffer(igbProducer, 0, 0, 255, 0);
964 queueBuffer(igbProducer, 0, 0, 255, 0);
965 queueBuffer(igbProducer, 0, 0, 255, 0);
966
967 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000968 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500969 queueBuffer(igbProducer, r, g, b, 0);
970 // Expect 3 buffers to be released because the non sync transactions should merge
971 // with the sync
972 mProducerListener->waitOnNumberReleased(3);
973
chaviwa1c4c822021-11-10 18:11:58 -0600974 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500975 // Expect 4 buffers to be released due to merging the two syncs.
976 mProducerListener->waitOnNumberReleased(4);
977
978 CallbackHelper transactionCallback;
979 mainTransaction
980 .addTransactionCompletedCallback(transactionCallback.function,
981 transactionCallback.getContext())
982 .apply();
983
984 CallbackData callbackData;
985 transactionCallback.getCallbackData(&callbackData);
986
987 // capture screen and verify that it is red
988 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
989 ASSERT_NO_FATAL_FAILURE(
990 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
991}
992
993// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
994// continue processing is for a release callback from SurfaceFlinger.
995// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
996// continue acquiring buffers.
997TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
998 uint8_t r = 255;
999 uint8_t g = 0;
1000 uint8_t b = 0;
1001
1002 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1003
1004 sp<IGraphicBufferProducer> igbProducer;
1005 setUpProducer(adapter, igbProducer, 4);
1006
1007 Transaction mainTransaction;
1008
1009 // Send a buffer to SF
1010 queueBuffer(igbProducer, 0, 255, 0, 0);
1011
chaviwa1c4c822021-11-10 18:11:58 -06001012 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001013 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001014 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001015 queueBuffer(igbProducer, 0, 255, 0, 0);
1016
chaviwa1c4c822021-11-10 18:11:58 -06001017 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001018
chaviwa1c4c822021-11-10 18:11:58 -06001019 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001020 queueBuffer(igbProducer, 0, 0, 255, 0);
1021 queueBuffer(igbProducer, 0, 0, 255, 0);
1022 queueBuffer(igbProducer, 0, 0, 255, 0);
1023
1024 // apply the first synced buffer to ensure we have to wait on SF
1025 mainTransaction.apply();
1026
1027 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001028 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001029 queueBuffer(igbProducer, r, g, b, 0);
1030 // Expect 2 buffers to be released because the non sync transactions should merge
1031 // with the sync
1032 mProducerListener->waitOnNumberReleased(3);
1033
chaviwa1c4c822021-11-10 18:11:58 -06001034 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001035
1036 CallbackHelper transactionCallback;
1037 mainTransaction
1038 .addTransactionCompletedCallback(transactionCallback.function,
1039 transactionCallback.getContext())
1040 .apply();
1041
1042 CallbackData callbackData;
1043 transactionCallback.getCallbackData(&callbackData);
1044
1045 // capture screen and verify that it is red
1046 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1047 ASSERT_NO_FATAL_FAILURE(
1048 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1049}
1050
Tianhao Yao4861b102022-02-03 20:18:35 +00001051TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001052 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1053
1054 sp<IGraphicBufferProducer> igbProducer;
1055 setUpProducer(adapter, igbProducer);
1056
1057 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001058 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001059 queueBuffer(igbProducer, 0, 255, 0, 0);
1060 queueBuffer(igbProducer, 0, 0, 255, 0);
1061 // There should only be one frame submitted since the first frame will be released.
1062 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001063 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001064
1065 // queue non sync buffer, so this one should get blocked
1066 // Add a present delay to allow the first screenshot to get taken.
1067 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1068 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1069
1070 CallbackHelper transactionCallback;
1071 next.addTransactionCompletedCallback(transactionCallback.function,
1072 transactionCallback.getContext())
1073 .apply();
1074
1075 CallbackData callbackData;
1076 transactionCallback.getCallbackData(&callbackData);
1077
1078 // capture screen and verify that it is blue
1079 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1080 ASSERT_NO_FATAL_FAILURE(
1081 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1082
1083 mProducerListener->waitOnNumberReleased(2);
1084 // capture screen and verify that it is red
1085 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1086 ASSERT_NO_FATAL_FAILURE(
1087 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1088}
1089
chaviw3b4bdcf2022-03-17 09:27:03 -05001090TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1091 std::mutex mutex;
1092 std::condition_variable callbackReceivedCv;
1093 bool receivedCallback = false;
1094
1095 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1096 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1097 auto callback = [&](Transaction*) {
1098 std::unique_lock<std::mutex> lock(mutex);
1099 receivedCallback = true;
1100 callbackReceivedCv.notify_one();
1101 };
1102 adapter.syncNextTransaction(callback);
1103 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1104
1105 auto callback2 = [](Transaction*) {};
1106 adapter.syncNextTransaction(callback2);
1107
1108 std::unique_lock<std::mutex> lock(mutex);
1109 if (!receivedCallback) {
1110 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1111 std::cv_status::timeout)
1112 << "did not receive callback";
1113 }
1114
1115 ASSERT_TRUE(receivedCallback);
1116}
1117
chaviwc1cf4022022-06-03 13:32:33 -05001118TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1119 uint8_t r = 255;
1120 uint8_t g = 0;
1121 uint8_t b = 0;
1122
1123 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1124
1125 sp<IGraphicBufferProducer> igbProducer;
1126 setUpProducer(adapter, igbProducer);
1127
1128 Transaction sync;
1129 adapter.setSyncTransaction(sync);
1130 queueBuffer(igbProducer, 0, 255, 0, 0);
1131
1132 // Merge a transaction that has a complete callback into the next frame so we can get notified
1133 // when to take a screenshot
1134 CallbackHelper transactionCallback;
1135 Transaction t;
1136 t.addTransactionCompletedCallback(transactionCallback.function,
1137 transactionCallback.getContext());
1138 adapter.mergeWithNextTransaction(&t, 2);
1139 queueBuffer(igbProducer, r, g, b, 0);
1140
1141 // Drop the buffer, but ensure the next one continues to get processed.
1142 sync.setBuffer(mSurfaceControl, nullptr);
1143
1144 CallbackData callbackData;
1145 transactionCallback.getCallbackData(&callbackData);
1146 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1147 ASSERT_NO_FATAL_FAILURE(
1148 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1149}
1150
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001151// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1152// until the old surface control is destroyed. This is not necessarily a bug but to document a
1153// limitation with the update API and to test any changes to make the api more robust. The current
1154// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1155TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1156 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1157 std::vector<sp<SurfaceControl>> surfaceControls;
1158 sp<IGraphicBufferProducer> igbProducer;
1159 for (int i = 0; i < 10; i++) {
1160 sp<SurfaceControl> sc =
1161 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1162 PIXEL_FORMAT_RGBA_8888,
1163 ISurfaceComposerClient::eFXSurfaceBufferState,
1164 /*parent*/ nullptr);
1165 Transaction()
1166 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1167 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1168 .show(mSurfaceControl)
1169 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1170 .apply(true);
1171 surfaceControls.push_back(sc);
1172 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1173
1174 setUpProducer(adapter, igbProducer);
1175 Transaction next;
1176 queueBuffer(igbProducer, 0, 255, 0, 0);
1177 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001178 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001179 queueBuffer(igbProducer, 255, 0, 0, 0);
1180
1181 CallbackHelper transactionCallback;
1182 next.addTransactionCompletedCallback(transactionCallback.function,
1183 transactionCallback.getContext())
1184 .apply();
1185
1186 CallbackData callbackData;
1187 transactionCallback.getCallbackData(&callbackData);
1188 // capture screen and verify that it is red
1189 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1190 ASSERT_NO_FATAL_FAILURE(
1191 checkScreenCapture(255, 0, 0,
1192 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1193 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1194 }
1195}
1196
1197// See DISABLED_DisconnectProducerTest
1198TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1199 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1200 std::vector<sp<SurfaceControl>> surfaceControls;
1201 sp<IGraphicBufferProducer> igbProducer;
1202 for (int i = 0; i < 10; i++) {
1203 sp<SurfaceControl> sc =
1204 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1205 PIXEL_FORMAT_RGBA_8888,
1206 ISurfaceComposerClient::eFXSurfaceBufferState,
1207 /*parent*/ nullptr);
1208 Transaction()
1209 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1210 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1211 .show(mSurfaceControl)
1212 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1213 .apply(true);
1214 surfaceControls.push_back(sc);
1215 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1216 setUpProducer(adapter, igbProducer);
1217
1218 Transaction next;
1219 queueBuffer(igbProducer, 0, 255, 0, 0);
1220 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001221 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001222 queueBuffer(igbProducer, 255, 0, 0, 0);
1223
1224 CallbackHelper transactionCallback;
1225 next.addTransactionCompletedCallback(transactionCallback.function,
1226 transactionCallback.getContext())
1227 .apply();
1228
1229 CallbackData callbackData;
1230 transactionCallback.getCallbackData(&callbackData);
1231 // capture screen and verify that it is red
1232 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1233 ASSERT_NO_FATAL_FAILURE(
1234 checkScreenCapture(255, 0, 0,
1235 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1236 }
1237}
1238
Vishnu Nair89496122020-12-14 17:14:53 -08001239class TestProducerListener : public BnProducerListener {
1240public:
1241 sp<IGraphicBufferProducer> mIgbp;
1242 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1243 void onBufferReleased() override {
1244 sp<GraphicBuffer> buffer;
1245 sp<Fence> fence;
1246 mIgbp->detachNextBuffer(&buffer, &fence);
1247 }
1248};
1249
1250TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1251 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1252 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1253 ASSERT_NE(nullptr, igbProducer.get());
1254 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1255 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1256 ASSERT_EQ(NO_ERROR,
1257 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1258 false, &qbOutput));
1259 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1260 for (int i = 0; i < 3; i++) {
1261 int slot;
1262 sp<Fence> fence;
1263 sp<GraphicBuffer> buf;
1264 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1265 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1266 nullptr, nullptr);
1267 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1268 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1269 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001270 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1271 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001272 Rect(mDisplayWidth, mDisplayHeight),
1273 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1274 Fence::NO_FENCE);
1275 igbProducer->queueBuffer(slot, input, &qbOutput);
1276 }
1277 adapter.waitForCallbacks();
1278}
1279
Vishnu Nair17dde612020-12-28 11:39:59 -08001280TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1281 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1282
1283 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1284 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1285 int queuesToNativeWindow = 0;
1286 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1287 &queuesToNativeWindow);
1288 ASSERT_EQ(NO_ERROR, err);
1289 ASSERT_EQ(queuesToNativeWindow, 1);
1290}
1291
Vishnu Nair083efd32021-02-12 09:32:30 -08001292// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1293// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001294TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1295 sp<SurfaceControl> bgSurface =
1296 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1297 ISurfaceComposerClient::eFXSurfaceBufferState);
1298 ASSERT_NE(nullptr, bgSurface.get());
1299 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001300 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001301 .show(bgSurface)
1302 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001303 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1304 .apply();
1305
1306 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1307 sp<IGraphicBufferProducer> slowIgbProducer;
1308 setUpProducer(slowAdapter, slowIgbProducer);
1309 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001310 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001311
1312 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1313 sp<IGraphicBufferProducer> fastIgbProducer;
1314 setUpProducer(fastAdapter, fastIgbProducer);
1315 uint8_t r = 255;
1316 uint8_t g = 0;
1317 uint8_t b = 0;
1318 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1319 fastAdapter.waitForCallbacks();
1320
1321 // capture screen and verify that it is red
1322 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1323
1324 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001325 checkScreenCapture(r, g, b,
1326 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001327}
1328
Vishnu Naira4fbca52021-07-07 16:52:34 -07001329TEST_F(BLASTBufferQueueTest, TransformHint) {
1330 // Transform hint is provided to BBQ via the surface control passed by WM
1331 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1332
1333 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1334 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1335 ASSERT_NE(nullptr, igbProducer.get());
1336 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1337 sp<Surface> surface = adapter.getSurface();
1338
1339 // Before connecting to the surface, we do not get a valid transform hint
1340 int transformHint;
1341 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1342 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1343
1344 ASSERT_EQ(NO_ERROR,
1345 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1346
1347 // After connecting to the surface, we should get the correct hint.
1348 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1349 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1350
1351 ANativeWindow_Buffer buffer;
1352 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1353
1354 // Transform hint is updated via callbacks or surface control updates
1355 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1356 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1357
1358 // The hint does not change and matches the value used when dequeueing the buffer.
1359 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1360 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1361
1362 surface->unlockAndPost();
1363
1364 // After queuing the buffer, we get the updated transform hint
1365 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1366 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1367
1368 adapter.waitForCallbacks();
1369}
1370
Valerie Hau5977fc82019-12-05 15:56:39 -08001371class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1372public:
1373 void test(uint32_t tr) {
1374 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1375 sp<IGraphicBufferProducer> igbProducer;
1376 setUpProducer(adapter, igbProducer);
1377
1378 auto bufWidth = mDisplayWidth;
1379 auto bufHeight = mDisplayHeight;
1380 int slot;
1381 sp<Fence> fence;
1382 sp<GraphicBuffer> buf;
1383
1384 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1385 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1386 nullptr, nullptr);
1387 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1388 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1389
1390 fillQuadrants(buf);
1391
1392 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001393 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1394 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001395 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001396 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1397 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001398 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001399 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001400
1401 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001402 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001403
Valerie Hau5977fc82019-12-05 15:56:39 -08001404 switch (tr) {
1405 case ui::Transform::ROT_0:
1406 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1407 {0, 0, (int32_t)mDisplayWidth / 2,
1408 (int32_t)mDisplayHeight / 2},
1409 1));
1410 ASSERT_NO_FATAL_FAILURE(
1411 checkScreenCapture(255, 0, 0,
1412 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1413 (int32_t)mDisplayHeight / 2},
1414 1));
1415 ASSERT_NO_FATAL_FAILURE(
1416 checkScreenCapture(0, 255, 0,
1417 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1418 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1419 1));
1420 ASSERT_NO_FATAL_FAILURE(
1421 checkScreenCapture(0, 0, 255,
1422 {0, (int32_t)mDisplayHeight / 2,
1423 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1424 1));
1425 break;
1426 case ui::Transform::FLIP_H:
1427 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1428 {0, 0, (int32_t)mDisplayWidth / 2,
1429 (int32_t)mDisplayHeight / 2},
1430 1));
1431 ASSERT_NO_FATAL_FAILURE(
1432 checkScreenCapture(0, 0, 0,
1433 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1434 (int32_t)mDisplayHeight / 2},
1435 1));
1436 ASSERT_NO_FATAL_FAILURE(
1437 checkScreenCapture(0, 0, 255,
1438 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1439 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1440 1));
1441 ASSERT_NO_FATAL_FAILURE(
1442 checkScreenCapture(0, 255, 0,
1443 {0, (int32_t)mDisplayHeight / 2,
1444 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1445 1));
1446 break;
1447 case ui::Transform::FLIP_V:
1448 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1449 {0, 0, (int32_t)mDisplayWidth / 2,
1450 (int32_t)mDisplayHeight / 2},
1451 1));
1452 ASSERT_NO_FATAL_FAILURE(
1453 checkScreenCapture(0, 255, 0,
1454 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1455 (int32_t)mDisplayHeight / 2},
1456 1));
1457 ASSERT_NO_FATAL_FAILURE(
1458 checkScreenCapture(255, 0, 0,
1459 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1460 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1461 1));
1462 ASSERT_NO_FATAL_FAILURE(
1463 checkScreenCapture(0, 0, 0,
1464 {0, (int32_t)mDisplayHeight / 2,
1465 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1466 1));
1467 break;
1468 case ui::Transform::ROT_90:
1469 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1470 {0, 0, (int32_t)mDisplayWidth / 2,
1471 (int32_t)mDisplayHeight / 2},
1472 1));
1473 ASSERT_NO_FATAL_FAILURE(
1474 checkScreenCapture(0, 0, 0,
1475 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1476 (int32_t)mDisplayHeight / 2},
1477 1));
1478 ASSERT_NO_FATAL_FAILURE(
1479 checkScreenCapture(255, 0, 0,
1480 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1481 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1482 1));
1483 ASSERT_NO_FATAL_FAILURE(
1484 checkScreenCapture(0, 255, 0,
1485 {0, (int32_t)mDisplayHeight / 2,
1486 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1487 1));
1488 break;
1489 case ui::Transform::ROT_180:
1490 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1491 {0, 0, (int32_t)mDisplayWidth / 2,
1492 (int32_t)mDisplayHeight / 2},
1493 1));
1494 ASSERT_NO_FATAL_FAILURE(
1495 checkScreenCapture(0, 0, 255,
1496 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1497 (int32_t)mDisplayHeight / 2},
1498 1));
1499 ASSERT_NO_FATAL_FAILURE(
1500 checkScreenCapture(0, 0, 0,
1501 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1502 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1503 1));
1504 ASSERT_NO_FATAL_FAILURE(
1505 checkScreenCapture(255, 0, 0,
1506 {0, (int32_t)mDisplayHeight / 2,
1507 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1508 1));
1509 break;
1510 case ui::Transform::ROT_270:
1511 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1512 {0, 0, (int32_t)mDisplayWidth / 2,
1513 (int32_t)mDisplayHeight / 2},
1514 1));
1515 ASSERT_NO_FATAL_FAILURE(
1516 checkScreenCapture(0, 255, 0,
1517 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1518 (int32_t)mDisplayHeight / 2},
1519 1));
1520 ASSERT_NO_FATAL_FAILURE(
1521 checkScreenCapture(0, 0, 255,
1522 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1523 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1524 1));
1525 ASSERT_NO_FATAL_FAILURE(
1526 checkScreenCapture(0, 0, 0,
1527 {0, (int32_t)mDisplayHeight / 2,
1528 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1529 1));
1530 }
1531 }
1532};
1533
1534TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1535 test(ui::Transform::ROT_0);
1536}
1537
1538TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1539 test(ui::Transform::FLIP_H);
1540}
1541
1542TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1543 test(ui::Transform::FLIP_V);
1544}
1545
1546TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1547 test(ui::Transform::ROT_90);
1548}
1549
1550TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1551 test(ui::Transform::ROT_180);
1552}
1553
1554TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1555 test(ui::Transform::ROT_270);
1556}
Valerie Hau871d6352020-01-29 08:44:02 -08001557
1558class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1559public:
1560 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001561 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001562 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001563 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001564 int slot;
1565 sp<Fence> fence;
1566 sp<GraphicBuffer> buf;
1567 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1568 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1569 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001570 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1571 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1572 }
Valerie Hau871d6352020-01-29 08:44:02 -08001573
Vishnu Nairde66dc72021-06-17 17:54:41 -07001574 *outRequestedPresentTime = requestedPresentTime;
1575 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1576 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001577 Rect(mDisplayWidth, mDisplayHeight),
1578 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1579 Fence::NO_FENCE, /*sticky*/ 0,
1580 getFrameTimestamps);
1581 if (postedTime) *postedTime = systemTime();
1582 igbProducer->queueBuffer(slot, input, qbOutput);
1583 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001584 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001585};
1586
1587TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1588 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1589 sp<IGraphicBufferProducer> igbProducer;
1590 ProducerFrameEventHistory history;
1591 setUpProducer(adapter, igbProducer);
1592
1593 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1594 nsecs_t requestedPresentTimeA = 0;
1595 nsecs_t postedTimeA = 0;
1596 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1597 history.applyDelta(qbOutput.frameTimestamps);
1598
1599 FrameEvents* events = nullptr;
1600 events = history.getFrame(1);
1601 ASSERT_NE(nullptr, events);
1602 ASSERT_EQ(1, events->frameNumber);
1603 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1604 ASSERT_GE(events->postedTime, postedTimeA);
1605
Vishnu Nair1506b182021-02-22 14:35:15 -08001606 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001607
1608 // queue another buffer so we query for frame event deltas
1609 nsecs_t requestedPresentTimeB = 0;
1610 nsecs_t postedTimeB = 0;
1611 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1612 history.applyDelta(qbOutput.frameTimestamps);
1613 events = history.getFrame(1);
1614 ASSERT_NE(nullptr, events);
1615
1616 // frame number, requestedPresentTime, and postTime should not have changed
1617 ASSERT_EQ(1, events->frameNumber);
1618 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1619 ASSERT_GE(events->postedTime, postedTimeA);
1620
1621 ASSERT_GE(events->latchTime, postedTimeA);
1622 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1623 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1624 ASSERT_NE(nullptr, events->displayPresentFence);
1625 ASSERT_NE(nullptr, events->releaseFence);
1626
1627 // we should also have gotten the initial values for the next frame
1628 events = history.getFrame(2);
1629 ASSERT_NE(nullptr, events);
1630 ASSERT_EQ(2, events->frameNumber);
1631 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1632 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001633
1634 // wait for any callbacks that have not been received
1635 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001636}
Vishnu Nair083efd32021-02-12 09:32:30 -08001637
Vishnu Nair083efd32021-02-12 09:32:30 -08001638TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1639 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1640 sp<IGraphicBufferProducer> igbProducer;
1641 setUpProducer(adapter, igbProducer);
1642
1643 ProducerFrameEventHistory history;
1644 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1645 nsecs_t requestedPresentTimeA = 0;
1646 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001647 // Present the frame sometime in the future so we can add two frames to the queue so the older
1648 // one will be dropped.
1649 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001650 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001651 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001652 history.applyDelta(qbOutput.frameTimestamps);
1653
1654 FrameEvents* events = nullptr;
1655 events = history.getFrame(1);
1656 ASSERT_NE(nullptr, events);
1657 ASSERT_EQ(1, events->frameNumber);
1658 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1659 ASSERT_GE(events->postedTime, postedTimeA);
1660
1661 // queue another buffer so the first can be dropped
1662 nsecs_t requestedPresentTimeB = 0;
1663 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001664 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1665 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1666 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001667 history.applyDelta(qbOutput.frameTimestamps);
1668 events = history.getFrame(1);
1669 ASSERT_NE(nullptr, events);
1670
1671 // frame number, requestedPresentTime, and postTime should not have changed
1672 ASSERT_EQ(1, events->frameNumber);
1673 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1674 ASSERT_GE(events->postedTime, postedTimeA);
1675
Vishnu Nairde66dc72021-06-17 17:54:41 -07001676 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001677 ASSERT_FALSE(events->hasLatchInfo());
1678 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001679 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1680 ASSERT_FALSE(events->hasDisplayPresentInfo());
1681 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001682
Vishnu Nairde66dc72021-06-17 17:54:41 -07001683 // wait for the last transaction to be completed.
1684 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001685
Vishnu Nairde66dc72021-06-17 17:54:41 -07001686 // queue another buffer so we query for frame event deltas
1687 nsecs_t requestedPresentTimeC = 0;
1688 nsecs_t postedTimeC = 0;
1689 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1690 history.applyDelta(qbOutput.frameTimestamps);
1691
1692 // frame number, requestedPresentTime, and postTime should not have changed
1693 ASSERT_EQ(1, events->frameNumber);
1694 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1695 ASSERT_GE(events->postedTime, postedTimeA);
1696
1697 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1698 ASSERT_FALSE(events->hasLatchInfo());
1699 ASSERT_FALSE(events->hasDequeueReadyInfo());
1700 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1701 ASSERT_FALSE(events->hasDisplayPresentInfo());
1702 ASSERT_FALSE(events->hasReleaseInfo());
1703
1704 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001705 events = history.getFrame(2);
1706 ASSERT_NE(nullptr, events);
1707 ASSERT_EQ(2, events->frameNumber);
1708 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1709 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001710 ASSERT_GE(events->latchTime, postedTimeB);
1711 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1712 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1713 ASSERT_NE(nullptr, events->displayPresentFence);
1714 ASSERT_NE(nullptr, events->releaseFence);
1715
1716 // wait for any callbacks that have not been received
1717 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001718}
1719
Vishnu Nair9a69a042021-06-18 13:19:49 -07001720TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1721 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1722 sp<IGraphicBufferProducer> igbProducer;
1723 ProducerFrameEventHistory history;
1724 setUpProducer(adapter, igbProducer);
1725
1726 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1727 nsecs_t requestedPresentTimeA = 0;
1728 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001729 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1730 history.applyDelta(qbOutput.frameTimestamps);
1731 adapter.waitForCallback(1);
1732
1733 // queue another buffer so we query for frame event deltas
1734 nsecs_t requestedPresentTimeB = 0;
1735 nsecs_t postedTimeB = 0;
1736 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1737 history.applyDelta(qbOutput.frameTimestamps);
1738
1739 // check for a valid compositor deadline
1740 ASSERT_NE(0, history.getReportedCompositeDeadline());
1741
1742 // wait for any callbacks that have not been received
1743 adapter.waitForCallbacks();
1744}
1745
Valerie Hauc5011f92019-10-11 09:52:07 -07001746} // namespace android