blob: 0c3236c9ce35fba3fac57e2515618f7a18827ada [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
Valerie Hauc5011f92019-10-11 09:52:07 -0700164private:
chaviwf10b9042021-10-13 15:48:59 -0500165 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700166};
167
168class BLASTBufferQueueTest : public ::testing::Test {
169public:
170protected:
171 BLASTBufferQueueTest() {
172 const ::testing::TestInfo* const testInfo =
173 ::testing::UnitTest::GetInstance()->current_test_info();
174 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
175 }
176
177 ~BLASTBufferQueueTest() {
178 const ::testing::TestInfo* const testInfo =
179 ::testing::UnitTest::GetInstance()->current_test_info();
180 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
181 }
182
183 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700184 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700185 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700186 mDisplayToken = mClient->getInternalDisplayToken();
187 ASSERT_NE(nullptr, mDisplayToken.get());
188 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700189 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700190 t.apply();
191 t.clear();
192
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100193 ui::DisplayMode mode;
194 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
195 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800196 mDisplayWidth = resolution.getWidth();
197 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700198
199 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
200 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
201 ISurfaceComposerClient::eFXSurfaceBufferState,
202 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700203 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700204 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700205 .show(mSurfaceControl)
206 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
207 .apply();
chaviwd2432892020-07-24 17:42:39 -0700208
209 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800210 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700211 }
212
chaviwd7deef72021-10-06 11:53:40 -0500213 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
214 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800215 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500216 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800217 }
218
chaviwd7deef72021-10-06 11:53:40 -0500219 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800220 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500221 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800222 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500223 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800224 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500225 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800226 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800227 }
228
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800229 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
230 uint8_t b) {
231 for (uint32_t row = rect.top; row < rect.bottom; row++) {
232 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700233 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
234 *pixel = r;
235 *(pixel + 1) = g;
236 *(pixel + 2) = b;
237 *(pixel + 3) = 255;
238 }
239 }
240 }
241
Valerie Hau5977fc82019-12-05 15:56:39 -0800242 void fillQuadrants(sp<GraphicBuffer>& buf) {
243 const auto bufWidth = buf->getWidth();
244 const auto bufHeight = buf->getHeight();
245 uint32_t* bufData;
246 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
247 reinterpret_cast<void**>(&bufData));
248 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
249 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
250 0, 0);
251 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
252 buf->getStride(), 0, 255, 0);
253 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
254 255);
255 buf->unlock();
256 }
257
258 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
259 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700260 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800261 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700262 const auto width = captureBuf->getWidth();
263 const auto height = captureBuf->getHeight();
264 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700265
266 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700267 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
268 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700269
270 for (uint32_t row = 0; row < height; row++) {
271 for (uint32_t col = 0; col < width; col++) {
272 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800273 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800274 bool inRegion;
275 if (!outsideRegion) {
276 inRegion = row >= region.top + border && row < region.bottom - border &&
277 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800278 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800279 inRegion = row >= region.top - border && row < region.bottom + border &&
280 col >= region.left - border && col < region.right + border;
281 }
282 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000283 ASSERT_GE(epsilon, abs(r - *(pixel)));
284 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
285 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800286 } else 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 Hau45e4b3b2019-12-03 10:49:17 -0800290 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800291 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700292 }
293 }
chaviwd2432892020-07-24 17:42:39 -0700294 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700295 }
296
chaviw8ffc7b82020-08-18 11:25:37 -0700297 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
298 ScreenCaptureResults& captureResults) {
Huihong Luo9e84f332021-12-16 14:33:46 -0800299 const auto sf = ComposerServiceAIDL::getComposerService();
chaviw8ffc7b82020-08-18 11:25:37 -0700300 SurfaceComposerClient::Transaction().apply(true);
301
302 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
Huihong Luo9e84f332021-12-16 14:33:46 -0800303 binder::Status status = sf->captureDisplay(captureArgs, captureListener);
304 if (status.transactionError() != NO_ERROR) {
305 return status.transactionError();
chaviw8ffc7b82020-08-18 11:25:37 -0700306 }
307 captureResults = captureListener->waitForResults();
308 return captureResults.result;
309 }
310
Vishnu Nair277142c2021-01-05 18:35:29 -0800311 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
312 nsecs_t presentTimeDelay) {
313 int slot;
314 sp<Fence> fence;
315 sp<GraphicBuffer> buf;
316 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
317 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
318 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500319 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800320 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
321
322 uint32_t* bufData;
323 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
324 reinterpret_cast<void**>(&bufData));
325 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
326 buf->unlock();
327
328 IGraphicBufferProducer::QueueBufferOutput qbOutput;
329 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
330 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
331 Rect(mDisplayWidth, mDisplayHeight / 2),
332 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
333 Fence::NO_FENCE);
334 igbp->queueBuffer(slot, input, &qbOutput);
335 }
336
Valerie Hauc5011f92019-10-11 09:52:07 -0700337 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700338 sp<ISurfaceComposer> mComposer;
339
340 sp<IBinder> mDisplayToken;
341
Valerie Hauc5011f92019-10-11 09:52:07 -0700342 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700343
344 uint32_t mDisplayWidth;
345 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700346
347 DisplayCaptureArgs mCaptureArgs;
348 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500349 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700350};
351
352TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
353 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700354 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700355 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700356 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
357 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000358 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700359}
360
361TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700362 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700363 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700364 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
365 PIXEL_FORMAT_RGBA_8888);
366 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700367 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800368 sp<IGraphicBufferProducer> igbProducer;
369 setUpProducer(adapter, igbProducer);
370
371 int32_t width;
372 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
373 ASSERT_EQ(mDisplayWidth / 2, width);
374 int32_t height;
375 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
376 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700377}
378
Tianhao Yao4861b102022-02-03 20:18:35 +0000379TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700380 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000381 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
382 auto callback = [](Transaction*) {};
383 adapter.syncNextTransaction(callback);
384 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700385}
Valerie Hauda3446e2019-10-14 15:49:22 -0700386
Valerie Haubf29e042020-02-06 11:40:38 -0800387TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800388 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
389 sp<IGraphicBufferProducer> igbProducer;
390 setUpProducer(adapter, igbProducer);
391
392 int slot;
393 sp<Fence> fence;
394 sp<GraphicBuffer> buf;
395 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
396 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
397 nullptr, nullptr);
398 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
399 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
400
401 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
402 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800403 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
404 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800405 Rect(mDisplayWidth, mDisplayHeight),
406 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
407 Fence::NO_FENCE);
408 igbProducer->queueBuffer(slot, input, &qbOutput);
409 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
410
411 adapter.waitForCallbacks();
412 ASSERT_GE(systemTime(), desiredPresentTime);
413}
414
Valerie Hauda3446e2019-10-14 15:49:22 -0700415TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
416 uint8_t r = 255;
417 uint8_t g = 0;
418 uint8_t b = 0;
419
420 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800421 sp<IGraphicBufferProducer> igbProducer;
422 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700423
424 int slot;
425 sp<Fence> fence;
426 sp<GraphicBuffer> buf;
427 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
428 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
429 nullptr, nullptr);
430 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
431 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
432
433 uint32_t* bufData;
434 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
435 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800436 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700437 buf->unlock();
438
Valerie Haud3b90d22019-11-06 09:37:31 -0800439 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800440 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
441 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700442 Rect(mDisplayWidth, mDisplayHeight),
443 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
444 Fence::NO_FENCE);
445 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800446 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700447
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800448 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700449
450 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700451 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800452 ASSERT_NO_FATAL_FAILURE(
453 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700454}
Valerie Haud3b90d22019-11-06 09:37:31 -0800455
456TEST_F(BLASTBufferQueueTest, TripleBuffering) {
457 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
458 sp<IGraphicBufferProducer> igbProducer;
459 setUpProducer(adapter, igbProducer);
460
461 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700462 int minUndequeuedBuffers = 0;
463 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
464 const auto bufferCount = minUndequeuedBuffers + 2;
465
466 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800467 int slot;
468 sp<Fence> fence;
469 sp<GraphicBuffer> buf;
470 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
471 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
472 nullptr, nullptr);
473 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
474 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
475 allocated.push_back({slot, fence});
476 }
477 for (int i = 0; i < allocated.size(); i++) {
478 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
479 }
480
Valerie Haua32c5522019-12-09 10:11:08 -0800481 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800482 int slot;
483 sp<Fence> fence;
484 sp<GraphicBuffer> buf;
485 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
486 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
487 nullptr, nullptr);
488 ASSERT_EQ(NO_ERROR, ret);
489 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800490 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
491 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800492 Rect(mDisplayWidth, mDisplayHeight),
493 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
494 Fence::NO_FENCE);
495 igbProducer->queueBuffer(slot, input, &qbOutput);
496 }
497 adapter.waitForCallbacks();
498}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800499
500TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
501 uint8_t r = 255;
502 uint8_t g = 0;
503 uint8_t b = 0;
504
505 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
506 sp<IGraphicBufferProducer> igbProducer;
507 setUpProducer(adapter, igbProducer);
508 int slot;
509 sp<Fence> fence;
510 sp<GraphicBuffer> buf;
511 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
512 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
513 nullptr, nullptr);
514 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
515 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
516
517 uint32_t* bufData;
518 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
519 reinterpret_cast<void**>(&bufData));
520 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
521 buf->unlock();
522
523 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800524 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
525 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800526 Rect(mDisplayWidth, mDisplayHeight / 2),
527 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
528 Fence::NO_FENCE);
529 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800530 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800531
532 adapter.waitForCallbacks();
533 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700534 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700535
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800536 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000537 checkScreenCapture(r, g, b,
538 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800539}
540
541TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
542 uint8_t r = 255;
543 uint8_t g = 0;
544 uint8_t b = 0;
545
546 int32_t bufferSideLength =
547 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
548 int32_t finalCropSideLength = bufferSideLength / 2;
549
550 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800551 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800552 ASSERT_NE(nullptr, bg.get());
553 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700554 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800555 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800556 .setColor(bg, half3{0, 0, 0})
557 .setLayer(bg, 0)
558 .apply();
559
560 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
561 sp<IGraphicBufferProducer> igbProducer;
562 setUpProducer(adapter, igbProducer);
563 int slot;
564 sp<Fence> fence;
565 sp<GraphicBuffer> buf;
566 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
567 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
568 nullptr, nullptr);
569 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
570 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
571
572 uint32_t* bufData;
573 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
574 reinterpret_cast<void**>(&bufData));
575 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
576 fillBuffer(bufData,
577 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
578 buf->getHeight()),
579 buf->getStride(), r, g, b);
580 buf->unlock();
581
582 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800583 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
584 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800585 Rect(bufferSideLength, finalCropSideLength),
586 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
587 Fence::NO_FENCE);
588 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800589 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800590
591 adapter.waitForCallbacks();
592 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700593 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700594 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
595 {10, 10, (int32_t)bufferSideLength - 10,
596 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800597 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700598 checkScreenCapture(0, 0, 0,
599 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
600 /*border*/ 0, /*outsideRegion*/ true));
601}
602
603TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
604 // add black background
605 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
606 ISurfaceComposerClient::eFXSurfaceEffect);
607 ASSERT_NE(nullptr, bg.get());
608 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700609 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700610 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
611 .setColor(bg, half3{0, 0, 0})
612 .setLayer(bg, 0)
613 .apply();
614
615 Rect windowSize(1000, 1000);
616 Rect bufferSize(windowSize);
617 Rect bufferCrop(200, 200, 700, 700);
618
619 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
620 sp<IGraphicBufferProducer> igbProducer;
621 setUpProducer(adapter, igbProducer);
622 int slot;
623 sp<Fence> fence;
624 sp<GraphicBuffer> buf;
625 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
626 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
627 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
628 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
629 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
630
631 uint32_t* bufData;
632 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
633 reinterpret_cast<void**>(&bufData));
634 // fill buffer with grey
635 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
636
637 // fill crop area with different colors so we can verify the cropped region has been scaled
638 // correctly.
639 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
640 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
641 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
642 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
643 buf->unlock();
644
645 IGraphicBufferProducer::QueueBufferOutput qbOutput;
646 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
647 HAL_DATASPACE_UNKNOWN,
648 bufferCrop /* Rect::INVALID_RECT */,
649 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
650 Fence::NO_FENCE);
651 igbProducer->queueBuffer(slot, input, &qbOutput);
652 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
653
654 adapter.waitForCallbacks();
655
656 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
657
658 // Verify cropped region is scaled correctly.
659 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
660 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
661 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
662 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
663 // Verify outside region is black.
664 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
665 {0, 0, (int32_t)windowSize.getWidth(),
666 (int32_t)windowSize.getHeight()},
667 /*border*/ 0, /*outsideRegion*/ true));
668}
669
670TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
671 // add black background
672 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
673 ISurfaceComposerClient::eFXSurfaceEffect);
674 ASSERT_NE(nullptr, bg.get());
675 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700676 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700677 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
678 .setColor(bg, half3{0, 0, 0})
679 .setLayer(bg, 0)
680 .apply();
681
682 Rect windowSize(1000, 1000);
683 Rect bufferSize(500, 500);
684 Rect bufferCrop(100, 100, 350, 350);
685
686 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
687 sp<IGraphicBufferProducer> igbProducer;
688 setUpProducer(adapter, igbProducer);
689 int slot;
690 sp<Fence> fence;
691 sp<GraphicBuffer> buf;
692 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
693 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
694 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
695 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
696 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
697
698 uint32_t* bufData;
699 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
700 reinterpret_cast<void**>(&bufData));
701 // fill buffer with grey
702 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
703
704 // fill crop area with different colors so we can verify the cropped region has been scaled
705 // correctly.
706 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
707 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
708 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
709 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
710 buf->unlock();
711
712 IGraphicBufferProducer::QueueBufferOutput qbOutput;
713 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
714 HAL_DATASPACE_UNKNOWN,
715 bufferCrop /* Rect::INVALID_RECT */,
716 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
717 Fence::NO_FENCE);
718 igbProducer->queueBuffer(slot, input, &qbOutput);
719 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
720
721 adapter.waitForCallbacks();
722
723 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
724 // Verify cropped region is scaled correctly.
725 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
726 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
727 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
728 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
729 // Verify outside region is black.
730 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
731 {0, 0, (int32_t)windowSize.getWidth(),
732 (int32_t)windowSize.getHeight()},
733 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800734}
735
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700736// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
737// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
738TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
739 uint8_t r = 255;
740 uint8_t g = 0;
741 uint8_t b = 0;
742
743 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
744 sp<IGraphicBufferProducer> igbProducer;
745 setUpProducer(adapter, igbProducer);
746 {
747 int slot;
748 sp<Fence> fence;
749 sp<GraphicBuffer> buf;
750 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
751 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
752 nullptr, nullptr);
753 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
754 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
755
756 uint32_t* bufData;
757 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
758 reinterpret_cast<void**>(&bufData));
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_FREEZE, 0,
766 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
773 ASSERT_NO_FATAL_FAILURE(
774 checkScreenCapture(r, g, b,
775 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
776
777 // update the size to half the display and dequeue a buffer quarter of the display.
778 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
779
780 {
781 int slot;
782 sp<Fence> fence;
783 sp<GraphicBuffer> buf;
784 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
785 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
786 nullptr, nullptr);
787 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
788 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
789
790 uint32_t* bufData;
791 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
792 reinterpret_cast<void**>(&bufData));
793 g = 255;
794 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
795 buf->unlock();
796
797 IGraphicBufferProducer::QueueBufferOutput qbOutput;
798 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
799 HAL_DATASPACE_UNKNOWN, {},
800 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
801 0, Fence::NO_FENCE);
802 igbProducer->queueBuffer(slot, input, &qbOutput);
803 adapter.waitForCallbacks();
804 }
805 // capture screen and verify that it is red
806 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
807 // verify we still scale the buffer to the new size (half the screen height)
808 ASSERT_NO_FATAL_FAILURE(
809 checkScreenCapture(r, g, b,
810 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
811}
812
chaviwd7deef72021-10-06 11:53:40 -0500813TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
814 uint8_t r = 255;
815 uint8_t g = 0;
816 uint8_t b = 0;
817
818 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
819
820 sp<IGraphicBufferProducer> igbProducer;
821 setUpProducer(adapter, igbProducer);
822
chaviwa1c4c822021-11-10 18:11:58 -0600823 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000824 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500825 queueBuffer(igbProducer, 0, 255, 0, 0);
826
827 // queue non sync buffer, so this one should get blocked
828 // Add a present delay to allow the first screenshot to get taken.
829 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
830 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
831
832 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600833 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500834 transactionCallback.getContext())
835 .apply();
836
837 CallbackData callbackData;
838 transactionCallback.getCallbackData(&callbackData);
839
chaviw0acd33a2021-11-02 11:55:37 -0500840 // capture screen and verify that it is green
chaviwd7deef72021-10-06 11:53:40 -0500841 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
842 ASSERT_NO_FATAL_FAILURE(
843 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
844
845 mProducerListener->waitOnNumberReleased(1);
846 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
847 ASSERT_NO_FATAL_FAILURE(
848 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
849}
850
851TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
852 uint8_t r = 255;
853 uint8_t g = 0;
854 uint8_t b = 0;
855
856 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
857
858 sp<IGraphicBufferProducer> igbProducer;
859 setUpProducer(adapter, igbProducer);
860
861 Transaction mainTransaction;
862
chaviwa1c4c822021-11-10 18:11:58 -0600863 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000864 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500865 queueBuffer(igbProducer, 0, 255, 0, 0);
866
chaviwa1c4c822021-11-10 18:11:58 -0600867 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500868
Tianhao Yao4861b102022-02-03 20:18:35 +0000869 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500870 queueBuffer(igbProducer, r, g, b, 0);
871
chaviwa1c4c822021-11-10 18:11:58 -0600872 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500873 // Expect 1 buffer to be released even before sending to SurfaceFlinger
874 mProducerListener->waitOnNumberReleased(1);
875
876 CallbackHelper transactionCallback;
877 mainTransaction
878 .addTransactionCompletedCallback(transactionCallback.function,
879 transactionCallback.getContext())
880 .apply();
881
882 CallbackData callbackData;
883 transactionCallback.getCallbackData(&callbackData);
884
885 // capture screen and verify that it is red
886 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
887 ASSERT_NO_FATAL_FAILURE(
888 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
889}
890
891TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
892 uint8_t r = 255;
893 uint8_t g = 0;
894 uint8_t b = 0;
895
896 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
897
898 sp<IGraphicBufferProducer> igbProducer;
899 setUpProducer(adapter, igbProducer);
900
901 Transaction mainTransaction;
902
chaviwa1c4c822021-11-10 18:11:58 -0600903 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500904 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000905 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500906 queueBuffer(igbProducer, 0, 255, 0, 0);
907
chaviwa1c4c822021-11-10 18:11:58 -0600908 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500909
chaviwa1c4c822021-11-10 18:11:58 -0600910 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500911 queueBuffer(igbProducer, 0, 0, 255, 0);
912
913 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000914 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500915 queueBuffer(igbProducer, r, g, b, 0);
916 // Expect 1 buffer to be released because the non sync transaction should merge
917 // with the sync
918 mProducerListener->waitOnNumberReleased(1);
919
chaviwa1c4c822021-11-10 18:11:58 -0600920 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500921 // Expect 2 buffers to be released due to merging the two syncs.
922 mProducerListener->waitOnNumberReleased(2);
923
924 CallbackHelper transactionCallback;
925 mainTransaction
926 .addTransactionCompletedCallback(transactionCallback.function,
927 transactionCallback.getContext())
928 .apply();
929
930 CallbackData callbackData;
931 transactionCallback.getCallbackData(&callbackData);
932
933 // capture screen and verify that it is red
934 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
935 ASSERT_NO_FATAL_FAILURE(
936 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
937}
938
939TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
940 uint8_t r = 255;
941 uint8_t g = 0;
942 uint8_t b = 0;
943
944 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
945
946 sp<IGraphicBufferProducer> igbProducer;
947 setUpProducer(adapter, igbProducer, 3);
948
949 Transaction mainTransaction;
950
chaviwa1c4c822021-11-10 18:11:58 -0600951 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500952 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000953 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500954 queueBuffer(igbProducer, 0, 255, 0, 0);
955
chaviwa1c4c822021-11-10 18:11:58 -0600956 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500957
chaviwa1c4c822021-11-10 18:11:58 -0600958 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500959 queueBuffer(igbProducer, 0, 0, 255, 0);
960 queueBuffer(igbProducer, 0, 0, 255, 0);
961 queueBuffer(igbProducer, 0, 0, 255, 0);
962
963 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000964 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500965 queueBuffer(igbProducer, r, g, b, 0);
966 // Expect 3 buffers to be released because the non sync transactions should merge
967 // with the sync
968 mProducerListener->waitOnNumberReleased(3);
969
chaviwa1c4c822021-11-10 18:11:58 -0600970 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500971 // Expect 4 buffers to be released due to merging the two syncs.
972 mProducerListener->waitOnNumberReleased(4);
973
974 CallbackHelper transactionCallback;
975 mainTransaction
976 .addTransactionCompletedCallback(transactionCallback.function,
977 transactionCallback.getContext())
978 .apply();
979
980 CallbackData callbackData;
981 transactionCallback.getCallbackData(&callbackData);
982
983 // capture screen and verify that it is red
984 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
985 ASSERT_NO_FATAL_FAILURE(
986 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
987}
988
989// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
990// continue processing is for a release callback from SurfaceFlinger.
991// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
992// continue acquiring buffers.
993TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
994 uint8_t r = 255;
995 uint8_t g = 0;
996 uint8_t b = 0;
997
998 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
999
1000 sp<IGraphicBufferProducer> igbProducer;
1001 setUpProducer(adapter, igbProducer, 4);
1002
1003 Transaction mainTransaction;
1004
1005 // Send a buffer to SF
1006 queueBuffer(igbProducer, 0, 255, 0, 0);
1007
chaviwa1c4c822021-11-10 18:11:58 -06001008 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001009 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001010 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001011 queueBuffer(igbProducer, 0, 255, 0, 0);
1012
chaviwa1c4c822021-11-10 18:11:58 -06001013 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001014
chaviwa1c4c822021-11-10 18:11:58 -06001015 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001016 queueBuffer(igbProducer, 0, 0, 255, 0);
1017 queueBuffer(igbProducer, 0, 0, 255, 0);
1018 queueBuffer(igbProducer, 0, 0, 255, 0);
1019
1020 // apply the first synced buffer to ensure we have to wait on SF
1021 mainTransaction.apply();
1022
1023 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001024 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001025 queueBuffer(igbProducer, r, g, b, 0);
1026 // Expect 2 buffers to be released because the non sync transactions should merge
1027 // with the sync
1028 mProducerListener->waitOnNumberReleased(3);
1029
chaviwa1c4c822021-11-10 18:11:58 -06001030 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001031
1032 CallbackHelper transactionCallback;
1033 mainTransaction
1034 .addTransactionCompletedCallback(transactionCallback.function,
1035 transactionCallback.getContext())
1036 .apply();
1037
1038 CallbackData callbackData;
1039 transactionCallback.getCallbackData(&callbackData);
1040
1041 // capture screen and verify that it is red
1042 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1043 ASSERT_NO_FATAL_FAILURE(
1044 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1045}
1046
Tianhao Yao4861b102022-02-03 20:18:35 +00001047TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001048 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1049
1050 sp<IGraphicBufferProducer> igbProducer;
1051 setUpProducer(adapter, igbProducer);
1052
1053 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001054 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001055 queueBuffer(igbProducer, 0, 255, 0, 0);
1056 queueBuffer(igbProducer, 0, 0, 255, 0);
1057 // There should only be one frame submitted since the first frame will be released.
1058 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001059 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001060
1061 // queue non sync buffer, so this one should get blocked
1062 // Add a present delay to allow the first screenshot to get taken.
1063 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1064 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1065
1066 CallbackHelper transactionCallback;
1067 next.addTransactionCompletedCallback(transactionCallback.function,
1068 transactionCallback.getContext())
1069 .apply();
1070
1071 CallbackData callbackData;
1072 transactionCallback.getCallbackData(&callbackData);
1073
1074 // capture screen and verify that it is blue
1075 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1076 ASSERT_NO_FATAL_FAILURE(
1077 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1078
1079 mProducerListener->waitOnNumberReleased(2);
1080 // capture screen and verify that it is red
1081 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1082 ASSERT_NO_FATAL_FAILURE(
1083 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1084}
1085
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001086// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1087// until the old surface control is destroyed. This is not necessarily a bug but to document a
1088// limitation with the update API and to test any changes to make the api more robust. The current
1089// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1090TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1091 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1092 std::vector<sp<SurfaceControl>> surfaceControls;
1093 sp<IGraphicBufferProducer> igbProducer;
1094 for (int i = 0; i < 10; i++) {
1095 sp<SurfaceControl> sc =
1096 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1097 PIXEL_FORMAT_RGBA_8888,
1098 ISurfaceComposerClient::eFXSurfaceBufferState,
1099 /*parent*/ nullptr);
1100 Transaction()
1101 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1102 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1103 .show(mSurfaceControl)
1104 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1105 .apply(true);
1106 surfaceControls.push_back(sc);
1107 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1108
1109 setUpProducer(adapter, igbProducer);
1110 Transaction next;
1111 queueBuffer(igbProducer, 0, 255, 0, 0);
1112 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001113 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001114 queueBuffer(igbProducer, 255, 0, 0, 0);
1115
1116 CallbackHelper transactionCallback;
1117 next.addTransactionCompletedCallback(transactionCallback.function,
1118 transactionCallback.getContext())
1119 .apply();
1120
1121 CallbackData callbackData;
1122 transactionCallback.getCallbackData(&callbackData);
1123 // capture screen and verify that it is red
1124 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1125 ASSERT_NO_FATAL_FAILURE(
1126 checkScreenCapture(255, 0, 0,
1127 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1128 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1129 }
1130}
1131
1132// See DISABLED_DisconnectProducerTest
1133TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1134 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1135 std::vector<sp<SurfaceControl>> surfaceControls;
1136 sp<IGraphicBufferProducer> igbProducer;
1137 for (int i = 0; i < 10; i++) {
1138 sp<SurfaceControl> sc =
1139 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1140 PIXEL_FORMAT_RGBA_8888,
1141 ISurfaceComposerClient::eFXSurfaceBufferState,
1142 /*parent*/ nullptr);
1143 Transaction()
1144 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1145 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1146 .show(mSurfaceControl)
1147 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1148 .apply(true);
1149 surfaceControls.push_back(sc);
1150 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1151 setUpProducer(adapter, igbProducer);
1152
1153 Transaction next;
1154 queueBuffer(igbProducer, 0, 255, 0, 0);
1155 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001156 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001157 queueBuffer(igbProducer, 255, 0, 0, 0);
1158
1159 CallbackHelper transactionCallback;
1160 next.addTransactionCompletedCallback(transactionCallback.function,
1161 transactionCallback.getContext())
1162 .apply();
1163
1164 CallbackData callbackData;
1165 transactionCallback.getCallbackData(&callbackData);
1166 // capture screen and verify that it is red
1167 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1168 ASSERT_NO_FATAL_FAILURE(
1169 checkScreenCapture(255, 0, 0,
1170 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1171 }
1172}
1173
Vishnu Nair89496122020-12-14 17:14:53 -08001174class TestProducerListener : public BnProducerListener {
1175public:
1176 sp<IGraphicBufferProducer> mIgbp;
1177 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1178 void onBufferReleased() override {
1179 sp<GraphicBuffer> buffer;
1180 sp<Fence> fence;
1181 mIgbp->detachNextBuffer(&buffer, &fence);
1182 }
1183};
1184
1185TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1186 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1187 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1188 ASSERT_NE(nullptr, igbProducer.get());
1189 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1190 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1191 ASSERT_EQ(NO_ERROR,
1192 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1193 false, &qbOutput));
1194 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1195 for (int i = 0; i < 3; i++) {
1196 int slot;
1197 sp<Fence> fence;
1198 sp<GraphicBuffer> buf;
1199 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1200 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1201 nullptr, nullptr);
1202 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1203 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1204 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001205 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1206 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001207 Rect(mDisplayWidth, mDisplayHeight),
1208 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1209 Fence::NO_FENCE);
1210 igbProducer->queueBuffer(slot, input, &qbOutput);
1211 }
1212 adapter.waitForCallbacks();
1213}
1214
Vishnu Nair17dde612020-12-28 11:39:59 -08001215TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1216 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1217
1218 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1219 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1220 int queuesToNativeWindow = 0;
1221 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1222 &queuesToNativeWindow);
1223 ASSERT_EQ(NO_ERROR, err);
1224 ASSERT_EQ(queuesToNativeWindow, 1);
1225}
1226
Vishnu Nair083efd32021-02-12 09:32:30 -08001227// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1228// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001229TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1230 sp<SurfaceControl> bgSurface =
1231 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1232 ISurfaceComposerClient::eFXSurfaceBufferState);
1233 ASSERT_NE(nullptr, bgSurface.get());
1234 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001235 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001236 .show(bgSurface)
1237 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001238 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1239 .apply();
1240
1241 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1242 sp<IGraphicBufferProducer> slowIgbProducer;
1243 setUpProducer(slowAdapter, slowIgbProducer);
1244 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001245 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001246
1247 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1248 sp<IGraphicBufferProducer> fastIgbProducer;
1249 setUpProducer(fastAdapter, fastIgbProducer);
1250 uint8_t r = 255;
1251 uint8_t g = 0;
1252 uint8_t b = 0;
1253 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1254 fastAdapter.waitForCallbacks();
1255
1256 // capture screen and verify that it is red
1257 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1258
1259 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001260 checkScreenCapture(r, g, b,
1261 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001262}
1263
Vishnu Naira4fbca52021-07-07 16:52:34 -07001264TEST_F(BLASTBufferQueueTest, TransformHint) {
1265 // Transform hint is provided to BBQ via the surface control passed by WM
1266 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1267
1268 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1269 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1270 ASSERT_NE(nullptr, igbProducer.get());
1271 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1272 sp<Surface> surface = adapter.getSurface();
1273
1274 // Before connecting to the surface, we do not get a valid transform hint
1275 int transformHint;
1276 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1277 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1278
1279 ASSERT_EQ(NO_ERROR,
1280 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1281
1282 // After connecting to the surface, we should get the correct hint.
1283 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1284 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1285
1286 ANativeWindow_Buffer buffer;
1287 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1288
1289 // Transform hint is updated via callbacks or surface control updates
1290 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1291 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1292
1293 // The hint does not change and matches the value used when dequeueing the buffer.
1294 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1295 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1296
1297 surface->unlockAndPost();
1298
1299 // After queuing the buffer, we get the updated transform hint
1300 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1301 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1302
1303 adapter.waitForCallbacks();
1304}
1305
Valerie Hau5977fc82019-12-05 15:56:39 -08001306class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1307public:
1308 void test(uint32_t tr) {
1309 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1310 sp<IGraphicBufferProducer> igbProducer;
1311 setUpProducer(adapter, igbProducer);
1312
1313 auto bufWidth = mDisplayWidth;
1314 auto bufHeight = mDisplayHeight;
1315 int slot;
1316 sp<Fence> fence;
1317 sp<GraphicBuffer> buf;
1318
1319 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1320 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1321 nullptr, nullptr);
1322 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1323 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1324
1325 fillQuadrants(buf);
1326
1327 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001328 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1329 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001330 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001331 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1332 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001333 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001334 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001335
1336 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001337 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001338
Valerie Hau5977fc82019-12-05 15:56:39 -08001339 switch (tr) {
1340 case ui::Transform::ROT_0:
1341 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1342 {0, 0, (int32_t)mDisplayWidth / 2,
1343 (int32_t)mDisplayHeight / 2},
1344 1));
1345 ASSERT_NO_FATAL_FAILURE(
1346 checkScreenCapture(255, 0, 0,
1347 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1348 (int32_t)mDisplayHeight / 2},
1349 1));
1350 ASSERT_NO_FATAL_FAILURE(
1351 checkScreenCapture(0, 255, 0,
1352 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1353 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1354 1));
1355 ASSERT_NO_FATAL_FAILURE(
1356 checkScreenCapture(0, 0, 255,
1357 {0, (int32_t)mDisplayHeight / 2,
1358 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1359 1));
1360 break;
1361 case ui::Transform::FLIP_H:
1362 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1363 {0, 0, (int32_t)mDisplayWidth / 2,
1364 (int32_t)mDisplayHeight / 2},
1365 1));
1366 ASSERT_NO_FATAL_FAILURE(
1367 checkScreenCapture(0, 0, 0,
1368 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1369 (int32_t)mDisplayHeight / 2},
1370 1));
1371 ASSERT_NO_FATAL_FAILURE(
1372 checkScreenCapture(0, 0, 255,
1373 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1374 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1375 1));
1376 ASSERT_NO_FATAL_FAILURE(
1377 checkScreenCapture(0, 255, 0,
1378 {0, (int32_t)mDisplayHeight / 2,
1379 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1380 1));
1381 break;
1382 case ui::Transform::FLIP_V:
1383 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1384 {0, 0, (int32_t)mDisplayWidth / 2,
1385 (int32_t)mDisplayHeight / 2},
1386 1));
1387 ASSERT_NO_FATAL_FAILURE(
1388 checkScreenCapture(0, 255, 0,
1389 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1390 (int32_t)mDisplayHeight / 2},
1391 1));
1392 ASSERT_NO_FATAL_FAILURE(
1393 checkScreenCapture(255, 0, 0,
1394 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1395 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1396 1));
1397 ASSERT_NO_FATAL_FAILURE(
1398 checkScreenCapture(0, 0, 0,
1399 {0, (int32_t)mDisplayHeight / 2,
1400 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1401 1));
1402 break;
1403 case ui::Transform::ROT_90:
1404 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1405 {0, 0, (int32_t)mDisplayWidth / 2,
1406 (int32_t)mDisplayHeight / 2},
1407 1));
1408 ASSERT_NO_FATAL_FAILURE(
1409 checkScreenCapture(0, 0, 0,
1410 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1411 (int32_t)mDisplayHeight / 2},
1412 1));
1413 ASSERT_NO_FATAL_FAILURE(
1414 checkScreenCapture(255, 0, 0,
1415 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1416 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1417 1));
1418 ASSERT_NO_FATAL_FAILURE(
1419 checkScreenCapture(0, 255, 0,
1420 {0, (int32_t)mDisplayHeight / 2,
1421 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1422 1));
1423 break;
1424 case ui::Transform::ROT_180:
1425 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1426 {0, 0, (int32_t)mDisplayWidth / 2,
1427 (int32_t)mDisplayHeight / 2},
1428 1));
1429 ASSERT_NO_FATAL_FAILURE(
1430 checkScreenCapture(0, 0, 255,
1431 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1432 (int32_t)mDisplayHeight / 2},
1433 1));
1434 ASSERT_NO_FATAL_FAILURE(
1435 checkScreenCapture(0, 0, 0,
1436 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1437 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1438 1));
1439 ASSERT_NO_FATAL_FAILURE(
1440 checkScreenCapture(255, 0, 0,
1441 {0, (int32_t)mDisplayHeight / 2,
1442 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1443 1));
1444 break;
1445 case ui::Transform::ROT_270:
1446 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1447 {0, 0, (int32_t)mDisplayWidth / 2,
1448 (int32_t)mDisplayHeight / 2},
1449 1));
1450 ASSERT_NO_FATAL_FAILURE(
1451 checkScreenCapture(0, 255, 0,
1452 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1453 (int32_t)mDisplayHeight / 2},
1454 1));
1455 ASSERT_NO_FATAL_FAILURE(
1456 checkScreenCapture(0, 0, 255,
1457 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1458 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1459 1));
1460 ASSERT_NO_FATAL_FAILURE(
1461 checkScreenCapture(0, 0, 0,
1462 {0, (int32_t)mDisplayHeight / 2,
1463 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1464 1));
1465 }
1466 }
1467};
1468
1469TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1470 test(ui::Transform::ROT_0);
1471}
1472
1473TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1474 test(ui::Transform::FLIP_H);
1475}
1476
1477TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1478 test(ui::Transform::FLIP_V);
1479}
1480
1481TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1482 test(ui::Transform::ROT_90);
1483}
1484
1485TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1486 test(ui::Transform::ROT_180);
1487}
1488
1489TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1490 test(ui::Transform::ROT_270);
1491}
Valerie Hau871d6352020-01-29 08:44:02 -08001492
1493class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1494public:
1495 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001496 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001497 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001498 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001499 int slot;
1500 sp<Fence> fence;
1501 sp<GraphicBuffer> buf;
1502 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1503 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1504 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001505 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1506 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1507 }
Valerie Hau871d6352020-01-29 08:44:02 -08001508
Vishnu Nairde66dc72021-06-17 17:54:41 -07001509 *outRequestedPresentTime = requestedPresentTime;
1510 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1511 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001512 Rect(mDisplayWidth, mDisplayHeight),
1513 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1514 Fence::NO_FENCE, /*sticky*/ 0,
1515 getFrameTimestamps);
1516 if (postedTime) *postedTime = systemTime();
1517 igbProducer->queueBuffer(slot, input, qbOutput);
1518 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001519 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001520};
1521
1522TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1523 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1524 sp<IGraphicBufferProducer> igbProducer;
1525 ProducerFrameEventHistory history;
1526 setUpProducer(adapter, igbProducer);
1527
1528 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1529 nsecs_t requestedPresentTimeA = 0;
1530 nsecs_t postedTimeA = 0;
1531 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1532 history.applyDelta(qbOutput.frameTimestamps);
1533
1534 FrameEvents* events = nullptr;
1535 events = history.getFrame(1);
1536 ASSERT_NE(nullptr, events);
1537 ASSERT_EQ(1, events->frameNumber);
1538 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1539 ASSERT_GE(events->postedTime, postedTimeA);
1540
Vishnu Nair1506b182021-02-22 14:35:15 -08001541 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001542
1543 // queue another buffer so we query for frame event deltas
1544 nsecs_t requestedPresentTimeB = 0;
1545 nsecs_t postedTimeB = 0;
1546 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1547 history.applyDelta(qbOutput.frameTimestamps);
1548 events = history.getFrame(1);
1549 ASSERT_NE(nullptr, events);
1550
1551 // frame number, requestedPresentTime, and postTime should not have changed
1552 ASSERT_EQ(1, events->frameNumber);
1553 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1554 ASSERT_GE(events->postedTime, postedTimeA);
1555
1556 ASSERT_GE(events->latchTime, postedTimeA);
1557 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1558 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1559 ASSERT_NE(nullptr, events->displayPresentFence);
1560 ASSERT_NE(nullptr, events->releaseFence);
1561
1562 // we should also have gotten the initial values for the next frame
1563 events = history.getFrame(2);
1564 ASSERT_NE(nullptr, events);
1565 ASSERT_EQ(2, events->frameNumber);
1566 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1567 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001568
1569 // wait for any callbacks that have not been received
1570 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001571}
Vishnu Nair083efd32021-02-12 09:32:30 -08001572
Vishnu Nair083efd32021-02-12 09:32:30 -08001573TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1574 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1575 sp<IGraphicBufferProducer> igbProducer;
1576 setUpProducer(adapter, igbProducer);
1577
1578 ProducerFrameEventHistory history;
1579 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1580 nsecs_t requestedPresentTimeA = 0;
1581 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001582 // Present the frame sometime in the future so we can add two frames to the queue so the older
1583 // one will be dropped.
1584 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001585 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001586 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001587 history.applyDelta(qbOutput.frameTimestamps);
1588
1589 FrameEvents* events = nullptr;
1590 events = history.getFrame(1);
1591 ASSERT_NE(nullptr, events);
1592 ASSERT_EQ(1, events->frameNumber);
1593 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1594 ASSERT_GE(events->postedTime, postedTimeA);
1595
1596 // queue another buffer so the first can be dropped
1597 nsecs_t requestedPresentTimeB = 0;
1598 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001599 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1600 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1601 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001602 history.applyDelta(qbOutput.frameTimestamps);
1603 events = history.getFrame(1);
1604 ASSERT_NE(nullptr, events);
1605
1606 // frame number, requestedPresentTime, and postTime should not have changed
1607 ASSERT_EQ(1, events->frameNumber);
1608 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1609 ASSERT_GE(events->postedTime, postedTimeA);
1610
Vishnu Nairde66dc72021-06-17 17:54:41 -07001611 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001612 ASSERT_FALSE(events->hasLatchInfo());
1613 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001614 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1615 ASSERT_FALSE(events->hasDisplayPresentInfo());
1616 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001617
Vishnu Nairde66dc72021-06-17 17:54:41 -07001618 // wait for the last transaction to be completed.
1619 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001620
Vishnu Nairde66dc72021-06-17 17:54:41 -07001621 // queue another buffer so we query for frame event deltas
1622 nsecs_t requestedPresentTimeC = 0;
1623 nsecs_t postedTimeC = 0;
1624 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1625 history.applyDelta(qbOutput.frameTimestamps);
1626
1627 // frame number, requestedPresentTime, and postTime should not have changed
1628 ASSERT_EQ(1, events->frameNumber);
1629 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1630 ASSERT_GE(events->postedTime, postedTimeA);
1631
1632 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1633 ASSERT_FALSE(events->hasLatchInfo());
1634 ASSERT_FALSE(events->hasDequeueReadyInfo());
1635 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1636 ASSERT_FALSE(events->hasDisplayPresentInfo());
1637 ASSERT_FALSE(events->hasReleaseInfo());
1638
1639 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001640 events = history.getFrame(2);
1641 ASSERT_NE(nullptr, events);
1642 ASSERT_EQ(2, events->frameNumber);
1643 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1644 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001645 ASSERT_GE(events->latchTime, postedTimeB);
1646 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1647 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1648 ASSERT_NE(nullptr, events->displayPresentFence);
1649 ASSERT_NE(nullptr, events->releaseFence);
1650
1651 // wait for any callbacks that have not been received
1652 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001653}
1654
Vishnu Nair9a69a042021-06-18 13:19:49 -07001655TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1656 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1657 sp<IGraphicBufferProducer> igbProducer;
1658 ProducerFrameEventHistory history;
1659 setUpProducer(adapter, igbProducer);
1660
1661 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1662 nsecs_t requestedPresentTimeA = 0;
1663 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001664 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1665 history.applyDelta(qbOutput.frameTimestamps);
1666 adapter.waitForCallback(1);
1667
1668 // queue another buffer so we query for frame event deltas
1669 nsecs_t requestedPresentTimeB = 0;
1670 nsecs_t postedTimeB = 0;
1671 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1672 history.applyDelta(qbOutput.frameTimestamps);
1673
1674 // check for a valid compositor deadline
1675 ASSERT_NE(0, history.getReportedCompositeDeadline());
1676
1677 // wait for any callbacks that have not been received
1678 adapter.waitForCallbacks();
1679}
1680
Valerie Hauc5011f92019-10-11 09:52:07 -07001681} // namespace android