blob: 0cc0156d264f92d28d08cee4aff470e210eafa39 [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
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -070019#pragma clang diagnostic ignored "-Wsign-compare"
20#pragma clang diagnostic ignored "-Wthread-safety"
21
Valerie Hauc5011f92019-10-11 09:52:07 -070022#include <gui/BLASTBufferQueue.h>
23
Valerie Hauda3446e2019-10-14 15:49:22 -070024#include <android/hardware/graphics/common/1.2/types.h>
Huihong Luo3bdef862022-03-03 11:57:19 -080025#include <gui/AidlStatusUtil.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080026#include <gui/BufferQueueCore.h>
27#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080028#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070029#include <gui/IGraphicBufferProducer.h>
30#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080031#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070032#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070033#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050034#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070035#include <private/gui/ComposerService.h>
Huihong Luo9e84f332021-12-16 14:33:46 -080036#include <private/gui/ComposerServiceAIDL.h>
Melody Hsub9578222023-10-02 23:09:36 +000037#include <tests/utils/ScreenshotUtils.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010038#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070039#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070040#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070041#include <ui/GraphicTypes.h>
Melody Hsub9578222023-10-02 23:09:36 +000042#include <ui/Rect.h>
43#include <ui/Size.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080044#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070045
46#include <gtest/gtest.h>
47
Alec Mouri21d94322023-10-17 19:51:39 +000048#include <com_android_graphics_libgui_flags.h>
49
Valerie Hauc5011f92019-10-11 09:52:07 -070050using namespace std::chrono_literals;
51
52namespace android {
Alec Mouri21d94322023-10-17 19:51:39 +000053using namespace com::android::graphics::libgui;
Valerie Hauc5011f92019-10-11 09:52:07 -070054
Valerie Hauc5011f92019-10-11 09:52:07 -070055using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070056using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070057
chaviwd7deef72021-10-06 11:53:40 -050058class CountProducerListener : public BnProducerListener {
59public:
60 void onBufferReleased() override {
61 std::scoped_lock<std::mutex> lock(mMutex);
62 mNumReleased++;
63 mReleaseCallback.notify_one();
64 }
65
66 void waitOnNumberReleased(int32_t expectedNumReleased) {
67 std::unique_lock<std::mutex> lock(mMutex);
68 while (mNumReleased < expectedNumReleased) {
69 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
70 std::cv_status::timeout)
71 << "did not receive release";
72 }
73 }
74
75private:
76 std::mutex mMutex;
77 std::condition_variable mReleaseCallback;
78 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
79};
80
chaviwf10b9042021-10-13 15:48:59 -050081class TestBLASTBufferQueue : public BLASTBufferQueue {
82public:
83 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
84 int height, int32_t format)
85 : BLASTBufferQueue(name, surface, width, height, format) {}
86
chaviw6b9ffea2021-11-08 09:25:48 -060087 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
88 const std::vector<SurfaceControlStats>& stats) override {
89 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050090 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
91
92 {
93 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060094 mLastTransactionFrameNumber = frameNumber;
95 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050096 }
97 }
98
99 void waitForCallback(int64_t frameNumber) {
100 std::unique_lock lock{frameNumberMutex};
101 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -0600102 while (mLastTransactionFrameNumber < frameNumber) {
103 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -0500104 }
105 }
106
107private:
108 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600109 std::condition_variable mWaitForCallbackCV;
110 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500111};
112
Valerie Hauc5011f92019-10-11 09:52:07 -0700113class BLASTBufferQueueHelper {
114public:
115 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500116 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
117 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700118 }
119
120 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800121 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700122 }
123
Tianhao Yao4861b102022-02-03 20:18:35 +0000124 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
125 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
126 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
127 }
128
Chavi Weingartenc398c012023-04-12 17:26:02 +0000129 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000130 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000131 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000132 }
133
134 void stopContinuousSyncTransaction() {
135 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700136 }
137
Chavi Weingartenc398c012023-04-12 17:26:02 +0000138 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
139
Vishnu Nairea0de002020-11-17 17:42:37 -0800140 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700141
Vishnu Nairea0de002020-11-17 17:42:37 -0800142 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700143
Tianhao Yao4861b102022-02-03 20:18:35 +0000144 std::function<void(Transaction*)> getTransactionReadyCallback() {
145 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
146 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700147
148 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
149 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
150 }
151
Valerie Hauc5011f92019-10-11 09:52:07 -0700152 const sp<SurfaceControl> getSurfaceControl() {
153 return mBlastBufferQueueAdapter->mSurfaceControl;
154 }
155
Vishnu Naira4fbca52021-07-07 16:52:34 -0700156 sp<Surface> getSurface() {
157 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
158 }
159
Valerie Haud3b90d22019-11-06 09:37:31 -0800160 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700161 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800162 // Wait until all but one of the submitted buffers have been released.
163 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800164 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
165 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700166 }
167
Vishnu Nair1506b182021-02-22 14:35:15 -0800168 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500169 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800170 }
171
chaviw0acd33a2021-11-02 11:55:37 -0500172 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
173 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
174 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
175 }
176
chaviwc1cf4022022-06-03 13:32:33 -0500177 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
178 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
179 }
180
Valerie Hauc5011f92019-10-11 09:52:07 -0700181private:
chaviwf10b9042021-10-13 15:48:59 -0500182 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700183};
184
185class BLASTBufferQueueTest : public ::testing::Test {
186public:
187protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700188 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700189 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700190 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700191 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
192 ASSERT_FALSE(ids.empty());
193 // display 0 is picked as this test is not much display depedent
194 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700195 ASSERT_NE(nullptr, mDisplayToken.get());
196 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700197 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700198 t.apply();
199 t.clear();
200
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700201 ui::DisplayState displayState;
202 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
203 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800204 mDisplayWidth = resolution.getWidth();
205 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000206 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700207 displayState.orientation);
Valerie Hauda3446e2019-10-14 15:49:22 -0700208
Melody Hsub9578222023-10-02 23:09:36 +0000209 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
210 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
211 ISurfaceComposerClient::eFXSurfaceBufferState,
212 /*parent*/ nullptr);
213
214 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
215 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
216 .show(mRootSurfaceControl)
217 .apply();
218
Valerie Hauda3446e2019-10-14 15:49:22 -0700219 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
220 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
221 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000222 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700223
Melody Hsub9578222023-10-02 23:09:36 +0000224 mCaptureArgs.sourceCrop = Rect(ui::Size(mDisplayWidth, mDisplayHeight));
225 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700226 }
227
chaviwd7deef72021-10-06 11:53:40 -0500228 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
229 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800230 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500231 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800232 }
233
chaviwd7deef72021-10-06 11:53:40 -0500234 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800235 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500236 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800237 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500238 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800239 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500240 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800241 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800242 }
243
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800244 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
245 uint8_t b) {
246 for (uint32_t row = rect.top; row < rect.bottom; row++) {
247 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700248 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
249 *pixel = r;
250 *(pixel + 1) = g;
251 *(pixel + 2) = b;
252 *(pixel + 3) = 255;
253 }
254 }
255 }
256
Valerie Hau5977fc82019-12-05 15:56:39 -0800257 void fillQuadrants(sp<GraphicBuffer>& buf) {
258 const auto bufWidth = buf->getWidth();
259 const auto bufHeight = buf->getHeight();
260 uint32_t* bufData;
261 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
262 reinterpret_cast<void**>(&bufData));
263 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
264 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
265 0, 0);
266 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
267 buf->getStride(), 0, 255, 0);
268 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
269 255);
270 buf->unlock();
271 }
272
273 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
274 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700275 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800276 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700277 const auto width = captureBuf->getWidth();
278 const auto height = captureBuf->getHeight();
279 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700280
281 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700282 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
283 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700284
285 for (uint32_t row = 0; row < height; row++) {
286 for (uint32_t col = 0; col < width; col++) {
287 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800288 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800289 bool inRegion;
290 if (!outsideRegion) {
291 inRegion = row >= region.top + border && row < region.bottom - border &&
292 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800293 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800294 inRegion = row >= region.top - border && row < region.bottom + border &&
295 col >= region.left - border && col < region.right + border;
296 }
297 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000298 ASSERT_GE(epsilon, abs(r - *(pixel)));
299 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
300 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800301 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000302 ASSERT_GE(epsilon, abs(r - *(pixel)));
303 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
304 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800305 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800306 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700307 }
308 }
chaviwd2432892020-07-24 17:42:39 -0700309 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700310 }
311
Vishnu Nair277142c2021-01-05 18:35:29 -0800312 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
313 nsecs_t presentTimeDelay) {
314 int slot;
315 sp<Fence> fence;
316 sp<GraphicBuffer> buf;
317 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
318 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
319 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500320 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800321 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
322
323 uint32_t* bufData;
324 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
325 reinterpret_cast<void**>(&bufData));
326 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
327 buf->unlock();
328
329 IGraphicBufferProducer::QueueBufferOutput qbOutput;
330 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
331 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
332 Rect(mDisplayWidth, mDisplayHeight / 2),
333 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
334 Fence::NO_FENCE);
335 igbp->queueBuffer(slot, input, &qbOutput);
336 }
337
Valerie Hauc5011f92019-10-11 09:52:07 -0700338 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700339 sp<ISurfaceComposer> mComposer;
340
341 sp<IBinder> mDisplayToken;
342
Valerie Hauc5011f92019-10-11 09:52:07 -0700343 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000344 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700345
346 uint32_t mDisplayWidth;
347 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700348
Melody Hsub9578222023-10-02 23:09:36 +0000349 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700350 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500351 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700352};
353
354TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
355 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700356 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700357 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700358 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
359 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000360 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700361}
362
363TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700364 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700365 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700366 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
Melody Hsub9578222023-10-02 23:09:36 +0000367 PIXEL_FORMAT_RGBA_8888,
368 ISurfaceComposerClient::eFXSurfaceBufferState,
369 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700370 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700371 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800372 sp<IGraphicBufferProducer> igbProducer;
373 setUpProducer(adapter, igbProducer);
374
375 int32_t width;
376 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
377 ASSERT_EQ(mDisplayWidth / 2, width);
378 int32_t height;
379 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
380 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700381}
382
Tianhao Yao4861b102022-02-03 20:18:35 +0000383TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700384 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000385 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
386 auto callback = [](Transaction*) {};
387 adapter.syncNextTransaction(callback);
388 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700389}
Valerie Hauda3446e2019-10-14 15:49:22 -0700390
Valerie Haubf29e042020-02-06 11:40:38 -0800391TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800392 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
393 sp<IGraphicBufferProducer> igbProducer;
394 setUpProducer(adapter, igbProducer);
395
396 int slot;
397 sp<Fence> fence;
398 sp<GraphicBuffer> buf;
399 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
400 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
401 nullptr, nullptr);
402 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
403 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
404
405 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
406 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800407 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
408 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800409 Rect(mDisplayWidth, mDisplayHeight),
410 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
411 Fence::NO_FENCE);
412 igbProducer->queueBuffer(slot, input, &qbOutput);
413 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
414
415 adapter.waitForCallbacks();
416 ASSERT_GE(systemTime(), desiredPresentTime);
417}
418
Valerie Hauda3446e2019-10-14 15:49:22 -0700419TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
420 uint8_t r = 255;
421 uint8_t g = 0;
422 uint8_t b = 0;
423
424 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800425 sp<IGraphicBufferProducer> igbProducer;
426 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700427
428 int slot;
429 sp<Fence> fence;
430 sp<GraphicBuffer> buf;
431 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
432 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
433 nullptr, nullptr);
434 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
435 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
436
437 uint32_t* bufData;
438 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
439 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800440 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700441 buf->unlock();
442
Valerie Haud3b90d22019-11-06 09:37:31 -0800443 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800444 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
445 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700446 Rect(mDisplayWidth, mDisplayHeight),
447 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
448 Fence::NO_FENCE);
449 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800450 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700451
Patrick Williams0eb09c62023-07-28 11:24:35 -0500452 // ensure the buffer queue transaction has been committed
453 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700454
455 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000456 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800457 ASSERT_NO_FATAL_FAILURE(
458 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700459}
Valerie Haud3b90d22019-11-06 09:37:31 -0800460
461TEST_F(BLASTBufferQueueTest, TripleBuffering) {
462 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
463 sp<IGraphicBufferProducer> igbProducer;
464 setUpProducer(adapter, igbProducer);
465
466 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700467 int minUndequeuedBuffers = 0;
468 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
469 const auto bufferCount = minUndequeuedBuffers + 2;
470
471 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800472 int slot;
473 sp<Fence> fence;
474 sp<GraphicBuffer> buf;
475 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
476 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
477 nullptr, nullptr);
478 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
479 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
480 allocated.push_back({slot, fence});
481 }
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700482 for (size_t i = 0; i < allocated.size(); i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800483 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
484 }
485
Valerie Haua32c5522019-12-09 10:11:08 -0800486 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800487 int slot;
488 sp<Fence> fence;
489 sp<GraphicBuffer> buf;
490 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
491 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
492 nullptr, nullptr);
493 ASSERT_EQ(NO_ERROR, ret);
494 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800495 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
496 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800497 Rect(mDisplayWidth, mDisplayHeight),
498 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
499 Fence::NO_FENCE);
500 igbProducer->queueBuffer(slot, input, &qbOutput);
501 }
502 adapter.waitForCallbacks();
503}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800504
505TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
506 uint8_t r = 255;
507 uint8_t g = 0;
508 uint8_t b = 0;
509
510 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
511 sp<IGraphicBufferProducer> igbProducer;
512 setUpProducer(adapter, igbProducer);
513 int slot;
514 sp<Fence> fence;
515 sp<GraphicBuffer> buf;
516 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
517 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
518 nullptr, nullptr);
519 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
520 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
521
522 uint32_t* bufData;
523 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
524 reinterpret_cast<void**>(&bufData));
525 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
526 buf->unlock();
527
528 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800529 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
530 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800531 Rect(mDisplayWidth, mDisplayHeight / 2),
532 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
533 Fence::NO_FENCE);
534 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800535 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800536
Patrick Williams0eb09c62023-07-28 11:24:35 -0500537 // ensure the buffer queue transaction has been committed
538 Transaction().apply(true /* synchronous */);
539
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800540 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000541 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700542
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800543 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000544 checkScreenCapture(r, g, b,
545 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800546}
547
548TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
549 uint8_t r = 255;
550 uint8_t g = 0;
551 uint8_t b = 0;
552
553 int32_t bufferSideLength =
554 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
555 int32_t finalCropSideLength = bufferSideLength / 2;
556
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800557 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
558 sp<IGraphicBufferProducer> igbProducer;
559 setUpProducer(adapter, igbProducer);
560 int slot;
561 sp<Fence> fence;
562 sp<GraphicBuffer> buf;
563 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
564 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
565 nullptr, nullptr);
566 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
567 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
568
569 uint32_t* bufData;
570 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
571 reinterpret_cast<void**>(&bufData));
572 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
573 fillBuffer(bufData,
574 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
575 buf->getHeight()),
576 buf->getStride(), r, g, b);
577 buf->unlock();
578
579 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800580 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
581 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800582 Rect(bufferSideLength, finalCropSideLength),
583 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
584 Fence::NO_FENCE);
585 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800586 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800587
Patrick Williams0eb09c62023-07-28 11:24:35 -0500588 // ensure the buffer queue transaction has been committed
589 Transaction().apply(true /* synchronous */);
590
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800591 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000592 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700593 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
594 {10, 10, (int32_t)bufferSideLength - 10,
595 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800596 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700597 checkScreenCapture(0, 0, 0,
598 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
599 /*border*/ 0, /*outsideRegion*/ true));
600}
601
602TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700603 Rect windowSize(1000, 1000);
604 Rect bufferSize(windowSize);
605 Rect bufferCrop(200, 200, 700, 700);
606
607 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
608 sp<IGraphicBufferProducer> igbProducer;
609 setUpProducer(adapter, igbProducer);
610 int slot;
611 sp<Fence> fence;
612 sp<GraphicBuffer> buf;
613 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
614 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
615 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
616 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
617 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
618
619 uint32_t* bufData;
620 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
621 reinterpret_cast<void**>(&bufData));
622 // fill buffer with grey
623 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
624
625 // fill crop area with different colors so we can verify the cropped region has been scaled
626 // correctly.
627 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
628 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
629 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
630 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
631 buf->unlock();
632
633 IGraphicBufferProducer::QueueBufferOutput qbOutput;
634 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
635 HAL_DATASPACE_UNKNOWN,
636 bufferCrop /* Rect::INVALID_RECT */,
637 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
638 Fence::NO_FENCE);
639 igbProducer->queueBuffer(slot, input, &qbOutput);
640 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
641
Patrick Williams0eb09c62023-07-28 11:24:35 -0500642 // ensure the buffer queue transaction has been committed
643 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700644
Melody Hsub9578222023-10-02 23:09:36 +0000645 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700646
647 // Verify cropped region is scaled correctly.
648 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
649 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
650 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
651 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
652 // Verify outside region is black.
653 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
654 {0, 0, (int32_t)windowSize.getWidth(),
655 (int32_t)windowSize.getHeight()},
656 /*border*/ 0, /*outsideRegion*/ true));
657}
658
659TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700660 Rect windowSize(1000, 1000);
661 Rect bufferSize(500, 500);
662 Rect bufferCrop(100, 100, 350, 350);
663
664 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
665 sp<IGraphicBufferProducer> igbProducer;
666 setUpProducer(adapter, igbProducer);
667 int slot;
668 sp<Fence> fence;
669 sp<GraphicBuffer> buf;
670 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
671 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
672 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
673 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
674 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
675
676 uint32_t* bufData;
677 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
678 reinterpret_cast<void**>(&bufData));
679 // fill buffer with grey
680 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
681
682 // fill crop area with different colors so we can verify the cropped region has been scaled
683 // correctly.
684 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
685 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
686 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
687 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
688 buf->unlock();
689
690 IGraphicBufferProducer::QueueBufferOutput qbOutput;
691 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
692 HAL_DATASPACE_UNKNOWN,
693 bufferCrop /* Rect::INVALID_RECT */,
694 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
695 Fence::NO_FENCE);
696 igbProducer->queueBuffer(slot, input, &qbOutput);
697 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
698
Patrick Williams0eb09c62023-07-28 11:24:35 -0500699 // ensure the buffer queue transaction has been committed
700 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700701
Melody Hsub9578222023-10-02 23:09:36 +0000702 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700703 // Verify cropped region is scaled correctly.
704 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
705 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
706 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
707 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
708 // Verify outside region is black.
709 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
710 {0, 0, (int32_t)windowSize.getWidth(),
711 (int32_t)windowSize.getHeight()},
712 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800713}
714
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700715// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
716// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
717TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
718 uint8_t r = 255;
719 uint8_t g = 0;
720 uint8_t b = 0;
721
722 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
723 sp<IGraphicBufferProducer> igbProducer;
724 setUpProducer(adapter, igbProducer);
725 {
726 int slot;
727 sp<Fence> fence;
728 sp<GraphicBuffer> buf;
729 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
730 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
731 nullptr, nullptr);
732 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
733 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
734
735 uint32_t* bufData;
736 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
737 reinterpret_cast<void**>(&bufData));
738 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
739 buf->unlock();
740
741 IGraphicBufferProducer::QueueBufferOutput qbOutput;
742 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
743 HAL_DATASPACE_UNKNOWN, {},
744 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
745 Fence::NO_FENCE);
746 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500747
748 // ensure the buffer queue transaction has been committed
749 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700750 }
751 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000752 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700753
754 ASSERT_NO_FATAL_FAILURE(
755 checkScreenCapture(r, g, b,
756 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
757
758 // update the size to half the display and dequeue a buffer quarter of the display.
759 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
760
761 {
762 int slot;
763 sp<Fence> fence;
764 sp<GraphicBuffer> buf;
765 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
766 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
767 nullptr, nullptr);
768 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
769 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
770
771 uint32_t* bufData;
772 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
773 reinterpret_cast<void**>(&bufData));
774 g = 255;
775 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
776 buf->unlock();
777
778 IGraphicBufferProducer::QueueBufferOutput qbOutput;
779 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
780 HAL_DATASPACE_UNKNOWN, {},
781 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
782 0, Fence::NO_FENCE);
783 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500784 // ensure the buffer queue transaction has been committed
785 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700786 }
787 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000788 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700789 // verify we still scale the buffer to the new size (half the screen height)
790 ASSERT_NO_FATAL_FAILURE(
791 checkScreenCapture(r, g, b,
792 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
793}
794
chaviwd7deef72021-10-06 11:53:40 -0500795TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
796 uint8_t r = 255;
797 uint8_t g = 0;
798 uint8_t b = 0;
799
800 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
801
802 sp<IGraphicBufferProducer> igbProducer;
803 setUpProducer(adapter, igbProducer);
804
chaviwa1c4c822021-11-10 18:11:58 -0600805 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000806 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500807 queueBuffer(igbProducer, 0, 255, 0, 0);
808
809 // queue non sync buffer, so this one should get blocked
810 // Add a present delay to allow the first screenshot to get taken.
811 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
812 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
813
814 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600815 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500816 transactionCallback.getContext())
817 .apply();
818
819 CallbackData callbackData;
820 transactionCallback.getCallbackData(&callbackData);
821
chaviw0acd33a2021-11-02 11:55:37 -0500822 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000823 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500824 ASSERT_NO_FATAL_FAILURE(
825 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
826
827 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000828 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500829 ASSERT_NO_FATAL_FAILURE(
830 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
831}
832
833TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
834 uint8_t r = 255;
835 uint8_t g = 0;
836 uint8_t b = 0;
837
838 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
839
840 sp<IGraphicBufferProducer> igbProducer;
841 setUpProducer(adapter, igbProducer);
842
843 Transaction mainTransaction;
844
chaviwa1c4c822021-11-10 18:11:58 -0600845 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000846 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500847 queueBuffer(igbProducer, 0, 255, 0, 0);
848
chaviwa1c4c822021-11-10 18:11:58 -0600849 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500850
Tianhao Yao4861b102022-02-03 20:18:35 +0000851 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500852 queueBuffer(igbProducer, r, g, b, 0);
853
chaviwa1c4c822021-11-10 18:11:58 -0600854 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500855 // Expect 1 buffer to be released even before sending to SurfaceFlinger
856 mProducerListener->waitOnNumberReleased(1);
857
858 CallbackHelper transactionCallback;
859 mainTransaction
860 .addTransactionCompletedCallback(transactionCallback.function,
861 transactionCallback.getContext())
862 .apply();
863
864 CallbackData callbackData;
865 transactionCallback.getCallbackData(&callbackData);
866
867 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000868 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500869 ASSERT_NO_FATAL_FAILURE(
870 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
871}
872
873TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
874 uint8_t r = 255;
875 uint8_t g = 0;
876 uint8_t b = 0;
877
878 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
879
880 sp<IGraphicBufferProducer> igbProducer;
881 setUpProducer(adapter, igbProducer);
882
883 Transaction mainTransaction;
884
chaviwa1c4c822021-11-10 18:11:58 -0600885 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500886 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000887 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500888 queueBuffer(igbProducer, 0, 255, 0, 0);
889
chaviwa1c4c822021-11-10 18:11:58 -0600890 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500891
chaviwa1c4c822021-11-10 18:11:58 -0600892 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500893 queueBuffer(igbProducer, 0, 0, 255, 0);
894
895 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000896 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500897 queueBuffer(igbProducer, r, g, b, 0);
898 // Expect 1 buffer to be released because the non sync transaction should merge
899 // with the sync
900 mProducerListener->waitOnNumberReleased(1);
901
chaviwa1c4c822021-11-10 18:11:58 -0600902 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500903 // Expect 2 buffers to be released due to merging the two syncs.
904 mProducerListener->waitOnNumberReleased(2);
905
906 CallbackHelper transactionCallback;
907 mainTransaction
908 .addTransactionCompletedCallback(transactionCallback.function,
909 transactionCallback.getContext())
910 .apply();
911
912 CallbackData callbackData;
913 transactionCallback.getCallbackData(&callbackData);
914
915 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000916 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500917 ASSERT_NO_FATAL_FAILURE(
918 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
919}
920
921TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
922 uint8_t r = 255;
923 uint8_t g = 0;
924 uint8_t b = 0;
925
926 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
927
928 sp<IGraphicBufferProducer> igbProducer;
929 setUpProducer(adapter, igbProducer, 3);
930
931 Transaction mainTransaction;
932
chaviwa1c4c822021-11-10 18:11:58 -0600933 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500934 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000935 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500936 queueBuffer(igbProducer, 0, 255, 0, 0);
937
chaviwa1c4c822021-11-10 18:11:58 -0600938 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500939
chaviwa1c4c822021-11-10 18:11:58 -0600940 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500941 queueBuffer(igbProducer, 0, 0, 255, 0);
942 queueBuffer(igbProducer, 0, 0, 255, 0);
943 queueBuffer(igbProducer, 0, 0, 255, 0);
944
945 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000946 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500947 queueBuffer(igbProducer, r, g, b, 0);
948 // Expect 3 buffers to be released because the non sync transactions should merge
949 // with the sync
950 mProducerListener->waitOnNumberReleased(3);
951
chaviwa1c4c822021-11-10 18:11:58 -0600952 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500953 // Expect 4 buffers to be released due to merging the two syncs.
954 mProducerListener->waitOnNumberReleased(4);
955
956 CallbackHelper transactionCallback;
957 mainTransaction
958 .addTransactionCompletedCallback(transactionCallback.function,
959 transactionCallback.getContext())
960 .apply();
961
962 CallbackData callbackData;
963 transactionCallback.getCallbackData(&callbackData);
964
965 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000966 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500967 ASSERT_NO_FATAL_FAILURE(
968 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
969}
970
971// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
972// continue processing is for a release callback from SurfaceFlinger.
973// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
974// continue acquiring buffers.
975TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
976 uint8_t r = 255;
977 uint8_t g = 0;
978 uint8_t b = 0;
979
980 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
981
982 sp<IGraphicBufferProducer> igbProducer;
983 setUpProducer(adapter, igbProducer, 4);
984
985 Transaction mainTransaction;
986
987 // Send a buffer to SF
988 queueBuffer(igbProducer, 0, 255, 0, 0);
989
chaviwa1c4c822021-11-10 18:11:58 -0600990 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500991 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000992 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500993 queueBuffer(igbProducer, 0, 255, 0, 0);
994
chaviwa1c4c822021-11-10 18:11:58 -0600995 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500996
chaviwa1c4c822021-11-10 18:11:58 -0600997 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500998 queueBuffer(igbProducer, 0, 0, 255, 0);
999 queueBuffer(igbProducer, 0, 0, 255, 0);
1000 queueBuffer(igbProducer, 0, 0, 255, 0);
1001
1002 // apply the first synced buffer to ensure we have to wait on SF
1003 mainTransaction.apply();
1004
1005 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001006 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001007 queueBuffer(igbProducer, r, g, b, 0);
1008 // Expect 2 buffers to be released because the non sync transactions should merge
1009 // with the sync
1010 mProducerListener->waitOnNumberReleased(3);
1011
chaviwa1c4c822021-11-10 18:11:58 -06001012 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001013
1014 CallbackHelper transactionCallback;
1015 mainTransaction
1016 .addTransactionCompletedCallback(transactionCallback.function,
1017 transactionCallback.getContext())
1018 .apply();
1019
1020 CallbackData callbackData;
1021 transactionCallback.getCallbackData(&callbackData);
1022
1023 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001024 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001025 ASSERT_NO_FATAL_FAILURE(
1026 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1027}
1028
Tianhao Yao4861b102022-02-03 20:18:35 +00001029TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001030 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1031
1032 sp<IGraphicBufferProducer> igbProducer;
1033 setUpProducer(adapter, igbProducer);
1034
1035 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001036 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001037 queueBuffer(igbProducer, 0, 255, 0, 0);
1038 queueBuffer(igbProducer, 0, 0, 255, 0);
1039 // There should only be one frame submitted since the first frame will be released.
1040 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001041 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001042
1043 // queue non sync buffer, so this one should get blocked
1044 // Add a present delay to allow the first screenshot to get taken.
1045 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1046 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1047
1048 CallbackHelper transactionCallback;
1049 next.addTransactionCompletedCallback(transactionCallback.function,
1050 transactionCallback.getContext())
1051 .apply();
1052
1053 CallbackData callbackData;
1054 transactionCallback.getCallbackData(&callbackData);
1055
1056 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001057 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001058 ASSERT_NO_FATAL_FAILURE(
1059 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1060
1061 mProducerListener->waitOnNumberReleased(2);
1062 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001063 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001064 ASSERT_NO_FATAL_FAILURE(
1065 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1066}
1067
chaviw3b4bdcf2022-03-17 09:27:03 -05001068TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1069 std::mutex mutex;
1070 std::condition_variable callbackReceivedCv;
1071 bool receivedCallback = false;
1072
1073 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1074 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1075 auto callback = [&](Transaction*) {
1076 std::unique_lock<std::mutex> lock(mutex);
1077 receivedCallback = true;
1078 callbackReceivedCv.notify_one();
1079 };
1080 adapter.syncNextTransaction(callback);
1081 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1082
1083 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001084 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1085
1086 sp<IGraphicBufferProducer> igbProducer;
1087 setUpProducer(adapter, igbProducer);
1088 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001089
1090 std::unique_lock<std::mutex> lock(mutex);
1091 if (!receivedCallback) {
1092 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1093 std::cv_status::timeout)
1094 << "did not receive callback";
1095 }
1096
1097 ASSERT_TRUE(receivedCallback);
1098}
1099
Chavi Weingartenc398c012023-04-12 17:26:02 +00001100TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1101 std::mutex mutex;
1102 std::condition_variable callbackReceivedCv;
1103 bool receivedCallback = false;
1104
1105 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1106 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1107 auto callback = [&](Transaction*) {
1108 std::unique_lock<std::mutex> lock(mutex);
1109 receivedCallback = true;
1110 callbackReceivedCv.notify_one();
1111 };
1112 adapter.syncNextTransaction(callback);
1113 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1114
1115 adapter.clearSyncTransaction();
1116
1117 sp<IGraphicBufferProducer> igbProducer;
1118 setUpProducer(adapter, igbProducer);
1119 queueBuffer(igbProducer, 0, 255, 0, 0);
1120
1121 std::unique_lock<std::mutex> lock(mutex);
1122 if (!receivedCallback) {
1123 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1124 std::cv_status::timeout)
1125 << "did not receive callback";
1126 }
1127
1128 ASSERT_FALSE(receivedCallback);
1129}
1130
chaviwc1cf4022022-06-03 13:32:33 -05001131TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1132 uint8_t r = 255;
1133 uint8_t g = 0;
1134 uint8_t b = 0;
1135
1136 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1137
1138 sp<IGraphicBufferProducer> igbProducer;
1139 setUpProducer(adapter, igbProducer);
1140
1141 Transaction sync;
1142 adapter.setSyncTransaction(sync);
1143 queueBuffer(igbProducer, 0, 255, 0, 0);
1144
1145 // Merge a transaction that has a complete callback into the next frame so we can get notified
1146 // when to take a screenshot
1147 CallbackHelper transactionCallback;
1148 Transaction t;
1149 t.addTransactionCompletedCallback(transactionCallback.function,
1150 transactionCallback.getContext());
1151 adapter.mergeWithNextTransaction(&t, 2);
1152 queueBuffer(igbProducer, r, g, b, 0);
1153
1154 // Drop the buffer, but ensure the next one continues to get processed.
1155 sync.setBuffer(mSurfaceControl, nullptr);
1156
1157 CallbackData callbackData;
1158 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001159 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001160 ASSERT_NO_FATAL_FAILURE(
1161 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001162 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001163}
1164
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001165// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1166// until the old surface control is destroyed. This is not necessarily a bug but to document a
1167// limitation with the update API and to test any changes to make the api more robust. The current
1168// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1169TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1170 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1171 std::vector<sp<SurfaceControl>> surfaceControls;
1172 sp<IGraphicBufferProducer> igbProducer;
1173 for (int i = 0; i < 10; i++) {
1174 sp<SurfaceControl> sc =
1175 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1176 PIXEL_FORMAT_RGBA_8888,
1177 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001178 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001179 Transaction()
1180 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1181 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1182 .show(mSurfaceControl)
1183 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1184 .apply(true);
1185 surfaceControls.push_back(sc);
1186 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1187
1188 setUpProducer(adapter, igbProducer);
1189 Transaction next;
1190 queueBuffer(igbProducer, 0, 255, 0, 0);
1191 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001192 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001193 queueBuffer(igbProducer, 255, 0, 0, 0);
1194
1195 CallbackHelper transactionCallback;
1196 next.addTransactionCompletedCallback(transactionCallback.function,
1197 transactionCallback.getContext())
1198 .apply();
1199
1200 CallbackData callbackData;
1201 transactionCallback.getCallbackData(&callbackData);
1202 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001203 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001204 ASSERT_NO_FATAL_FAILURE(
1205 checkScreenCapture(255, 0, 0,
1206 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1207 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1208 }
1209}
1210
1211// See DISABLED_DisconnectProducerTest
1212TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1213 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1214 std::vector<sp<SurfaceControl>> surfaceControls;
1215 sp<IGraphicBufferProducer> igbProducer;
1216 for (int i = 0; i < 10; i++) {
1217 sp<SurfaceControl> sc =
1218 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1219 PIXEL_FORMAT_RGBA_8888,
1220 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001221 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001222 Transaction()
1223 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1224 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1225 .show(mSurfaceControl)
1226 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1227 .apply(true);
1228 surfaceControls.push_back(sc);
1229 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1230 setUpProducer(adapter, igbProducer);
1231
1232 Transaction next;
1233 queueBuffer(igbProducer, 0, 255, 0, 0);
1234 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001235 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001236 queueBuffer(igbProducer, 255, 0, 0, 0);
1237
1238 CallbackHelper transactionCallback;
1239 next.addTransactionCompletedCallback(transactionCallback.function,
1240 transactionCallback.getContext())
1241 .apply();
1242
1243 CallbackData callbackData;
1244 transactionCallback.getCallbackData(&callbackData);
1245 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001246 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001247 ASSERT_NO_FATAL_FAILURE(
1248 checkScreenCapture(255, 0, 0,
1249 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1250 }
1251}
1252
Vishnu Nair89496122020-12-14 17:14:53 -08001253class TestProducerListener : public BnProducerListener {
1254public:
1255 sp<IGraphicBufferProducer> mIgbp;
1256 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1257 void onBufferReleased() override {
1258 sp<GraphicBuffer> buffer;
1259 sp<Fence> fence;
1260 mIgbp->detachNextBuffer(&buffer, &fence);
1261 }
1262};
1263
1264TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1265 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1266 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1267 ASSERT_NE(nullptr, igbProducer.get());
1268 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1269 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1270 ASSERT_EQ(NO_ERROR,
1271 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1272 false, &qbOutput));
1273 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1274 for (int i = 0; i < 3; i++) {
1275 int slot;
1276 sp<Fence> fence;
1277 sp<GraphicBuffer> buf;
1278 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1279 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1280 nullptr, nullptr);
1281 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1282 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1283 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001284 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1285 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001286 Rect(mDisplayWidth, mDisplayHeight),
1287 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1288 Fence::NO_FENCE);
1289 igbProducer->queueBuffer(slot, input, &qbOutput);
1290 }
1291 adapter.waitForCallbacks();
1292}
1293
Vishnu Nair17dde612020-12-28 11:39:59 -08001294TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1295 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1296
1297 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1298 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1299 int queuesToNativeWindow = 0;
1300 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1301 &queuesToNativeWindow);
1302 ASSERT_EQ(NO_ERROR, err);
1303 ASSERT_EQ(queuesToNativeWindow, 1);
1304}
1305
Vishnu Naira4fbca52021-07-07 16:52:34 -07001306TEST_F(BLASTBufferQueueTest, TransformHint) {
1307 // Transform hint is provided to BBQ via the surface control passed by WM
1308 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1309
1310 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1311 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1312 ASSERT_NE(nullptr, igbProducer.get());
1313 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1314 sp<Surface> surface = adapter.getSurface();
1315
1316 // Before connecting to the surface, we do not get a valid transform hint
1317 int transformHint;
1318 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1319 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1320
1321 ASSERT_EQ(NO_ERROR,
1322 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1323
1324 // After connecting to the surface, we should get the correct hint.
1325 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1326 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1327
1328 ANativeWindow_Buffer buffer;
1329 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1330
1331 // Transform hint is updated via callbacks or surface control updates
1332 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1333 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1334
1335 // The hint does not change and matches the value used when dequeueing the buffer.
1336 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1337 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1338
1339 surface->unlockAndPost();
1340
1341 // After queuing the buffer, we get the updated transform hint
1342 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1343 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1344
1345 adapter.waitForCallbacks();
1346}
1347
Valerie Hau5977fc82019-12-05 15:56:39 -08001348class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1349public:
1350 void test(uint32_t tr) {
1351 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1352 sp<IGraphicBufferProducer> igbProducer;
1353 setUpProducer(adapter, igbProducer);
1354
1355 auto bufWidth = mDisplayWidth;
1356 auto bufHeight = mDisplayHeight;
1357 int slot;
1358 sp<Fence> fence;
1359 sp<GraphicBuffer> buf;
1360
1361 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1362 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1363 nullptr, nullptr);
1364 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1365 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1366
1367 fillQuadrants(buf);
1368
1369 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001370 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1371 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001372 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001373 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1374 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001375 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001376 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001377
Patrick Williams0eb09c62023-07-28 11:24:35 -05001378 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001379 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001380
Valerie Hau5977fc82019-12-05 15:56:39 -08001381 switch (tr) {
1382 case ui::Transform::ROT_0:
1383 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1384 {0, 0, (int32_t)mDisplayWidth / 2,
1385 (int32_t)mDisplayHeight / 2},
1386 1));
1387 ASSERT_NO_FATAL_FAILURE(
1388 checkScreenCapture(255, 0, 0,
1389 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1390 (int32_t)mDisplayHeight / 2},
1391 1));
1392 ASSERT_NO_FATAL_FAILURE(
1393 checkScreenCapture(0, 255, 0,
1394 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1395 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1396 1));
1397 ASSERT_NO_FATAL_FAILURE(
1398 checkScreenCapture(0, 0, 255,
1399 {0, (int32_t)mDisplayHeight / 2,
1400 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1401 1));
1402 break;
1403 case ui::Transform::FLIP_H:
1404 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1405 {0, 0, (int32_t)mDisplayWidth / 2,
1406 (int32_t)mDisplayHeight / 2},
1407 1));
1408 ASSERT_NO_FATAL_FAILURE(
1409 checkScreenCapture(0, 0, 0,
1410 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1411 (int32_t)mDisplayHeight / 2},
1412 1));
1413 ASSERT_NO_FATAL_FAILURE(
1414 checkScreenCapture(0, 0, 255,
1415 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1416 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1417 1));
1418 ASSERT_NO_FATAL_FAILURE(
1419 checkScreenCapture(0, 255, 0,
1420 {0, (int32_t)mDisplayHeight / 2,
1421 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1422 1));
1423 break;
1424 case ui::Transform::FLIP_V:
1425 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1426 {0, 0, (int32_t)mDisplayWidth / 2,
1427 (int32_t)mDisplayHeight / 2},
1428 1));
1429 ASSERT_NO_FATAL_FAILURE(
1430 checkScreenCapture(0, 255, 0,
1431 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1432 (int32_t)mDisplayHeight / 2},
1433 1));
1434 ASSERT_NO_FATAL_FAILURE(
1435 checkScreenCapture(255, 0, 0,
1436 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1437 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1438 1));
1439 ASSERT_NO_FATAL_FAILURE(
1440 checkScreenCapture(0, 0, 0,
1441 {0, (int32_t)mDisplayHeight / 2,
1442 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1443 1));
1444 break;
1445 case ui::Transform::ROT_90:
1446 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1447 {0, 0, (int32_t)mDisplayWidth / 2,
1448 (int32_t)mDisplayHeight / 2},
1449 1));
1450 ASSERT_NO_FATAL_FAILURE(
1451 checkScreenCapture(0, 0, 0,
1452 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1453 (int32_t)mDisplayHeight / 2},
1454 1));
1455 ASSERT_NO_FATAL_FAILURE(
1456 checkScreenCapture(255, 0, 0,
1457 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1458 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1459 1));
1460 ASSERT_NO_FATAL_FAILURE(
1461 checkScreenCapture(0, 255, 0,
1462 {0, (int32_t)mDisplayHeight / 2,
1463 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1464 1));
1465 break;
1466 case ui::Transform::ROT_180:
1467 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1468 {0, 0, (int32_t)mDisplayWidth / 2,
1469 (int32_t)mDisplayHeight / 2},
1470 1));
1471 ASSERT_NO_FATAL_FAILURE(
1472 checkScreenCapture(0, 0, 255,
1473 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1474 (int32_t)mDisplayHeight / 2},
1475 1));
1476 ASSERT_NO_FATAL_FAILURE(
1477 checkScreenCapture(0, 0, 0,
1478 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1479 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1480 1));
1481 ASSERT_NO_FATAL_FAILURE(
1482 checkScreenCapture(255, 0, 0,
1483 {0, (int32_t)mDisplayHeight / 2,
1484 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1485 1));
1486 break;
1487 case ui::Transform::ROT_270:
1488 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1489 {0, 0, (int32_t)mDisplayWidth / 2,
1490 (int32_t)mDisplayHeight / 2},
1491 1));
1492 ASSERT_NO_FATAL_FAILURE(
1493 checkScreenCapture(0, 255, 0,
1494 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1495 (int32_t)mDisplayHeight / 2},
1496 1));
1497 ASSERT_NO_FATAL_FAILURE(
1498 checkScreenCapture(0, 0, 255,
1499 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1500 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1501 1));
1502 ASSERT_NO_FATAL_FAILURE(
1503 checkScreenCapture(0, 0, 0,
1504 {0, (int32_t)mDisplayHeight / 2,
1505 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1506 1));
1507 }
1508 }
1509};
1510
1511TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1512 test(ui::Transform::ROT_0);
1513}
1514
1515TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1516 test(ui::Transform::FLIP_H);
1517}
1518
1519TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1520 test(ui::Transform::FLIP_V);
1521}
1522
1523TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1524 test(ui::Transform::ROT_90);
1525}
1526
1527TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1528 test(ui::Transform::ROT_180);
1529}
1530
1531TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1532 test(ui::Transform::ROT_270);
1533}
Valerie Hau871d6352020-01-29 08:44:02 -08001534
1535class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1536public:
1537 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001538 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001539 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001540 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001541 int slot;
1542 sp<Fence> fence;
1543 sp<GraphicBuffer> buf;
1544 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1545 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1546 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001547 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1548 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1549 }
Valerie Hau871d6352020-01-29 08:44:02 -08001550
Vishnu Nairde66dc72021-06-17 17:54:41 -07001551 *outRequestedPresentTime = requestedPresentTime;
1552 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1553 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001554 Rect(mDisplayWidth, mDisplayHeight),
1555 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1556 Fence::NO_FENCE, /*sticky*/ 0,
1557 getFrameTimestamps);
1558 if (postedTime) *postedTime = systemTime();
1559 igbProducer->queueBuffer(slot, input, qbOutput);
1560 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001561 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001562};
1563
1564TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1565 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1566 sp<IGraphicBufferProducer> igbProducer;
1567 ProducerFrameEventHistory history;
1568 setUpProducer(adapter, igbProducer);
1569
1570 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1571 nsecs_t requestedPresentTimeA = 0;
1572 nsecs_t postedTimeA = 0;
1573 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1574 history.applyDelta(qbOutput.frameTimestamps);
1575
1576 FrameEvents* events = nullptr;
1577 events = history.getFrame(1);
1578 ASSERT_NE(nullptr, events);
1579 ASSERT_EQ(1, events->frameNumber);
1580 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1581 ASSERT_GE(events->postedTime, postedTimeA);
1582
Vishnu Nair1506b182021-02-22 14:35:15 -08001583 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001584
1585 // queue another buffer so we query for frame event deltas
1586 nsecs_t requestedPresentTimeB = 0;
1587 nsecs_t postedTimeB = 0;
1588 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1589 history.applyDelta(qbOutput.frameTimestamps);
Alec Mouri21d94322023-10-17 19:51:39 +00001590
1591 adapter.waitForCallback(2);
1592
Valerie Hau871d6352020-01-29 08:44:02 -08001593 events = history.getFrame(1);
1594 ASSERT_NE(nullptr, events);
1595
1596 // frame number, requestedPresentTime, and postTime should not have changed
1597 ASSERT_EQ(1, events->frameNumber);
1598 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1599 ASSERT_GE(events->postedTime, postedTimeA);
1600
1601 ASSERT_GE(events->latchTime, postedTimeA);
Alec Mouri21d94322023-10-17 19:51:39 +00001602 if (flags::frametimestamps_previousrelease()) {
1603 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1604 }
Valerie Hau871d6352020-01-29 08:44:02 -08001605 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1606 ASSERT_NE(nullptr, events->displayPresentFence);
1607 ASSERT_NE(nullptr, events->releaseFence);
1608
1609 // we should also have gotten the initial values for the next frame
1610 events = history.getFrame(2);
1611 ASSERT_NE(nullptr, events);
1612 ASSERT_EQ(2, events->frameNumber);
1613 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1614 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001615
Alec Mouri21d94322023-10-17 19:51:39 +00001616 // Now do the same as above with a third buffer, so that timings related to
1617 // buffer releases make it back to the first frame.
1618 nsecs_t requestedPresentTimeC = 0;
1619 nsecs_t postedTimeC = 0;
1620 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1621 history.applyDelta(qbOutput.frameTimestamps);
1622
1623 adapter.waitForCallback(3);
1624
1625 // Check the first frame...
1626 events = history.getFrame(1);
1627 ASSERT_NE(nullptr, events);
1628 ASSERT_EQ(1, events->frameNumber);
1629 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1630 ASSERT_GE(events->postedTime, postedTimeA);
1631 ASSERT_GE(events->latchTime, postedTimeA);
1632 // Now dequeueReadyTime is valid, because the release timings finally
1633 // propaged to queueBuffer()
1634 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1635 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1636 ASSERT_NE(nullptr, events->displayPresentFence);
1637 ASSERT_NE(nullptr, events->releaseFence);
1638
1639 // ...and the second
1640 events = history.getFrame(2);
1641 ASSERT_NE(nullptr, events);
1642 ASSERT_EQ(2, events->frameNumber);
1643 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1644 ASSERT_GE(events->postedTime, postedTimeB);
1645 ASSERT_GE(events->latchTime, postedTimeB);
1646 if (flags::frametimestamps_previousrelease()) {
1647 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1648 }
1649 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1650 ASSERT_NE(nullptr, events->displayPresentFence);
1651 ASSERT_NE(nullptr, events->releaseFence);
1652
1653 // ...and finally the third!
1654 events = history.getFrame(3);
1655 ASSERT_NE(nullptr, events);
1656 ASSERT_EQ(3, events->frameNumber);
1657 ASSERT_EQ(requestedPresentTimeC, events->requestedPresentTime);
1658 ASSERT_GE(events->postedTime, postedTimeC);
1659
Valerie Hau78491e92020-04-15 13:10:56 -07001660 // wait for any callbacks that have not been received
1661 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001662}
Vishnu Nair083efd32021-02-12 09:32:30 -08001663
Vishnu Nair083efd32021-02-12 09:32:30 -08001664TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1665 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1666 sp<IGraphicBufferProducer> igbProducer;
1667 setUpProducer(adapter, igbProducer);
1668
1669 ProducerFrameEventHistory history;
1670 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1671 nsecs_t requestedPresentTimeA = 0;
1672 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001673 // Present the frame sometime in the future so we can add two frames to the queue so the older
1674 // one will be dropped.
1675 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001676 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001677 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001678 history.applyDelta(qbOutput.frameTimestamps);
1679
1680 FrameEvents* events = nullptr;
1681 events = history.getFrame(1);
1682 ASSERT_NE(nullptr, events);
1683 ASSERT_EQ(1, events->frameNumber);
1684 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1685 ASSERT_GE(events->postedTime, postedTimeA);
1686
1687 // queue another buffer so the first can be dropped
1688 nsecs_t requestedPresentTimeB = 0;
1689 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001690 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1691 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1692 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001693 history.applyDelta(qbOutput.frameTimestamps);
1694 events = history.getFrame(1);
1695 ASSERT_NE(nullptr, events);
1696
1697 // frame number, requestedPresentTime, and postTime should not have changed
1698 ASSERT_EQ(1, events->frameNumber);
1699 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1700 ASSERT_GE(events->postedTime, postedTimeA);
1701
Vishnu Nairde66dc72021-06-17 17:54:41 -07001702 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001703 ASSERT_FALSE(events->hasLatchInfo());
1704 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001705 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1706 ASSERT_FALSE(events->hasDisplayPresentInfo());
1707 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001708
Vishnu Nairde66dc72021-06-17 17:54:41 -07001709 // wait for the last transaction to be completed.
1710 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001711
Vishnu Nairde66dc72021-06-17 17:54:41 -07001712 // queue another buffer so we query for frame event deltas
1713 nsecs_t requestedPresentTimeC = 0;
1714 nsecs_t postedTimeC = 0;
1715 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1716 history.applyDelta(qbOutput.frameTimestamps);
1717
Alec Mouri21d94322023-10-17 19:51:39 +00001718 adapter.waitForCallback(3);
1719
Vishnu Nairde66dc72021-06-17 17:54:41 -07001720 // frame number, requestedPresentTime, and postTime should not have changed
1721 ASSERT_EQ(1, events->frameNumber);
1722 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1723 ASSERT_GE(events->postedTime, postedTimeA);
1724
1725 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1726 ASSERT_FALSE(events->hasLatchInfo());
1727 ASSERT_FALSE(events->hasDequeueReadyInfo());
1728 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1729 ASSERT_FALSE(events->hasDisplayPresentInfo());
1730 ASSERT_FALSE(events->hasReleaseInfo());
1731
1732 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001733 events = history.getFrame(2);
1734 ASSERT_NE(nullptr, events);
1735 ASSERT_EQ(2, events->frameNumber);
1736 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1737 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001738 ASSERT_GE(events->latchTime, postedTimeB);
Alec Mouri21d94322023-10-17 19:51:39 +00001739
1740 if (flags::frametimestamps_previousrelease()) {
1741 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1742 }
1743 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1744 ASSERT_NE(nullptr, events->displayPresentFence);
1745 ASSERT_NE(nullptr, events->releaseFence);
1746
1747 // Queue another buffer to check for timestamps that came late
1748 nsecs_t requestedPresentTimeD = 0;
1749 nsecs_t postedTimeD = 0;
1750 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeD, &postedTimeD, &qbOutput, true);
1751 history.applyDelta(qbOutput.frameTimestamps);
1752
1753 adapter.waitForCallback(4);
1754
1755 // frame number, requestedPresentTime, and postTime should not have changed
1756 events = history.getFrame(1);
1757 ASSERT_EQ(1, events->frameNumber);
1758 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1759 ASSERT_GE(events->postedTime, postedTimeA);
1760
1761 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1762 ASSERT_FALSE(events->hasLatchInfo());
1763 ASSERT_FALSE(events->hasDequeueReadyInfo());
1764 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1765 ASSERT_FALSE(events->hasDisplayPresentInfo());
1766 ASSERT_FALSE(events->hasReleaseInfo());
1767
1768 // we should also have gotten values for the presented frame
1769 events = history.getFrame(2);
1770 ASSERT_NE(nullptr, events);
1771 ASSERT_EQ(2, events->frameNumber);
1772 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1773 ASSERT_GE(events->postedTime, postedTimeB);
1774 ASSERT_GE(events->latchTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001775 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1776 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1777 ASSERT_NE(nullptr, events->displayPresentFence);
1778 ASSERT_NE(nullptr, events->releaseFence);
1779
1780 // wait for any callbacks that have not been received
1781 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001782}
1783
Vishnu Nair9a69a042021-06-18 13:19:49 -07001784TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1785 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1786 sp<IGraphicBufferProducer> igbProducer;
1787 ProducerFrameEventHistory history;
1788 setUpProducer(adapter, igbProducer);
1789
1790 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1791 nsecs_t requestedPresentTimeA = 0;
1792 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001793 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1794 history.applyDelta(qbOutput.frameTimestamps);
1795 adapter.waitForCallback(1);
1796
1797 // queue another buffer so we query for frame event deltas
1798 nsecs_t requestedPresentTimeB = 0;
1799 nsecs_t postedTimeB = 0;
1800 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1801 history.applyDelta(qbOutput.frameTimestamps);
1802
1803 // check for a valid compositor deadline
1804 ASSERT_NE(0, history.getReportedCompositeDeadline());
1805
1806 // wait for any callbacks that have not been received
1807 adapter.waitForCallbacks();
1808}
1809
Valerie Hauc5011f92019-10-11 09:52:07 -07001810} // namespace android