blob: 9893c7146e9eb478d4d6ea7266a131f76ba14f25 [file] [log] [blame]
Valerie Hauc5011f92019-10-11 09:52:07 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BLASTBufferQueue_test"
18
19#include <gui/BLASTBufferQueue.h>
20
Valerie Hauda3446e2019-10-14 15:49:22 -070021#include <android/hardware/graphics/common/1.2/types.h>
Huihong Luo3bdef862022-03-03 11:57:19 -080022#include <gui/AidlStatusUtil.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080023#include <gui/BufferQueueCore.h>
24#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080025#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070026#include <gui/IGraphicBufferProducer.h>
27#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080028#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070029#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070030#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050031#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070032#include <private/gui/ComposerService.h>
Huihong Luo9e84f332021-12-16 14:33:46 -080033#include <private/gui/ComposerServiceAIDL.h>
Melody Hsub9578222023-10-02 23:09:36 +000034#include <tests/utils/ScreenshotUtils.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010035#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070036#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070037#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070038#include <ui/GraphicTypes.h>
Melody Hsub9578222023-10-02 23:09:36 +000039#include <ui/Rect.h>
40#include <ui/Size.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080041#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070042
43#include <gtest/gtest.h>
44
45using namespace std::chrono_literals;
46
47namespace android {
48
Valerie Hauc5011f92019-10-11 09:52:07 -070049using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070050using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070051
chaviwd7deef72021-10-06 11:53:40 -050052class CountProducerListener : public BnProducerListener {
53public:
54 void onBufferReleased() override {
55 std::scoped_lock<std::mutex> lock(mMutex);
56 mNumReleased++;
57 mReleaseCallback.notify_one();
58 }
59
60 void waitOnNumberReleased(int32_t expectedNumReleased) {
61 std::unique_lock<std::mutex> lock(mMutex);
62 while (mNumReleased < expectedNumReleased) {
63 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
64 std::cv_status::timeout)
65 << "did not receive release";
66 }
67 }
68
69private:
70 std::mutex mMutex;
71 std::condition_variable mReleaseCallback;
72 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
73};
74
chaviwf10b9042021-10-13 15:48:59 -050075class TestBLASTBufferQueue : public BLASTBufferQueue {
76public:
77 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
78 int height, int32_t format)
79 : BLASTBufferQueue(name, surface, width, height, format) {}
80
chaviw6b9ffea2021-11-08 09:25:48 -060081 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
82 const std::vector<SurfaceControlStats>& stats) override {
83 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050084 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
85
86 {
87 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060088 mLastTransactionFrameNumber = frameNumber;
89 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050090 }
91 }
92
93 void waitForCallback(int64_t frameNumber) {
94 std::unique_lock lock{frameNumberMutex};
95 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -060096 while (mLastTransactionFrameNumber < frameNumber) {
97 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -050098 }
99 }
100
101private:
102 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600103 std::condition_variable mWaitForCallbackCV;
104 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500105};
106
Valerie Hauc5011f92019-10-11 09:52:07 -0700107class BLASTBufferQueueHelper {
108public:
109 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500110 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
111 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700112 }
113
114 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800115 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700116 }
117
Tianhao Yao4861b102022-02-03 20:18:35 +0000118 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
119 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
120 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
121 }
122
Chavi Weingartenc398c012023-04-12 17:26:02 +0000123 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000124 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000125 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000126 }
127
128 void stopContinuousSyncTransaction() {
129 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700130 }
131
Chavi Weingartenc398c012023-04-12 17:26:02 +0000132 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
133
Vishnu Nairea0de002020-11-17 17:42:37 -0800134 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700135
Vishnu Nairea0de002020-11-17 17:42:37 -0800136 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700137
Tianhao Yao4861b102022-02-03 20:18:35 +0000138 std::function<void(Transaction*)> getTransactionReadyCallback() {
139 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
140 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700141
142 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
143 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
144 }
145
Valerie Hauc5011f92019-10-11 09:52:07 -0700146 const sp<SurfaceControl> getSurfaceControl() {
147 return mBlastBufferQueueAdapter->mSurfaceControl;
148 }
149
Vishnu Naira4fbca52021-07-07 16:52:34 -0700150 sp<Surface> getSurface() {
151 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
152 }
153
Valerie Haud3b90d22019-11-06 09:37:31 -0800154 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700155 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800156 // Wait until all but one of the submitted buffers have been released.
157 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800158 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
159 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700160 }
161
Vishnu Nair1506b182021-02-22 14:35:15 -0800162 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500163 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800164 }
165
chaviw0acd33a2021-11-02 11:55:37 -0500166 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
167 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
168 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
169 }
170
chaviwc1cf4022022-06-03 13:32:33 -0500171 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
172 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
173 }
174
Valerie Hauc5011f92019-10-11 09:52:07 -0700175private:
chaviwf10b9042021-10-13 15:48:59 -0500176 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700177};
178
179class BLASTBufferQueueTest : public ::testing::Test {
180public:
181protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700182 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700183 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700184 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700185 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
186 ASSERT_FALSE(ids.empty());
187 // display 0 is picked as this test is not much display depedent
188 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700189 ASSERT_NE(nullptr, mDisplayToken.get());
190 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700191 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700192 t.apply();
193 t.clear();
194
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700195 ui::DisplayState displayState;
196 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
197 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800198 mDisplayWidth = resolution.getWidth();
199 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000200 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700201 displayState.orientation);
Valerie Hauda3446e2019-10-14 15:49:22 -0700202
Melody Hsub9578222023-10-02 23:09:36 +0000203 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
204 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
205 ISurfaceComposerClient::eFXSurfaceBufferState,
206 /*parent*/ nullptr);
207
208 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
209 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
210 .show(mRootSurfaceControl)
211 .apply();
212
Valerie Hauda3446e2019-10-14 15:49:22 -0700213 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
214 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
215 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000216 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700217
Melody Hsub9578222023-10-02 23:09:36 +0000218 mCaptureArgs.sourceCrop = Rect(ui::Size(mDisplayWidth, mDisplayHeight));
219 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700220 }
221
chaviwd7deef72021-10-06 11:53:40 -0500222 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
223 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800224 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500225 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800226 }
227
chaviwd7deef72021-10-06 11:53:40 -0500228 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800229 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500230 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800231 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500232 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800233 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500234 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800235 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800236 }
237
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800238 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
239 uint8_t b) {
240 for (uint32_t row = rect.top; row < rect.bottom; row++) {
241 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700242 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
243 *pixel = r;
244 *(pixel + 1) = g;
245 *(pixel + 2) = b;
246 *(pixel + 3) = 255;
247 }
248 }
249 }
250
Valerie Hau5977fc82019-12-05 15:56:39 -0800251 void fillQuadrants(sp<GraphicBuffer>& buf) {
252 const auto bufWidth = buf->getWidth();
253 const auto bufHeight = buf->getHeight();
254 uint32_t* bufData;
255 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
256 reinterpret_cast<void**>(&bufData));
257 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
258 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
259 0, 0);
260 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
261 buf->getStride(), 0, 255, 0);
262 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
263 255);
264 buf->unlock();
265 }
266
267 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
268 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700269 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800270 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700271 const auto width = captureBuf->getWidth();
272 const auto height = captureBuf->getHeight();
273 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700274
275 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700276 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
277 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700278
279 for (uint32_t row = 0; row < height; row++) {
280 for (uint32_t col = 0; col < width; col++) {
281 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800282 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800283 bool inRegion;
284 if (!outsideRegion) {
285 inRegion = row >= region.top + border && row < region.bottom - border &&
286 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800287 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800288 inRegion = row >= region.top - border && row < region.bottom + border &&
289 col >= region.left - border && col < region.right + border;
290 }
291 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000292 ASSERT_GE(epsilon, abs(r - *(pixel)));
293 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
294 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800295 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000296 ASSERT_GE(epsilon, abs(r - *(pixel)));
297 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
298 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800299 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800300 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700301 }
302 }
chaviwd2432892020-07-24 17:42:39 -0700303 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700304 }
305
Vishnu Nair277142c2021-01-05 18:35:29 -0800306 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
307 nsecs_t presentTimeDelay) {
308 int slot;
309 sp<Fence> fence;
310 sp<GraphicBuffer> buf;
311 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
312 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
313 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500314 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800315 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
316
317 uint32_t* bufData;
318 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
319 reinterpret_cast<void**>(&bufData));
320 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
321 buf->unlock();
322
323 IGraphicBufferProducer::QueueBufferOutput qbOutput;
324 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
325 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
326 Rect(mDisplayWidth, mDisplayHeight / 2),
327 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
328 Fence::NO_FENCE);
329 igbp->queueBuffer(slot, input, &qbOutput);
330 }
331
Valerie Hauc5011f92019-10-11 09:52:07 -0700332 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700333 sp<ISurfaceComposer> mComposer;
334
335 sp<IBinder> mDisplayToken;
336
Valerie Hauc5011f92019-10-11 09:52:07 -0700337 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000338 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700339
340 uint32_t mDisplayWidth;
341 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700342
Melody Hsub9578222023-10-02 23:09:36 +0000343 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700344 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500345 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700346};
347
348TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
349 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700350 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700351 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700352 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
353 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000354 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700355}
356
357TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700358 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700359 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700360 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
Melody Hsub9578222023-10-02 23:09:36 +0000361 PIXEL_FORMAT_RGBA_8888,
362 ISurfaceComposerClient::eFXSurfaceBufferState,
363 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700364 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700365 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800366 sp<IGraphicBufferProducer> igbProducer;
367 setUpProducer(adapter, igbProducer);
368
369 int32_t width;
370 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
371 ASSERT_EQ(mDisplayWidth / 2, width);
372 int32_t height;
373 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
374 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700375}
376
Tianhao Yao4861b102022-02-03 20:18:35 +0000377TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700378 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000379 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
380 auto callback = [](Transaction*) {};
381 adapter.syncNextTransaction(callback);
382 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700383}
Valerie Hauda3446e2019-10-14 15:49:22 -0700384
Valerie Haubf29e042020-02-06 11:40:38 -0800385TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800386 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
387 sp<IGraphicBufferProducer> igbProducer;
388 setUpProducer(adapter, igbProducer);
389
390 int slot;
391 sp<Fence> fence;
392 sp<GraphicBuffer> buf;
393 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
394 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
395 nullptr, nullptr);
396 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
397 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
398
399 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
400 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800401 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
402 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800403 Rect(mDisplayWidth, mDisplayHeight),
404 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
405 Fence::NO_FENCE);
406 igbProducer->queueBuffer(slot, input, &qbOutput);
407 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
408
409 adapter.waitForCallbacks();
410 ASSERT_GE(systemTime(), desiredPresentTime);
411}
412
Valerie Hauda3446e2019-10-14 15:49:22 -0700413TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
414 uint8_t r = 255;
415 uint8_t g = 0;
416 uint8_t b = 0;
417
418 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800419 sp<IGraphicBufferProducer> igbProducer;
420 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700421
422 int slot;
423 sp<Fence> fence;
424 sp<GraphicBuffer> buf;
425 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
426 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
427 nullptr, nullptr);
428 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
429 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
430
431 uint32_t* bufData;
432 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
433 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800434 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700435 buf->unlock();
436
Valerie Haud3b90d22019-11-06 09:37:31 -0800437 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800438 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
439 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700440 Rect(mDisplayWidth, mDisplayHeight),
441 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
442 Fence::NO_FENCE);
443 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800444 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700445
Patrick Williams0eb09c62023-07-28 11:24:35 -0500446 // ensure the buffer queue transaction has been committed
447 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700448
449 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000450 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800451 ASSERT_NO_FATAL_FAILURE(
452 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700453}
Valerie Haud3b90d22019-11-06 09:37:31 -0800454
455TEST_F(BLASTBufferQueueTest, TripleBuffering) {
456 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
457 sp<IGraphicBufferProducer> igbProducer;
458 setUpProducer(adapter, igbProducer);
459
460 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700461 int minUndequeuedBuffers = 0;
462 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
463 const auto bufferCount = minUndequeuedBuffers + 2;
464
465 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800466 int slot;
467 sp<Fence> fence;
468 sp<GraphicBuffer> buf;
469 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
470 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
471 nullptr, nullptr);
472 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
473 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
474 allocated.push_back({slot, fence});
475 }
476 for (int i = 0; i < allocated.size(); i++) {
477 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
478 }
479
Valerie Haua32c5522019-12-09 10:11:08 -0800480 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800481 int slot;
482 sp<Fence> fence;
483 sp<GraphicBuffer> buf;
484 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
485 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
486 nullptr, nullptr);
487 ASSERT_EQ(NO_ERROR, ret);
488 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800489 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
490 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800491 Rect(mDisplayWidth, mDisplayHeight),
492 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
493 Fence::NO_FENCE);
494 igbProducer->queueBuffer(slot, input, &qbOutput);
495 }
496 adapter.waitForCallbacks();
497}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800498
499TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
500 uint8_t r = 255;
501 uint8_t g = 0;
502 uint8_t b = 0;
503
504 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
505 sp<IGraphicBufferProducer> igbProducer;
506 setUpProducer(adapter, igbProducer);
507 int slot;
508 sp<Fence> fence;
509 sp<GraphicBuffer> buf;
510 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
511 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
512 nullptr, nullptr);
513 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
514 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
515
516 uint32_t* bufData;
517 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
518 reinterpret_cast<void**>(&bufData));
519 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
520 buf->unlock();
521
522 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800523 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
524 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800525 Rect(mDisplayWidth, mDisplayHeight / 2),
526 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
527 Fence::NO_FENCE);
528 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800529 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800530
Patrick Williams0eb09c62023-07-28 11:24:35 -0500531 // ensure the buffer queue transaction has been committed
532 Transaction().apply(true /* synchronous */);
533
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800534 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000535 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700536
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800537 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000538 checkScreenCapture(r, g, b,
539 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800540}
541
542TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
543 uint8_t r = 255;
544 uint8_t g = 0;
545 uint8_t b = 0;
546
547 int32_t bufferSideLength =
548 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
549 int32_t finalCropSideLength = bufferSideLength / 2;
550
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800551 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
552 sp<IGraphicBufferProducer> igbProducer;
553 setUpProducer(adapter, igbProducer);
554 int slot;
555 sp<Fence> fence;
556 sp<GraphicBuffer> buf;
557 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
558 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
559 nullptr, nullptr);
560 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
561 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
562
563 uint32_t* bufData;
564 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
565 reinterpret_cast<void**>(&bufData));
566 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
567 fillBuffer(bufData,
568 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
569 buf->getHeight()),
570 buf->getStride(), r, g, b);
571 buf->unlock();
572
573 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800574 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
575 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800576 Rect(bufferSideLength, finalCropSideLength),
577 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
578 Fence::NO_FENCE);
579 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800580 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800581
Patrick Williams0eb09c62023-07-28 11:24:35 -0500582 // ensure the buffer queue transaction has been committed
583 Transaction().apply(true /* synchronous */);
584
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800585 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000586 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700587 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
588 {10, 10, (int32_t)bufferSideLength - 10,
589 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800590 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700591 checkScreenCapture(0, 0, 0,
592 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
593 /*border*/ 0, /*outsideRegion*/ true));
594}
595
596TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700597 Rect windowSize(1000, 1000);
598 Rect bufferSize(windowSize);
599 Rect bufferCrop(200, 200, 700, 700);
600
601 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
602 sp<IGraphicBufferProducer> igbProducer;
603 setUpProducer(adapter, igbProducer);
604 int slot;
605 sp<Fence> fence;
606 sp<GraphicBuffer> buf;
607 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
608 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
609 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
610 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
611 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
612
613 uint32_t* bufData;
614 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
615 reinterpret_cast<void**>(&bufData));
616 // fill buffer with grey
617 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
618
619 // fill crop area with different colors so we can verify the cropped region has been scaled
620 // correctly.
621 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
622 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
623 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
624 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
625 buf->unlock();
626
627 IGraphicBufferProducer::QueueBufferOutput qbOutput;
628 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
629 HAL_DATASPACE_UNKNOWN,
630 bufferCrop /* Rect::INVALID_RECT */,
631 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
632 Fence::NO_FENCE);
633 igbProducer->queueBuffer(slot, input, &qbOutput);
634 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
635
Patrick Williams0eb09c62023-07-28 11:24:35 -0500636 // ensure the buffer queue transaction has been committed
637 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700638
Melody Hsub9578222023-10-02 23:09:36 +0000639 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700640
641 // Verify cropped region is scaled correctly.
642 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
643 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
644 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
645 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
646 // Verify outside region is black.
647 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
648 {0, 0, (int32_t)windowSize.getWidth(),
649 (int32_t)windowSize.getHeight()},
650 /*border*/ 0, /*outsideRegion*/ true));
651}
652
653TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700654 Rect windowSize(1000, 1000);
655 Rect bufferSize(500, 500);
656 Rect bufferCrop(100, 100, 350, 350);
657
658 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
659 sp<IGraphicBufferProducer> igbProducer;
660 setUpProducer(adapter, igbProducer);
661 int slot;
662 sp<Fence> fence;
663 sp<GraphicBuffer> buf;
664 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
665 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
666 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
667 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
668 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
669
670 uint32_t* bufData;
671 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
672 reinterpret_cast<void**>(&bufData));
673 // fill buffer with grey
674 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
675
676 // fill crop area with different colors so we can verify the cropped region has been scaled
677 // correctly.
678 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
679 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
680 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
681 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
682 buf->unlock();
683
684 IGraphicBufferProducer::QueueBufferOutput qbOutput;
685 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
686 HAL_DATASPACE_UNKNOWN,
687 bufferCrop /* Rect::INVALID_RECT */,
688 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
689 Fence::NO_FENCE);
690 igbProducer->queueBuffer(slot, input, &qbOutput);
691 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
692
Patrick Williams0eb09c62023-07-28 11:24:35 -0500693 // ensure the buffer queue transaction has been committed
694 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700695
Melody Hsub9578222023-10-02 23:09:36 +0000696 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700697 // Verify cropped region is scaled correctly.
698 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
699 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
700 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
701 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
702 // Verify outside region is black.
703 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
704 {0, 0, (int32_t)windowSize.getWidth(),
705 (int32_t)windowSize.getHeight()},
706 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800707}
708
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700709// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
710// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
711TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
712 uint8_t r = 255;
713 uint8_t g = 0;
714 uint8_t b = 0;
715
716 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
717 sp<IGraphicBufferProducer> igbProducer;
718 setUpProducer(adapter, igbProducer);
719 {
720 int slot;
721 sp<Fence> fence;
722 sp<GraphicBuffer> buf;
723 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
724 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
725 nullptr, nullptr);
726 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
727 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
728
729 uint32_t* bufData;
730 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
731 reinterpret_cast<void**>(&bufData));
732 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
733 buf->unlock();
734
735 IGraphicBufferProducer::QueueBufferOutput qbOutput;
736 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
737 HAL_DATASPACE_UNKNOWN, {},
738 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
739 Fence::NO_FENCE);
740 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500741
742 // ensure the buffer queue transaction has been committed
743 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700744 }
745 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000746 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700747
748 ASSERT_NO_FATAL_FAILURE(
749 checkScreenCapture(r, g, b,
750 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
751
752 // update the size to half the display and dequeue a buffer quarter of the display.
753 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
754
755 {
756 int slot;
757 sp<Fence> fence;
758 sp<GraphicBuffer> buf;
759 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
760 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
761 nullptr, nullptr);
762 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
763 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
764
765 uint32_t* bufData;
766 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
767 reinterpret_cast<void**>(&bufData));
768 g = 255;
769 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
770 buf->unlock();
771
772 IGraphicBufferProducer::QueueBufferOutput qbOutput;
773 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
774 HAL_DATASPACE_UNKNOWN, {},
775 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
776 0, Fence::NO_FENCE);
777 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500778 // ensure the buffer queue transaction has been committed
779 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700780 }
781 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000782 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700783 // verify we still scale the buffer to the new size (half the screen height)
784 ASSERT_NO_FATAL_FAILURE(
785 checkScreenCapture(r, g, b,
786 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
787}
788
chaviwd7deef72021-10-06 11:53:40 -0500789TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
790 uint8_t r = 255;
791 uint8_t g = 0;
792 uint8_t b = 0;
793
794 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
795
796 sp<IGraphicBufferProducer> igbProducer;
797 setUpProducer(adapter, igbProducer);
798
chaviwa1c4c822021-11-10 18:11:58 -0600799 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000800 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500801 queueBuffer(igbProducer, 0, 255, 0, 0);
802
803 // queue non sync buffer, so this one should get blocked
804 // Add a present delay to allow the first screenshot to get taken.
805 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
806 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
807
808 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600809 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500810 transactionCallback.getContext())
811 .apply();
812
813 CallbackData callbackData;
814 transactionCallback.getCallbackData(&callbackData);
815
chaviw0acd33a2021-11-02 11:55:37 -0500816 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000817 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500818 ASSERT_NO_FATAL_FAILURE(
819 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
820
821 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000822 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500823 ASSERT_NO_FATAL_FAILURE(
824 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
825}
826
827TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
828 uint8_t r = 255;
829 uint8_t g = 0;
830 uint8_t b = 0;
831
832 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
833
834 sp<IGraphicBufferProducer> igbProducer;
835 setUpProducer(adapter, igbProducer);
836
837 Transaction mainTransaction;
838
chaviwa1c4c822021-11-10 18:11:58 -0600839 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000840 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500841 queueBuffer(igbProducer, 0, 255, 0, 0);
842
chaviwa1c4c822021-11-10 18:11:58 -0600843 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500844
Tianhao Yao4861b102022-02-03 20:18:35 +0000845 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500846 queueBuffer(igbProducer, r, g, b, 0);
847
chaviwa1c4c822021-11-10 18:11:58 -0600848 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500849 // Expect 1 buffer to be released even before sending to SurfaceFlinger
850 mProducerListener->waitOnNumberReleased(1);
851
852 CallbackHelper transactionCallback;
853 mainTransaction
854 .addTransactionCompletedCallback(transactionCallback.function,
855 transactionCallback.getContext())
856 .apply();
857
858 CallbackData callbackData;
859 transactionCallback.getCallbackData(&callbackData);
860
861 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000862 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500863 ASSERT_NO_FATAL_FAILURE(
864 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
865}
866
867TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
868 uint8_t r = 255;
869 uint8_t g = 0;
870 uint8_t b = 0;
871
872 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
873
874 sp<IGraphicBufferProducer> igbProducer;
875 setUpProducer(adapter, igbProducer);
876
877 Transaction mainTransaction;
878
chaviwa1c4c822021-11-10 18:11:58 -0600879 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500880 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000881 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500882 queueBuffer(igbProducer, 0, 255, 0, 0);
883
chaviwa1c4c822021-11-10 18:11:58 -0600884 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500885
chaviwa1c4c822021-11-10 18:11:58 -0600886 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500887 queueBuffer(igbProducer, 0, 0, 255, 0);
888
889 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000890 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500891 queueBuffer(igbProducer, r, g, b, 0);
892 // Expect 1 buffer to be released because the non sync transaction should merge
893 // with the sync
894 mProducerListener->waitOnNumberReleased(1);
895
chaviwa1c4c822021-11-10 18:11:58 -0600896 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500897 // Expect 2 buffers to be released due to merging the two syncs.
898 mProducerListener->waitOnNumberReleased(2);
899
900 CallbackHelper transactionCallback;
901 mainTransaction
902 .addTransactionCompletedCallback(transactionCallback.function,
903 transactionCallback.getContext())
904 .apply();
905
906 CallbackData callbackData;
907 transactionCallback.getCallbackData(&callbackData);
908
909 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000910 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500911 ASSERT_NO_FATAL_FAILURE(
912 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
913}
914
915TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
916 uint8_t r = 255;
917 uint8_t g = 0;
918 uint8_t b = 0;
919
920 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
921
922 sp<IGraphicBufferProducer> igbProducer;
923 setUpProducer(adapter, igbProducer, 3);
924
925 Transaction mainTransaction;
926
chaviwa1c4c822021-11-10 18:11:58 -0600927 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500928 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000929 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500930 queueBuffer(igbProducer, 0, 255, 0, 0);
931
chaviwa1c4c822021-11-10 18:11:58 -0600932 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500933
chaviwa1c4c822021-11-10 18:11:58 -0600934 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500935 queueBuffer(igbProducer, 0, 0, 255, 0);
936 queueBuffer(igbProducer, 0, 0, 255, 0);
937 queueBuffer(igbProducer, 0, 0, 255, 0);
938
939 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000940 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500941 queueBuffer(igbProducer, r, g, b, 0);
942 // Expect 3 buffers to be released because the non sync transactions should merge
943 // with the sync
944 mProducerListener->waitOnNumberReleased(3);
945
chaviwa1c4c822021-11-10 18:11:58 -0600946 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500947 // Expect 4 buffers to be released due to merging the two syncs.
948 mProducerListener->waitOnNumberReleased(4);
949
950 CallbackHelper transactionCallback;
951 mainTransaction
952 .addTransactionCompletedCallback(transactionCallback.function,
953 transactionCallback.getContext())
954 .apply();
955
956 CallbackData callbackData;
957 transactionCallback.getCallbackData(&callbackData);
958
959 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000960 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500961 ASSERT_NO_FATAL_FAILURE(
962 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
963}
964
965// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
966// continue processing is for a release callback from SurfaceFlinger.
967// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
968// continue acquiring buffers.
969TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
970 uint8_t r = 255;
971 uint8_t g = 0;
972 uint8_t b = 0;
973
974 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
975
976 sp<IGraphicBufferProducer> igbProducer;
977 setUpProducer(adapter, igbProducer, 4);
978
979 Transaction mainTransaction;
980
981 // Send a buffer to SF
982 queueBuffer(igbProducer, 0, 255, 0, 0);
983
chaviwa1c4c822021-11-10 18:11:58 -0600984 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500985 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000986 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500987 queueBuffer(igbProducer, 0, 255, 0, 0);
988
chaviwa1c4c822021-11-10 18:11:58 -0600989 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500990
chaviwa1c4c822021-11-10 18:11:58 -0600991 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500992 queueBuffer(igbProducer, 0, 0, 255, 0);
993 queueBuffer(igbProducer, 0, 0, 255, 0);
994 queueBuffer(igbProducer, 0, 0, 255, 0);
995
996 // apply the first synced buffer to ensure we have to wait on SF
997 mainTransaction.apply();
998
999 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001000 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001001 queueBuffer(igbProducer, r, g, b, 0);
1002 // Expect 2 buffers to be released because the non sync transactions should merge
1003 // with the sync
1004 mProducerListener->waitOnNumberReleased(3);
1005
chaviwa1c4c822021-11-10 18:11:58 -06001006 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001007
1008 CallbackHelper transactionCallback;
1009 mainTransaction
1010 .addTransactionCompletedCallback(transactionCallback.function,
1011 transactionCallback.getContext())
1012 .apply();
1013
1014 CallbackData callbackData;
1015 transactionCallback.getCallbackData(&callbackData);
1016
1017 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001018 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001019 ASSERT_NO_FATAL_FAILURE(
1020 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1021}
1022
Tianhao Yao4861b102022-02-03 20:18:35 +00001023TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001024 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1025
1026 sp<IGraphicBufferProducer> igbProducer;
1027 setUpProducer(adapter, igbProducer);
1028
1029 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001030 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001031 queueBuffer(igbProducer, 0, 255, 0, 0);
1032 queueBuffer(igbProducer, 0, 0, 255, 0);
1033 // There should only be one frame submitted since the first frame will be released.
1034 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001035 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001036
1037 // queue non sync buffer, so this one should get blocked
1038 // Add a present delay to allow the first screenshot to get taken.
1039 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1040 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1041
1042 CallbackHelper transactionCallback;
1043 next.addTransactionCompletedCallback(transactionCallback.function,
1044 transactionCallback.getContext())
1045 .apply();
1046
1047 CallbackData callbackData;
1048 transactionCallback.getCallbackData(&callbackData);
1049
1050 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001051 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001052 ASSERT_NO_FATAL_FAILURE(
1053 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1054
1055 mProducerListener->waitOnNumberReleased(2);
1056 // capture screen and verify that it is red
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(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1060}
1061
chaviw3b4bdcf2022-03-17 09:27:03 -05001062TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1063 std::mutex mutex;
1064 std::condition_variable callbackReceivedCv;
1065 bool receivedCallback = false;
1066
1067 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1068 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1069 auto callback = [&](Transaction*) {
1070 std::unique_lock<std::mutex> lock(mutex);
1071 receivedCallback = true;
1072 callbackReceivedCv.notify_one();
1073 };
1074 adapter.syncNextTransaction(callback);
1075 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1076
1077 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001078 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1079
1080 sp<IGraphicBufferProducer> igbProducer;
1081 setUpProducer(adapter, igbProducer);
1082 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001083
1084 std::unique_lock<std::mutex> lock(mutex);
1085 if (!receivedCallback) {
1086 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1087 std::cv_status::timeout)
1088 << "did not receive callback";
1089 }
1090
1091 ASSERT_TRUE(receivedCallback);
1092}
1093
Chavi Weingartenc398c012023-04-12 17:26:02 +00001094TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1095 std::mutex mutex;
1096 std::condition_variable callbackReceivedCv;
1097 bool receivedCallback = false;
1098
1099 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1100 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1101 auto callback = [&](Transaction*) {
1102 std::unique_lock<std::mutex> lock(mutex);
1103 receivedCallback = true;
1104 callbackReceivedCv.notify_one();
1105 };
1106 adapter.syncNextTransaction(callback);
1107 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1108
1109 adapter.clearSyncTransaction();
1110
1111 sp<IGraphicBufferProducer> igbProducer;
1112 setUpProducer(adapter, igbProducer);
1113 queueBuffer(igbProducer, 0, 255, 0, 0);
1114
1115 std::unique_lock<std::mutex> lock(mutex);
1116 if (!receivedCallback) {
1117 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1118 std::cv_status::timeout)
1119 << "did not receive callback";
1120 }
1121
1122 ASSERT_FALSE(receivedCallback);
1123}
1124
chaviwc1cf4022022-06-03 13:32:33 -05001125TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1126 uint8_t r = 255;
1127 uint8_t g = 0;
1128 uint8_t b = 0;
1129
1130 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1131
1132 sp<IGraphicBufferProducer> igbProducer;
1133 setUpProducer(adapter, igbProducer);
1134
1135 Transaction sync;
1136 adapter.setSyncTransaction(sync);
1137 queueBuffer(igbProducer, 0, 255, 0, 0);
1138
1139 // Merge a transaction that has a complete callback into the next frame so we can get notified
1140 // when to take a screenshot
1141 CallbackHelper transactionCallback;
1142 Transaction t;
1143 t.addTransactionCompletedCallback(transactionCallback.function,
1144 transactionCallback.getContext());
1145 adapter.mergeWithNextTransaction(&t, 2);
1146 queueBuffer(igbProducer, r, g, b, 0);
1147
1148 // Drop the buffer, but ensure the next one continues to get processed.
1149 sync.setBuffer(mSurfaceControl, nullptr);
1150
1151 CallbackData callbackData;
1152 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001153 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001154 ASSERT_NO_FATAL_FAILURE(
1155 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001156 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001157}
1158
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001159// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1160// until the old surface control is destroyed. This is not necessarily a bug but to document a
1161// limitation with the update API and to test any changes to make the api more robust. The current
1162// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1163TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1164 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1165 std::vector<sp<SurfaceControl>> surfaceControls;
1166 sp<IGraphicBufferProducer> igbProducer;
1167 for (int i = 0; i < 10; i++) {
1168 sp<SurfaceControl> sc =
1169 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1170 PIXEL_FORMAT_RGBA_8888,
1171 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001172 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001173 Transaction()
1174 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1175 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1176 .show(mSurfaceControl)
1177 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1178 .apply(true);
1179 surfaceControls.push_back(sc);
1180 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1181
1182 setUpProducer(adapter, igbProducer);
1183 Transaction next;
1184 queueBuffer(igbProducer, 0, 255, 0, 0);
1185 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001186 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001187 queueBuffer(igbProducer, 255, 0, 0, 0);
1188
1189 CallbackHelper transactionCallback;
1190 next.addTransactionCompletedCallback(transactionCallback.function,
1191 transactionCallback.getContext())
1192 .apply();
1193
1194 CallbackData callbackData;
1195 transactionCallback.getCallbackData(&callbackData);
1196 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001197 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001198 ASSERT_NO_FATAL_FAILURE(
1199 checkScreenCapture(255, 0, 0,
1200 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1201 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1202 }
1203}
1204
1205// See DISABLED_DisconnectProducerTest
1206TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1207 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1208 std::vector<sp<SurfaceControl>> surfaceControls;
1209 sp<IGraphicBufferProducer> igbProducer;
1210 for (int i = 0; i < 10; i++) {
1211 sp<SurfaceControl> sc =
1212 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1213 PIXEL_FORMAT_RGBA_8888,
1214 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001215 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001216 Transaction()
1217 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1218 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1219 .show(mSurfaceControl)
1220 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1221 .apply(true);
1222 surfaceControls.push_back(sc);
1223 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1224 setUpProducer(adapter, igbProducer);
1225
1226 Transaction next;
1227 queueBuffer(igbProducer, 0, 255, 0, 0);
1228 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001229 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001230 queueBuffer(igbProducer, 255, 0, 0, 0);
1231
1232 CallbackHelper transactionCallback;
1233 next.addTransactionCompletedCallback(transactionCallback.function,
1234 transactionCallback.getContext())
1235 .apply();
1236
1237 CallbackData callbackData;
1238 transactionCallback.getCallbackData(&callbackData);
1239 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001240 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001241 ASSERT_NO_FATAL_FAILURE(
1242 checkScreenCapture(255, 0, 0,
1243 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1244 }
1245}
1246
Vishnu Nair89496122020-12-14 17:14:53 -08001247class TestProducerListener : public BnProducerListener {
1248public:
1249 sp<IGraphicBufferProducer> mIgbp;
1250 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1251 void onBufferReleased() override {
1252 sp<GraphicBuffer> buffer;
1253 sp<Fence> fence;
1254 mIgbp->detachNextBuffer(&buffer, &fence);
1255 }
1256};
1257
1258TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1259 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1260 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1261 ASSERT_NE(nullptr, igbProducer.get());
1262 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1263 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1264 ASSERT_EQ(NO_ERROR,
1265 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1266 false, &qbOutput));
1267 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1268 for (int i = 0; i < 3; i++) {
1269 int slot;
1270 sp<Fence> fence;
1271 sp<GraphicBuffer> buf;
1272 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1273 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1274 nullptr, nullptr);
1275 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1276 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1277 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001278 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1279 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001280 Rect(mDisplayWidth, mDisplayHeight),
1281 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1282 Fence::NO_FENCE);
1283 igbProducer->queueBuffer(slot, input, &qbOutput);
1284 }
1285 adapter.waitForCallbacks();
1286}
1287
Vishnu Nair17dde612020-12-28 11:39:59 -08001288TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1289 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1290
1291 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1292 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1293 int queuesToNativeWindow = 0;
1294 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1295 &queuesToNativeWindow);
1296 ASSERT_EQ(NO_ERROR, err);
1297 ASSERT_EQ(queuesToNativeWindow, 1);
1298}
1299
Vishnu Naira4fbca52021-07-07 16:52:34 -07001300TEST_F(BLASTBufferQueueTest, TransformHint) {
1301 // Transform hint is provided to BBQ via the surface control passed by WM
1302 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1303
1304 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1305 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1306 ASSERT_NE(nullptr, igbProducer.get());
1307 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1308 sp<Surface> surface = adapter.getSurface();
1309
1310 // Before connecting to the surface, we do not get a valid transform hint
1311 int transformHint;
1312 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1313 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1314
1315 ASSERT_EQ(NO_ERROR,
1316 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1317
1318 // After connecting to the surface, we should get the correct hint.
1319 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1320 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1321
1322 ANativeWindow_Buffer buffer;
1323 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1324
1325 // Transform hint is updated via callbacks or surface control updates
1326 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1327 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1328
1329 // The hint does not change and matches the value used when dequeueing the buffer.
1330 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1331 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1332
1333 surface->unlockAndPost();
1334
1335 // After queuing the buffer, we get the updated transform hint
1336 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1337 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1338
1339 adapter.waitForCallbacks();
1340}
1341
Valerie Hau5977fc82019-12-05 15:56:39 -08001342class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1343public:
1344 void test(uint32_t tr) {
1345 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1346 sp<IGraphicBufferProducer> igbProducer;
1347 setUpProducer(adapter, igbProducer);
1348
1349 auto bufWidth = mDisplayWidth;
1350 auto bufHeight = mDisplayHeight;
1351 int slot;
1352 sp<Fence> fence;
1353 sp<GraphicBuffer> buf;
1354
1355 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1356 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1357 nullptr, nullptr);
1358 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1359 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1360
1361 fillQuadrants(buf);
1362
1363 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001364 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1365 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001366 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001367 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1368 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001369 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001370 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001371
Patrick Williams0eb09c62023-07-28 11:24:35 -05001372 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001373 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001374
Valerie Hau5977fc82019-12-05 15:56:39 -08001375 switch (tr) {
1376 case ui::Transform::ROT_0:
1377 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1378 {0, 0, (int32_t)mDisplayWidth / 2,
1379 (int32_t)mDisplayHeight / 2},
1380 1));
1381 ASSERT_NO_FATAL_FAILURE(
1382 checkScreenCapture(255, 0, 0,
1383 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1384 (int32_t)mDisplayHeight / 2},
1385 1));
1386 ASSERT_NO_FATAL_FAILURE(
1387 checkScreenCapture(0, 255, 0,
1388 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1389 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1390 1));
1391 ASSERT_NO_FATAL_FAILURE(
1392 checkScreenCapture(0, 0, 255,
1393 {0, (int32_t)mDisplayHeight / 2,
1394 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1395 1));
1396 break;
1397 case ui::Transform::FLIP_H:
1398 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1399 {0, 0, (int32_t)mDisplayWidth / 2,
1400 (int32_t)mDisplayHeight / 2},
1401 1));
1402 ASSERT_NO_FATAL_FAILURE(
1403 checkScreenCapture(0, 0, 0,
1404 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1405 (int32_t)mDisplayHeight / 2},
1406 1));
1407 ASSERT_NO_FATAL_FAILURE(
1408 checkScreenCapture(0, 0, 255,
1409 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1410 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1411 1));
1412 ASSERT_NO_FATAL_FAILURE(
1413 checkScreenCapture(0, 255, 0,
1414 {0, (int32_t)mDisplayHeight / 2,
1415 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1416 1));
1417 break;
1418 case ui::Transform::FLIP_V:
1419 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1420 {0, 0, (int32_t)mDisplayWidth / 2,
1421 (int32_t)mDisplayHeight / 2},
1422 1));
1423 ASSERT_NO_FATAL_FAILURE(
1424 checkScreenCapture(0, 255, 0,
1425 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1426 (int32_t)mDisplayHeight / 2},
1427 1));
1428 ASSERT_NO_FATAL_FAILURE(
1429 checkScreenCapture(255, 0, 0,
1430 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1431 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1432 1));
1433 ASSERT_NO_FATAL_FAILURE(
1434 checkScreenCapture(0, 0, 0,
1435 {0, (int32_t)mDisplayHeight / 2,
1436 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1437 1));
1438 break;
1439 case ui::Transform::ROT_90:
1440 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1441 {0, 0, (int32_t)mDisplayWidth / 2,
1442 (int32_t)mDisplayHeight / 2},
1443 1));
1444 ASSERT_NO_FATAL_FAILURE(
1445 checkScreenCapture(0, 0, 0,
1446 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1447 (int32_t)mDisplayHeight / 2},
1448 1));
1449 ASSERT_NO_FATAL_FAILURE(
1450 checkScreenCapture(255, 0, 0,
1451 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1452 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1453 1));
1454 ASSERT_NO_FATAL_FAILURE(
1455 checkScreenCapture(0, 255, 0,
1456 {0, (int32_t)mDisplayHeight / 2,
1457 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1458 1));
1459 break;
1460 case ui::Transform::ROT_180:
1461 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1462 {0, 0, (int32_t)mDisplayWidth / 2,
1463 (int32_t)mDisplayHeight / 2},
1464 1));
1465 ASSERT_NO_FATAL_FAILURE(
1466 checkScreenCapture(0, 0, 255,
1467 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1468 (int32_t)mDisplayHeight / 2},
1469 1));
1470 ASSERT_NO_FATAL_FAILURE(
1471 checkScreenCapture(0, 0, 0,
1472 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1473 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1474 1));
1475 ASSERT_NO_FATAL_FAILURE(
1476 checkScreenCapture(255, 0, 0,
1477 {0, (int32_t)mDisplayHeight / 2,
1478 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1479 1));
1480 break;
1481 case ui::Transform::ROT_270:
1482 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1483 {0, 0, (int32_t)mDisplayWidth / 2,
1484 (int32_t)mDisplayHeight / 2},
1485 1));
1486 ASSERT_NO_FATAL_FAILURE(
1487 checkScreenCapture(0, 255, 0,
1488 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1489 (int32_t)mDisplayHeight / 2},
1490 1));
1491 ASSERT_NO_FATAL_FAILURE(
1492 checkScreenCapture(0, 0, 255,
1493 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1494 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1495 1));
1496 ASSERT_NO_FATAL_FAILURE(
1497 checkScreenCapture(0, 0, 0,
1498 {0, (int32_t)mDisplayHeight / 2,
1499 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1500 1));
1501 }
1502 }
1503};
1504
1505TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1506 test(ui::Transform::ROT_0);
1507}
1508
1509TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1510 test(ui::Transform::FLIP_H);
1511}
1512
1513TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1514 test(ui::Transform::FLIP_V);
1515}
1516
1517TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1518 test(ui::Transform::ROT_90);
1519}
1520
1521TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1522 test(ui::Transform::ROT_180);
1523}
1524
1525TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1526 test(ui::Transform::ROT_270);
1527}
Valerie Hau871d6352020-01-29 08:44:02 -08001528
1529class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1530public:
1531 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001532 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001533 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001534 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001535 int slot;
1536 sp<Fence> fence;
1537 sp<GraphicBuffer> buf;
1538 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1539 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1540 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001541 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1542 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1543 }
Valerie Hau871d6352020-01-29 08:44:02 -08001544
Vishnu Nairde66dc72021-06-17 17:54:41 -07001545 *outRequestedPresentTime = requestedPresentTime;
1546 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1547 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001548 Rect(mDisplayWidth, mDisplayHeight),
1549 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1550 Fence::NO_FENCE, /*sticky*/ 0,
1551 getFrameTimestamps);
1552 if (postedTime) *postedTime = systemTime();
1553 igbProducer->queueBuffer(slot, input, qbOutput);
1554 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001555 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001556};
1557
1558TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1559 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1560 sp<IGraphicBufferProducer> igbProducer;
1561 ProducerFrameEventHistory history;
1562 setUpProducer(adapter, igbProducer);
1563
1564 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1565 nsecs_t requestedPresentTimeA = 0;
1566 nsecs_t postedTimeA = 0;
1567 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1568 history.applyDelta(qbOutput.frameTimestamps);
1569
1570 FrameEvents* events = nullptr;
1571 events = history.getFrame(1);
1572 ASSERT_NE(nullptr, events);
1573 ASSERT_EQ(1, events->frameNumber);
1574 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1575 ASSERT_GE(events->postedTime, postedTimeA);
1576
Vishnu Nair1506b182021-02-22 14:35:15 -08001577 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001578
1579 // queue another buffer so we query for frame event deltas
1580 nsecs_t requestedPresentTimeB = 0;
1581 nsecs_t postedTimeB = 0;
1582 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1583 history.applyDelta(qbOutput.frameTimestamps);
1584 events = history.getFrame(1);
1585 ASSERT_NE(nullptr, events);
1586
1587 // frame number, requestedPresentTime, and postTime should not have changed
1588 ASSERT_EQ(1, events->frameNumber);
1589 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1590 ASSERT_GE(events->postedTime, postedTimeA);
1591
1592 ASSERT_GE(events->latchTime, postedTimeA);
1593 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1594 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1595 ASSERT_NE(nullptr, events->displayPresentFence);
1596 ASSERT_NE(nullptr, events->releaseFence);
1597
1598 // we should also have gotten the initial values for the next frame
1599 events = history.getFrame(2);
1600 ASSERT_NE(nullptr, events);
1601 ASSERT_EQ(2, events->frameNumber);
1602 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1603 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001604
1605 // wait for any callbacks that have not been received
1606 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001607}
Vishnu Nair083efd32021-02-12 09:32:30 -08001608
Vishnu Nair083efd32021-02-12 09:32:30 -08001609TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1610 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1611 sp<IGraphicBufferProducer> igbProducer;
1612 setUpProducer(adapter, igbProducer);
1613
1614 ProducerFrameEventHistory history;
1615 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1616 nsecs_t requestedPresentTimeA = 0;
1617 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001618 // Present the frame sometime in the future so we can add two frames to the queue so the older
1619 // one will be dropped.
1620 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001621 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001622 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001623 history.applyDelta(qbOutput.frameTimestamps);
1624
1625 FrameEvents* events = nullptr;
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
1632 // queue another buffer so the first can be dropped
1633 nsecs_t requestedPresentTimeB = 0;
1634 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001635 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1636 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1637 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001638 history.applyDelta(qbOutput.frameTimestamps);
1639 events = history.getFrame(1);
1640 ASSERT_NE(nullptr, events);
1641
1642 // frame number, requestedPresentTime, and postTime should not have changed
1643 ASSERT_EQ(1, events->frameNumber);
1644 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1645 ASSERT_GE(events->postedTime, postedTimeA);
1646
Vishnu Nairde66dc72021-06-17 17:54:41 -07001647 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001648 ASSERT_FALSE(events->hasLatchInfo());
1649 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001650 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1651 ASSERT_FALSE(events->hasDisplayPresentInfo());
1652 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001653
Vishnu Nairde66dc72021-06-17 17:54:41 -07001654 // wait for the last transaction to be completed.
1655 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001656
Vishnu Nairde66dc72021-06-17 17:54:41 -07001657 // queue another buffer so we query for frame event deltas
1658 nsecs_t requestedPresentTimeC = 0;
1659 nsecs_t postedTimeC = 0;
1660 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1661 history.applyDelta(qbOutput.frameTimestamps);
1662
1663 // frame number, requestedPresentTime, and postTime should not have changed
1664 ASSERT_EQ(1, events->frameNumber);
1665 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1666 ASSERT_GE(events->postedTime, postedTimeA);
1667
1668 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1669 ASSERT_FALSE(events->hasLatchInfo());
1670 ASSERT_FALSE(events->hasDequeueReadyInfo());
1671 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1672 ASSERT_FALSE(events->hasDisplayPresentInfo());
1673 ASSERT_FALSE(events->hasReleaseInfo());
1674
1675 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001676 events = history.getFrame(2);
1677 ASSERT_NE(nullptr, events);
1678 ASSERT_EQ(2, events->frameNumber);
1679 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1680 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001681 ASSERT_GE(events->latchTime, postedTimeB);
1682 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1683 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1684 ASSERT_NE(nullptr, events->displayPresentFence);
1685 ASSERT_NE(nullptr, events->releaseFence);
1686
1687 // wait for any callbacks that have not been received
1688 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001689}
1690
Vishnu Nair9a69a042021-06-18 13:19:49 -07001691TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1692 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1693 sp<IGraphicBufferProducer> igbProducer;
1694 ProducerFrameEventHistory history;
1695 setUpProducer(adapter, igbProducer);
1696
1697 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1698 nsecs_t requestedPresentTimeA = 0;
1699 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001700 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1701 history.applyDelta(qbOutput.frameTimestamps);
1702 adapter.waitForCallback(1);
1703
1704 // queue another buffer so we query for frame event deltas
1705 nsecs_t requestedPresentTimeB = 0;
1706 nsecs_t postedTimeB = 0;
1707 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1708 history.applyDelta(qbOutput.frameTimestamps);
1709
1710 // check for a valid compositor deadline
1711 ASSERT_NE(0, history.getReportedCompositeDeadline());
1712
1713 // wait for any callbacks that have not been received
1714 adapter.waitForCallbacks();
1715}
1716
Valerie Hauc5011f92019-10-11 09:52:07 -07001717} // namespace android