blob: ea7078dd05c2e97e392ab6ca3bb8ae6e8fae3ce9 [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
Alec Mouri21d94322023-10-17 19:51:39 +000045#include <com_android_graphics_libgui_flags.h>
46
Valerie Hauc5011f92019-10-11 09:52:07 -070047using namespace std::chrono_literals;
48
49namespace android {
Alec Mouri21d94322023-10-17 19:51:39 +000050using namespace com::android::graphics::libgui;
Valerie Hauc5011f92019-10-11 09:52:07 -070051
Valerie Hauc5011f92019-10-11 09:52:07 -070052using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070053using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070054
chaviwd7deef72021-10-06 11:53:40 -050055class CountProducerListener : public BnProducerListener {
56public:
57 void onBufferReleased() override {
58 std::scoped_lock<std::mutex> lock(mMutex);
59 mNumReleased++;
60 mReleaseCallback.notify_one();
61 }
62
63 void waitOnNumberReleased(int32_t expectedNumReleased) {
64 std::unique_lock<std::mutex> lock(mMutex);
65 while (mNumReleased < expectedNumReleased) {
66 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
67 std::cv_status::timeout)
68 << "did not receive release";
69 }
70 }
71
72private:
73 std::mutex mMutex;
74 std::condition_variable mReleaseCallback;
75 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
76};
77
chaviwf10b9042021-10-13 15:48:59 -050078class TestBLASTBufferQueue : public BLASTBufferQueue {
79public:
80 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
81 int height, int32_t format)
82 : BLASTBufferQueue(name, surface, width, height, format) {}
83
chaviw6b9ffea2021-11-08 09:25:48 -060084 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
85 const std::vector<SurfaceControlStats>& stats) override {
86 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050087 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
88
89 {
90 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060091 mLastTransactionFrameNumber = frameNumber;
92 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050093 }
94 }
95
96 void waitForCallback(int64_t frameNumber) {
97 std::unique_lock lock{frameNumberMutex};
98 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -060099 while (mLastTransactionFrameNumber < frameNumber) {
100 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -0500101 }
102 }
103
104private:
105 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600106 std::condition_variable mWaitForCallbackCV;
107 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500108};
109
Valerie Hauc5011f92019-10-11 09:52:07 -0700110class BLASTBufferQueueHelper {
111public:
112 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500113 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
114 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700115 }
116
117 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800118 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700119 }
120
Tianhao Yao4861b102022-02-03 20:18:35 +0000121 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
122 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
123 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
124 }
125
Chavi Weingartenc398c012023-04-12 17:26:02 +0000126 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000127 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000128 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000129 }
130
131 void stopContinuousSyncTransaction() {
132 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700133 }
134
Chavi Weingartenc398c012023-04-12 17:26:02 +0000135 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
136
Vishnu Nairea0de002020-11-17 17:42:37 -0800137 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700138
Vishnu Nairea0de002020-11-17 17:42:37 -0800139 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700140
Tianhao Yao4861b102022-02-03 20:18:35 +0000141 std::function<void(Transaction*)> getTransactionReadyCallback() {
142 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
143 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700144
145 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
146 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
147 }
148
Valerie Hauc5011f92019-10-11 09:52:07 -0700149 const sp<SurfaceControl> getSurfaceControl() {
150 return mBlastBufferQueueAdapter->mSurfaceControl;
151 }
152
Vishnu Naira4fbca52021-07-07 16:52:34 -0700153 sp<Surface> getSurface() {
154 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
155 }
156
Valerie Haud3b90d22019-11-06 09:37:31 -0800157 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700158 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800159 // Wait until all but one of the submitted buffers have been released.
160 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800161 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
162 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700163 }
164
Vishnu Nair1506b182021-02-22 14:35:15 -0800165 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500166 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800167 }
168
chaviw0acd33a2021-11-02 11:55:37 -0500169 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
170 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
171 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
172 }
173
chaviwc1cf4022022-06-03 13:32:33 -0500174 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
175 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
176 }
177
Valerie Hauc5011f92019-10-11 09:52:07 -0700178private:
chaviwf10b9042021-10-13 15:48:59 -0500179 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700180};
181
182class BLASTBufferQueueTest : public ::testing::Test {
183public:
184protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700185 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700186 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700187 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700188 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
189 ASSERT_FALSE(ids.empty());
190 // display 0 is picked as this test is not much display depedent
191 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700192 ASSERT_NE(nullptr, mDisplayToken.get());
193 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700194 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700195 t.apply();
196 t.clear();
197
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700198 ui::DisplayState displayState;
199 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
200 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800201 mDisplayWidth = resolution.getWidth();
202 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000203 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700204 displayState.orientation);
Valerie Hauda3446e2019-10-14 15:49:22 -0700205
Melody Hsub9578222023-10-02 23:09:36 +0000206 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
207 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
208 ISurfaceComposerClient::eFXSurfaceBufferState,
209 /*parent*/ nullptr);
210
211 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
212 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
213 .show(mRootSurfaceControl)
214 .apply();
215
Valerie Hauda3446e2019-10-14 15:49:22 -0700216 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
217 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
218 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000219 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700220
Melody Hsub9578222023-10-02 23:09:36 +0000221 mCaptureArgs.sourceCrop = Rect(ui::Size(mDisplayWidth, mDisplayHeight));
222 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700223 }
224
chaviwd7deef72021-10-06 11:53:40 -0500225 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
226 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800227 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500228 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800229 }
230
chaviwd7deef72021-10-06 11:53:40 -0500231 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800232 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500233 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800234 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500235 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800236 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500237 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800238 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800239 }
240
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800241 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
242 uint8_t b) {
243 for (uint32_t row = rect.top; row < rect.bottom; row++) {
244 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700245 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
246 *pixel = r;
247 *(pixel + 1) = g;
248 *(pixel + 2) = b;
249 *(pixel + 3) = 255;
250 }
251 }
252 }
253
Valerie Hau5977fc82019-12-05 15:56:39 -0800254 void fillQuadrants(sp<GraphicBuffer>& buf) {
255 const auto bufWidth = buf->getWidth();
256 const auto bufHeight = buf->getHeight();
257 uint32_t* bufData;
258 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
259 reinterpret_cast<void**>(&bufData));
260 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
261 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
262 0, 0);
263 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
264 buf->getStride(), 0, 255, 0);
265 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
266 255);
267 buf->unlock();
268 }
269
270 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
271 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700272 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800273 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700274 const auto width = captureBuf->getWidth();
275 const auto height = captureBuf->getHeight();
276 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700277
278 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700279 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
280 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700281
282 for (uint32_t row = 0; row < height; row++) {
283 for (uint32_t col = 0; col < width; col++) {
284 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800285 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800286 bool inRegion;
287 if (!outsideRegion) {
288 inRegion = row >= region.top + border && row < region.bottom - border &&
289 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800290 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800291 inRegion = row >= region.top - border && row < region.bottom + border &&
292 col >= region.left - border && col < region.right + border;
293 }
294 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000295 ASSERT_GE(epsilon, abs(r - *(pixel)));
296 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
297 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800298 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000299 ASSERT_GE(epsilon, abs(r - *(pixel)));
300 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
301 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800302 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800303 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700304 }
305 }
chaviwd2432892020-07-24 17:42:39 -0700306 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700307 }
308
Vishnu Nair277142c2021-01-05 18:35:29 -0800309 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
310 nsecs_t presentTimeDelay) {
311 int slot;
312 sp<Fence> fence;
313 sp<GraphicBuffer> buf;
314 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
315 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
316 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500317 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800318 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
319
320 uint32_t* bufData;
321 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
322 reinterpret_cast<void**>(&bufData));
323 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
324 buf->unlock();
325
326 IGraphicBufferProducer::QueueBufferOutput qbOutput;
327 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
328 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
329 Rect(mDisplayWidth, mDisplayHeight / 2),
330 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
331 Fence::NO_FENCE);
332 igbp->queueBuffer(slot, input, &qbOutput);
333 }
334
Valerie Hauc5011f92019-10-11 09:52:07 -0700335 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700336 sp<ISurfaceComposer> mComposer;
337
338 sp<IBinder> mDisplayToken;
339
Valerie Hauc5011f92019-10-11 09:52:07 -0700340 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000341 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700342
343 uint32_t mDisplayWidth;
344 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700345
Melody Hsub9578222023-10-02 23:09:36 +0000346 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700347 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500348 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700349};
350
351TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
352 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700353 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700354 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700355 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
356 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000357 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700358}
359
360TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700361 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700362 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700363 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
Melody Hsub9578222023-10-02 23:09:36 +0000364 PIXEL_FORMAT_RGBA_8888,
365 ISurfaceComposerClient::eFXSurfaceBufferState,
366 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700367 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700368 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800369 sp<IGraphicBufferProducer> igbProducer;
370 setUpProducer(adapter, igbProducer);
371
372 int32_t width;
373 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
374 ASSERT_EQ(mDisplayWidth / 2, width);
375 int32_t height;
376 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
377 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700378}
379
Tianhao Yao4861b102022-02-03 20:18:35 +0000380TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700381 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000382 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
383 auto callback = [](Transaction*) {};
384 adapter.syncNextTransaction(callback);
385 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700386}
Valerie Hauda3446e2019-10-14 15:49:22 -0700387
Valerie Haubf29e042020-02-06 11:40:38 -0800388TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800389 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
390 sp<IGraphicBufferProducer> igbProducer;
391 setUpProducer(adapter, igbProducer);
392
393 int slot;
394 sp<Fence> fence;
395 sp<GraphicBuffer> buf;
396 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
397 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
398 nullptr, nullptr);
399 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
400 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
401
402 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
403 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800404 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
405 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800406 Rect(mDisplayWidth, mDisplayHeight),
407 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
408 Fence::NO_FENCE);
409 igbProducer->queueBuffer(slot, input, &qbOutput);
410 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
411
412 adapter.waitForCallbacks();
413 ASSERT_GE(systemTime(), desiredPresentTime);
414}
415
Valerie Hauda3446e2019-10-14 15:49:22 -0700416TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
417 uint8_t r = 255;
418 uint8_t g = 0;
419 uint8_t b = 0;
420
421 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800422 sp<IGraphicBufferProducer> igbProducer;
423 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700424
425 int slot;
426 sp<Fence> fence;
427 sp<GraphicBuffer> buf;
428 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
429 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
430 nullptr, nullptr);
431 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
432 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
433
434 uint32_t* bufData;
435 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
436 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800437 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700438 buf->unlock();
439
Valerie Haud3b90d22019-11-06 09:37:31 -0800440 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800441 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
442 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700443 Rect(mDisplayWidth, mDisplayHeight),
444 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
445 Fence::NO_FENCE);
446 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800447 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700448
Patrick Williams0eb09c62023-07-28 11:24:35 -0500449 // ensure the buffer queue transaction has been committed
450 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700451
452 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000453 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800454 ASSERT_NO_FATAL_FAILURE(
455 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700456}
Valerie Haud3b90d22019-11-06 09:37:31 -0800457
458TEST_F(BLASTBufferQueueTest, TripleBuffering) {
459 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
460 sp<IGraphicBufferProducer> igbProducer;
461 setUpProducer(adapter, igbProducer);
462
463 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700464 int minUndequeuedBuffers = 0;
465 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
466 const auto bufferCount = minUndequeuedBuffers + 2;
467
468 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800469 int slot;
470 sp<Fence> fence;
471 sp<GraphicBuffer> buf;
472 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
473 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
474 nullptr, nullptr);
475 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
476 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
477 allocated.push_back({slot, fence});
478 }
479 for (int i = 0; i < allocated.size(); i++) {
480 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
481 }
482
Valerie Haua32c5522019-12-09 10:11:08 -0800483 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800484 int slot;
485 sp<Fence> fence;
486 sp<GraphicBuffer> buf;
487 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
488 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
489 nullptr, nullptr);
490 ASSERT_EQ(NO_ERROR, ret);
491 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800492 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
493 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800494 Rect(mDisplayWidth, mDisplayHeight),
495 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
496 Fence::NO_FENCE);
497 igbProducer->queueBuffer(slot, input, &qbOutput);
498 }
499 adapter.waitForCallbacks();
500}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800501
502TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
503 uint8_t r = 255;
504 uint8_t g = 0;
505 uint8_t b = 0;
506
507 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
508 sp<IGraphicBufferProducer> igbProducer;
509 setUpProducer(adapter, igbProducer);
510 int slot;
511 sp<Fence> fence;
512 sp<GraphicBuffer> buf;
513 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
514 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
515 nullptr, nullptr);
516 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
517 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
518
519 uint32_t* bufData;
520 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
521 reinterpret_cast<void**>(&bufData));
522 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
523 buf->unlock();
524
525 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800526 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
527 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800528 Rect(mDisplayWidth, mDisplayHeight / 2),
529 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
530 Fence::NO_FENCE);
531 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800532 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800533
Patrick Williams0eb09c62023-07-28 11:24:35 -0500534 // ensure the buffer queue transaction has been committed
535 Transaction().apply(true /* synchronous */);
536
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800537 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000538 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700539
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800540 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000541 checkScreenCapture(r, g, b,
542 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800543}
544
545TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
546 uint8_t r = 255;
547 uint8_t g = 0;
548 uint8_t b = 0;
549
550 int32_t bufferSideLength =
551 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
552 int32_t finalCropSideLength = bufferSideLength / 2;
553
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800554 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
555 sp<IGraphicBufferProducer> igbProducer;
556 setUpProducer(adapter, igbProducer);
557 int slot;
558 sp<Fence> fence;
559 sp<GraphicBuffer> buf;
560 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
561 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
562 nullptr, nullptr);
563 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
564 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
565
566 uint32_t* bufData;
567 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
568 reinterpret_cast<void**>(&bufData));
569 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
570 fillBuffer(bufData,
571 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
572 buf->getHeight()),
573 buf->getStride(), r, g, b);
574 buf->unlock();
575
576 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800577 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
578 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800579 Rect(bufferSideLength, finalCropSideLength),
580 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
581 Fence::NO_FENCE);
582 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800583 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800584
Patrick Williams0eb09c62023-07-28 11:24:35 -0500585 // ensure the buffer queue transaction has been committed
586 Transaction().apply(true /* synchronous */);
587
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800588 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000589 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700590 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
591 {10, 10, (int32_t)bufferSideLength - 10,
592 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800593 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700594 checkScreenCapture(0, 0, 0,
595 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
596 /*border*/ 0, /*outsideRegion*/ true));
597}
598
599TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700600 Rect windowSize(1000, 1000);
601 Rect bufferSize(windowSize);
602 Rect bufferCrop(200, 200, 700, 700);
603
604 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
605 sp<IGraphicBufferProducer> igbProducer;
606 setUpProducer(adapter, igbProducer);
607 int slot;
608 sp<Fence> fence;
609 sp<GraphicBuffer> buf;
610 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
611 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
612 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
613 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
614 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
615
616 uint32_t* bufData;
617 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
618 reinterpret_cast<void**>(&bufData));
619 // fill buffer with grey
620 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
621
622 // fill crop area with different colors so we can verify the cropped region has been scaled
623 // correctly.
624 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
625 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
626 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
627 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
628 buf->unlock();
629
630 IGraphicBufferProducer::QueueBufferOutput qbOutput;
631 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
632 HAL_DATASPACE_UNKNOWN,
633 bufferCrop /* Rect::INVALID_RECT */,
634 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
635 Fence::NO_FENCE);
636 igbProducer->queueBuffer(slot, input, &qbOutput);
637 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
638
Patrick Williams0eb09c62023-07-28 11:24:35 -0500639 // ensure the buffer queue transaction has been committed
640 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700641
Melody Hsub9578222023-10-02 23:09:36 +0000642 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700643
644 // Verify cropped region is scaled correctly.
645 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
646 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
647 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
648 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
649 // Verify outside region is black.
650 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
651 {0, 0, (int32_t)windowSize.getWidth(),
652 (int32_t)windowSize.getHeight()},
653 /*border*/ 0, /*outsideRegion*/ true));
654}
655
656TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700657 Rect windowSize(1000, 1000);
658 Rect bufferSize(500, 500);
659 Rect bufferCrop(100, 100, 350, 350);
660
661 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
662 sp<IGraphicBufferProducer> igbProducer;
663 setUpProducer(adapter, igbProducer);
664 int slot;
665 sp<Fence> fence;
666 sp<GraphicBuffer> buf;
667 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
668 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
669 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
670 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
671 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
672
673 uint32_t* bufData;
674 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
675 reinterpret_cast<void**>(&bufData));
676 // fill buffer with grey
677 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
678
679 // fill crop area with different colors so we can verify the cropped region has been scaled
680 // correctly.
681 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
682 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
683 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
684 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
685 buf->unlock();
686
687 IGraphicBufferProducer::QueueBufferOutput qbOutput;
688 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
689 HAL_DATASPACE_UNKNOWN,
690 bufferCrop /* Rect::INVALID_RECT */,
691 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
692 Fence::NO_FENCE);
693 igbProducer->queueBuffer(slot, input, &qbOutput);
694 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
695
Patrick Williams0eb09c62023-07-28 11:24:35 -0500696 // ensure the buffer queue transaction has been committed
697 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700698
Melody Hsub9578222023-10-02 23:09:36 +0000699 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700700 // Verify cropped region is scaled correctly.
701 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
702 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
703 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
704 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
705 // Verify outside region is black.
706 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
707 {0, 0, (int32_t)windowSize.getWidth(),
708 (int32_t)windowSize.getHeight()},
709 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800710}
711
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700712// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
713// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
714TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
715 uint8_t r = 255;
716 uint8_t g = 0;
717 uint8_t b = 0;
718
719 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
720 sp<IGraphicBufferProducer> igbProducer;
721 setUpProducer(adapter, igbProducer);
722 {
723 int slot;
724 sp<Fence> fence;
725 sp<GraphicBuffer> buf;
726 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
727 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
728 nullptr, nullptr);
729 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
730 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
731
732 uint32_t* bufData;
733 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
734 reinterpret_cast<void**>(&bufData));
735 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
736 buf->unlock();
737
738 IGraphicBufferProducer::QueueBufferOutput qbOutput;
739 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
740 HAL_DATASPACE_UNKNOWN, {},
741 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
742 Fence::NO_FENCE);
743 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500744
745 // ensure the buffer queue transaction has been committed
746 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700747 }
748 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000749 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700750
751 ASSERT_NO_FATAL_FAILURE(
752 checkScreenCapture(r, g, b,
753 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
754
755 // update the size to half the display and dequeue a buffer quarter of the display.
756 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
757
758 {
759 int slot;
760 sp<Fence> fence;
761 sp<GraphicBuffer> buf;
762 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
763 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
764 nullptr, nullptr);
765 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
766 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
767
768 uint32_t* bufData;
769 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
770 reinterpret_cast<void**>(&bufData));
771 g = 255;
772 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
773 buf->unlock();
774
775 IGraphicBufferProducer::QueueBufferOutput qbOutput;
776 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
777 HAL_DATASPACE_UNKNOWN, {},
778 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
779 0, Fence::NO_FENCE);
780 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500781 // ensure the buffer queue transaction has been committed
782 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700783 }
784 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000785 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700786 // verify we still scale the buffer to the new size (half the screen height)
787 ASSERT_NO_FATAL_FAILURE(
788 checkScreenCapture(r, g, b,
789 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
790}
791
chaviwd7deef72021-10-06 11:53:40 -0500792TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
793 uint8_t r = 255;
794 uint8_t g = 0;
795 uint8_t b = 0;
796
797 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
798
799 sp<IGraphicBufferProducer> igbProducer;
800 setUpProducer(adapter, igbProducer);
801
chaviwa1c4c822021-11-10 18:11:58 -0600802 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000803 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500804 queueBuffer(igbProducer, 0, 255, 0, 0);
805
806 // queue non sync buffer, so this one should get blocked
807 // Add a present delay to allow the first screenshot to get taken.
808 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
809 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
810
811 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600812 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500813 transactionCallback.getContext())
814 .apply();
815
816 CallbackData callbackData;
817 transactionCallback.getCallbackData(&callbackData);
818
chaviw0acd33a2021-11-02 11:55:37 -0500819 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000820 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500821 ASSERT_NO_FATAL_FAILURE(
822 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
823
824 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000825 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500826 ASSERT_NO_FATAL_FAILURE(
827 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
828}
829
830TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
831 uint8_t r = 255;
832 uint8_t g = 0;
833 uint8_t b = 0;
834
835 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
836
837 sp<IGraphicBufferProducer> igbProducer;
838 setUpProducer(adapter, igbProducer);
839
840 Transaction mainTransaction;
841
chaviwa1c4c822021-11-10 18:11:58 -0600842 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000843 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500844 queueBuffer(igbProducer, 0, 255, 0, 0);
845
chaviwa1c4c822021-11-10 18:11:58 -0600846 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500847
Tianhao Yao4861b102022-02-03 20:18:35 +0000848 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500849 queueBuffer(igbProducer, r, g, b, 0);
850
chaviwa1c4c822021-11-10 18:11:58 -0600851 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500852 // Expect 1 buffer to be released even before sending to SurfaceFlinger
853 mProducerListener->waitOnNumberReleased(1);
854
855 CallbackHelper transactionCallback;
856 mainTransaction
857 .addTransactionCompletedCallback(transactionCallback.function,
858 transactionCallback.getContext())
859 .apply();
860
861 CallbackData callbackData;
862 transactionCallback.getCallbackData(&callbackData);
863
864 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000865 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500866 ASSERT_NO_FATAL_FAILURE(
867 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
868}
869
870TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
871 uint8_t r = 255;
872 uint8_t g = 0;
873 uint8_t b = 0;
874
875 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
876
877 sp<IGraphicBufferProducer> igbProducer;
878 setUpProducer(adapter, igbProducer);
879
880 Transaction mainTransaction;
881
chaviwa1c4c822021-11-10 18:11:58 -0600882 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500883 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000884 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500885 queueBuffer(igbProducer, 0, 255, 0, 0);
886
chaviwa1c4c822021-11-10 18:11:58 -0600887 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500888
chaviwa1c4c822021-11-10 18:11:58 -0600889 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500890 queueBuffer(igbProducer, 0, 0, 255, 0);
891
892 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000893 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500894 queueBuffer(igbProducer, r, g, b, 0);
895 // Expect 1 buffer to be released because the non sync transaction should merge
896 // with the sync
897 mProducerListener->waitOnNumberReleased(1);
898
chaviwa1c4c822021-11-10 18:11:58 -0600899 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500900 // Expect 2 buffers to be released due to merging the two syncs.
901 mProducerListener->waitOnNumberReleased(2);
902
903 CallbackHelper transactionCallback;
904 mainTransaction
905 .addTransactionCompletedCallback(transactionCallback.function,
906 transactionCallback.getContext())
907 .apply();
908
909 CallbackData callbackData;
910 transactionCallback.getCallbackData(&callbackData);
911
912 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000913 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500914 ASSERT_NO_FATAL_FAILURE(
915 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
916}
917
918TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
919 uint8_t r = 255;
920 uint8_t g = 0;
921 uint8_t b = 0;
922
923 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
924
925 sp<IGraphicBufferProducer> igbProducer;
926 setUpProducer(adapter, igbProducer, 3);
927
928 Transaction mainTransaction;
929
chaviwa1c4c822021-11-10 18:11:58 -0600930 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500931 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000932 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500933 queueBuffer(igbProducer, 0, 255, 0, 0);
934
chaviwa1c4c822021-11-10 18:11:58 -0600935 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500936
chaviwa1c4c822021-11-10 18:11:58 -0600937 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500938 queueBuffer(igbProducer, 0, 0, 255, 0);
939 queueBuffer(igbProducer, 0, 0, 255, 0);
940 queueBuffer(igbProducer, 0, 0, 255, 0);
941
942 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000943 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500944 queueBuffer(igbProducer, r, g, b, 0);
945 // Expect 3 buffers to be released because the non sync transactions should merge
946 // with the sync
947 mProducerListener->waitOnNumberReleased(3);
948
chaviwa1c4c822021-11-10 18:11:58 -0600949 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500950 // Expect 4 buffers to be released due to merging the two syncs.
951 mProducerListener->waitOnNumberReleased(4);
952
953 CallbackHelper transactionCallback;
954 mainTransaction
955 .addTransactionCompletedCallback(transactionCallback.function,
956 transactionCallback.getContext())
957 .apply();
958
959 CallbackData callbackData;
960 transactionCallback.getCallbackData(&callbackData);
961
962 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000963 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500964 ASSERT_NO_FATAL_FAILURE(
965 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
966}
967
968// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
969// continue processing is for a release callback from SurfaceFlinger.
970// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
971// continue acquiring buffers.
972TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
973 uint8_t r = 255;
974 uint8_t g = 0;
975 uint8_t b = 0;
976
977 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
978
979 sp<IGraphicBufferProducer> igbProducer;
980 setUpProducer(adapter, igbProducer, 4);
981
982 Transaction mainTransaction;
983
984 // Send a buffer to SF
985 queueBuffer(igbProducer, 0, 255, 0, 0);
986
chaviwa1c4c822021-11-10 18:11:58 -0600987 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500988 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000989 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500990 queueBuffer(igbProducer, 0, 255, 0, 0);
991
chaviwa1c4c822021-11-10 18:11:58 -0600992 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500993
chaviwa1c4c822021-11-10 18:11:58 -0600994 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500995 queueBuffer(igbProducer, 0, 0, 255, 0);
996 queueBuffer(igbProducer, 0, 0, 255, 0);
997 queueBuffer(igbProducer, 0, 0, 255, 0);
998
999 // apply the first synced buffer to ensure we have to wait on SF
1000 mainTransaction.apply();
1001
1002 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001003 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001004 queueBuffer(igbProducer, r, g, b, 0);
1005 // Expect 2 buffers to be released because the non sync transactions should merge
1006 // with the sync
1007 mProducerListener->waitOnNumberReleased(3);
1008
chaviwa1c4c822021-11-10 18:11:58 -06001009 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001010
1011 CallbackHelper transactionCallback;
1012 mainTransaction
1013 .addTransactionCompletedCallback(transactionCallback.function,
1014 transactionCallback.getContext())
1015 .apply();
1016
1017 CallbackData callbackData;
1018 transactionCallback.getCallbackData(&callbackData);
1019
1020 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001021 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001022 ASSERT_NO_FATAL_FAILURE(
1023 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1024}
1025
Tianhao Yao4861b102022-02-03 20:18:35 +00001026TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001027 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1028
1029 sp<IGraphicBufferProducer> igbProducer;
1030 setUpProducer(adapter, igbProducer);
1031
1032 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001033 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001034 queueBuffer(igbProducer, 0, 255, 0, 0);
1035 queueBuffer(igbProducer, 0, 0, 255, 0);
1036 // There should only be one frame submitted since the first frame will be released.
1037 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001038 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001039
1040 // queue non sync buffer, so this one should get blocked
1041 // Add a present delay to allow the first screenshot to get taken.
1042 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1043 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1044
1045 CallbackHelper transactionCallback;
1046 next.addTransactionCompletedCallback(transactionCallback.function,
1047 transactionCallback.getContext())
1048 .apply();
1049
1050 CallbackData callbackData;
1051 transactionCallback.getCallbackData(&callbackData);
1052
1053 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001054 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001055 ASSERT_NO_FATAL_FAILURE(
1056 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1057
1058 mProducerListener->waitOnNumberReleased(2);
1059 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001060 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001061 ASSERT_NO_FATAL_FAILURE(
1062 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1063}
1064
chaviw3b4bdcf2022-03-17 09:27:03 -05001065TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1066 std::mutex mutex;
1067 std::condition_variable callbackReceivedCv;
1068 bool receivedCallback = false;
1069
1070 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1071 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1072 auto callback = [&](Transaction*) {
1073 std::unique_lock<std::mutex> lock(mutex);
1074 receivedCallback = true;
1075 callbackReceivedCv.notify_one();
1076 };
1077 adapter.syncNextTransaction(callback);
1078 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1079
1080 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001081 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1082
1083 sp<IGraphicBufferProducer> igbProducer;
1084 setUpProducer(adapter, igbProducer);
1085 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001086
1087 std::unique_lock<std::mutex> lock(mutex);
1088 if (!receivedCallback) {
1089 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1090 std::cv_status::timeout)
1091 << "did not receive callback";
1092 }
1093
1094 ASSERT_TRUE(receivedCallback);
1095}
1096
Chavi Weingartenc398c012023-04-12 17:26:02 +00001097TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1098 std::mutex mutex;
1099 std::condition_variable callbackReceivedCv;
1100 bool receivedCallback = false;
1101
1102 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1103 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1104 auto callback = [&](Transaction*) {
1105 std::unique_lock<std::mutex> lock(mutex);
1106 receivedCallback = true;
1107 callbackReceivedCv.notify_one();
1108 };
1109 adapter.syncNextTransaction(callback);
1110 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1111
1112 adapter.clearSyncTransaction();
1113
1114 sp<IGraphicBufferProducer> igbProducer;
1115 setUpProducer(adapter, igbProducer);
1116 queueBuffer(igbProducer, 0, 255, 0, 0);
1117
1118 std::unique_lock<std::mutex> lock(mutex);
1119 if (!receivedCallback) {
1120 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1121 std::cv_status::timeout)
1122 << "did not receive callback";
1123 }
1124
1125 ASSERT_FALSE(receivedCallback);
1126}
1127
chaviwc1cf4022022-06-03 13:32:33 -05001128TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1129 uint8_t r = 255;
1130 uint8_t g = 0;
1131 uint8_t b = 0;
1132
1133 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1134
1135 sp<IGraphicBufferProducer> igbProducer;
1136 setUpProducer(adapter, igbProducer);
1137
1138 Transaction sync;
1139 adapter.setSyncTransaction(sync);
1140 queueBuffer(igbProducer, 0, 255, 0, 0);
1141
1142 // Merge a transaction that has a complete callback into the next frame so we can get notified
1143 // when to take a screenshot
1144 CallbackHelper transactionCallback;
1145 Transaction t;
1146 t.addTransactionCompletedCallback(transactionCallback.function,
1147 transactionCallback.getContext());
1148 adapter.mergeWithNextTransaction(&t, 2);
1149 queueBuffer(igbProducer, r, g, b, 0);
1150
1151 // Drop the buffer, but ensure the next one continues to get processed.
1152 sync.setBuffer(mSurfaceControl, nullptr);
1153
1154 CallbackData callbackData;
1155 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001156 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001157 ASSERT_NO_FATAL_FAILURE(
1158 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001159 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001160}
1161
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001162// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1163// until the old surface control is destroyed. This is not necessarily a bug but to document a
1164// limitation with the update API and to test any changes to make the api more robust. The current
1165// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1166TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1167 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1168 std::vector<sp<SurfaceControl>> surfaceControls;
1169 sp<IGraphicBufferProducer> igbProducer;
1170 for (int i = 0; i < 10; i++) {
1171 sp<SurfaceControl> sc =
1172 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1173 PIXEL_FORMAT_RGBA_8888,
1174 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001175 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001176 Transaction()
1177 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1178 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1179 .show(mSurfaceControl)
1180 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1181 .apply(true);
1182 surfaceControls.push_back(sc);
1183 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1184
1185 setUpProducer(adapter, igbProducer);
1186 Transaction next;
1187 queueBuffer(igbProducer, 0, 255, 0, 0);
1188 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001189 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001190 queueBuffer(igbProducer, 255, 0, 0, 0);
1191
1192 CallbackHelper transactionCallback;
1193 next.addTransactionCompletedCallback(transactionCallback.function,
1194 transactionCallback.getContext())
1195 .apply();
1196
1197 CallbackData callbackData;
1198 transactionCallback.getCallbackData(&callbackData);
1199 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001200 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001201 ASSERT_NO_FATAL_FAILURE(
1202 checkScreenCapture(255, 0, 0,
1203 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1204 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1205 }
1206}
1207
1208// See DISABLED_DisconnectProducerTest
1209TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1210 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1211 std::vector<sp<SurfaceControl>> surfaceControls;
1212 sp<IGraphicBufferProducer> igbProducer;
1213 for (int i = 0; i < 10; i++) {
1214 sp<SurfaceControl> sc =
1215 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1216 PIXEL_FORMAT_RGBA_8888,
1217 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001218 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001219 Transaction()
1220 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1221 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1222 .show(mSurfaceControl)
1223 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1224 .apply(true);
1225 surfaceControls.push_back(sc);
1226 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1227 setUpProducer(adapter, igbProducer);
1228
1229 Transaction next;
1230 queueBuffer(igbProducer, 0, 255, 0, 0);
1231 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001232 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001233 queueBuffer(igbProducer, 255, 0, 0, 0);
1234
1235 CallbackHelper transactionCallback;
1236 next.addTransactionCompletedCallback(transactionCallback.function,
1237 transactionCallback.getContext())
1238 .apply();
1239
1240 CallbackData callbackData;
1241 transactionCallback.getCallbackData(&callbackData);
1242 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001243 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001244 ASSERT_NO_FATAL_FAILURE(
1245 checkScreenCapture(255, 0, 0,
1246 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1247 }
1248}
1249
Vishnu Nair89496122020-12-14 17:14:53 -08001250class TestProducerListener : public BnProducerListener {
1251public:
1252 sp<IGraphicBufferProducer> mIgbp;
1253 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1254 void onBufferReleased() override {
1255 sp<GraphicBuffer> buffer;
1256 sp<Fence> fence;
1257 mIgbp->detachNextBuffer(&buffer, &fence);
1258 }
1259};
1260
1261TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1262 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1263 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1264 ASSERT_NE(nullptr, igbProducer.get());
1265 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1266 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1267 ASSERT_EQ(NO_ERROR,
1268 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1269 false, &qbOutput));
1270 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1271 for (int i = 0; i < 3; i++) {
1272 int slot;
1273 sp<Fence> fence;
1274 sp<GraphicBuffer> buf;
1275 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1276 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1277 nullptr, nullptr);
1278 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1279 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1280 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001281 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1282 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001283 Rect(mDisplayWidth, mDisplayHeight),
1284 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1285 Fence::NO_FENCE);
1286 igbProducer->queueBuffer(slot, input, &qbOutput);
1287 }
1288 adapter.waitForCallbacks();
1289}
1290
Vishnu Nair17dde612020-12-28 11:39:59 -08001291TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1292 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1293
1294 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1295 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1296 int queuesToNativeWindow = 0;
1297 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1298 &queuesToNativeWindow);
1299 ASSERT_EQ(NO_ERROR, err);
1300 ASSERT_EQ(queuesToNativeWindow, 1);
1301}
1302
Vishnu Naira4fbca52021-07-07 16:52:34 -07001303TEST_F(BLASTBufferQueueTest, TransformHint) {
1304 // Transform hint is provided to BBQ via the surface control passed by WM
1305 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1306
1307 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1308 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1309 ASSERT_NE(nullptr, igbProducer.get());
1310 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1311 sp<Surface> surface = adapter.getSurface();
1312
1313 // Before connecting to the surface, we do not get a valid transform hint
1314 int transformHint;
1315 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1316 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1317
1318 ASSERT_EQ(NO_ERROR,
1319 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1320
1321 // After connecting to the surface, we should get the correct hint.
1322 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1323 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1324
1325 ANativeWindow_Buffer buffer;
1326 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1327
1328 // Transform hint is updated via callbacks or surface control updates
1329 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1330 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1331
1332 // The hint does not change and matches the value used when dequeueing the buffer.
1333 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1334 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1335
1336 surface->unlockAndPost();
1337
1338 // After queuing the buffer, we get the updated transform hint
1339 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1340 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1341
1342 adapter.waitForCallbacks();
1343}
1344
Valerie Hau5977fc82019-12-05 15:56:39 -08001345class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1346public:
1347 void test(uint32_t tr) {
1348 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1349 sp<IGraphicBufferProducer> igbProducer;
1350 setUpProducer(adapter, igbProducer);
1351
1352 auto bufWidth = mDisplayWidth;
1353 auto bufHeight = mDisplayHeight;
1354 int slot;
1355 sp<Fence> fence;
1356 sp<GraphicBuffer> buf;
1357
1358 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1359 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1360 nullptr, nullptr);
1361 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1362 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1363
1364 fillQuadrants(buf);
1365
1366 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001367 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1368 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001369 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001370 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1371 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001372 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001373 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001374
Patrick Williams0eb09c62023-07-28 11:24:35 -05001375 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001376 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001377
Valerie Hau5977fc82019-12-05 15:56:39 -08001378 switch (tr) {
1379 case ui::Transform::ROT_0:
1380 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1381 {0, 0, (int32_t)mDisplayWidth / 2,
1382 (int32_t)mDisplayHeight / 2},
1383 1));
1384 ASSERT_NO_FATAL_FAILURE(
1385 checkScreenCapture(255, 0, 0,
1386 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1387 (int32_t)mDisplayHeight / 2},
1388 1));
1389 ASSERT_NO_FATAL_FAILURE(
1390 checkScreenCapture(0, 255, 0,
1391 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1392 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1393 1));
1394 ASSERT_NO_FATAL_FAILURE(
1395 checkScreenCapture(0, 0, 255,
1396 {0, (int32_t)mDisplayHeight / 2,
1397 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1398 1));
1399 break;
1400 case ui::Transform::FLIP_H:
1401 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1402 {0, 0, (int32_t)mDisplayWidth / 2,
1403 (int32_t)mDisplayHeight / 2},
1404 1));
1405 ASSERT_NO_FATAL_FAILURE(
1406 checkScreenCapture(0, 0, 0,
1407 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1408 (int32_t)mDisplayHeight / 2},
1409 1));
1410 ASSERT_NO_FATAL_FAILURE(
1411 checkScreenCapture(0, 0, 255,
1412 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1413 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1414 1));
1415 ASSERT_NO_FATAL_FAILURE(
1416 checkScreenCapture(0, 255, 0,
1417 {0, (int32_t)mDisplayHeight / 2,
1418 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1419 1));
1420 break;
1421 case ui::Transform::FLIP_V:
1422 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1423 {0, 0, (int32_t)mDisplayWidth / 2,
1424 (int32_t)mDisplayHeight / 2},
1425 1));
1426 ASSERT_NO_FATAL_FAILURE(
1427 checkScreenCapture(0, 255, 0,
1428 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1429 (int32_t)mDisplayHeight / 2},
1430 1));
1431 ASSERT_NO_FATAL_FAILURE(
1432 checkScreenCapture(255, 0, 0,
1433 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1434 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1435 1));
1436 ASSERT_NO_FATAL_FAILURE(
1437 checkScreenCapture(0, 0, 0,
1438 {0, (int32_t)mDisplayHeight / 2,
1439 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1440 1));
1441 break;
1442 case ui::Transform::ROT_90:
1443 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1444 {0, 0, (int32_t)mDisplayWidth / 2,
1445 (int32_t)mDisplayHeight / 2},
1446 1));
1447 ASSERT_NO_FATAL_FAILURE(
1448 checkScreenCapture(0, 0, 0,
1449 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1450 (int32_t)mDisplayHeight / 2},
1451 1));
1452 ASSERT_NO_FATAL_FAILURE(
1453 checkScreenCapture(255, 0, 0,
1454 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1455 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1456 1));
1457 ASSERT_NO_FATAL_FAILURE(
1458 checkScreenCapture(0, 255, 0,
1459 {0, (int32_t)mDisplayHeight / 2,
1460 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1461 1));
1462 break;
1463 case ui::Transform::ROT_180:
1464 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1465 {0, 0, (int32_t)mDisplayWidth / 2,
1466 (int32_t)mDisplayHeight / 2},
1467 1));
1468 ASSERT_NO_FATAL_FAILURE(
1469 checkScreenCapture(0, 0, 255,
1470 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1471 (int32_t)mDisplayHeight / 2},
1472 1));
1473 ASSERT_NO_FATAL_FAILURE(
1474 checkScreenCapture(0, 0, 0,
1475 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1476 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1477 1));
1478 ASSERT_NO_FATAL_FAILURE(
1479 checkScreenCapture(255, 0, 0,
1480 {0, (int32_t)mDisplayHeight / 2,
1481 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1482 1));
1483 break;
1484 case ui::Transform::ROT_270:
1485 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1486 {0, 0, (int32_t)mDisplayWidth / 2,
1487 (int32_t)mDisplayHeight / 2},
1488 1));
1489 ASSERT_NO_FATAL_FAILURE(
1490 checkScreenCapture(0, 255, 0,
1491 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1492 (int32_t)mDisplayHeight / 2},
1493 1));
1494 ASSERT_NO_FATAL_FAILURE(
1495 checkScreenCapture(0, 0, 255,
1496 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1497 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1498 1));
1499 ASSERT_NO_FATAL_FAILURE(
1500 checkScreenCapture(0, 0, 0,
1501 {0, (int32_t)mDisplayHeight / 2,
1502 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1503 1));
1504 }
1505 }
1506};
1507
1508TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1509 test(ui::Transform::ROT_0);
1510}
1511
1512TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1513 test(ui::Transform::FLIP_H);
1514}
1515
1516TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1517 test(ui::Transform::FLIP_V);
1518}
1519
1520TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1521 test(ui::Transform::ROT_90);
1522}
1523
1524TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1525 test(ui::Transform::ROT_180);
1526}
1527
1528TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1529 test(ui::Transform::ROT_270);
1530}
Valerie Hau871d6352020-01-29 08:44:02 -08001531
1532class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1533public:
1534 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001535 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001536 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001537 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001538 int slot;
1539 sp<Fence> fence;
1540 sp<GraphicBuffer> buf;
1541 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1542 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1543 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001544 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1545 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1546 }
Valerie Hau871d6352020-01-29 08:44:02 -08001547
Vishnu Nairde66dc72021-06-17 17:54:41 -07001548 *outRequestedPresentTime = requestedPresentTime;
1549 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1550 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001551 Rect(mDisplayWidth, mDisplayHeight),
1552 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1553 Fence::NO_FENCE, /*sticky*/ 0,
1554 getFrameTimestamps);
1555 if (postedTime) *postedTime = systemTime();
1556 igbProducer->queueBuffer(slot, input, qbOutput);
1557 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001558 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001559};
1560
1561TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1562 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1563 sp<IGraphicBufferProducer> igbProducer;
1564 ProducerFrameEventHistory history;
1565 setUpProducer(adapter, igbProducer);
1566
1567 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1568 nsecs_t requestedPresentTimeA = 0;
1569 nsecs_t postedTimeA = 0;
1570 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1571 history.applyDelta(qbOutput.frameTimestamps);
1572
1573 FrameEvents* events = nullptr;
1574 events = history.getFrame(1);
1575 ASSERT_NE(nullptr, events);
1576 ASSERT_EQ(1, events->frameNumber);
1577 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1578 ASSERT_GE(events->postedTime, postedTimeA);
1579
Vishnu Nair1506b182021-02-22 14:35:15 -08001580 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001581
1582 // queue another buffer so we query for frame event deltas
1583 nsecs_t requestedPresentTimeB = 0;
1584 nsecs_t postedTimeB = 0;
1585 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1586 history.applyDelta(qbOutput.frameTimestamps);
Alec Mouri21d94322023-10-17 19:51:39 +00001587
1588 adapter.waitForCallback(2);
1589
Valerie Hau871d6352020-01-29 08:44:02 -08001590 events = history.getFrame(1);
1591 ASSERT_NE(nullptr, events);
1592
1593 // frame number, requestedPresentTime, and postTime should not have changed
1594 ASSERT_EQ(1, events->frameNumber);
1595 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1596 ASSERT_GE(events->postedTime, postedTimeA);
1597
1598 ASSERT_GE(events->latchTime, postedTimeA);
Alec Mouri21d94322023-10-17 19:51:39 +00001599 if (flags::frametimestamps_previousrelease()) {
1600 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1601 }
Valerie Hau871d6352020-01-29 08:44:02 -08001602 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1603 ASSERT_NE(nullptr, events->displayPresentFence);
1604 ASSERT_NE(nullptr, events->releaseFence);
1605
1606 // we should also have gotten the initial values for the next frame
1607 events = history.getFrame(2);
1608 ASSERT_NE(nullptr, events);
1609 ASSERT_EQ(2, events->frameNumber);
1610 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1611 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001612
Alec Mouri21d94322023-10-17 19:51:39 +00001613 // Now do the same as above with a third buffer, so that timings related to
1614 // buffer releases make it back to the first frame.
1615 nsecs_t requestedPresentTimeC = 0;
1616 nsecs_t postedTimeC = 0;
1617 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1618 history.applyDelta(qbOutput.frameTimestamps);
1619
1620 adapter.waitForCallback(3);
1621
1622 // Check the first frame...
1623 events = history.getFrame(1);
1624 ASSERT_NE(nullptr, events);
1625 ASSERT_EQ(1, events->frameNumber);
1626 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1627 ASSERT_GE(events->postedTime, postedTimeA);
1628 ASSERT_GE(events->latchTime, postedTimeA);
1629 // Now dequeueReadyTime is valid, because the release timings finally
1630 // propaged to queueBuffer()
1631 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1632 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1633 ASSERT_NE(nullptr, events->displayPresentFence);
1634 ASSERT_NE(nullptr, events->releaseFence);
1635
1636 // ...and the second
1637 events = history.getFrame(2);
1638 ASSERT_NE(nullptr, events);
1639 ASSERT_EQ(2, events->frameNumber);
1640 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1641 ASSERT_GE(events->postedTime, postedTimeB);
1642 ASSERT_GE(events->latchTime, postedTimeB);
1643 if (flags::frametimestamps_previousrelease()) {
1644 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1645 }
1646 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1647 ASSERT_NE(nullptr, events->displayPresentFence);
1648 ASSERT_NE(nullptr, events->releaseFence);
1649
1650 // ...and finally the third!
1651 events = history.getFrame(3);
1652 ASSERT_NE(nullptr, events);
1653 ASSERT_EQ(3, events->frameNumber);
1654 ASSERT_EQ(requestedPresentTimeC, events->requestedPresentTime);
1655 ASSERT_GE(events->postedTime, postedTimeC);
1656
Valerie Hau78491e92020-04-15 13:10:56 -07001657 // wait for any callbacks that have not been received
1658 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001659}
Vishnu Nair083efd32021-02-12 09:32:30 -08001660
Vishnu Nair083efd32021-02-12 09:32:30 -08001661TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1662 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1663 sp<IGraphicBufferProducer> igbProducer;
1664 setUpProducer(adapter, igbProducer);
1665
1666 ProducerFrameEventHistory history;
1667 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1668 nsecs_t requestedPresentTimeA = 0;
1669 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001670 // Present the frame sometime in the future so we can add two frames to the queue so the older
1671 // one will be dropped.
1672 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001673 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001674 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001675 history.applyDelta(qbOutput.frameTimestamps);
1676
1677 FrameEvents* events = nullptr;
1678 events = history.getFrame(1);
1679 ASSERT_NE(nullptr, events);
1680 ASSERT_EQ(1, events->frameNumber);
1681 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1682 ASSERT_GE(events->postedTime, postedTimeA);
1683
1684 // queue another buffer so the first can be dropped
1685 nsecs_t requestedPresentTimeB = 0;
1686 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001687 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1688 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1689 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001690 history.applyDelta(qbOutput.frameTimestamps);
1691 events = history.getFrame(1);
1692 ASSERT_NE(nullptr, events);
1693
1694 // frame number, requestedPresentTime, and postTime should not have changed
1695 ASSERT_EQ(1, events->frameNumber);
1696 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1697 ASSERT_GE(events->postedTime, postedTimeA);
1698
Vishnu Nairde66dc72021-06-17 17:54:41 -07001699 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001700 ASSERT_FALSE(events->hasLatchInfo());
1701 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001702 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1703 ASSERT_FALSE(events->hasDisplayPresentInfo());
1704 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001705
Vishnu Nairde66dc72021-06-17 17:54:41 -07001706 // wait for the last transaction to be completed.
1707 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001708
Vishnu Nairde66dc72021-06-17 17:54:41 -07001709 // queue another buffer so we query for frame event deltas
1710 nsecs_t requestedPresentTimeC = 0;
1711 nsecs_t postedTimeC = 0;
1712 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1713 history.applyDelta(qbOutput.frameTimestamps);
1714
Alec Mouri21d94322023-10-17 19:51:39 +00001715 adapter.waitForCallback(3);
1716
Vishnu Nairde66dc72021-06-17 17:54:41 -07001717 // frame number, requestedPresentTime, and postTime should not have changed
1718 ASSERT_EQ(1, events->frameNumber);
1719 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1720 ASSERT_GE(events->postedTime, postedTimeA);
1721
1722 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1723 ASSERT_FALSE(events->hasLatchInfo());
1724 ASSERT_FALSE(events->hasDequeueReadyInfo());
1725 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1726 ASSERT_FALSE(events->hasDisplayPresentInfo());
1727 ASSERT_FALSE(events->hasReleaseInfo());
1728
1729 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001730 events = history.getFrame(2);
1731 ASSERT_NE(nullptr, events);
1732 ASSERT_EQ(2, events->frameNumber);
1733 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1734 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001735 ASSERT_GE(events->latchTime, postedTimeB);
Alec Mouri21d94322023-10-17 19:51:39 +00001736
1737 if (flags::frametimestamps_previousrelease()) {
1738 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1739 }
1740 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1741 ASSERT_NE(nullptr, events->displayPresentFence);
1742 ASSERT_NE(nullptr, events->releaseFence);
1743
1744 // Queue another buffer to check for timestamps that came late
1745 nsecs_t requestedPresentTimeD = 0;
1746 nsecs_t postedTimeD = 0;
1747 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeD, &postedTimeD, &qbOutput, true);
1748 history.applyDelta(qbOutput.frameTimestamps);
1749
1750 adapter.waitForCallback(4);
1751
1752 // frame number, requestedPresentTime, and postTime should not have changed
1753 events = history.getFrame(1);
1754 ASSERT_EQ(1, events->frameNumber);
1755 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1756 ASSERT_GE(events->postedTime, postedTimeA);
1757
1758 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1759 ASSERT_FALSE(events->hasLatchInfo());
1760 ASSERT_FALSE(events->hasDequeueReadyInfo());
1761 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1762 ASSERT_FALSE(events->hasDisplayPresentInfo());
1763 ASSERT_FALSE(events->hasReleaseInfo());
1764
1765 // we should also have gotten values for the presented frame
1766 events = history.getFrame(2);
1767 ASSERT_NE(nullptr, events);
1768 ASSERT_EQ(2, events->frameNumber);
1769 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1770 ASSERT_GE(events->postedTime, postedTimeB);
1771 ASSERT_GE(events->latchTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001772 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1773 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1774 ASSERT_NE(nullptr, events->displayPresentFence);
1775 ASSERT_NE(nullptr, events->releaseFence);
1776
1777 // wait for any callbacks that have not been received
1778 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001779}
1780
Vishnu Nair9a69a042021-06-18 13:19:49 -07001781TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1782 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1783 sp<IGraphicBufferProducer> igbProducer;
1784 ProducerFrameEventHistory history;
1785 setUpProducer(adapter, igbProducer);
1786
1787 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1788 nsecs_t requestedPresentTimeA = 0;
1789 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001790 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1791 history.applyDelta(qbOutput.frameTimestamps);
1792 adapter.waitForCallback(1);
1793
1794 // queue another buffer so we query for frame event deltas
1795 nsecs_t requestedPresentTimeB = 0;
1796 nsecs_t postedTimeB = 0;
1797 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1798 history.applyDelta(qbOutput.frameTimestamps);
1799
1800 // check for a valid compositor deadline
1801 ASSERT_NE(0, history.getReportedCompositeDeadline());
1802
1803 // wait for any callbacks that have not been received
1804 adapter.waitForCallbacks();
1805}
1806
Valerie Hauc5011f92019-10-11 09:52:07 -07001807} // namespace android