blob: 53f4a36c42868dd6223e75a0d2185e4e0020b00e [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
Vishnu Nair2e8ae852024-03-30 00:02:30 +000021#include <android-base/thread_annotations.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070022#include <android/hardware/graphics/common/1.2/types.h>
Alec Mouri924f9502024-08-15 20:01:08 +000023#include <gui/AidlUtil.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080024#include <gui/BufferQueueCore.h>
25#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080026#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070027#include <gui/IGraphicBufferProducer.h>
28#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080029#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070030#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070031#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050032#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070033#include <private/gui/ComposerService.h>
Huihong Luo9e84f332021-12-16 14:33:46 -080034#include <private/gui/ComposerServiceAIDL.h>
Melody Hsub9578222023-10-02 23:09:36 +000035#include <tests/utils/ScreenshotUtils.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010036#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070037#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070038#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070039#include <ui/GraphicTypes.h>
Melody Hsub9578222023-10-02 23:09:36 +000040#include <ui/Rect.h>
41#include <ui/Size.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080042#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070043
44#include <gtest/gtest.h>
45
Alec Mouri21d94322023-10-17 19:51:39 +000046#include <com_android_graphics_libgui_flags.h>
47
Valerie Hauc5011f92019-10-11 09:52:07 -070048using namespace std::chrono_literals;
49
50namespace android {
Alec Mouri21d94322023-10-17 19:51:39 +000051using namespace com::android::graphics::libgui;
Valerie Hauc5011f92019-10-11 09:52:07 -070052
Valerie Hauc5011f92019-10-11 09:52:07 -070053using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070054using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070055
chaviwd7deef72021-10-06 11:53:40 -050056class CountProducerListener : public BnProducerListener {
57public:
58 void onBufferReleased() override {
59 std::scoped_lock<std::mutex> lock(mMutex);
60 mNumReleased++;
61 mReleaseCallback.notify_one();
62 }
63
64 void waitOnNumberReleased(int32_t expectedNumReleased) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +000065 std::unique_lock lock{mMutex};
66 base::ScopedLockAssertion assumeLocked(mMutex);
chaviwd7deef72021-10-06 11:53:40 -050067 while (mNumReleased < expectedNumReleased) {
68 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
69 std::cv_status::timeout)
70 << "did not receive release";
71 }
72 }
73
74private:
75 std::mutex mMutex;
76 std::condition_variable mReleaseCallback;
77 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
78};
79
chaviwf10b9042021-10-13 15:48:59 -050080class TestBLASTBufferQueue : public BLASTBufferQueue {
81public:
82 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
83 int height, int32_t format)
84 : BLASTBufferQueue(name, surface, width, height, format) {}
85
chaviw6b9ffea2021-11-08 09:25:48 -060086 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
87 const std::vector<SurfaceControlStats>& stats) override {
88 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050089 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
90
91 {
92 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060093 mLastTransactionFrameNumber = frameNumber;
94 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050095 }
96 }
97
98 void waitForCallback(int64_t frameNumber) {
99 std::unique_lock lock{frameNumberMutex};
100 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -0600101 while (mLastTransactionFrameNumber < frameNumber) {
102 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -0500103 }
104 }
105
106private:
107 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600108 std::condition_variable mWaitForCallbackCV;
109 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500110};
111
Valerie Hauc5011f92019-10-11 09:52:07 -0700112class BLASTBufferQueueHelper {
113public:
114 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500115 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
116 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700117 }
118
119 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800120 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700121 }
122
Tianhao Yao4861b102022-02-03 20:18:35 +0000123 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
124 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
125 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
126 }
127
Chavi Weingartenc398c012023-04-12 17:26:02 +0000128 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000129 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000130 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000131 }
132
133 void stopContinuousSyncTransaction() {
134 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700135 }
136
Chavi Weingartenc398c012023-04-12 17:26:02 +0000137 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
138
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000139 int getWidth() {
140 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
141 return mBlastBufferQueueAdapter->mSize.width;
142 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700143
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000144 int getHeight() {
145 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
146 return mBlastBufferQueueAdapter->mSize.height;
147 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700148
Tianhao Yao4861b102022-02-03 20:18:35 +0000149 std::function<void(Transaction*)> getTransactionReadyCallback() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000150 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Tianhao Yao4861b102022-02-03 20:18:35 +0000151 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
152 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700153
154 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
155 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
156 }
157
Valerie Hauc5011f92019-10-11 09:52:07 -0700158 const sp<SurfaceControl> getSurfaceControl() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000159 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Valerie Hauc5011f92019-10-11 09:52:07 -0700160 return mBlastBufferQueueAdapter->mSurfaceControl;
161 }
162
Vishnu Naira4fbca52021-07-07 16:52:34 -0700163 sp<Surface> getSurface() {
164 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
165 }
166
Valerie Haud3b90d22019-11-06 09:37:31 -0800167 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700168 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000169 base::ScopedLockAssertion assumeLocked(mBlastBufferQueueAdapter->mMutex);
Vishnu Nair1506b182021-02-22 14:35:15 -0800170 // Wait until all but one of the submitted buffers have been released.
171 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800172 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
173 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700174 }
175
Vishnu Nair1506b182021-02-22 14:35:15 -0800176 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500177 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800178 }
179
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000180 void validateNumFramesSubmitted(size_t numFramesSubmitted) {
181 std::scoped_lock lock{mBlastBufferQueueAdapter->mMutex};
chaviw0acd33a2021-11-02 11:55:37 -0500182 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
183 }
184
chaviwc1cf4022022-06-03 13:32:33 -0500185 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
186 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
187 }
188
Vishnu Nairaf15fab2024-07-30 08:59:26 -0700189 void setApplyToken(sp<IBinder> applyToken) {
190 mBlastBufferQueueAdapter->setApplyToken(std::move(applyToken));
191 }
192
Valerie Hauc5011f92019-10-11 09:52:07 -0700193private:
chaviwf10b9042021-10-13 15:48:59 -0500194 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700195};
196
197class BLASTBufferQueueTest : public ::testing::Test {
198public:
199protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700200 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700201 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700202 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700203 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
204 ASSERT_FALSE(ids.empty());
205 // display 0 is picked as this test is not much display depedent
206 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700207 ASSERT_NE(nullptr, mDisplayToken.get());
208 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700209 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700210 t.apply();
211 t.clear();
212
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700213 ui::DisplayState displayState;
214 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
215 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800216 mDisplayWidth = resolution.getWidth();
217 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000218 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000219 static_cast<int32_t>(displayState.orientation));
Valerie Hauda3446e2019-10-14 15:49:22 -0700220
Melody Hsub9578222023-10-02 23:09:36 +0000221 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
222 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
223 ISurfaceComposerClient::eFXSurfaceBufferState,
224 /*parent*/ nullptr);
225
226 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
227 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
228 .show(mRootSurfaceControl)
229 .apply();
230
Valerie Hauda3446e2019-10-14 15:49:22 -0700231 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
232 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
233 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000234 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700235
Alec Mouribae67862024-08-06 14:53:46 +0000236 mCaptureArgs.captureArgs.sourceCrop =
237 gui::aidl_utils::toARect(mDisplayWidth, mDisplayHeight);
Melody Hsub9578222023-10-02 23:09:36 +0000238 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700239 }
240
chaviwd7deef72021-10-06 11:53:40 -0500241 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
242 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800243 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500244 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800245 }
246
chaviwd7deef72021-10-06 11:53:40 -0500247 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800248 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500249 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800250 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500251 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800252 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500253 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800254 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800255 }
256
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800257 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
258 uint8_t b) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000259 for (int32_t row = rect.top; row < rect.bottom; row++) {
260 for (int32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700261 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
262 *pixel = r;
263 *(pixel + 1) = g;
264 *(pixel + 2) = b;
265 *(pixel + 3) = 255;
266 }
267 }
268 }
269
Valerie Hau5977fc82019-12-05 15:56:39 -0800270 void fillQuadrants(sp<GraphicBuffer>& buf) {
271 const auto bufWidth = buf->getWidth();
272 const auto bufHeight = buf->getHeight();
273 uint32_t* bufData;
274 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
275 reinterpret_cast<void**>(&bufData));
276 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
277 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
278 0, 0);
279 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
280 buf->getStride(), 0, 255, 0);
281 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
282 255);
283 buf->unlock();
284 }
285
286 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
287 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700288 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800289 const auto epsilon = 3;
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000290 const int32_t width = static_cast<int32_t>(captureBuf->getWidth());
291 const int32_t height = static_cast<int32_t>(captureBuf->getHeight());
chaviwd2432892020-07-24 17:42:39 -0700292 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700293
294 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700295 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
296 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700297
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000298 for (int32_t row = 0; row < height; row++) {
299 for (int32_t col = 0; col < width; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700300 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800301 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800302 bool inRegion;
303 if (!outsideRegion) {
304 inRegion = row >= region.top + border && row < region.bottom - border &&
305 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800306 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800307 inRegion = row >= region.top - border && row < region.bottom + border &&
308 col >= region.left - border && col < region.right + border;
309 }
310 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000311 ASSERT_GE(epsilon, abs(r - *(pixel)));
312 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
313 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800314 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000315 ASSERT_GE(epsilon, abs(r - *(pixel)));
316 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
317 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800318 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800319 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700320 }
321 }
chaviwd2432892020-07-24 17:42:39 -0700322 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700323 }
324
Vishnu Nair277142c2021-01-05 18:35:29 -0800325 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
326 nsecs_t presentTimeDelay) {
327 int slot;
328 sp<Fence> fence;
329 sp<GraphicBuffer> buf;
330 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
331 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
332 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500333 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800334 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
335
336 uint32_t* bufData;
337 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
338 reinterpret_cast<void**>(&bufData));
339 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
340 buf->unlock();
341
342 IGraphicBufferProducer::QueueBufferOutput qbOutput;
343 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
344 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
345 Rect(mDisplayWidth, mDisplayHeight / 2),
346 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
347 Fence::NO_FENCE);
348 igbp->queueBuffer(slot, input, &qbOutput);
349 }
350
Valerie Hauc5011f92019-10-11 09:52:07 -0700351 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700352 sp<ISurfaceComposer> mComposer;
353
354 sp<IBinder> mDisplayToken;
355
Valerie Hauc5011f92019-10-11 09:52:07 -0700356 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000357 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700358
359 uint32_t mDisplayWidth;
360 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700361
Melody Hsub9578222023-10-02 23:09:36 +0000362 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700363 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500364 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700365};
366
367TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
368 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700369 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700370 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000371 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth), adapter.getWidth());
372 ASSERT_EQ(static_cast<int32_t>(mDisplayHeight), adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000373 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700374}
375
376TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700377 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700378 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700379 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
Melody Hsub9578222023-10-02 23:09:36 +0000380 PIXEL_FORMAT_RGBA_8888,
381 ISurfaceComposerClient::eFXSurfaceBufferState,
382 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700383 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700384 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800385 sp<IGraphicBufferProducer> igbProducer;
386 setUpProducer(adapter, igbProducer);
387
388 int32_t width;
389 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000390 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth) / 2, width);
Vishnu Nairea0de002020-11-17 17:42:37 -0800391 int32_t height;
392 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000393 ASSERT_EQ(static_cast<int32_t>(mDisplayHeight) / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700394}
395
Tianhao Yao4861b102022-02-03 20:18:35 +0000396TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700397 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000398 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
399 auto callback = [](Transaction*) {};
400 adapter.syncNextTransaction(callback);
401 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700402}
Valerie Hauda3446e2019-10-14 15:49:22 -0700403
Valerie Haubf29e042020-02-06 11:40:38 -0800404TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800405 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
406 sp<IGraphicBufferProducer> igbProducer;
407 setUpProducer(adapter, igbProducer);
408
409 int slot;
410 sp<Fence> fence;
411 sp<GraphicBuffer> buf;
412 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
413 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
414 nullptr, nullptr);
415 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
416 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
417
418 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
419 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800420 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
421 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800422 Rect(mDisplayWidth, mDisplayHeight),
423 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
424 Fence::NO_FENCE);
425 igbProducer->queueBuffer(slot, input, &qbOutput);
426 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
427
428 adapter.waitForCallbacks();
429 ASSERT_GE(systemTime(), desiredPresentTime);
430}
431
Valerie Hauda3446e2019-10-14 15:49:22 -0700432TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
433 uint8_t r = 255;
434 uint8_t g = 0;
435 uint8_t b = 0;
436
437 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800438 sp<IGraphicBufferProducer> igbProducer;
439 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700440
441 int slot;
442 sp<Fence> fence;
443 sp<GraphicBuffer> buf;
444 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
445 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
446 nullptr, nullptr);
447 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
448 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
449
450 uint32_t* bufData;
451 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
452 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800453 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700454 buf->unlock();
455
Valerie Haud3b90d22019-11-06 09:37:31 -0800456 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800457 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
458 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700459 Rect(mDisplayWidth, mDisplayHeight),
460 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
461 Fence::NO_FENCE);
462 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800463 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700464
Patrick Williams0eb09c62023-07-28 11:24:35 -0500465 // ensure the buffer queue transaction has been committed
466 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700467
468 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000469 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800470 ASSERT_NO_FATAL_FAILURE(
471 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700472}
Valerie Haud3b90d22019-11-06 09:37:31 -0800473
474TEST_F(BLASTBufferQueueTest, TripleBuffering) {
475 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
476 sp<IGraphicBufferProducer> igbProducer;
477 setUpProducer(adapter, igbProducer);
478
479 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700480 int minUndequeuedBuffers = 0;
481 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
482 const auto bufferCount = minUndequeuedBuffers + 2;
483
484 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800485 int slot;
486 sp<Fence> fence;
487 sp<GraphicBuffer> buf;
488 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
489 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
490 nullptr, nullptr);
491 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
492 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
493 allocated.push_back({slot, fence});
494 }
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700495 for (size_t i = 0; i < allocated.size(); i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800496 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
497 }
498
Valerie Haua32c5522019-12-09 10:11:08 -0800499 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800500 int slot;
501 sp<Fence> fence;
502 sp<GraphicBuffer> buf;
503 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
504 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
505 nullptr, nullptr);
506 ASSERT_EQ(NO_ERROR, ret);
507 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800508 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
509 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800510 Rect(mDisplayWidth, mDisplayHeight),
511 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
512 Fence::NO_FENCE);
513 igbProducer->queueBuffer(slot, input, &qbOutput);
514 }
515 adapter.waitForCallbacks();
516}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800517
Vishnu Nairaf15fab2024-07-30 08:59:26 -0700518class WaitForCommittedCallback {
519public:
520 WaitForCommittedCallback() = default;
521 ~WaitForCommittedCallback() = default;
522
523 void wait() {
524 std::unique_lock lock(mMutex);
525 cv.wait(lock, [this] { return mCallbackReceived; });
526 }
527
528 void notify() {
529 std::unique_lock lock(mMutex);
530 mCallbackReceived = true;
531 cv.notify_one();
532 mCallbackReceivedTimeStamp = std::chrono::system_clock::now();
533 }
534 auto getCallback() {
535 return [this](void* /* unused context */, nsecs_t /* latchTime */,
536 const sp<Fence>& /* presentFence */,
537 const std::vector<SurfaceControlStats>& /* stats */) { notify(); };
538 }
539 std::chrono::time_point<std::chrono::system_clock> mCallbackReceivedTimeStamp;
540
541private:
542 std::mutex mMutex;
543 std::condition_variable cv;
544 bool mCallbackReceived = false;
545};
546
547TEST_F(BLASTBufferQueueTest, setApplyToken) {
548 sp<IBinder> applyToken = sp<BBinder>::make();
549 WaitForCommittedCallback firstTransaction;
550 WaitForCommittedCallback secondTransaction;
551 {
552 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
553 adapter.setApplyToken(applyToken);
554 sp<IGraphicBufferProducer> igbProducer;
555 setUpProducer(adapter, igbProducer);
556
557 Transaction t;
558 t.addTransactionCommittedCallback(firstTransaction.getCallback(), nullptr);
559 adapter.mergeWithNextTransaction(&t, 1);
560 queueBuffer(igbProducer, 127, 127, 127,
561 /*presentTimeDelay*/ std::chrono::nanoseconds(500ms).count());
562 }
563 {
564 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
565 adapter.setApplyToken(applyToken);
566 sp<IGraphicBufferProducer> igbProducer;
567 setUpProducer(adapter, igbProducer);
568
569 Transaction t;
570 t.addTransactionCommittedCallback(secondTransaction.getCallback(), nullptr);
571 adapter.mergeWithNextTransaction(&t, 1);
572 queueBuffer(igbProducer, 127, 127, 127, /*presentTimeDelay*/ 0);
573 }
574
575 firstTransaction.wait();
576 secondTransaction.wait();
577 EXPECT_GT(secondTransaction.mCallbackReceivedTimeStamp,
578 firstTransaction.mCallbackReceivedTimeStamp);
579}
580
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800581TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
582 uint8_t r = 255;
583 uint8_t g = 0;
584 uint8_t b = 0;
585
586 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
587 sp<IGraphicBufferProducer> igbProducer;
588 setUpProducer(adapter, igbProducer);
589 int slot;
590 sp<Fence> fence;
591 sp<GraphicBuffer> buf;
592 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
593 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
594 nullptr, nullptr);
595 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
596 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
597
598 uint32_t* bufData;
599 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
600 reinterpret_cast<void**>(&bufData));
601 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
602 buf->unlock();
603
604 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800605 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
606 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800607 Rect(mDisplayWidth, mDisplayHeight / 2),
608 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
609 Fence::NO_FENCE);
610 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800611 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800612
Patrick Williams0eb09c62023-07-28 11:24:35 -0500613 // ensure the buffer queue transaction has been committed
614 Transaction().apply(true /* synchronous */);
615
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800616 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000617 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700618
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800619 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000620 checkScreenCapture(r, g, b,
621 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800622}
623
624TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
625 uint8_t r = 255;
626 uint8_t g = 0;
627 uint8_t b = 0;
628
629 int32_t bufferSideLength =
630 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
631 int32_t finalCropSideLength = bufferSideLength / 2;
632
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800633 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
634 sp<IGraphicBufferProducer> igbProducer;
635 setUpProducer(adapter, igbProducer);
636 int slot;
637 sp<Fence> fence;
638 sp<GraphicBuffer> buf;
639 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
640 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
641 nullptr, nullptr);
642 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
643 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
644
645 uint32_t* bufData;
646 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
647 reinterpret_cast<void**>(&bufData));
648 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
649 fillBuffer(bufData,
650 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
651 buf->getHeight()),
652 buf->getStride(), r, g, b);
653 buf->unlock();
654
655 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800656 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
657 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800658 Rect(bufferSideLength, finalCropSideLength),
659 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
660 Fence::NO_FENCE);
661 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800662 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800663
Patrick Williams0eb09c62023-07-28 11:24:35 -0500664 // ensure the buffer queue transaction has been committed
665 Transaction().apply(true /* synchronous */);
666
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800667 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000668 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700669 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
670 {10, 10, (int32_t)bufferSideLength - 10,
671 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800672 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700673 checkScreenCapture(0, 0, 0,
674 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
675 /*border*/ 0, /*outsideRegion*/ true));
676}
677
678TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700679 Rect windowSize(1000, 1000);
680 Rect bufferSize(windowSize);
681 Rect bufferCrop(200, 200, 700, 700);
682
683 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
684 sp<IGraphicBufferProducer> igbProducer;
685 setUpProducer(adapter, igbProducer);
686 int slot;
687 sp<Fence> fence;
688 sp<GraphicBuffer> buf;
689 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
690 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
691 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
692 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
693 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
694
695 uint32_t* bufData;
696 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
697 reinterpret_cast<void**>(&bufData));
698 // fill buffer with grey
699 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
700
701 // fill crop area with different colors so we can verify the cropped region has been scaled
702 // correctly.
703 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
704 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
705 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
706 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
707 buf->unlock();
708
709 IGraphicBufferProducer::QueueBufferOutput qbOutput;
710 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
711 HAL_DATASPACE_UNKNOWN,
712 bufferCrop /* Rect::INVALID_RECT */,
713 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
714 Fence::NO_FENCE);
715 igbProducer->queueBuffer(slot, input, &qbOutput);
716 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
717
Patrick Williams0eb09c62023-07-28 11:24:35 -0500718 // ensure the buffer queue transaction has been committed
719 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700720
Melody Hsub9578222023-10-02 23:09:36 +0000721 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700722
723 // Verify cropped region is scaled correctly.
724 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
725 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
726 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
727 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
728 // Verify outside region is black.
729 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
730 {0, 0, (int32_t)windowSize.getWidth(),
731 (int32_t)windowSize.getHeight()},
732 /*border*/ 0, /*outsideRegion*/ true));
733}
734
735TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700736 Rect windowSize(1000, 1000);
737 Rect bufferSize(500, 500);
738 Rect bufferCrop(100, 100, 350, 350);
739
740 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
741 sp<IGraphicBufferProducer> igbProducer;
742 setUpProducer(adapter, igbProducer);
743 int slot;
744 sp<Fence> fence;
745 sp<GraphicBuffer> buf;
746 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
747 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
748 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
749 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
750 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
751
752 uint32_t* bufData;
753 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
754 reinterpret_cast<void**>(&bufData));
755 // fill buffer with grey
756 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
757
758 // fill crop area with different colors so we can verify the cropped region has been scaled
759 // correctly.
760 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
761 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
762 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
763 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
764 buf->unlock();
765
766 IGraphicBufferProducer::QueueBufferOutput qbOutput;
767 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
768 HAL_DATASPACE_UNKNOWN,
769 bufferCrop /* Rect::INVALID_RECT */,
770 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
771 Fence::NO_FENCE);
772 igbProducer->queueBuffer(slot, input, &qbOutput);
773 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
774
Patrick Williams0eb09c62023-07-28 11:24:35 -0500775 // ensure the buffer queue transaction has been committed
776 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700777
Melody Hsub9578222023-10-02 23:09:36 +0000778 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700779 // Verify cropped region is scaled correctly.
780 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
781 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
782 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
783 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
784 // Verify outside region is black.
785 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
786 {0, 0, (int32_t)windowSize.getWidth(),
787 (int32_t)windowSize.getHeight()},
788 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800789}
790
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700791// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
792// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
793TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
794 uint8_t r = 255;
795 uint8_t g = 0;
796 uint8_t b = 0;
797
798 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
799 sp<IGraphicBufferProducer> igbProducer;
800 setUpProducer(adapter, igbProducer);
801 {
802 int slot;
803 sp<Fence> fence;
804 sp<GraphicBuffer> buf;
805 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
806 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
807 nullptr, nullptr);
808 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
809 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
810
811 uint32_t* bufData;
812 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
813 reinterpret_cast<void**>(&bufData));
814 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
815 buf->unlock();
816
817 IGraphicBufferProducer::QueueBufferOutput qbOutput;
818 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
819 HAL_DATASPACE_UNKNOWN, {},
820 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
821 Fence::NO_FENCE);
822 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500823
824 // ensure the buffer queue transaction has been committed
825 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700826 }
827 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000828 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700829
830 ASSERT_NO_FATAL_FAILURE(
831 checkScreenCapture(r, g, b,
832 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
833
834 // update the size to half the display and dequeue a buffer quarter of the display.
835 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
836
837 {
838 int slot;
839 sp<Fence> fence;
840 sp<GraphicBuffer> buf;
841 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
842 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
843 nullptr, nullptr);
844 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
845 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
846
847 uint32_t* bufData;
848 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
849 reinterpret_cast<void**>(&bufData));
850 g = 255;
851 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
852 buf->unlock();
853
854 IGraphicBufferProducer::QueueBufferOutput qbOutput;
855 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
856 HAL_DATASPACE_UNKNOWN, {},
857 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
858 0, Fence::NO_FENCE);
859 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500860 // ensure the buffer queue transaction has been committed
861 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700862 }
863 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000864 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700865 // verify we still scale the buffer to the new size (half the screen height)
866 ASSERT_NO_FATAL_FAILURE(
867 checkScreenCapture(r, g, b,
868 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
869}
870
chaviwd7deef72021-10-06 11:53:40 -0500871TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
872 uint8_t r = 255;
873 uint8_t g = 0;
874 uint8_t b = 0;
875
876 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
877
878 sp<IGraphicBufferProducer> igbProducer;
879 setUpProducer(adapter, igbProducer);
880
chaviwa1c4c822021-11-10 18:11:58 -0600881 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000882 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500883 queueBuffer(igbProducer, 0, 255, 0, 0);
884
885 // queue non sync buffer, so this one should get blocked
886 // Add a present delay to allow the first screenshot to get taken.
887 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
888 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
889
890 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600891 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500892 transactionCallback.getContext())
893 .apply();
894
895 CallbackData callbackData;
896 transactionCallback.getCallbackData(&callbackData);
897
chaviw0acd33a2021-11-02 11:55:37 -0500898 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000899 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500900 ASSERT_NO_FATAL_FAILURE(
901 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
902
903 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000904 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500905 ASSERT_NO_FATAL_FAILURE(
906 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
907}
908
909TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
910 uint8_t r = 255;
911 uint8_t g = 0;
912 uint8_t b = 0;
913
914 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
915
916 sp<IGraphicBufferProducer> igbProducer;
917 setUpProducer(adapter, igbProducer);
918
919 Transaction mainTransaction;
920
chaviwa1c4c822021-11-10 18:11:58 -0600921 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000922 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500923 queueBuffer(igbProducer, 0, 255, 0, 0);
924
chaviwa1c4c822021-11-10 18:11:58 -0600925 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500926
Tianhao Yao4861b102022-02-03 20:18:35 +0000927 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500928 queueBuffer(igbProducer, r, g, b, 0);
929
chaviwa1c4c822021-11-10 18:11:58 -0600930 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500931 // Expect 1 buffer to be released even before sending to SurfaceFlinger
932 mProducerListener->waitOnNumberReleased(1);
933
934 CallbackHelper transactionCallback;
935 mainTransaction
936 .addTransactionCompletedCallback(transactionCallback.function,
937 transactionCallback.getContext())
938 .apply();
939
940 CallbackData callbackData;
941 transactionCallback.getCallbackData(&callbackData);
942
943 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000944 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500945 ASSERT_NO_FATAL_FAILURE(
946 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
947}
948
949TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
950 uint8_t r = 255;
951 uint8_t g = 0;
952 uint8_t b = 0;
953
954 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
955
956 sp<IGraphicBufferProducer> igbProducer;
957 setUpProducer(adapter, igbProducer);
958
959 Transaction mainTransaction;
960
chaviwa1c4c822021-11-10 18:11:58 -0600961 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500962 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000963 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500964 queueBuffer(igbProducer, 0, 255, 0, 0);
965
chaviwa1c4c822021-11-10 18:11:58 -0600966 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500967
chaviwa1c4c822021-11-10 18:11:58 -0600968 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500969 queueBuffer(igbProducer, 0, 0, 255, 0);
970
971 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000972 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500973 queueBuffer(igbProducer, r, g, b, 0);
974 // Expect 1 buffer to be released because the non sync transaction should merge
975 // with the sync
976 mProducerListener->waitOnNumberReleased(1);
977
chaviwa1c4c822021-11-10 18:11:58 -0600978 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500979 // Expect 2 buffers to be released due to merging the two syncs.
980 mProducerListener->waitOnNumberReleased(2);
981
982 CallbackHelper transactionCallback;
983 mainTransaction
984 .addTransactionCompletedCallback(transactionCallback.function,
985 transactionCallback.getContext())
986 .apply();
987
988 CallbackData callbackData;
989 transactionCallback.getCallbackData(&callbackData);
990
991 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000992 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500993 ASSERT_NO_FATAL_FAILURE(
994 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
995}
996
997TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
998 uint8_t r = 255;
999 uint8_t g = 0;
1000 uint8_t b = 0;
1001
1002 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1003
1004 sp<IGraphicBufferProducer> igbProducer;
1005 setUpProducer(adapter, igbProducer, 3);
1006
1007 Transaction mainTransaction;
1008
chaviwa1c4c822021-11-10 18:11:58 -06001009 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001010 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001011 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001012 queueBuffer(igbProducer, 0, 255, 0, 0);
1013
chaviwa1c4c822021-11-10 18:11:58 -06001014 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001015
chaviwa1c4c822021-11-10 18:11:58 -06001016 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001017 queueBuffer(igbProducer, 0, 0, 255, 0);
1018 queueBuffer(igbProducer, 0, 0, 255, 0);
1019 queueBuffer(igbProducer, 0, 0, 255, 0);
1020
1021 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001022 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001023 queueBuffer(igbProducer, r, g, b, 0);
1024 // Expect 3 buffers to be released because the non sync transactions should merge
1025 // with the sync
1026 mProducerListener->waitOnNumberReleased(3);
1027
chaviwa1c4c822021-11-10 18:11:58 -06001028 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001029 // Expect 4 buffers to be released due to merging the two syncs.
1030 mProducerListener->waitOnNumberReleased(4);
1031
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
Melody Hsub9578222023-10-02 23:09:36 +00001042 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001043 ASSERT_NO_FATAL_FAILURE(
1044 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1045}
1046
1047// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
1048// continue processing is for a release callback from SurfaceFlinger.
1049// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
1050// continue acquiring buffers.
1051TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
1052 uint8_t r = 255;
1053 uint8_t g = 0;
1054 uint8_t b = 0;
1055
1056 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1057
1058 sp<IGraphicBufferProducer> igbProducer;
1059 setUpProducer(adapter, igbProducer, 4);
1060
1061 Transaction mainTransaction;
1062
1063 // Send a buffer to SF
1064 queueBuffer(igbProducer, 0, 255, 0, 0);
1065
chaviwa1c4c822021-11-10 18:11:58 -06001066 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001067 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001068 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001069 queueBuffer(igbProducer, 0, 255, 0, 0);
1070
chaviwa1c4c822021-11-10 18:11:58 -06001071 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001072
chaviwa1c4c822021-11-10 18:11:58 -06001073 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001074 queueBuffer(igbProducer, 0, 0, 255, 0);
1075 queueBuffer(igbProducer, 0, 0, 255, 0);
1076 queueBuffer(igbProducer, 0, 0, 255, 0);
1077
1078 // apply the first synced buffer to ensure we have to wait on SF
1079 mainTransaction.apply();
1080
1081 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001082 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001083 queueBuffer(igbProducer, r, g, b, 0);
1084 // Expect 2 buffers to be released because the non sync transactions should merge
1085 // with the sync
1086 mProducerListener->waitOnNumberReleased(3);
1087
chaviwa1c4c822021-11-10 18:11:58 -06001088 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001089
1090 CallbackHelper transactionCallback;
1091 mainTransaction
1092 .addTransactionCompletedCallback(transactionCallback.function,
1093 transactionCallback.getContext())
1094 .apply();
1095
1096 CallbackData callbackData;
1097 transactionCallback.getCallbackData(&callbackData);
1098
1099 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001100 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001101 ASSERT_NO_FATAL_FAILURE(
1102 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1103}
1104
Tianhao Yao4861b102022-02-03 20:18:35 +00001105TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001106 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1107
1108 sp<IGraphicBufferProducer> igbProducer;
1109 setUpProducer(adapter, igbProducer);
1110
1111 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001112 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001113 queueBuffer(igbProducer, 0, 255, 0, 0);
1114 queueBuffer(igbProducer, 0, 0, 255, 0);
1115 // There should only be one frame submitted since the first frame will be released.
1116 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001117 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001118
1119 // queue non sync buffer, so this one should get blocked
1120 // Add a present delay to allow the first screenshot to get taken.
1121 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1122 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1123
1124 CallbackHelper transactionCallback;
1125 next.addTransactionCompletedCallback(transactionCallback.function,
1126 transactionCallback.getContext())
1127 .apply();
1128
1129 CallbackData callbackData;
1130 transactionCallback.getCallbackData(&callbackData);
1131
1132 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001133 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001134 ASSERT_NO_FATAL_FAILURE(
1135 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1136
1137 mProducerListener->waitOnNumberReleased(2);
1138 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001139 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001140 ASSERT_NO_FATAL_FAILURE(
1141 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1142}
1143
chaviw3b4bdcf2022-03-17 09:27:03 -05001144TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1145 std::mutex mutex;
1146 std::condition_variable callbackReceivedCv;
1147 bool receivedCallback = false;
1148
1149 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1150 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1151 auto callback = [&](Transaction*) {
1152 std::unique_lock<std::mutex> lock(mutex);
1153 receivedCallback = true;
1154 callbackReceivedCv.notify_one();
1155 };
1156 adapter.syncNextTransaction(callback);
1157 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1158
1159 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001160 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1161
1162 sp<IGraphicBufferProducer> igbProducer;
1163 setUpProducer(adapter, igbProducer);
1164 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001165
1166 std::unique_lock<std::mutex> lock(mutex);
1167 if (!receivedCallback) {
1168 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1169 std::cv_status::timeout)
1170 << "did not receive callback";
1171 }
1172
1173 ASSERT_TRUE(receivedCallback);
1174}
1175
Chavi Weingartenc398c012023-04-12 17:26:02 +00001176TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1177 std::mutex mutex;
1178 std::condition_variable callbackReceivedCv;
1179 bool receivedCallback = false;
1180
1181 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1182 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1183 auto callback = [&](Transaction*) {
1184 std::unique_lock<std::mutex> lock(mutex);
1185 receivedCallback = true;
1186 callbackReceivedCv.notify_one();
1187 };
1188 adapter.syncNextTransaction(callback);
1189 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1190
1191 adapter.clearSyncTransaction();
1192
1193 sp<IGraphicBufferProducer> igbProducer;
1194 setUpProducer(adapter, igbProducer);
1195 queueBuffer(igbProducer, 0, 255, 0, 0);
1196
1197 std::unique_lock<std::mutex> lock(mutex);
1198 if (!receivedCallback) {
1199 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1200 std::cv_status::timeout)
1201 << "did not receive callback";
1202 }
1203
1204 ASSERT_FALSE(receivedCallback);
1205}
1206
chaviwc1cf4022022-06-03 13:32:33 -05001207TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1208 uint8_t r = 255;
1209 uint8_t g = 0;
1210 uint8_t b = 0;
1211
1212 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1213
1214 sp<IGraphicBufferProducer> igbProducer;
1215 setUpProducer(adapter, igbProducer);
1216
1217 Transaction sync;
1218 adapter.setSyncTransaction(sync);
1219 queueBuffer(igbProducer, 0, 255, 0, 0);
1220
1221 // Merge a transaction that has a complete callback into the next frame so we can get notified
1222 // when to take a screenshot
1223 CallbackHelper transactionCallback;
1224 Transaction t;
1225 t.addTransactionCompletedCallback(transactionCallback.function,
1226 transactionCallback.getContext());
1227 adapter.mergeWithNextTransaction(&t, 2);
1228 queueBuffer(igbProducer, r, g, b, 0);
1229
1230 // Drop the buffer, but ensure the next one continues to get processed.
1231 sync.setBuffer(mSurfaceControl, nullptr);
1232
1233 CallbackData callbackData;
1234 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001235 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001236 ASSERT_NO_FATAL_FAILURE(
1237 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001238 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001239}
1240
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001241// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1242// until the old surface control is destroyed. This is not necessarily a bug but to document a
1243// limitation with the update API and to test any changes to make the api more robust. The current
1244// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1245TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1246 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1247 std::vector<sp<SurfaceControl>> surfaceControls;
1248 sp<IGraphicBufferProducer> igbProducer;
1249 for (int i = 0; i < 10; i++) {
1250 sp<SurfaceControl> sc =
1251 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1252 PIXEL_FORMAT_RGBA_8888,
1253 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001254 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001255 Transaction()
1256 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1257 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1258 .show(mSurfaceControl)
1259 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1260 .apply(true);
1261 surfaceControls.push_back(sc);
1262 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1263
1264 setUpProducer(adapter, igbProducer);
1265 Transaction next;
1266 queueBuffer(igbProducer, 0, 255, 0, 0);
1267 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001268 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001269 queueBuffer(igbProducer, 255, 0, 0, 0);
1270
1271 CallbackHelper transactionCallback;
1272 next.addTransactionCompletedCallback(transactionCallback.function,
1273 transactionCallback.getContext())
1274 .apply();
1275
1276 CallbackData callbackData;
1277 transactionCallback.getCallbackData(&callbackData);
1278 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001279 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001280 ASSERT_NO_FATAL_FAILURE(
1281 checkScreenCapture(255, 0, 0,
1282 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1283 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1284 }
1285}
1286
1287// See DISABLED_DisconnectProducerTest
1288TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1289 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1290 std::vector<sp<SurfaceControl>> surfaceControls;
1291 sp<IGraphicBufferProducer> igbProducer;
1292 for (int i = 0; i < 10; i++) {
1293 sp<SurfaceControl> sc =
1294 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1295 PIXEL_FORMAT_RGBA_8888,
1296 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001297 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001298 Transaction()
1299 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1300 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1301 .show(mSurfaceControl)
1302 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1303 .apply(true);
1304 surfaceControls.push_back(sc);
1305 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1306 setUpProducer(adapter, igbProducer);
1307
1308 Transaction next;
1309 queueBuffer(igbProducer, 0, 255, 0, 0);
1310 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001311 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001312 queueBuffer(igbProducer, 255, 0, 0, 0);
1313
1314 CallbackHelper transactionCallback;
1315 next.addTransactionCompletedCallback(transactionCallback.function,
1316 transactionCallback.getContext())
1317 .apply();
1318
1319 CallbackData callbackData;
1320 transactionCallback.getCallbackData(&callbackData);
1321 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001322 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001323 ASSERT_NO_FATAL_FAILURE(
1324 checkScreenCapture(255, 0, 0,
1325 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1326 }
1327}
1328
Vishnu Nair89496122020-12-14 17:14:53 -08001329class TestProducerListener : public BnProducerListener {
1330public:
1331 sp<IGraphicBufferProducer> mIgbp;
1332 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1333 void onBufferReleased() override {
1334 sp<GraphicBuffer> buffer;
1335 sp<Fence> fence;
1336 mIgbp->detachNextBuffer(&buffer, &fence);
1337 }
1338};
1339
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001340class TestSurfaceListener : public SurfaceListener {
1341public:
1342 sp<IGraphicBufferProducer> mIgbp;
1343 TestSurfaceListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1344 void onBufferReleased() override {
1345 sp<GraphicBuffer> buffer;
1346 sp<Fence> fence;
1347 mIgbp->detachNextBuffer(&buffer, &fence);
1348 }
1349 bool needsReleaseNotify() override { return true; }
1350 void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
1351 void onBufferDetached(int /*slot*/) {}
1352};
1353
Vishnu Nair89496122020-12-14 17:14:53 -08001354TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1355 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1356 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1357 ASSERT_NE(nullptr, igbProducer.get());
1358 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1359 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1360 ASSERT_EQ(NO_ERROR,
1361 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1362 false, &qbOutput));
1363 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1364 for (int i = 0; i < 3; i++) {
1365 int slot;
1366 sp<Fence> fence;
1367 sp<GraphicBuffer> buf;
1368 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1369 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1370 nullptr, nullptr);
1371 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1372 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1373 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001374 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1375 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001376 Rect(mDisplayWidth, mDisplayHeight),
1377 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1378 Fence::NO_FENCE);
1379 igbProducer->queueBuffer(slot, input, &qbOutput);
1380 }
1381 adapter.waitForCallbacks();
1382}
1383
Vishnu Nair17dde612020-12-28 11:39:59 -08001384TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1385 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1386
1387 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1388 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1389 int queuesToNativeWindow = 0;
1390 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1391 &queuesToNativeWindow);
1392 ASSERT_EQ(NO_ERROR, err);
1393 ASSERT_EQ(queuesToNativeWindow, 1);
1394}
1395
Vishnu Naira4fbca52021-07-07 16:52:34 -07001396TEST_F(BLASTBufferQueueTest, TransformHint) {
1397 // Transform hint is provided to BBQ via the surface control passed by WM
1398 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1399
1400 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1401 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1402 ASSERT_NE(nullptr, igbProducer.get());
1403 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1404 sp<Surface> surface = adapter.getSurface();
1405
1406 // Before connecting to the surface, we do not get a valid transform hint
1407 int transformHint;
1408 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001409 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001410
1411 ASSERT_EQ(NO_ERROR,
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001412 surface->connect(NATIVE_WINDOW_API_CPU, new TestSurfaceListener(igbProducer)));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001413
1414 // After connecting to the surface, we should get the correct hint.
1415 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001416 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001417
1418 ANativeWindow_Buffer buffer;
1419 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1420
1421 // Transform hint is updated via callbacks or surface control updates
1422 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1423 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1424
1425 // The hint does not change and matches the value used when dequeueing the buffer.
1426 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001427 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001428
1429 surface->unlockAndPost();
1430
1431 // After queuing the buffer, we get the updated transform hint
1432 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001433 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001434
1435 adapter.waitForCallbacks();
1436}
1437
Valerie Hau5977fc82019-12-05 15:56:39 -08001438class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1439public:
1440 void test(uint32_t tr) {
1441 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1442 sp<IGraphicBufferProducer> igbProducer;
1443 setUpProducer(adapter, igbProducer);
1444
1445 auto bufWidth = mDisplayWidth;
1446 auto bufHeight = mDisplayHeight;
1447 int slot;
1448 sp<Fence> fence;
1449 sp<GraphicBuffer> buf;
1450
1451 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1452 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1453 nullptr, nullptr);
1454 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1455 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1456
1457 fillQuadrants(buf);
1458
1459 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001460 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1461 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001462 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001463 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1464 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001465 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001466 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001467
Patrick Williams0eb09c62023-07-28 11:24:35 -05001468 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001469 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001470
Valerie Hau5977fc82019-12-05 15:56:39 -08001471 switch (tr) {
1472 case ui::Transform::ROT_0:
1473 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1474 {0, 0, (int32_t)mDisplayWidth / 2,
1475 (int32_t)mDisplayHeight / 2},
1476 1));
1477 ASSERT_NO_FATAL_FAILURE(
1478 checkScreenCapture(255, 0, 0,
1479 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1480 (int32_t)mDisplayHeight / 2},
1481 1));
1482 ASSERT_NO_FATAL_FAILURE(
1483 checkScreenCapture(0, 255, 0,
1484 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1485 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1486 1));
1487 ASSERT_NO_FATAL_FAILURE(
1488 checkScreenCapture(0, 0, 255,
1489 {0, (int32_t)mDisplayHeight / 2,
1490 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1491 1));
1492 break;
1493 case ui::Transform::FLIP_H:
1494 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1495 {0, 0, (int32_t)mDisplayWidth / 2,
1496 (int32_t)mDisplayHeight / 2},
1497 1));
1498 ASSERT_NO_FATAL_FAILURE(
1499 checkScreenCapture(0, 0, 0,
1500 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1501 (int32_t)mDisplayHeight / 2},
1502 1));
1503 ASSERT_NO_FATAL_FAILURE(
1504 checkScreenCapture(0, 0, 255,
1505 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1506 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1507 1));
1508 ASSERT_NO_FATAL_FAILURE(
1509 checkScreenCapture(0, 255, 0,
1510 {0, (int32_t)mDisplayHeight / 2,
1511 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1512 1));
1513 break;
1514 case ui::Transform::FLIP_V:
1515 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1516 {0, 0, (int32_t)mDisplayWidth / 2,
1517 (int32_t)mDisplayHeight / 2},
1518 1));
1519 ASSERT_NO_FATAL_FAILURE(
1520 checkScreenCapture(0, 255, 0,
1521 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1522 (int32_t)mDisplayHeight / 2},
1523 1));
1524 ASSERT_NO_FATAL_FAILURE(
1525 checkScreenCapture(255, 0, 0,
1526 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1527 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1528 1));
1529 ASSERT_NO_FATAL_FAILURE(
1530 checkScreenCapture(0, 0, 0,
1531 {0, (int32_t)mDisplayHeight / 2,
1532 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1533 1));
1534 break;
1535 case ui::Transform::ROT_90:
1536 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1537 {0, 0, (int32_t)mDisplayWidth / 2,
1538 (int32_t)mDisplayHeight / 2},
1539 1));
1540 ASSERT_NO_FATAL_FAILURE(
1541 checkScreenCapture(0, 0, 0,
1542 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1543 (int32_t)mDisplayHeight / 2},
1544 1));
1545 ASSERT_NO_FATAL_FAILURE(
1546 checkScreenCapture(255, 0, 0,
1547 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1548 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1549 1));
1550 ASSERT_NO_FATAL_FAILURE(
1551 checkScreenCapture(0, 255, 0,
1552 {0, (int32_t)mDisplayHeight / 2,
1553 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1554 1));
1555 break;
1556 case ui::Transform::ROT_180:
1557 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1558 {0, 0, (int32_t)mDisplayWidth / 2,
1559 (int32_t)mDisplayHeight / 2},
1560 1));
1561 ASSERT_NO_FATAL_FAILURE(
1562 checkScreenCapture(0, 0, 255,
1563 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1564 (int32_t)mDisplayHeight / 2},
1565 1));
1566 ASSERT_NO_FATAL_FAILURE(
1567 checkScreenCapture(0, 0, 0,
1568 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1569 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1570 1));
1571 ASSERT_NO_FATAL_FAILURE(
1572 checkScreenCapture(255, 0, 0,
1573 {0, (int32_t)mDisplayHeight / 2,
1574 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1575 1));
1576 break;
1577 case ui::Transform::ROT_270:
1578 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1579 {0, 0, (int32_t)mDisplayWidth / 2,
1580 (int32_t)mDisplayHeight / 2},
1581 1));
1582 ASSERT_NO_FATAL_FAILURE(
1583 checkScreenCapture(0, 255, 0,
1584 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1585 (int32_t)mDisplayHeight / 2},
1586 1));
1587 ASSERT_NO_FATAL_FAILURE(
1588 checkScreenCapture(0, 0, 255,
1589 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1590 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1591 1));
1592 ASSERT_NO_FATAL_FAILURE(
1593 checkScreenCapture(0, 0, 0,
1594 {0, (int32_t)mDisplayHeight / 2,
1595 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1596 1));
1597 }
1598 }
1599};
1600
1601TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1602 test(ui::Transform::ROT_0);
1603}
1604
1605TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1606 test(ui::Transform::FLIP_H);
1607}
1608
1609TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1610 test(ui::Transform::FLIP_V);
1611}
1612
1613TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1614 test(ui::Transform::ROT_90);
1615}
1616
1617TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1618 test(ui::Transform::ROT_180);
1619}
1620
1621TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1622 test(ui::Transform::ROT_270);
1623}
Valerie Hau871d6352020-01-29 08:44:02 -08001624
1625class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1626public:
1627 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001628 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001629 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001630 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001631 int slot;
1632 sp<Fence> fence;
1633 sp<GraphicBuffer> buf;
1634 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1635 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1636 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001637 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1638 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1639 }
Valerie Hau871d6352020-01-29 08:44:02 -08001640
Vishnu Nairde66dc72021-06-17 17:54:41 -07001641 *outRequestedPresentTime = requestedPresentTime;
1642 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1643 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001644 Rect(mDisplayWidth, mDisplayHeight),
1645 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1646 Fence::NO_FENCE, /*sticky*/ 0,
1647 getFrameTimestamps);
1648 if (postedTime) *postedTime = systemTime();
1649 igbProducer->queueBuffer(slot, input, qbOutput);
1650 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001651 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001652};
1653
1654TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1655 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1656 sp<IGraphicBufferProducer> igbProducer;
1657 ProducerFrameEventHistory history;
1658 setUpProducer(adapter, igbProducer);
1659
1660 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1661 nsecs_t requestedPresentTimeA = 0;
1662 nsecs_t postedTimeA = 0;
1663 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1664 history.applyDelta(qbOutput.frameTimestamps);
1665
1666 FrameEvents* events = nullptr;
1667 events = history.getFrame(1);
1668 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001669 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001670 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1671 ASSERT_GE(events->postedTime, postedTimeA);
1672
Vishnu Nair1506b182021-02-22 14:35:15 -08001673 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001674
1675 // queue another buffer so we query for frame event deltas
1676 nsecs_t requestedPresentTimeB = 0;
1677 nsecs_t postedTimeB = 0;
1678 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1679 history.applyDelta(qbOutput.frameTimestamps);
Alec Mouri21d94322023-10-17 19:51:39 +00001680
1681 adapter.waitForCallback(2);
1682
Valerie Hau871d6352020-01-29 08:44:02 -08001683 events = history.getFrame(1);
1684 ASSERT_NE(nullptr, events);
1685
1686 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001687 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001688 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1689 ASSERT_GE(events->postedTime, postedTimeA);
1690
1691 ASSERT_GE(events->latchTime, postedTimeA);
Alec Mouri21d94322023-10-17 19:51:39 +00001692 if (flags::frametimestamps_previousrelease()) {
1693 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1694 }
Valerie Hau871d6352020-01-29 08:44:02 -08001695 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1696 ASSERT_NE(nullptr, events->displayPresentFence);
1697 ASSERT_NE(nullptr, events->releaseFence);
1698
1699 // we should also have gotten the initial values for the next frame
1700 events = history.getFrame(2);
1701 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001702 ASSERT_EQ(2u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001703 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1704 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001705
Alec Mouri21d94322023-10-17 19:51:39 +00001706 // Now do the same as above with a third buffer, so that timings related to
1707 // buffer releases make it back to the first frame.
1708 nsecs_t requestedPresentTimeC = 0;
1709 nsecs_t postedTimeC = 0;
1710 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1711 history.applyDelta(qbOutput.frameTimestamps);
1712
1713 adapter.waitForCallback(3);
1714
1715 // Check the first frame...
1716 events = history.getFrame(1);
1717 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001718 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001719 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1720 ASSERT_GE(events->postedTime, postedTimeA);
1721 ASSERT_GE(events->latchTime, postedTimeA);
1722 // Now dequeueReadyTime is valid, because the release timings finally
1723 // propaged to queueBuffer()
1724 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1725 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1726 ASSERT_NE(nullptr, events->displayPresentFence);
1727 ASSERT_NE(nullptr, events->releaseFence);
1728
1729 // ...and the second
1730 events = history.getFrame(2);
1731 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001732 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001733 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1734 ASSERT_GE(events->postedTime, postedTimeB);
1735 ASSERT_GE(events->latchTime, postedTimeB);
1736 if (flags::frametimestamps_previousrelease()) {
1737 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1738 }
1739 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1740 ASSERT_NE(nullptr, events->displayPresentFence);
1741 ASSERT_NE(nullptr, events->releaseFence);
1742
1743 // ...and finally the third!
1744 events = history.getFrame(3);
1745 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001746 ASSERT_EQ(3u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001747 ASSERT_EQ(requestedPresentTimeC, events->requestedPresentTime);
1748 ASSERT_GE(events->postedTime, postedTimeC);
1749
Valerie Hau78491e92020-04-15 13:10:56 -07001750 // wait for any callbacks that have not been received
1751 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001752}
Vishnu Nair083efd32021-02-12 09:32:30 -08001753
Vishnu Nair083efd32021-02-12 09:32:30 -08001754TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1755 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1756 sp<IGraphicBufferProducer> igbProducer;
1757 setUpProducer(adapter, igbProducer);
1758
1759 ProducerFrameEventHistory history;
1760 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1761 nsecs_t requestedPresentTimeA = 0;
1762 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001763 // Present the frame sometime in the future so we can add two frames to the queue so the older
1764 // one will be dropped.
1765 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001766 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001767 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001768 history.applyDelta(qbOutput.frameTimestamps);
1769
1770 FrameEvents* events = nullptr;
1771 events = history.getFrame(1);
1772 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001773 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001774 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1775 ASSERT_GE(events->postedTime, postedTimeA);
1776
1777 // queue another buffer so the first can be dropped
1778 nsecs_t requestedPresentTimeB = 0;
1779 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001780 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1781 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1782 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001783 history.applyDelta(qbOutput.frameTimestamps);
1784 events = history.getFrame(1);
1785 ASSERT_NE(nullptr, events);
1786
1787 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001788 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001789 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1790 ASSERT_GE(events->postedTime, postedTimeA);
1791
Vishnu Nairde66dc72021-06-17 17:54:41 -07001792 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001793 ASSERT_FALSE(events->hasLatchInfo());
1794 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001795 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1796 ASSERT_FALSE(events->hasDisplayPresentInfo());
1797 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001798
Vishnu Nairde66dc72021-06-17 17:54:41 -07001799 // wait for the last transaction to be completed.
1800 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001801
Vishnu Nairde66dc72021-06-17 17:54:41 -07001802 // queue another buffer so we query for frame event deltas
1803 nsecs_t requestedPresentTimeC = 0;
1804 nsecs_t postedTimeC = 0;
1805 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1806 history.applyDelta(qbOutput.frameTimestamps);
1807
Alec Mouri21d94322023-10-17 19:51:39 +00001808 adapter.waitForCallback(3);
1809
Vishnu Nairde66dc72021-06-17 17:54:41 -07001810 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001811 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001812 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1813 ASSERT_GE(events->postedTime, postedTimeA);
1814
1815 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1816 ASSERT_FALSE(events->hasLatchInfo());
1817 ASSERT_FALSE(events->hasDequeueReadyInfo());
1818 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1819 ASSERT_FALSE(events->hasDisplayPresentInfo());
1820 ASSERT_FALSE(events->hasReleaseInfo());
1821
1822 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001823 events = history.getFrame(2);
1824 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001825 ASSERT_EQ(2u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001826 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1827 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001828 ASSERT_GE(events->latchTime, postedTimeB);
Alec Mouri21d94322023-10-17 19:51:39 +00001829
1830 if (flags::frametimestamps_previousrelease()) {
1831 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1832 }
1833 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1834 ASSERT_NE(nullptr, events->displayPresentFence);
1835 ASSERT_NE(nullptr, events->releaseFence);
1836
1837 // Queue another buffer to check for timestamps that came late
1838 nsecs_t requestedPresentTimeD = 0;
1839 nsecs_t postedTimeD = 0;
1840 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeD, &postedTimeD, &qbOutput, true);
1841 history.applyDelta(qbOutput.frameTimestamps);
1842
1843 adapter.waitForCallback(4);
1844
1845 // frame number, requestedPresentTime, and postTime should not have changed
1846 events = history.getFrame(1);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001847 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001848 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1849 ASSERT_GE(events->postedTime, postedTimeA);
1850
1851 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1852 ASSERT_FALSE(events->hasLatchInfo());
1853 ASSERT_FALSE(events->hasDequeueReadyInfo());
1854 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1855 ASSERT_FALSE(events->hasDisplayPresentInfo());
1856 ASSERT_FALSE(events->hasReleaseInfo());
1857
1858 // we should also have gotten values for the presented frame
1859 events = history.getFrame(2);
1860 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001861 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001862 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1863 ASSERT_GE(events->postedTime, postedTimeB);
1864 ASSERT_GE(events->latchTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001865 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1866 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1867 ASSERT_NE(nullptr, events->displayPresentFence);
1868 ASSERT_NE(nullptr, events->releaseFence);
1869
1870 // wait for any callbacks that have not been received
1871 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001872}
1873
Vishnu Nair9a69a042021-06-18 13:19:49 -07001874TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1875 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1876 sp<IGraphicBufferProducer> igbProducer;
1877 ProducerFrameEventHistory history;
1878 setUpProducer(adapter, igbProducer);
1879
1880 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1881 nsecs_t requestedPresentTimeA = 0;
1882 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001883 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1884 history.applyDelta(qbOutput.frameTimestamps);
1885 adapter.waitForCallback(1);
1886
1887 // queue another buffer so we query for frame event deltas
1888 nsecs_t requestedPresentTimeB = 0;
1889 nsecs_t postedTimeB = 0;
1890 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1891 history.applyDelta(qbOutput.frameTimestamps);
1892
1893 // check for a valid compositor deadline
1894 ASSERT_NE(0, history.getReportedCompositeDeadline());
1895
1896 // wait for any callbacks that have not been received
1897 adapter.waitForCallbacks();
1898}
1899
Valerie Hauc5011f92019-10-11 09:52:07 -07001900} // namespace android