blob: 42a32f3b424b1c0be2a387dc8cd9367887f5a701 [file] [log] [blame]
Valerie Hauc5011f92019-10-11 09:52:07 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BLASTBufferQueue_test"
18
19#include <gui/BLASTBufferQueue.h>
20
Valerie Hauda3446e2019-10-14 15:49:22 -070021#include <android/hardware/graphics/common/1.2/types.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080022#include <gui/BufferQueueCore.h>
23#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080024#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070025#include <gui/IGraphicBufferProducer.h>
26#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080027#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070028#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070029#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050030#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070031#include <private/gui/ComposerService.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010032#include <ui/DisplayMode.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070033#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070034#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080035#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070036
37#include <gtest/gtest.h>
38
39using namespace std::chrono_literals;
40
41namespace android {
42
Valerie Hauc5011f92019-10-11 09:52:07 -070043using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070044using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070045
chaviwd7deef72021-10-06 11:53:40 -050046class CountProducerListener : public BnProducerListener {
47public:
48 void onBufferReleased() override {
49 std::scoped_lock<std::mutex> lock(mMutex);
50 mNumReleased++;
51 mReleaseCallback.notify_one();
52 }
53
54 void waitOnNumberReleased(int32_t expectedNumReleased) {
55 std::unique_lock<std::mutex> lock(mMutex);
56 while (mNumReleased < expectedNumReleased) {
57 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
58 std::cv_status::timeout)
59 << "did not receive release";
60 }
61 }
62
63private:
64 std::mutex mMutex;
65 std::condition_variable mReleaseCallback;
66 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
67};
68
chaviwf10b9042021-10-13 15:48:59 -050069class TestBLASTBufferQueue : public BLASTBufferQueue {
70public:
71 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
72 int height, int32_t format)
73 : BLASTBufferQueue(name, surface, width, height, format) {}
74
chaviw6b9ffea2021-11-08 09:25:48 -060075 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
76 const std::vector<SurfaceControlStats>& stats) override {
77 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050078 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
79
80 {
81 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060082 mLastTransactionFrameNumber = frameNumber;
83 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050084 }
85 }
86
87 void waitForCallback(int64_t frameNumber) {
88 std::unique_lock lock{frameNumberMutex};
89 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -060090 while (mLastTransactionFrameNumber < frameNumber) {
91 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -050092 }
93 }
94
95private:
96 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -060097 std::condition_variable mWaitForCallbackCV;
98 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -050099};
100
Valerie Hauc5011f92019-10-11 09:52:07 -0700101class BLASTBufferQueueHelper {
102public:
103 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500104 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
105 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700106 }
107
108 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800109 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700110 }
111
chaviw0acd33a2021-11-02 11:55:37 -0500112 void setSyncTransaction(Transaction* next, bool acquireSingleBuffer = true) {
113 mBlastBufferQueueAdapter->setSyncTransaction(next, acquireSingleBuffer);
Valerie Hauc5011f92019-10-11 09:52:07 -0700114 }
115
Vishnu Nairea0de002020-11-17 17:42:37 -0800116 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700117
Vishnu Nairea0de002020-11-17 17:42:37 -0800118 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700119
chaviwa1c4c822021-11-10 18:11:58 -0600120 Transaction* getSyncTransaction() { return mBlastBufferQueueAdapter->mSyncTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700121
122 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
123 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
124 }
125
Valerie Hauc5011f92019-10-11 09:52:07 -0700126 const sp<SurfaceControl> getSurfaceControl() {
127 return mBlastBufferQueueAdapter->mSurfaceControl;
128 }
129
Vishnu Naira4fbca52021-07-07 16:52:34 -0700130 sp<Surface> getSurface() {
131 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
132 }
133
Valerie Haud3b90d22019-11-06 09:37:31 -0800134 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700135 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800136 // Wait until all but one of the submitted buffers have been released.
137 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800138 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
139 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700140 }
141
Vishnu Nair1506b182021-02-22 14:35:15 -0800142 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500143 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800144 }
145
chaviw0acd33a2021-11-02 11:55:37 -0500146 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
147 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
148 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
149 }
150
Valerie Hauc5011f92019-10-11 09:52:07 -0700151private:
chaviwf10b9042021-10-13 15:48:59 -0500152 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700153};
154
155class BLASTBufferQueueTest : public ::testing::Test {
156public:
157protected:
158 BLASTBufferQueueTest() {
159 const ::testing::TestInfo* const testInfo =
160 ::testing::UnitTest::GetInstance()->current_test_info();
161 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
162 }
163
164 ~BLASTBufferQueueTest() {
165 const ::testing::TestInfo* const testInfo =
166 ::testing::UnitTest::GetInstance()->current_test_info();
167 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
168 }
169
170 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700171 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700172 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700173 mDisplayToken = mClient->getInternalDisplayToken();
174 ASSERT_NE(nullptr, mDisplayToken.get());
175 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700176 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700177 t.apply();
178 t.clear();
179
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100180 ui::DisplayMode mode;
181 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
182 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800183 mDisplayWidth = resolution.getWidth();
184 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700185
186 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
187 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
188 ISurfaceComposerClient::eFXSurfaceBufferState,
189 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700190 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700191 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700192 .show(mSurfaceControl)
193 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
194 .apply();
chaviwd2432892020-07-24 17:42:39 -0700195
196 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800197 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700198 }
199
chaviwd7deef72021-10-06 11:53:40 -0500200 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
201 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800202 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500203 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800204 }
205
chaviwd7deef72021-10-06 11:53:40 -0500206 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800207 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500208 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800209 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500210 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800211 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500212 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800213 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800214 }
215
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800216 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
217 uint8_t b) {
218 for (uint32_t row = rect.top; row < rect.bottom; row++) {
219 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700220 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
221 *pixel = r;
222 *(pixel + 1) = g;
223 *(pixel + 2) = b;
224 *(pixel + 3) = 255;
225 }
226 }
227 }
228
Valerie Hau5977fc82019-12-05 15:56:39 -0800229 void fillQuadrants(sp<GraphicBuffer>& buf) {
230 const auto bufWidth = buf->getWidth();
231 const auto bufHeight = buf->getHeight();
232 uint32_t* bufData;
233 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
234 reinterpret_cast<void**>(&bufData));
235 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
236 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
237 0, 0);
238 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
239 buf->getStride(), 0, 255, 0);
240 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
241 255);
242 buf->unlock();
243 }
244
245 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
246 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700247 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800248 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700249 const auto width = captureBuf->getWidth();
250 const auto height = captureBuf->getHeight();
251 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700252
253 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700254 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
255 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700256
257 for (uint32_t row = 0; row < height; row++) {
258 for (uint32_t col = 0; col < width; col++) {
259 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800260 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800261 bool inRegion;
262 if (!outsideRegion) {
263 inRegion = row >= region.top + border && row < region.bottom - border &&
264 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800265 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800266 inRegion = row >= region.top - border && row < region.bottom + border &&
267 col >= region.left - border && col < region.right + border;
268 }
269 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000270 ASSERT_GE(epsilon, abs(r - *(pixel)));
271 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
272 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800273 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000274 ASSERT_GE(epsilon, abs(r - *(pixel)));
275 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
276 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800277 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800278 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700279 }
280 }
chaviwd2432892020-07-24 17:42:39 -0700281 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700282 }
283
chaviw8ffc7b82020-08-18 11:25:37 -0700284 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
285 ScreenCaptureResults& captureResults) {
286 const auto sf = ComposerService::getComposerService();
287 SurfaceComposerClient::Transaction().apply(true);
288
289 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
290 status_t status = sf->captureDisplay(captureArgs, captureListener);
291 if (status != NO_ERROR) {
292 return status;
293 }
294 captureResults = captureListener->waitForResults();
295 return captureResults.result;
296 }
297
Vishnu Nair277142c2021-01-05 18:35:29 -0800298 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
299 nsecs_t presentTimeDelay) {
300 int slot;
301 sp<Fence> fence;
302 sp<GraphicBuffer> buf;
303 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
304 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
305 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500306 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800307 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
308
309 uint32_t* bufData;
310 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
311 reinterpret_cast<void**>(&bufData));
312 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
313 buf->unlock();
314
315 IGraphicBufferProducer::QueueBufferOutput qbOutput;
316 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
317 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
318 Rect(mDisplayWidth, mDisplayHeight / 2),
319 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
320 Fence::NO_FENCE);
321 igbp->queueBuffer(slot, input, &qbOutput);
322 }
323
Valerie Hauc5011f92019-10-11 09:52:07 -0700324 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700325 sp<ISurfaceComposer> mComposer;
326
327 sp<IBinder> mDisplayToken;
328
Valerie Hauc5011f92019-10-11 09:52:07 -0700329 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700330
331 uint32_t mDisplayWidth;
332 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700333
334 DisplayCaptureArgs mCaptureArgs;
335 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500336 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700337};
338
339TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
340 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700341 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700342 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700343 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
344 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
chaviwa1c4c822021-11-10 18:11:58 -0600345 ASSERT_EQ(nullptr, adapter.getSyncTransaction());
Valerie Hauc5011f92019-10-11 09:52:07 -0700346}
347
348TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700349 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700350 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700351 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
352 PIXEL_FORMAT_RGBA_8888);
353 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700354 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800355 sp<IGraphicBufferProducer> igbProducer;
356 setUpProducer(adapter, igbProducer);
357
358 int32_t width;
359 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
360 ASSERT_EQ(mDisplayWidth / 2, width);
361 int32_t height;
362 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
363 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700364}
365
chaviwa1c4c822021-11-10 18:11:58 -0600366TEST_F(BLASTBufferQueueTest, SetSyncTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700367 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
chaviwa1c4c822021-11-10 18:11:58 -0600368 Transaction sync;
369 adapter.setSyncTransaction(&sync);
370 ASSERT_EQ(&sync, adapter.getSyncTransaction());
Valerie Hauc5011f92019-10-11 09:52:07 -0700371}
Valerie Hauda3446e2019-10-14 15:49:22 -0700372
Valerie Haubf29e042020-02-06 11:40:38 -0800373TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800374 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
375 sp<IGraphicBufferProducer> igbProducer;
376 setUpProducer(adapter, igbProducer);
377
378 int slot;
379 sp<Fence> fence;
380 sp<GraphicBuffer> buf;
381 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
382 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
383 nullptr, nullptr);
384 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
385 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
386
387 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
388 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800389 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
390 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800391 Rect(mDisplayWidth, mDisplayHeight),
392 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
393 Fence::NO_FENCE);
394 igbProducer->queueBuffer(slot, input, &qbOutput);
395 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
396
397 adapter.waitForCallbacks();
398 ASSERT_GE(systemTime(), desiredPresentTime);
399}
400
Valerie Hauda3446e2019-10-14 15:49:22 -0700401TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
402 uint8_t r = 255;
403 uint8_t g = 0;
404 uint8_t b = 0;
405
406 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800407 sp<IGraphicBufferProducer> igbProducer;
408 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700409
410 int slot;
411 sp<Fence> fence;
412 sp<GraphicBuffer> buf;
413 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
414 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
415 nullptr, nullptr);
416 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
417 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
418
419 uint32_t* bufData;
420 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
421 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800422 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700423 buf->unlock();
424
Valerie Haud3b90d22019-11-06 09:37:31 -0800425 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800426 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
427 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700428 Rect(mDisplayWidth, mDisplayHeight),
429 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
430 Fence::NO_FENCE);
431 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800432 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700433
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800434 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700435
436 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700437 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800438 ASSERT_NO_FATAL_FAILURE(
439 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700440}
Valerie Haud3b90d22019-11-06 09:37:31 -0800441
442TEST_F(BLASTBufferQueueTest, TripleBuffering) {
443 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
444 sp<IGraphicBufferProducer> igbProducer;
445 setUpProducer(adapter, igbProducer);
446
447 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700448 int minUndequeuedBuffers = 0;
449 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
450 const auto bufferCount = minUndequeuedBuffers + 2;
451
452 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800453 int slot;
454 sp<Fence> fence;
455 sp<GraphicBuffer> buf;
456 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
457 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
458 nullptr, nullptr);
459 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
460 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
461 allocated.push_back({slot, fence});
462 }
463 for (int i = 0; i < allocated.size(); i++) {
464 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
465 }
466
Valerie Haua32c5522019-12-09 10:11:08 -0800467 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800468 int slot;
469 sp<Fence> fence;
470 sp<GraphicBuffer> buf;
471 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
472 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
473 nullptr, nullptr);
474 ASSERT_EQ(NO_ERROR, ret);
475 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800476 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
477 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800478 Rect(mDisplayWidth, mDisplayHeight),
479 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
480 Fence::NO_FENCE);
481 igbProducer->queueBuffer(slot, input, &qbOutput);
482 }
483 adapter.waitForCallbacks();
484}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800485
486TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
487 uint8_t r = 255;
488 uint8_t g = 0;
489 uint8_t b = 0;
490
491 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
492 sp<IGraphicBufferProducer> igbProducer;
493 setUpProducer(adapter, igbProducer);
494 int slot;
495 sp<Fence> fence;
496 sp<GraphicBuffer> buf;
497 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
498 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
499 nullptr, nullptr);
500 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
501 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
502
503 uint32_t* bufData;
504 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
505 reinterpret_cast<void**>(&bufData));
506 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
507 buf->unlock();
508
509 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800510 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
511 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800512 Rect(mDisplayWidth, mDisplayHeight / 2),
513 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
514 Fence::NO_FENCE);
515 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800516 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800517
518 adapter.waitForCallbacks();
519 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700520 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700521
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800522 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000523 checkScreenCapture(r, g, b,
524 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800525}
526
527TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
528 uint8_t r = 255;
529 uint8_t g = 0;
530 uint8_t b = 0;
531
532 int32_t bufferSideLength =
533 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
534 int32_t finalCropSideLength = bufferSideLength / 2;
535
536 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800537 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800538 ASSERT_NE(nullptr, bg.get());
539 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700540 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800541 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800542 .setColor(bg, half3{0, 0, 0})
543 .setLayer(bg, 0)
544 .apply();
545
546 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
547 sp<IGraphicBufferProducer> igbProducer;
548 setUpProducer(adapter, igbProducer);
549 int slot;
550 sp<Fence> fence;
551 sp<GraphicBuffer> buf;
552 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
553 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
554 nullptr, nullptr);
555 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
556 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
557
558 uint32_t* bufData;
559 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
560 reinterpret_cast<void**>(&bufData));
561 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
562 fillBuffer(bufData,
563 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
564 buf->getHeight()),
565 buf->getStride(), r, g, b);
566 buf->unlock();
567
568 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800569 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
570 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800571 Rect(bufferSideLength, finalCropSideLength),
572 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
573 Fence::NO_FENCE);
574 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800575 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800576
577 adapter.waitForCallbacks();
578 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700579 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700580 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
581 {10, 10, (int32_t)bufferSideLength - 10,
582 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800583 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700584 checkScreenCapture(0, 0, 0,
585 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
586 /*border*/ 0, /*outsideRegion*/ true));
587}
588
589TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
590 // add black background
591 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
592 ISurfaceComposerClient::eFXSurfaceEffect);
593 ASSERT_NE(nullptr, bg.get());
594 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700595 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700596 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
597 .setColor(bg, half3{0, 0, 0})
598 .setLayer(bg, 0)
599 .apply();
600
601 Rect windowSize(1000, 1000);
602 Rect bufferSize(windowSize);
603 Rect bufferCrop(200, 200, 700, 700);
604
605 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
606 sp<IGraphicBufferProducer> igbProducer;
607 setUpProducer(adapter, igbProducer);
608 int slot;
609 sp<Fence> fence;
610 sp<GraphicBuffer> buf;
611 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
612 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
613 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
614 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
615 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
616
617 uint32_t* bufData;
618 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
619 reinterpret_cast<void**>(&bufData));
620 // fill buffer with grey
621 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
622
623 // fill crop area with different colors so we can verify the cropped region has been scaled
624 // correctly.
625 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
626 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
627 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
628 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
629 buf->unlock();
630
631 IGraphicBufferProducer::QueueBufferOutput qbOutput;
632 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
633 HAL_DATASPACE_UNKNOWN,
634 bufferCrop /* Rect::INVALID_RECT */,
635 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
636 Fence::NO_FENCE);
637 igbProducer->queueBuffer(slot, input, &qbOutput);
638 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
639
640 adapter.waitForCallbacks();
641
642 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
643
644 // Verify cropped region is scaled correctly.
645 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
646 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
647 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
648 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
649 // Verify outside region is black.
650 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
651 {0, 0, (int32_t)windowSize.getWidth(),
652 (int32_t)windowSize.getHeight()},
653 /*border*/ 0, /*outsideRegion*/ true));
654}
655
656TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
657 // add black background
658 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
659 ISurfaceComposerClient::eFXSurfaceEffect);
660 ASSERT_NE(nullptr, bg.get());
661 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700662 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700663 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
664 .setColor(bg, half3{0, 0, 0})
665 .setLayer(bg, 0)
666 .apply();
667
668 Rect windowSize(1000, 1000);
669 Rect bufferSize(500, 500);
670 Rect bufferCrop(100, 100, 350, 350);
671
672 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
673 sp<IGraphicBufferProducer> igbProducer;
674 setUpProducer(adapter, igbProducer);
675 int slot;
676 sp<Fence> fence;
677 sp<GraphicBuffer> buf;
678 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
679 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
680 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
681 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
682 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
683
684 uint32_t* bufData;
685 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
686 reinterpret_cast<void**>(&bufData));
687 // fill buffer with grey
688 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
689
690 // fill crop area with different colors so we can verify the cropped region has been scaled
691 // correctly.
692 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
693 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
694 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
695 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
696 buf->unlock();
697
698 IGraphicBufferProducer::QueueBufferOutput qbOutput;
699 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
700 HAL_DATASPACE_UNKNOWN,
701 bufferCrop /* Rect::INVALID_RECT */,
702 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
703 Fence::NO_FENCE);
704 igbProducer->queueBuffer(slot, input, &qbOutput);
705 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
706
707 adapter.waitForCallbacks();
708
709 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
710 // Verify cropped region is scaled correctly.
711 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
712 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
713 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
714 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
715 // Verify outside region is black.
716 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
717 {0, 0, (int32_t)windowSize.getWidth(),
718 (int32_t)windowSize.getHeight()},
719 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800720}
721
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700722// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
723// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
724TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
725 uint8_t r = 255;
726 uint8_t g = 0;
727 uint8_t b = 0;
728
729 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
730 sp<IGraphicBufferProducer> igbProducer;
731 setUpProducer(adapter, igbProducer);
732 {
733 int slot;
734 sp<Fence> fence;
735 sp<GraphicBuffer> buf;
736 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
737 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
738 nullptr, nullptr);
739 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
740 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
741
742 uint32_t* bufData;
743 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
744 reinterpret_cast<void**>(&bufData));
745 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
746 buf->unlock();
747
748 IGraphicBufferProducer::QueueBufferOutput qbOutput;
749 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
750 HAL_DATASPACE_UNKNOWN, {},
751 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
752 Fence::NO_FENCE);
753 igbProducer->queueBuffer(slot, input, &qbOutput);
754 adapter.waitForCallbacks();
755 }
756 // capture screen and verify that it is red
757 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
758
759 ASSERT_NO_FATAL_FAILURE(
760 checkScreenCapture(r, g, b,
761 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
762
763 // update the size to half the display and dequeue a buffer quarter of the display.
764 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
765
766 {
767 int slot;
768 sp<Fence> fence;
769 sp<GraphicBuffer> buf;
770 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
771 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
772 nullptr, nullptr);
773 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
774 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
775
776 uint32_t* bufData;
777 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
778 reinterpret_cast<void**>(&bufData));
779 g = 255;
780 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
781 buf->unlock();
782
783 IGraphicBufferProducer::QueueBufferOutput qbOutput;
784 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
785 HAL_DATASPACE_UNKNOWN, {},
786 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
787 0, Fence::NO_FENCE);
788 igbProducer->queueBuffer(slot, input, &qbOutput);
789 adapter.waitForCallbacks();
790 }
791 // capture screen and verify that it is red
792 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
793 // verify we still scale the buffer to the new size (half the screen height)
794 ASSERT_NO_FATAL_FAILURE(
795 checkScreenCapture(r, g, b,
796 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
797}
798
chaviwd7deef72021-10-06 11:53:40 -0500799TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
800 uint8_t r = 255;
801 uint8_t g = 0;
802 uint8_t b = 0;
803
804 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
805
806 sp<IGraphicBufferProducer> igbProducer;
807 setUpProducer(adapter, igbProducer);
808
chaviwa1c4c822021-11-10 18:11:58 -0600809 Transaction sync;
810 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500811 queueBuffer(igbProducer, 0, 255, 0, 0);
812
813 // queue non sync buffer, so this one should get blocked
814 // Add a present delay to allow the first screenshot to get taken.
815 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
816 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
817
818 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600819 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500820 transactionCallback.getContext())
821 .apply();
822
823 CallbackData callbackData;
824 transactionCallback.getCallbackData(&callbackData);
825
chaviw0acd33a2021-11-02 11:55:37 -0500826 // capture screen and verify that it is green
chaviwd7deef72021-10-06 11:53:40 -0500827 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
828 ASSERT_NO_FATAL_FAILURE(
829 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
830
831 mProducerListener->waitOnNumberReleased(1);
832 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
833 ASSERT_NO_FATAL_FAILURE(
834 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
835}
836
837TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
838 uint8_t r = 255;
839 uint8_t g = 0;
840 uint8_t b = 0;
841
842 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
843
844 sp<IGraphicBufferProducer> igbProducer;
845 setUpProducer(adapter, igbProducer);
846
847 Transaction mainTransaction;
848
chaviwa1c4c822021-11-10 18:11:58 -0600849 Transaction sync;
850 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500851 queueBuffer(igbProducer, 0, 255, 0, 0);
852
chaviwa1c4c822021-11-10 18:11:58 -0600853 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500854
chaviwa1c4c822021-11-10 18:11:58 -0600855 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500856 queueBuffer(igbProducer, r, g, b, 0);
857
chaviwa1c4c822021-11-10 18:11:58 -0600858 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500859 // Expect 1 buffer to be released even before sending to SurfaceFlinger
860 mProducerListener->waitOnNumberReleased(1);
861
862 CallbackHelper transactionCallback;
863 mainTransaction
864 .addTransactionCompletedCallback(transactionCallback.function,
865 transactionCallback.getContext())
866 .apply();
867
868 CallbackData callbackData;
869 transactionCallback.getCallbackData(&callbackData);
870
871 // capture screen and verify that it is red
872 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
873 ASSERT_NO_FATAL_FAILURE(
874 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
875}
876
877TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
878 uint8_t r = 255;
879 uint8_t g = 0;
880 uint8_t b = 0;
881
882 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
883
884 sp<IGraphicBufferProducer> igbProducer;
885 setUpProducer(adapter, igbProducer);
886
887 Transaction mainTransaction;
888
chaviwa1c4c822021-11-10 18:11:58 -0600889 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500890 // queue a sync transaction
chaviwa1c4c822021-11-10 18:11:58 -0600891 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500892 queueBuffer(igbProducer, 0, 255, 0, 0);
893
chaviwa1c4c822021-11-10 18:11:58 -0600894 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500895
chaviwa1c4c822021-11-10 18:11:58 -0600896 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500897 queueBuffer(igbProducer, 0, 0, 255, 0);
898
899 // queue another sync transaction
chaviwa1c4c822021-11-10 18:11:58 -0600900 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500901 queueBuffer(igbProducer, r, g, b, 0);
902 // Expect 1 buffer to be released because the non sync transaction should merge
903 // with the sync
904 mProducerListener->waitOnNumberReleased(1);
905
chaviwa1c4c822021-11-10 18:11:58 -0600906 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500907 // Expect 2 buffers to be released due to merging the two syncs.
908 mProducerListener->waitOnNumberReleased(2);
909
910 CallbackHelper transactionCallback;
911 mainTransaction
912 .addTransactionCompletedCallback(transactionCallback.function,
913 transactionCallback.getContext())
914 .apply();
915
916 CallbackData callbackData;
917 transactionCallback.getCallbackData(&callbackData);
918
919 // capture screen and verify that it is red
920 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
921 ASSERT_NO_FATAL_FAILURE(
922 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
923}
924
925TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
926 uint8_t r = 255;
927 uint8_t g = 0;
928 uint8_t b = 0;
929
930 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
931
932 sp<IGraphicBufferProducer> igbProducer;
933 setUpProducer(adapter, igbProducer, 3);
934
935 Transaction mainTransaction;
936
chaviwa1c4c822021-11-10 18:11:58 -0600937 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500938 // queue a sync transaction
chaviwa1c4c822021-11-10 18:11:58 -0600939 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500940 queueBuffer(igbProducer, 0, 255, 0, 0);
941
chaviwa1c4c822021-11-10 18:11:58 -0600942 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500943
chaviwa1c4c822021-11-10 18:11:58 -0600944 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500945 queueBuffer(igbProducer, 0, 0, 255, 0);
946 queueBuffer(igbProducer, 0, 0, 255, 0);
947 queueBuffer(igbProducer, 0, 0, 255, 0);
948
949 // queue another sync transaction
chaviwa1c4c822021-11-10 18:11:58 -0600950 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500951 queueBuffer(igbProducer, r, g, b, 0);
952 // Expect 3 buffers to be released because the non sync transactions should merge
953 // with the sync
954 mProducerListener->waitOnNumberReleased(3);
955
chaviwa1c4c822021-11-10 18:11:58 -0600956 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500957 // Expect 4 buffers to be released due to merging the two syncs.
958 mProducerListener->waitOnNumberReleased(4);
959
960 CallbackHelper transactionCallback;
961 mainTransaction
962 .addTransactionCompletedCallback(transactionCallback.function,
963 transactionCallback.getContext())
964 .apply();
965
966 CallbackData callbackData;
967 transactionCallback.getCallbackData(&callbackData);
968
969 // capture screen and verify that it is red
970 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
971 ASSERT_NO_FATAL_FAILURE(
972 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
973}
974
975// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
976// continue processing is for a release callback from SurfaceFlinger.
977// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
978// continue acquiring buffers.
979TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
980 uint8_t r = 255;
981 uint8_t g = 0;
982 uint8_t b = 0;
983
984 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
985
986 sp<IGraphicBufferProducer> igbProducer;
987 setUpProducer(adapter, igbProducer, 4);
988
989 Transaction mainTransaction;
990
991 // Send a buffer to SF
992 queueBuffer(igbProducer, 0, 255, 0, 0);
993
chaviwa1c4c822021-11-10 18:11:58 -0600994 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500995 // queue a sync transaction
chaviwa1c4c822021-11-10 18:11:58 -0600996 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -0500997 queueBuffer(igbProducer, 0, 255, 0, 0);
998
chaviwa1c4c822021-11-10 18:11:58 -0600999 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001000
chaviwa1c4c822021-11-10 18:11:58 -06001001 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001002 queueBuffer(igbProducer, 0, 0, 255, 0);
1003 queueBuffer(igbProducer, 0, 0, 255, 0);
1004 queueBuffer(igbProducer, 0, 0, 255, 0);
1005
1006 // apply the first synced buffer to ensure we have to wait on SF
1007 mainTransaction.apply();
1008
1009 // queue another sync transaction
chaviwa1c4c822021-11-10 18:11:58 -06001010 adapter.setSyncTransaction(&sync);
chaviwd7deef72021-10-06 11:53:40 -05001011 queueBuffer(igbProducer, r, g, b, 0);
1012 // Expect 2 buffers to be released because the non sync transactions should merge
1013 // with the sync
1014 mProducerListener->waitOnNumberReleased(3);
1015
chaviwa1c4c822021-11-10 18:11:58 -06001016 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001017
1018 CallbackHelper transactionCallback;
1019 mainTransaction
1020 .addTransactionCompletedCallback(transactionCallback.function,
1021 transactionCallback.getContext())
1022 .apply();
1023
1024 CallbackData callbackData;
1025 transactionCallback.getCallbackData(&callbackData);
1026
1027 // capture screen and verify that it is red
1028 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1029 ASSERT_NO_FATAL_FAILURE(
1030 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1031}
1032
chaviw0acd33a2021-11-02 11:55:37 -05001033TEST_F(BLASTBufferQueueTest, SetSyncTransactionAcquireMultipleBuffers) {
1034 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1035
1036 sp<IGraphicBufferProducer> igbProducer;
1037 setUpProducer(adapter, igbProducer);
1038
1039 Transaction next;
1040 adapter.setSyncTransaction(&next, false);
1041 queueBuffer(igbProducer, 0, 255, 0, 0);
1042 queueBuffer(igbProducer, 0, 0, 255, 0);
1043 // There should only be one frame submitted since the first frame will be released.
1044 adapter.validateNumFramesSubmitted(1);
1045 adapter.setSyncTransaction(nullptr);
1046
1047 // queue non sync buffer, so this one should get blocked
1048 // Add a present delay to allow the first screenshot to get taken.
1049 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1050 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1051
1052 CallbackHelper transactionCallback;
1053 next.addTransactionCompletedCallback(transactionCallback.function,
1054 transactionCallback.getContext())
1055 .apply();
1056
1057 CallbackData callbackData;
1058 transactionCallback.getCallbackData(&callbackData);
1059
1060 // capture screen and verify that it is blue
1061 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1062 ASSERT_NO_FATAL_FAILURE(
1063 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1064
1065 mProducerListener->waitOnNumberReleased(2);
1066 // capture screen and verify that it is red
1067 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1068 ASSERT_NO_FATAL_FAILURE(
1069 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1070}
1071
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001072// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1073// until the old surface control is destroyed. This is not necessarily a bug but to document a
1074// limitation with the update API and to test any changes to make the api more robust. The current
1075// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1076TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1077 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1078 std::vector<sp<SurfaceControl>> surfaceControls;
1079 sp<IGraphicBufferProducer> igbProducer;
1080 for (int i = 0; i < 10; i++) {
1081 sp<SurfaceControl> sc =
1082 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1083 PIXEL_FORMAT_RGBA_8888,
1084 ISurfaceComposerClient::eFXSurfaceBufferState,
1085 /*parent*/ nullptr);
1086 Transaction()
1087 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1088 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1089 .show(mSurfaceControl)
1090 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1091 .apply(true);
1092 surfaceControls.push_back(sc);
1093 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1094
1095 setUpProducer(adapter, igbProducer);
1096 Transaction next;
1097 queueBuffer(igbProducer, 0, 255, 0, 0);
1098 queueBuffer(igbProducer, 0, 0, 255, 0);
1099 adapter.setSyncTransaction(&next, false);
1100 queueBuffer(igbProducer, 255, 0, 0, 0);
1101
1102 CallbackHelper transactionCallback;
1103 next.addTransactionCompletedCallback(transactionCallback.function,
1104 transactionCallback.getContext())
1105 .apply();
1106
1107 CallbackData callbackData;
1108 transactionCallback.getCallbackData(&callbackData);
1109 // capture screen and verify that it is red
1110 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1111 ASSERT_NO_FATAL_FAILURE(
1112 checkScreenCapture(255, 0, 0,
1113 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1114 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1115 }
1116}
1117
1118// See DISABLED_DisconnectProducerTest
1119TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1120 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1121 std::vector<sp<SurfaceControl>> surfaceControls;
1122 sp<IGraphicBufferProducer> igbProducer;
1123 for (int i = 0; i < 10; i++) {
1124 sp<SurfaceControl> sc =
1125 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1126 PIXEL_FORMAT_RGBA_8888,
1127 ISurfaceComposerClient::eFXSurfaceBufferState,
1128 /*parent*/ nullptr);
1129 Transaction()
1130 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1131 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1132 .show(mSurfaceControl)
1133 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1134 .apply(true);
1135 surfaceControls.push_back(sc);
1136 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1137 setUpProducer(adapter, igbProducer);
1138
1139 Transaction next;
1140 queueBuffer(igbProducer, 0, 255, 0, 0);
1141 queueBuffer(igbProducer, 0, 0, 255, 0);
1142 adapter.setSyncTransaction(&next, false);
1143 queueBuffer(igbProducer, 255, 0, 0, 0);
1144
1145 CallbackHelper transactionCallback;
1146 next.addTransactionCompletedCallback(transactionCallback.function,
1147 transactionCallback.getContext())
1148 .apply();
1149
1150 CallbackData callbackData;
1151 transactionCallback.getCallbackData(&callbackData);
1152 // capture screen and verify that it is red
1153 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1154 ASSERT_NO_FATAL_FAILURE(
1155 checkScreenCapture(255, 0, 0,
1156 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1157 }
1158}
1159
Vishnu Nair89496122020-12-14 17:14:53 -08001160class TestProducerListener : public BnProducerListener {
1161public:
1162 sp<IGraphicBufferProducer> mIgbp;
1163 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1164 void onBufferReleased() override {
1165 sp<GraphicBuffer> buffer;
1166 sp<Fence> fence;
1167 mIgbp->detachNextBuffer(&buffer, &fence);
1168 }
1169};
1170
1171TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1172 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1173 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1174 ASSERT_NE(nullptr, igbProducer.get());
1175 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1176 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1177 ASSERT_EQ(NO_ERROR,
1178 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1179 false, &qbOutput));
1180 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1181 for (int i = 0; i < 3; i++) {
1182 int slot;
1183 sp<Fence> fence;
1184 sp<GraphicBuffer> buf;
1185 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1186 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1187 nullptr, nullptr);
1188 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1189 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1190 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001191 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1192 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001193 Rect(mDisplayWidth, mDisplayHeight),
1194 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1195 Fence::NO_FENCE);
1196 igbProducer->queueBuffer(slot, input, &qbOutput);
1197 }
1198 adapter.waitForCallbacks();
1199}
1200
Vishnu Nair17dde612020-12-28 11:39:59 -08001201TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1202 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1203
1204 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1205 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1206 int queuesToNativeWindow = 0;
1207 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1208 &queuesToNativeWindow);
1209 ASSERT_EQ(NO_ERROR, err);
1210 ASSERT_EQ(queuesToNativeWindow, 1);
1211}
1212
Vishnu Nair083efd32021-02-12 09:32:30 -08001213// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1214// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001215TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1216 sp<SurfaceControl> bgSurface =
1217 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1218 ISurfaceComposerClient::eFXSurfaceBufferState);
1219 ASSERT_NE(nullptr, bgSurface.get());
1220 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001221 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001222 .show(bgSurface)
1223 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001224 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1225 .apply();
1226
1227 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1228 sp<IGraphicBufferProducer> slowIgbProducer;
1229 setUpProducer(slowAdapter, slowIgbProducer);
1230 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001231 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001232
1233 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1234 sp<IGraphicBufferProducer> fastIgbProducer;
1235 setUpProducer(fastAdapter, fastIgbProducer);
1236 uint8_t r = 255;
1237 uint8_t g = 0;
1238 uint8_t b = 0;
1239 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1240 fastAdapter.waitForCallbacks();
1241
1242 // capture screen and verify that it is red
1243 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1244
1245 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001246 checkScreenCapture(r, g, b,
1247 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001248}
1249
Vishnu Naira4fbca52021-07-07 16:52:34 -07001250TEST_F(BLASTBufferQueueTest, TransformHint) {
1251 // Transform hint is provided to BBQ via the surface control passed by WM
1252 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1253
1254 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1255 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1256 ASSERT_NE(nullptr, igbProducer.get());
1257 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1258 sp<Surface> surface = adapter.getSurface();
1259
1260 // Before connecting to the surface, we do not get a valid transform hint
1261 int transformHint;
1262 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1263 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1264
1265 ASSERT_EQ(NO_ERROR,
1266 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1267
1268 // After connecting to the surface, we should get the correct hint.
1269 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1270 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1271
1272 ANativeWindow_Buffer buffer;
1273 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1274
1275 // Transform hint is updated via callbacks or surface control updates
1276 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1277 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1278
1279 // The hint does not change and matches the value used when dequeueing the buffer.
1280 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1281 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1282
1283 surface->unlockAndPost();
1284
1285 // After queuing the buffer, we get the updated transform hint
1286 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1287 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1288
1289 adapter.waitForCallbacks();
1290}
1291
Valerie Hau5977fc82019-12-05 15:56:39 -08001292class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1293public:
1294 void test(uint32_t tr) {
1295 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1296 sp<IGraphicBufferProducer> igbProducer;
1297 setUpProducer(adapter, igbProducer);
1298
1299 auto bufWidth = mDisplayWidth;
1300 auto bufHeight = mDisplayHeight;
1301 int slot;
1302 sp<Fence> fence;
1303 sp<GraphicBuffer> buf;
1304
1305 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1306 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1307 nullptr, nullptr);
1308 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1309 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1310
1311 fillQuadrants(buf);
1312
1313 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001314 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1315 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001316 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001317 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1318 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001319 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001320 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001321
1322 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001323 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001324
Valerie Hau5977fc82019-12-05 15:56:39 -08001325 switch (tr) {
1326 case ui::Transform::ROT_0:
1327 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1328 {0, 0, (int32_t)mDisplayWidth / 2,
1329 (int32_t)mDisplayHeight / 2},
1330 1));
1331 ASSERT_NO_FATAL_FAILURE(
1332 checkScreenCapture(255, 0, 0,
1333 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1334 (int32_t)mDisplayHeight / 2},
1335 1));
1336 ASSERT_NO_FATAL_FAILURE(
1337 checkScreenCapture(0, 255, 0,
1338 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1339 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1340 1));
1341 ASSERT_NO_FATAL_FAILURE(
1342 checkScreenCapture(0, 0, 255,
1343 {0, (int32_t)mDisplayHeight / 2,
1344 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1345 1));
1346 break;
1347 case ui::Transform::FLIP_H:
1348 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1349 {0, 0, (int32_t)mDisplayWidth / 2,
1350 (int32_t)mDisplayHeight / 2},
1351 1));
1352 ASSERT_NO_FATAL_FAILURE(
1353 checkScreenCapture(0, 0, 0,
1354 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1355 (int32_t)mDisplayHeight / 2},
1356 1));
1357 ASSERT_NO_FATAL_FAILURE(
1358 checkScreenCapture(0, 0, 255,
1359 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1360 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1361 1));
1362 ASSERT_NO_FATAL_FAILURE(
1363 checkScreenCapture(0, 255, 0,
1364 {0, (int32_t)mDisplayHeight / 2,
1365 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1366 1));
1367 break;
1368 case ui::Transform::FLIP_V:
1369 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1370 {0, 0, (int32_t)mDisplayWidth / 2,
1371 (int32_t)mDisplayHeight / 2},
1372 1));
1373 ASSERT_NO_FATAL_FAILURE(
1374 checkScreenCapture(0, 255, 0,
1375 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1376 (int32_t)mDisplayHeight / 2},
1377 1));
1378 ASSERT_NO_FATAL_FAILURE(
1379 checkScreenCapture(255, 0, 0,
1380 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1381 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1382 1));
1383 ASSERT_NO_FATAL_FAILURE(
1384 checkScreenCapture(0, 0, 0,
1385 {0, (int32_t)mDisplayHeight / 2,
1386 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1387 1));
1388 break;
1389 case ui::Transform::ROT_90:
1390 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1391 {0, 0, (int32_t)mDisplayWidth / 2,
1392 (int32_t)mDisplayHeight / 2},
1393 1));
1394 ASSERT_NO_FATAL_FAILURE(
1395 checkScreenCapture(0, 0, 0,
1396 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1397 (int32_t)mDisplayHeight / 2},
1398 1));
1399 ASSERT_NO_FATAL_FAILURE(
1400 checkScreenCapture(255, 0, 0,
1401 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1402 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1403 1));
1404 ASSERT_NO_FATAL_FAILURE(
1405 checkScreenCapture(0, 255, 0,
1406 {0, (int32_t)mDisplayHeight / 2,
1407 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1408 1));
1409 break;
1410 case ui::Transform::ROT_180:
1411 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1412 {0, 0, (int32_t)mDisplayWidth / 2,
1413 (int32_t)mDisplayHeight / 2},
1414 1));
1415 ASSERT_NO_FATAL_FAILURE(
1416 checkScreenCapture(0, 0, 255,
1417 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1418 (int32_t)mDisplayHeight / 2},
1419 1));
1420 ASSERT_NO_FATAL_FAILURE(
1421 checkScreenCapture(0, 0, 0,
1422 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1423 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1424 1));
1425 ASSERT_NO_FATAL_FAILURE(
1426 checkScreenCapture(255, 0, 0,
1427 {0, (int32_t)mDisplayHeight / 2,
1428 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1429 1));
1430 break;
1431 case ui::Transform::ROT_270:
1432 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1433 {0, 0, (int32_t)mDisplayWidth / 2,
1434 (int32_t)mDisplayHeight / 2},
1435 1));
1436 ASSERT_NO_FATAL_FAILURE(
1437 checkScreenCapture(0, 255, 0,
1438 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1439 (int32_t)mDisplayHeight / 2},
1440 1));
1441 ASSERT_NO_FATAL_FAILURE(
1442 checkScreenCapture(0, 0, 255,
1443 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1444 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1445 1));
1446 ASSERT_NO_FATAL_FAILURE(
1447 checkScreenCapture(0, 0, 0,
1448 {0, (int32_t)mDisplayHeight / 2,
1449 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1450 1));
1451 }
1452 }
1453};
1454
1455TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1456 test(ui::Transform::ROT_0);
1457}
1458
1459TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1460 test(ui::Transform::FLIP_H);
1461}
1462
1463TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1464 test(ui::Transform::FLIP_V);
1465}
1466
1467TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1468 test(ui::Transform::ROT_90);
1469}
1470
1471TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1472 test(ui::Transform::ROT_180);
1473}
1474
1475TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1476 test(ui::Transform::ROT_270);
1477}
Valerie Hau871d6352020-01-29 08:44:02 -08001478
1479class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1480public:
1481 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001482 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001483 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001484 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001485 int slot;
1486 sp<Fence> fence;
1487 sp<GraphicBuffer> buf;
1488 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1489 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1490 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001491 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1492 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1493 }
Valerie Hau871d6352020-01-29 08:44:02 -08001494
Vishnu Nairde66dc72021-06-17 17:54:41 -07001495 *outRequestedPresentTime = requestedPresentTime;
1496 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1497 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001498 Rect(mDisplayWidth, mDisplayHeight),
1499 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1500 Fence::NO_FENCE, /*sticky*/ 0,
1501 getFrameTimestamps);
1502 if (postedTime) *postedTime = systemTime();
1503 igbProducer->queueBuffer(slot, input, qbOutput);
1504 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001505 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001506};
1507
1508TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1509 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1510 sp<IGraphicBufferProducer> igbProducer;
1511 ProducerFrameEventHistory history;
1512 setUpProducer(adapter, igbProducer);
1513
1514 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1515 nsecs_t requestedPresentTimeA = 0;
1516 nsecs_t postedTimeA = 0;
1517 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1518 history.applyDelta(qbOutput.frameTimestamps);
1519
1520 FrameEvents* events = nullptr;
1521 events = history.getFrame(1);
1522 ASSERT_NE(nullptr, events);
1523 ASSERT_EQ(1, events->frameNumber);
1524 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1525 ASSERT_GE(events->postedTime, postedTimeA);
1526
Vishnu Nair1506b182021-02-22 14:35:15 -08001527 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001528
1529 // queue another buffer so we query for frame event deltas
1530 nsecs_t requestedPresentTimeB = 0;
1531 nsecs_t postedTimeB = 0;
1532 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1533 history.applyDelta(qbOutput.frameTimestamps);
1534 events = history.getFrame(1);
1535 ASSERT_NE(nullptr, events);
1536
1537 // frame number, requestedPresentTime, and postTime should not have changed
1538 ASSERT_EQ(1, events->frameNumber);
1539 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1540 ASSERT_GE(events->postedTime, postedTimeA);
1541
1542 ASSERT_GE(events->latchTime, postedTimeA);
1543 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1544 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1545 ASSERT_NE(nullptr, events->displayPresentFence);
1546 ASSERT_NE(nullptr, events->releaseFence);
1547
1548 // we should also have gotten the initial values for the next frame
1549 events = history.getFrame(2);
1550 ASSERT_NE(nullptr, events);
1551 ASSERT_EQ(2, events->frameNumber);
1552 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1553 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001554
1555 // wait for any callbacks that have not been received
1556 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001557}
Vishnu Nair083efd32021-02-12 09:32:30 -08001558
Vishnu Nair083efd32021-02-12 09:32:30 -08001559TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1560 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1561 sp<IGraphicBufferProducer> igbProducer;
1562 setUpProducer(adapter, igbProducer);
1563
1564 ProducerFrameEventHistory history;
1565 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1566 nsecs_t requestedPresentTimeA = 0;
1567 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001568 // Present the frame sometime in the future so we can add two frames to the queue so the older
1569 // one will be dropped.
1570 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001571 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001572 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001573 history.applyDelta(qbOutput.frameTimestamps);
1574
1575 FrameEvents* events = nullptr;
1576 events = history.getFrame(1);
1577 ASSERT_NE(nullptr, events);
1578 ASSERT_EQ(1, events->frameNumber);
1579 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1580 ASSERT_GE(events->postedTime, postedTimeA);
1581
1582 // queue another buffer so the first can be dropped
1583 nsecs_t requestedPresentTimeB = 0;
1584 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001585 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1586 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1587 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001588 history.applyDelta(qbOutput.frameTimestamps);
1589 events = history.getFrame(1);
1590 ASSERT_NE(nullptr, events);
1591
1592 // frame number, requestedPresentTime, and postTime should not have changed
1593 ASSERT_EQ(1, events->frameNumber);
1594 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1595 ASSERT_GE(events->postedTime, postedTimeA);
1596
Vishnu Nairde66dc72021-06-17 17:54:41 -07001597 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001598 ASSERT_FALSE(events->hasLatchInfo());
1599 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001600 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1601 ASSERT_FALSE(events->hasDisplayPresentInfo());
1602 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001603
Vishnu Nairde66dc72021-06-17 17:54:41 -07001604 // wait for the last transaction to be completed.
1605 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001606
Vishnu Nairde66dc72021-06-17 17:54:41 -07001607 // queue another buffer so we query for frame event deltas
1608 nsecs_t requestedPresentTimeC = 0;
1609 nsecs_t postedTimeC = 0;
1610 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1611 history.applyDelta(qbOutput.frameTimestamps);
1612
1613 // frame number, requestedPresentTime, and postTime should not have changed
1614 ASSERT_EQ(1, events->frameNumber);
1615 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1616 ASSERT_GE(events->postedTime, postedTimeA);
1617
1618 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1619 ASSERT_FALSE(events->hasLatchInfo());
1620 ASSERT_FALSE(events->hasDequeueReadyInfo());
1621 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1622 ASSERT_FALSE(events->hasDisplayPresentInfo());
1623 ASSERT_FALSE(events->hasReleaseInfo());
1624
1625 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001626 events = history.getFrame(2);
1627 ASSERT_NE(nullptr, events);
1628 ASSERT_EQ(2, events->frameNumber);
1629 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1630 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001631 ASSERT_GE(events->latchTime, postedTimeB);
1632 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1633 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1634 ASSERT_NE(nullptr, events->displayPresentFence);
1635 ASSERT_NE(nullptr, events->releaseFence);
1636
1637 // wait for any callbacks that have not been received
1638 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001639}
1640
Vishnu Nair9a69a042021-06-18 13:19:49 -07001641TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1642 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1643 sp<IGraphicBufferProducer> igbProducer;
1644 ProducerFrameEventHistory history;
1645 setUpProducer(adapter, igbProducer);
1646
1647 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1648 nsecs_t requestedPresentTimeA = 0;
1649 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001650 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1651 history.applyDelta(qbOutput.frameTimestamps);
1652 adapter.waitForCallback(1);
1653
1654 // queue another buffer so we query for frame event deltas
1655 nsecs_t requestedPresentTimeB = 0;
1656 nsecs_t postedTimeB = 0;
1657 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1658 history.applyDelta(qbOutput.frameTimestamps);
1659
1660 // check for a valid compositor deadline
1661 ASSERT_NE(0, history.getReportedCompositeDeadline());
1662
1663 // wait for any callbacks that have not been received
1664 adapter.waitForCallbacks();
1665}
1666
Valerie Hauc5011f92019-10-11 09:52:07 -07001667} // namespace android