blob: 7067c111a39bcbe835c75d195bb169c55f9f3ec3 [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>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010034#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070035#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070036#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070037#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080038#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070039
40#include <gtest/gtest.h>
41
42using namespace std::chrono_literals;
43
44namespace android {
45
Valerie Hauc5011f92019-10-11 09:52:07 -070046using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070047using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070048
chaviwd7deef72021-10-06 11:53:40 -050049class CountProducerListener : public BnProducerListener {
50public:
51 void onBufferReleased() override {
52 std::scoped_lock<std::mutex> lock(mMutex);
53 mNumReleased++;
54 mReleaseCallback.notify_one();
55 }
56
57 void waitOnNumberReleased(int32_t expectedNumReleased) {
58 std::unique_lock<std::mutex> lock(mMutex);
59 while (mNumReleased < expectedNumReleased) {
60 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
61 std::cv_status::timeout)
62 << "did not receive release";
63 }
64 }
65
66private:
67 std::mutex mMutex;
68 std::condition_variable mReleaseCallback;
69 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
70};
71
chaviwf10b9042021-10-13 15:48:59 -050072class TestBLASTBufferQueue : public BLASTBufferQueue {
73public:
74 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
75 int height, int32_t format)
76 : BLASTBufferQueue(name, surface, width, height, format) {}
77
chaviw6b9ffea2021-11-08 09:25:48 -060078 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
79 const std::vector<SurfaceControlStats>& stats) override {
80 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050081 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
82
83 {
84 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060085 mLastTransactionFrameNumber = frameNumber;
86 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050087 }
88 }
89
90 void waitForCallback(int64_t frameNumber) {
91 std::unique_lock lock{frameNumberMutex};
92 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -060093 while (mLastTransactionFrameNumber < frameNumber) {
94 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -050095 }
96 }
97
98private:
99 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600100 std::condition_variable mWaitForCallbackCV;
101 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500102};
103
Valerie Hauc5011f92019-10-11 09:52:07 -0700104class BLASTBufferQueueHelper {
105public:
106 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500107 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
108 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700109 }
110
111 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800112 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700113 }
114
Tianhao Yao4861b102022-02-03 20:18:35 +0000115 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
116 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
117 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
118 }
119
Chavi Weingartenc398c012023-04-12 17:26:02 +0000120 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000121 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000122 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000123 }
124
125 void stopContinuousSyncTransaction() {
126 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700127 }
128
Chavi Weingartenc398c012023-04-12 17:26:02 +0000129 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
130
Vishnu Nairea0de002020-11-17 17:42:37 -0800131 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700132
Vishnu Nairea0de002020-11-17 17:42:37 -0800133 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700134
Tianhao Yao4861b102022-02-03 20:18:35 +0000135 std::function<void(Transaction*)> getTransactionReadyCallback() {
136 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
137 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700138
139 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
140 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
141 }
142
Valerie Hauc5011f92019-10-11 09:52:07 -0700143 const sp<SurfaceControl> getSurfaceControl() {
144 return mBlastBufferQueueAdapter->mSurfaceControl;
145 }
146
Vishnu Naira4fbca52021-07-07 16:52:34 -0700147 sp<Surface> getSurface() {
148 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
149 }
150
Valerie Haud3b90d22019-11-06 09:37:31 -0800151 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700152 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800153 // Wait until all but one of the submitted buffers have been released.
154 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800155 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
156 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700157 }
158
Vishnu Nair1506b182021-02-22 14:35:15 -0800159 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500160 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800161 }
162
chaviw0acd33a2021-11-02 11:55:37 -0500163 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
164 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
165 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
166 }
167
chaviwc1cf4022022-06-03 13:32:33 -0500168 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
169 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
170 }
171
Valerie Hauc5011f92019-10-11 09:52:07 -0700172private:
chaviwf10b9042021-10-13 15:48:59 -0500173 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700174};
175
176class BLASTBufferQueueTest : public ::testing::Test {
177public:
178protected:
179 BLASTBufferQueueTest() {
180 const ::testing::TestInfo* const testInfo =
181 ::testing::UnitTest::GetInstance()->current_test_info();
182 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
183 }
184
185 ~BLASTBufferQueueTest() {
186 const ::testing::TestInfo* const testInfo =
187 ::testing::UnitTest::GetInstance()->current_test_info();
188 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
189 }
190
191 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700192 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700193 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700194 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
195 ASSERT_FALSE(ids.empty());
196 // display 0 is picked as this test is not much display depedent
197 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700198 ASSERT_NE(nullptr, mDisplayToken.get());
199 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700200 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700201 t.apply();
202 t.clear();
203
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700204 ui::DisplayState displayState;
205 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
206 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800207 mDisplayWidth = resolution.getWidth();
208 mDisplayHeight = resolution.getHeight();
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700209 ALOGV("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
210 displayState.orientation);
Valerie Hauda3446e2019-10-14 15:49:22 -0700211
212 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
213 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
214 ISurfaceComposerClient::eFXSurfaceBufferState,
215 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700216 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700217 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700218 .show(mSurfaceControl)
219 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
220 .apply();
chaviwd2432892020-07-24 17:42:39 -0700221
222 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800223 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700224 }
225
chaviwd7deef72021-10-06 11:53:40 -0500226 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
227 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800228 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500229 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800230 }
231
chaviwd7deef72021-10-06 11:53:40 -0500232 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800233 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500234 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800235 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500236 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800237 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500238 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800239 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800240 }
241
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800242 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
243 uint8_t b) {
244 for (uint32_t row = rect.top; row < rect.bottom; row++) {
245 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700246 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
247 *pixel = r;
248 *(pixel + 1) = g;
249 *(pixel + 2) = b;
250 *(pixel + 3) = 255;
251 }
252 }
253 }
254
Valerie Hau5977fc82019-12-05 15:56:39 -0800255 void fillQuadrants(sp<GraphicBuffer>& buf) {
256 const auto bufWidth = buf->getWidth();
257 const auto bufHeight = buf->getHeight();
258 uint32_t* bufData;
259 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
260 reinterpret_cast<void**>(&bufData));
261 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
262 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
263 0, 0);
264 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
265 buf->getStride(), 0, 255, 0);
266 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
267 255);
268 buf->unlock();
269 }
270
271 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
272 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700273 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800274 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700275 const auto width = captureBuf->getWidth();
276 const auto height = captureBuf->getHeight();
277 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700278
279 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700280 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
281 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700282
283 for (uint32_t row = 0; row < height; row++) {
284 for (uint32_t col = 0; col < width; col++) {
285 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800286 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800287 bool inRegion;
288 if (!outsideRegion) {
289 inRegion = row >= region.top + border && row < region.bottom - border &&
290 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800291 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800292 inRegion = row >= region.top - border && row < region.bottom + border &&
293 col >= region.left - border && col < region.right + border;
294 }
295 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 Hau5977fc82019-12-05 15:56:39 -0800299 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000300 ASSERT_GE(epsilon, abs(r - *(pixel)));
301 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
302 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800303 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800304 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700305 }
306 }
chaviwd2432892020-07-24 17:42:39 -0700307 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700308 }
309
chaviw8ffc7b82020-08-18 11:25:37 -0700310 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
311 ScreenCaptureResults& captureResults) {
Huihong Luo9e84f332021-12-16 14:33:46 -0800312 const auto sf = ComposerServiceAIDL::getComposerService();
chaviw8ffc7b82020-08-18 11:25:37 -0700313 SurfaceComposerClient::Transaction().apply(true);
314
315 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
Huihong Luo9e84f332021-12-16 14:33:46 -0800316 binder::Status status = sf->captureDisplay(captureArgs, captureListener);
Huihong Luo3bdef862022-03-03 11:57:19 -0800317 status_t err = gui::aidl_utils::statusTFromBinderStatus(status);
318 if (err != NO_ERROR) {
319 return err;
chaviw8ffc7b82020-08-18 11:25:37 -0700320 }
321 captureResults = captureListener->waitForResults();
Patrick Williamsfdb57bb2022-08-09 22:48:18 +0000322 return fenceStatus(captureResults.fenceResult);
chaviw8ffc7b82020-08-18 11:25:37 -0700323 }
324
Vishnu Nair277142c2021-01-05 18:35:29 -0800325 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
326 nsecs_t presentTimeDelay) {
327 int slot;
328 sp<Fence> fence;
329 sp<GraphicBuffer> buf;
330 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
331 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
332 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500333 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800334 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
335
336 uint32_t* bufData;
337 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
338 reinterpret_cast<void**>(&bufData));
339 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
340 buf->unlock();
341
342 IGraphicBufferProducer::QueueBufferOutput qbOutput;
343 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
344 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
345 Rect(mDisplayWidth, mDisplayHeight / 2),
346 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
347 Fence::NO_FENCE);
348 igbp->queueBuffer(slot, input, &qbOutput);
349 }
350
Valerie Hauc5011f92019-10-11 09:52:07 -0700351 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700352 sp<ISurfaceComposer> mComposer;
353
354 sp<IBinder> mDisplayToken;
355
Valerie Hauc5011f92019-10-11 09:52:07 -0700356 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700357
358 uint32_t mDisplayWidth;
359 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700360
361 DisplayCaptureArgs mCaptureArgs;
362 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500363 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700364};
365
366TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
367 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700368 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700369 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700370 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
371 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000372 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700373}
374
375TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700376 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700377 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700378 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
379 PIXEL_FORMAT_RGBA_8888);
380 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700381 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800382 sp<IGraphicBufferProducer> igbProducer;
383 setUpProducer(adapter, igbProducer);
384
385 int32_t width;
386 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
387 ASSERT_EQ(mDisplayWidth / 2, width);
388 int32_t height;
389 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
390 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700391}
392
Tianhao Yao4861b102022-02-03 20:18:35 +0000393TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700394 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000395 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
396 auto callback = [](Transaction*) {};
397 adapter.syncNextTransaction(callback);
398 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700399}
Valerie Hauda3446e2019-10-14 15:49:22 -0700400
Valerie Haubf29e042020-02-06 11:40:38 -0800401TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800402 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
403 sp<IGraphicBufferProducer> igbProducer;
404 setUpProducer(adapter, igbProducer);
405
406 int slot;
407 sp<Fence> fence;
408 sp<GraphicBuffer> buf;
409 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
410 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
411 nullptr, nullptr);
412 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
413 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
414
415 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
416 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800417 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
418 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800419 Rect(mDisplayWidth, mDisplayHeight),
420 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
421 Fence::NO_FENCE);
422 igbProducer->queueBuffer(slot, input, &qbOutput);
423 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
424
425 adapter.waitForCallbacks();
426 ASSERT_GE(systemTime(), desiredPresentTime);
427}
428
Valerie Hauda3446e2019-10-14 15:49:22 -0700429TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
430 uint8_t r = 255;
431 uint8_t g = 0;
432 uint8_t b = 0;
433
434 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800435 sp<IGraphicBufferProducer> igbProducer;
436 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700437
438 int slot;
439 sp<Fence> fence;
440 sp<GraphicBuffer> buf;
441 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
442 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
443 nullptr, nullptr);
444 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
445 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
446
447 uint32_t* bufData;
448 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
449 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800450 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700451 buf->unlock();
452
Valerie Haud3b90d22019-11-06 09:37:31 -0800453 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800454 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
455 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700456 Rect(mDisplayWidth, mDisplayHeight),
457 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
458 Fence::NO_FENCE);
459 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800460 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700461
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800462 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700463
464 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700465 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800466 ASSERT_NO_FATAL_FAILURE(
467 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700468}
Valerie Haud3b90d22019-11-06 09:37:31 -0800469
470TEST_F(BLASTBufferQueueTest, TripleBuffering) {
471 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
472 sp<IGraphicBufferProducer> igbProducer;
473 setUpProducer(adapter, igbProducer);
474
475 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700476 int minUndequeuedBuffers = 0;
477 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
478 const auto bufferCount = minUndequeuedBuffers + 2;
479
480 for (int i = 0; i < bufferCount; 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(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
488 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
489 allocated.push_back({slot, fence});
490 }
491 for (int i = 0; i < allocated.size(); i++) {
492 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
493 }
494
Valerie Haua32c5522019-12-09 10:11:08 -0800495 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800496 int slot;
497 sp<Fence> fence;
498 sp<GraphicBuffer> buf;
499 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
500 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
501 nullptr, nullptr);
502 ASSERT_EQ(NO_ERROR, ret);
503 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800504 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
505 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800506 Rect(mDisplayWidth, mDisplayHeight),
507 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
508 Fence::NO_FENCE);
509 igbProducer->queueBuffer(slot, input, &qbOutput);
510 }
511 adapter.waitForCallbacks();
512}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800513
514TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
515 uint8_t r = 255;
516 uint8_t g = 0;
517 uint8_t b = 0;
518
519 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
520 sp<IGraphicBufferProducer> igbProducer;
521 setUpProducer(adapter, igbProducer);
522 int slot;
523 sp<Fence> fence;
524 sp<GraphicBuffer> buf;
525 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
526 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
527 nullptr, nullptr);
528 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
529 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
530
531 uint32_t* bufData;
532 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
533 reinterpret_cast<void**>(&bufData));
534 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
535 buf->unlock();
536
537 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800538 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
539 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800540 Rect(mDisplayWidth, mDisplayHeight / 2),
541 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
542 Fence::NO_FENCE);
543 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800544 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800545
546 adapter.waitForCallbacks();
547 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700548 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700549
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800550 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000551 checkScreenCapture(r, g, b,
552 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800553}
554
555TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
556 uint8_t r = 255;
557 uint8_t g = 0;
558 uint8_t b = 0;
559
560 int32_t bufferSideLength =
561 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
562 int32_t finalCropSideLength = bufferSideLength / 2;
563
564 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800565 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800566 ASSERT_NE(nullptr, bg.get());
567 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700568 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800569 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800570 .setColor(bg, half3{0, 0, 0})
571 .setLayer(bg, 0)
572 .apply();
573
574 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
575 sp<IGraphicBufferProducer> igbProducer;
576 setUpProducer(adapter, igbProducer);
577 int slot;
578 sp<Fence> fence;
579 sp<GraphicBuffer> buf;
580 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
581 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
582 nullptr, nullptr);
583 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
584 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
585
586 uint32_t* bufData;
587 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
588 reinterpret_cast<void**>(&bufData));
589 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
590 fillBuffer(bufData,
591 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
592 buf->getHeight()),
593 buf->getStride(), r, g, b);
594 buf->unlock();
595
596 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800597 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
598 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800599 Rect(bufferSideLength, finalCropSideLength),
600 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
601 Fence::NO_FENCE);
602 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800603 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800604
605 adapter.waitForCallbacks();
606 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700607 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700608 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
609 {10, 10, (int32_t)bufferSideLength - 10,
610 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800611 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700612 checkScreenCapture(0, 0, 0,
613 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
614 /*border*/ 0, /*outsideRegion*/ true));
615}
616
617TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
618 // add black background
619 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
620 ISurfaceComposerClient::eFXSurfaceEffect);
621 ASSERT_NE(nullptr, bg.get());
622 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700623 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700624 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
625 .setColor(bg, half3{0, 0, 0})
626 .setLayer(bg, 0)
627 .apply();
628
629 Rect windowSize(1000, 1000);
630 Rect bufferSize(windowSize);
631 Rect bufferCrop(200, 200, 700, 700);
632
633 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
634 sp<IGraphicBufferProducer> igbProducer;
635 setUpProducer(adapter, igbProducer);
636 int slot;
637 sp<Fence> fence;
638 sp<GraphicBuffer> buf;
639 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
640 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
641 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
642 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
643 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
644
645 uint32_t* bufData;
646 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
647 reinterpret_cast<void**>(&bufData));
648 // fill buffer with grey
649 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
650
651 // fill crop area with different colors so we can verify the cropped region has been scaled
652 // correctly.
653 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
654 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
655 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
656 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
657 buf->unlock();
658
659 IGraphicBufferProducer::QueueBufferOutput qbOutput;
660 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
661 HAL_DATASPACE_UNKNOWN,
662 bufferCrop /* Rect::INVALID_RECT */,
663 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
664 Fence::NO_FENCE);
665 igbProducer->queueBuffer(slot, input, &qbOutput);
666 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
667
668 adapter.waitForCallbacks();
669
670 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
671
672 // Verify cropped region is scaled correctly.
673 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
674 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
675 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
676 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
677 // Verify outside region is black.
678 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
679 {0, 0, (int32_t)windowSize.getWidth(),
680 (int32_t)windowSize.getHeight()},
681 /*border*/ 0, /*outsideRegion*/ true));
682}
683
684TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
685 // add black background
686 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
687 ISurfaceComposerClient::eFXSurfaceEffect);
688 ASSERT_NE(nullptr, bg.get());
689 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700690 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700691 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
692 .setColor(bg, half3{0, 0, 0})
693 .setLayer(bg, 0)
694 .apply();
695
696 Rect windowSize(1000, 1000);
697 Rect bufferSize(500, 500);
698 Rect bufferCrop(100, 100, 350, 350);
699
700 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
701 sp<IGraphicBufferProducer> igbProducer;
702 setUpProducer(adapter, igbProducer);
703 int slot;
704 sp<Fence> fence;
705 sp<GraphicBuffer> buf;
706 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
707 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
708 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
709 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
710 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
711
712 uint32_t* bufData;
713 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
714 reinterpret_cast<void**>(&bufData));
715 // fill buffer with grey
716 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
717
718 // fill crop area with different colors so we can verify the cropped region has been scaled
719 // correctly.
720 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
721 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
722 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
723 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
724 buf->unlock();
725
726 IGraphicBufferProducer::QueueBufferOutput qbOutput;
727 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
728 HAL_DATASPACE_UNKNOWN,
729 bufferCrop /* Rect::INVALID_RECT */,
730 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
731 Fence::NO_FENCE);
732 igbProducer->queueBuffer(slot, input, &qbOutput);
733 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
734
735 adapter.waitForCallbacks();
736
737 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
738 // Verify cropped region is scaled correctly.
739 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
740 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
741 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
742 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
743 // Verify outside region is black.
744 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
745 {0, 0, (int32_t)windowSize.getWidth(),
746 (int32_t)windowSize.getHeight()},
747 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800748}
749
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700750// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
751// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
752TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
753 uint8_t r = 255;
754 uint8_t g = 0;
755 uint8_t b = 0;
756
757 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
758 sp<IGraphicBufferProducer> igbProducer;
759 setUpProducer(adapter, igbProducer);
760 {
761 int slot;
762 sp<Fence> fence;
763 sp<GraphicBuffer> buf;
764 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
765 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
766 nullptr, nullptr);
767 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
768 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
769
770 uint32_t* bufData;
771 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
772 reinterpret_cast<void**>(&bufData));
773 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
774 buf->unlock();
775
776 IGraphicBufferProducer::QueueBufferOutput qbOutput;
777 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
778 HAL_DATASPACE_UNKNOWN, {},
779 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
780 Fence::NO_FENCE);
781 igbProducer->queueBuffer(slot, input, &qbOutput);
782 adapter.waitForCallbacks();
783 }
784 // capture screen and verify that it is red
785 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
786
787 ASSERT_NO_FATAL_FAILURE(
788 checkScreenCapture(r, g, b,
789 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
790
791 // update the size to half the display and dequeue a buffer quarter of the display.
792 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
793
794 {
795 int slot;
796 sp<Fence> fence;
797 sp<GraphicBuffer> buf;
798 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
799 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
800 nullptr, nullptr);
801 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
802 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
803
804 uint32_t* bufData;
805 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
806 reinterpret_cast<void**>(&bufData));
807 g = 255;
808 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
809 buf->unlock();
810
811 IGraphicBufferProducer::QueueBufferOutput qbOutput;
812 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
813 HAL_DATASPACE_UNKNOWN, {},
814 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
815 0, Fence::NO_FENCE);
816 igbProducer->queueBuffer(slot, input, &qbOutput);
817 adapter.waitForCallbacks();
818 }
819 // capture screen and verify that it is red
820 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
821 // verify we still scale the buffer to the new size (half the screen height)
822 ASSERT_NO_FATAL_FAILURE(
823 checkScreenCapture(r, g, b,
824 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
825}
826
chaviwd7deef72021-10-06 11:53:40 -0500827TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
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
chaviwa1c4c822021-11-10 18:11:58 -0600837 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000838 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500839 queueBuffer(igbProducer, 0, 255, 0, 0);
840
841 // queue non sync buffer, so this one should get blocked
842 // Add a present delay to allow the first screenshot to get taken.
843 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
844 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
845
846 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600847 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500848 transactionCallback.getContext())
849 .apply();
850
851 CallbackData callbackData;
852 transactionCallback.getCallbackData(&callbackData);
853
chaviw0acd33a2021-11-02 11:55:37 -0500854 // capture screen and verify that it is green
chaviwd7deef72021-10-06 11:53:40 -0500855 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
856 ASSERT_NO_FATAL_FAILURE(
857 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
858
859 mProducerListener->waitOnNumberReleased(1);
860 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
861 ASSERT_NO_FATAL_FAILURE(
862 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
863}
864
865TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
866 uint8_t r = 255;
867 uint8_t g = 0;
868 uint8_t b = 0;
869
870 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
871
872 sp<IGraphicBufferProducer> igbProducer;
873 setUpProducer(adapter, igbProducer);
874
875 Transaction mainTransaction;
876
chaviwa1c4c822021-11-10 18:11:58 -0600877 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000878 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500879 queueBuffer(igbProducer, 0, 255, 0, 0);
880
chaviwa1c4c822021-11-10 18:11:58 -0600881 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500882
Tianhao Yao4861b102022-02-03 20:18:35 +0000883 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500884 queueBuffer(igbProducer, r, g, b, 0);
885
chaviwa1c4c822021-11-10 18:11:58 -0600886 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500887 // Expect 1 buffer to be released even before sending to SurfaceFlinger
888 mProducerListener->waitOnNumberReleased(1);
889
890 CallbackHelper transactionCallback;
891 mainTransaction
892 .addTransactionCompletedCallback(transactionCallback.function,
893 transactionCallback.getContext())
894 .apply();
895
896 CallbackData callbackData;
897 transactionCallback.getCallbackData(&callbackData);
898
899 // capture screen and verify that it is red
900 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
901 ASSERT_NO_FATAL_FAILURE(
902 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
903}
904
905TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
906 uint8_t r = 255;
907 uint8_t g = 0;
908 uint8_t b = 0;
909
910 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
911
912 sp<IGraphicBufferProducer> igbProducer;
913 setUpProducer(adapter, igbProducer);
914
915 Transaction mainTransaction;
916
chaviwa1c4c822021-11-10 18:11:58 -0600917 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500918 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000919 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500920 queueBuffer(igbProducer, 0, 255, 0, 0);
921
chaviwa1c4c822021-11-10 18:11:58 -0600922 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500923
chaviwa1c4c822021-11-10 18:11:58 -0600924 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500925 queueBuffer(igbProducer, 0, 0, 255, 0);
926
927 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000928 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500929 queueBuffer(igbProducer, r, g, b, 0);
930 // Expect 1 buffer to be released because the non sync transaction should merge
931 // with the sync
932 mProducerListener->waitOnNumberReleased(1);
933
chaviwa1c4c822021-11-10 18:11:58 -0600934 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500935 // Expect 2 buffers to be released due to merging the two syncs.
936 mProducerListener->waitOnNumberReleased(2);
937
938 CallbackHelper transactionCallback;
939 mainTransaction
940 .addTransactionCompletedCallback(transactionCallback.function,
941 transactionCallback.getContext())
942 .apply();
943
944 CallbackData callbackData;
945 transactionCallback.getCallbackData(&callbackData);
946
947 // capture screen and verify that it is red
948 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
949 ASSERT_NO_FATAL_FAILURE(
950 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
951}
952
953TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
954 uint8_t r = 255;
955 uint8_t g = 0;
956 uint8_t b = 0;
957
958 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
959
960 sp<IGraphicBufferProducer> igbProducer;
961 setUpProducer(adapter, igbProducer, 3);
962
963 Transaction mainTransaction;
964
chaviwa1c4c822021-11-10 18:11:58 -0600965 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500966 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000967 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500968 queueBuffer(igbProducer, 0, 255, 0, 0);
969
chaviwa1c4c822021-11-10 18:11:58 -0600970 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500971
chaviwa1c4c822021-11-10 18:11:58 -0600972 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500973 queueBuffer(igbProducer, 0, 0, 255, 0);
974 queueBuffer(igbProducer, 0, 0, 255, 0);
975 queueBuffer(igbProducer, 0, 0, 255, 0);
976
977 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000978 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500979 queueBuffer(igbProducer, r, g, b, 0);
980 // Expect 3 buffers to be released because the non sync transactions should merge
981 // with the sync
982 mProducerListener->waitOnNumberReleased(3);
983
chaviwa1c4c822021-11-10 18:11:58 -0600984 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500985 // Expect 4 buffers to be released due to merging the two syncs.
986 mProducerListener->waitOnNumberReleased(4);
987
988 CallbackHelper transactionCallback;
989 mainTransaction
990 .addTransactionCompletedCallback(transactionCallback.function,
991 transactionCallback.getContext())
992 .apply();
993
994 CallbackData callbackData;
995 transactionCallback.getCallbackData(&callbackData);
996
997 // capture screen and verify that it is red
998 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
999 ASSERT_NO_FATAL_FAILURE(
1000 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1001}
1002
1003// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
1004// continue processing is for a release callback from SurfaceFlinger.
1005// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
1006// continue acquiring buffers.
1007TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
1008 uint8_t r = 255;
1009 uint8_t g = 0;
1010 uint8_t b = 0;
1011
1012 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1013
1014 sp<IGraphicBufferProducer> igbProducer;
1015 setUpProducer(adapter, igbProducer, 4);
1016
1017 Transaction mainTransaction;
1018
1019 // Send a buffer to SF
1020 queueBuffer(igbProducer, 0, 255, 0, 0);
1021
chaviwa1c4c822021-11-10 18:11:58 -06001022 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001023 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001024 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001025 queueBuffer(igbProducer, 0, 255, 0, 0);
1026
chaviwa1c4c822021-11-10 18:11:58 -06001027 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001028
chaviwa1c4c822021-11-10 18:11:58 -06001029 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001030 queueBuffer(igbProducer, 0, 0, 255, 0);
1031 queueBuffer(igbProducer, 0, 0, 255, 0);
1032 queueBuffer(igbProducer, 0, 0, 255, 0);
1033
1034 // apply the first synced buffer to ensure we have to wait on SF
1035 mainTransaction.apply();
1036
1037 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001038 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001039 queueBuffer(igbProducer, r, g, b, 0);
1040 // Expect 2 buffers to be released because the non sync transactions should merge
1041 // with the sync
1042 mProducerListener->waitOnNumberReleased(3);
1043
chaviwa1c4c822021-11-10 18:11:58 -06001044 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001045
1046 CallbackHelper transactionCallback;
1047 mainTransaction
1048 .addTransactionCompletedCallback(transactionCallback.function,
1049 transactionCallback.getContext())
1050 .apply();
1051
1052 CallbackData callbackData;
1053 transactionCallback.getCallbackData(&callbackData);
1054
1055 // capture screen and verify that it is red
1056 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1057 ASSERT_NO_FATAL_FAILURE(
1058 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1059}
1060
Tianhao Yao4861b102022-02-03 20:18:35 +00001061TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001062 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1063
1064 sp<IGraphicBufferProducer> igbProducer;
1065 setUpProducer(adapter, igbProducer);
1066
1067 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001068 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001069 queueBuffer(igbProducer, 0, 255, 0, 0);
1070 queueBuffer(igbProducer, 0, 0, 255, 0);
1071 // There should only be one frame submitted since the first frame will be released.
1072 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001073 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001074
1075 // queue non sync buffer, so this one should get blocked
1076 // Add a present delay to allow the first screenshot to get taken.
1077 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1078 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1079
1080 CallbackHelper transactionCallback;
1081 next.addTransactionCompletedCallback(transactionCallback.function,
1082 transactionCallback.getContext())
1083 .apply();
1084
1085 CallbackData callbackData;
1086 transactionCallback.getCallbackData(&callbackData);
1087
1088 // capture screen and verify that it is blue
1089 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1090 ASSERT_NO_FATAL_FAILURE(
1091 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1092
1093 mProducerListener->waitOnNumberReleased(2);
1094 // capture screen and verify that it is red
1095 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1096 ASSERT_NO_FATAL_FAILURE(
1097 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1098}
1099
chaviw3b4bdcf2022-03-17 09:27:03 -05001100TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1101 std::mutex mutex;
1102 std::condition_variable callbackReceivedCv;
1103 bool receivedCallback = false;
1104
1105 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1106 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1107 auto callback = [&](Transaction*) {
1108 std::unique_lock<std::mutex> lock(mutex);
1109 receivedCallback = true;
1110 callbackReceivedCv.notify_one();
1111 };
1112 adapter.syncNextTransaction(callback);
1113 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1114
1115 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001116 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1117
1118 sp<IGraphicBufferProducer> igbProducer;
1119 setUpProducer(adapter, igbProducer);
1120 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001121
1122 std::unique_lock<std::mutex> lock(mutex);
1123 if (!receivedCallback) {
1124 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1125 std::cv_status::timeout)
1126 << "did not receive callback";
1127 }
1128
1129 ASSERT_TRUE(receivedCallback);
1130}
1131
Chavi Weingartenc398c012023-04-12 17:26:02 +00001132TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1133 std::mutex mutex;
1134 std::condition_variable callbackReceivedCv;
1135 bool receivedCallback = false;
1136
1137 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1138 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1139 auto callback = [&](Transaction*) {
1140 std::unique_lock<std::mutex> lock(mutex);
1141 receivedCallback = true;
1142 callbackReceivedCv.notify_one();
1143 };
1144 adapter.syncNextTransaction(callback);
1145 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1146
1147 adapter.clearSyncTransaction();
1148
1149 sp<IGraphicBufferProducer> igbProducer;
1150 setUpProducer(adapter, igbProducer);
1151 queueBuffer(igbProducer, 0, 255, 0, 0);
1152
1153 std::unique_lock<std::mutex> lock(mutex);
1154 if (!receivedCallback) {
1155 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1156 std::cv_status::timeout)
1157 << "did not receive callback";
1158 }
1159
1160 ASSERT_FALSE(receivedCallback);
1161}
1162
chaviwc1cf4022022-06-03 13:32:33 -05001163TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1164 uint8_t r = 255;
1165 uint8_t g = 0;
1166 uint8_t b = 0;
1167
1168 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1169
1170 sp<IGraphicBufferProducer> igbProducer;
1171 setUpProducer(adapter, igbProducer);
1172
1173 Transaction sync;
1174 adapter.setSyncTransaction(sync);
1175 queueBuffer(igbProducer, 0, 255, 0, 0);
1176
1177 // Merge a transaction that has a complete callback into the next frame so we can get notified
1178 // when to take a screenshot
1179 CallbackHelper transactionCallback;
1180 Transaction t;
1181 t.addTransactionCompletedCallback(transactionCallback.function,
1182 transactionCallback.getContext());
1183 adapter.mergeWithNextTransaction(&t, 2);
1184 queueBuffer(igbProducer, r, g, b, 0);
1185
1186 // Drop the buffer, but ensure the next one continues to get processed.
1187 sync.setBuffer(mSurfaceControl, nullptr);
1188
1189 CallbackData callbackData;
1190 transactionCallback.getCallbackData(&callbackData);
1191 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1192 ASSERT_NO_FATAL_FAILURE(
1193 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001194 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001195}
1196
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001197// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1198// until the old surface control is destroyed. This is not necessarily a bug but to document a
1199// limitation with the update API and to test any changes to make the api more robust. The current
1200// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1201TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1202 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1203 std::vector<sp<SurfaceControl>> surfaceControls;
1204 sp<IGraphicBufferProducer> igbProducer;
1205 for (int i = 0; i < 10; i++) {
1206 sp<SurfaceControl> sc =
1207 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1208 PIXEL_FORMAT_RGBA_8888,
1209 ISurfaceComposerClient::eFXSurfaceBufferState,
1210 /*parent*/ nullptr);
1211 Transaction()
1212 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1213 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1214 .show(mSurfaceControl)
1215 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1216 .apply(true);
1217 surfaceControls.push_back(sc);
1218 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1219
1220 setUpProducer(adapter, igbProducer);
1221 Transaction next;
1222 queueBuffer(igbProducer, 0, 255, 0, 0);
1223 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001224 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001225 queueBuffer(igbProducer, 255, 0, 0, 0);
1226
1227 CallbackHelper transactionCallback;
1228 next.addTransactionCompletedCallback(transactionCallback.function,
1229 transactionCallback.getContext())
1230 .apply();
1231
1232 CallbackData callbackData;
1233 transactionCallback.getCallbackData(&callbackData);
1234 // capture screen and verify that it is red
1235 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1236 ASSERT_NO_FATAL_FAILURE(
1237 checkScreenCapture(255, 0, 0,
1238 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1239 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1240 }
1241}
1242
1243// See DISABLED_DisconnectProducerTest
1244TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1245 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1246 std::vector<sp<SurfaceControl>> surfaceControls;
1247 sp<IGraphicBufferProducer> igbProducer;
1248 for (int i = 0; i < 10; i++) {
1249 sp<SurfaceControl> sc =
1250 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1251 PIXEL_FORMAT_RGBA_8888,
1252 ISurfaceComposerClient::eFXSurfaceBufferState,
1253 /*parent*/ nullptr);
1254 Transaction()
1255 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1256 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1257 .show(mSurfaceControl)
1258 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1259 .apply(true);
1260 surfaceControls.push_back(sc);
1261 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1262 setUpProducer(adapter, igbProducer);
1263
1264 Transaction next;
1265 queueBuffer(igbProducer, 0, 255, 0, 0);
1266 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001267 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001268 queueBuffer(igbProducer, 255, 0, 0, 0);
1269
1270 CallbackHelper transactionCallback;
1271 next.addTransactionCompletedCallback(transactionCallback.function,
1272 transactionCallback.getContext())
1273 .apply();
1274
1275 CallbackData callbackData;
1276 transactionCallback.getCallbackData(&callbackData);
1277 // capture screen and verify that it is red
1278 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1279 ASSERT_NO_FATAL_FAILURE(
1280 checkScreenCapture(255, 0, 0,
1281 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1282 }
1283}
1284
Vishnu Nair89496122020-12-14 17:14:53 -08001285class TestProducerListener : public BnProducerListener {
1286public:
1287 sp<IGraphicBufferProducer> mIgbp;
1288 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1289 void onBufferReleased() override {
1290 sp<GraphicBuffer> buffer;
1291 sp<Fence> fence;
1292 mIgbp->detachNextBuffer(&buffer, &fence);
1293 }
1294};
1295
1296TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1297 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1298 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1299 ASSERT_NE(nullptr, igbProducer.get());
1300 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1301 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1302 ASSERT_EQ(NO_ERROR,
1303 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1304 false, &qbOutput));
1305 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1306 for (int i = 0; i < 3; i++) {
1307 int slot;
1308 sp<Fence> fence;
1309 sp<GraphicBuffer> buf;
1310 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1311 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1312 nullptr, nullptr);
1313 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1314 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1315 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001316 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1317 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001318 Rect(mDisplayWidth, mDisplayHeight),
1319 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1320 Fence::NO_FENCE);
1321 igbProducer->queueBuffer(slot, input, &qbOutput);
1322 }
1323 adapter.waitForCallbacks();
1324}
1325
Vishnu Nair17dde612020-12-28 11:39:59 -08001326TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1327 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1328
1329 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1330 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1331 int queuesToNativeWindow = 0;
1332 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1333 &queuesToNativeWindow);
1334 ASSERT_EQ(NO_ERROR, err);
1335 ASSERT_EQ(queuesToNativeWindow, 1);
1336}
1337
Vishnu Nair083efd32021-02-12 09:32:30 -08001338// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1339// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001340TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1341 sp<SurfaceControl> bgSurface =
1342 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1343 ISurfaceComposerClient::eFXSurfaceBufferState);
1344 ASSERT_NE(nullptr, bgSurface.get());
1345 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001346 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001347 .show(bgSurface)
1348 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001349 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1350 .apply();
1351
1352 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1353 sp<IGraphicBufferProducer> slowIgbProducer;
1354 setUpProducer(slowAdapter, slowIgbProducer);
1355 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001356 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001357
1358 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1359 sp<IGraphicBufferProducer> fastIgbProducer;
1360 setUpProducer(fastAdapter, fastIgbProducer);
1361 uint8_t r = 255;
1362 uint8_t g = 0;
1363 uint8_t b = 0;
1364 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1365 fastAdapter.waitForCallbacks();
1366
1367 // capture screen and verify that it is red
1368 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1369
1370 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001371 checkScreenCapture(r, g, b,
1372 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001373}
1374
Vishnu Naira4fbca52021-07-07 16:52:34 -07001375TEST_F(BLASTBufferQueueTest, TransformHint) {
1376 // Transform hint is provided to BBQ via the surface control passed by WM
1377 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1378
1379 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1380 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1381 ASSERT_NE(nullptr, igbProducer.get());
1382 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1383 sp<Surface> surface = adapter.getSurface();
1384
1385 // Before connecting to the surface, we do not get a valid transform hint
1386 int transformHint;
1387 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1388 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1389
1390 ASSERT_EQ(NO_ERROR,
1391 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1392
1393 // After connecting to the surface, we should get the correct hint.
1394 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1395 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1396
1397 ANativeWindow_Buffer buffer;
1398 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1399
1400 // Transform hint is updated via callbacks or surface control updates
1401 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1402 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1403
1404 // The hint does not change and matches the value used when dequeueing the buffer.
1405 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1406 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1407
1408 surface->unlockAndPost();
1409
1410 // After queuing the buffer, we get the updated transform hint
1411 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1412 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1413
1414 adapter.waitForCallbacks();
1415}
1416
Valerie Hau5977fc82019-12-05 15:56:39 -08001417class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1418public:
1419 void test(uint32_t tr) {
1420 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1421 sp<IGraphicBufferProducer> igbProducer;
1422 setUpProducer(adapter, igbProducer);
1423
1424 auto bufWidth = mDisplayWidth;
1425 auto bufHeight = mDisplayHeight;
1426 int slot;
1427 sp<Fence> fence;
1428 sp<GraphicBuffer> buf;
1429
1430 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1431 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1432 nullptr, nullptr);
1433 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1434 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1435
1436 fillQuadrants(buf);
1437
1438 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001439 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1440 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001441 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001442 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1443 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001444 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001445 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001446
1447 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001448 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001449
Valerie Hau5977fc82019-12-05 15:56:39 -08001450 switch (tr) {
1451 case ui::Transform::ROT_0:
1452 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1453 {0, 0, (int32_t)mDisplayWidth / 2,
1454 (int32_t)mDisplayHeight / 2},
1455 1));
1456 ASSERT_NO_FATAL_FAILURE(
1457 checkScreenCapture(255, 0, 0,
1458 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1459 (int32_t)mDisplayHeight / 2},
1460 1));
1461 ASSERT_NO_FATAL_FAILURE(
1462 checkScreenCapture(0, 255, 0,
1463 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1464 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1465 1));
1466 ASSERT_NO_FATAL_FAILURE(
1467 checkScreenCapture(0, 0, 255,
1468 {0, (int32_t)mDisplayHeight / 2,
1469 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1470 1));
1471 break;
1472 case ui::Transform::FLIP_H:
1473 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1474 {0, 0, (int32_t)mDisplayWidth / 2,
1475 (int32_t)mDisplayHeight / 2},
1476 1));
1477 ASSERT_NO_FATAL_FAILURE(
1478 checkScreenCapture(0, 0, 0,
1479 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1480 (int32_t)mDisplayHeight / 2},
1481 1));
1482 ASSERT_NO_FATAL_FAILURE(
1483 checkScreenCapture(0, 0, 255,
1484 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1485 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1486 1));
1487 ASSERT_NO_FATAL_FAILURE(
1488 checkScreenCapture(0, 255, 0,
1489 {0, (int32_t)mDisplayHeight / 2,
1490 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1491 1));
1492 break;
1493 case ui::Transform::FLIP_V:
1494 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1495 {0, 0, (int32_t)mDisplayWidth / 2,
1496 (int32_t)mDisplayHeight / 2},
1497 1));
1498 ASSERT_NO_FATAL_FAILURE(
1499 checkScreenCapture(0, 255, 0,
1500 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1501 (int32_t)mDisplayHeight / 2},
1502 1));
1503 ASSERT_NO_FATAL_FAILURE(
1504 checkScreenCapture(255, 0, 0,
1505 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1506 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1507 1));
1508 ASSERT_NO_FATAL_FAILURE(
1509 checkScreenCapture(0, 0, 0,
1510 {0, (int32_t)mDisplayHeight / 2,
1511 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1512 1));
1513 break;
1514 case ui::Transform::ROT_90:
1515 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1516 {0, 0, (int32_t)mDisplayWidth / 2,
1517 (int32_t)mDisplayHeight / 2},
1518 1));
1519 ASSERT_NO_FATAL_FAILURE(
1520 checkScreenCapture(0, 0, 0,
1521 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1522 (int32_t)mDisplayHeight / 2},
1523 1));
1524 ASSERT_NO_FATAL_FAILURE(
1525 checkScreenCapture(255, 0, 0,
1526 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1527 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1528 1));
1529 ASSERT_NO_FATAL_FAILURE(
1530 checkScreenCapture(0, 255, 0,
1531 {0, (int32_t)mDisplayHeight / 2,
1532 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1533 1));
1534 break;
1535 case ui::Transform::ROT_180:
1536 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1537 {0, 0, (int32_t)mDisplayWidth / 2,
1538 (int32_t)mDisplayHeight / 2},
1539 1));
1540 ASSERT_NO_FATAL_FAILURE(
1541 checkScreenCapture(0, 0, 255,
1542 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1543 (int32_t)mDisplayHeight / 2},
1544 1));
1545 ASSERT_NO_FATAL_FAILURE(
1546 checkScreenCapture(0, 0, 0,
1547 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1548 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1549 1));
1550 ASSERT_NO_FATAL_FAILURE(
1551 checkScreenCapture(255, 0, 0,
1552 {0, (int32_t)mDisplayHeight / 2,
1553 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1554 1));
1555 break;
1556 case ui::Transform::ROT_270:
1557 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1558 {0, 0, (int32_t)mDisplayWidth / 2,
1559 (int32_t)mDisplayHeight / 2},
1560 1));
1561 ASSERT_NO_FATAL_FAILURE(
1562 checkScreenCapture(0, 255, 0,
1563 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1564 (int32_t)mDisplayHeight / 2},
1565 1));
1566 ASSERT_NO_FATAL_FAILURE(
1567 checkScreenCapture(0, 0, 255,
1568 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1569 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1570 1));
1571 ASSERT_NO_FATAL_FAILURE(
1572 checkScreenCapture(0, 0, 0,
1573 {0, (int32_t)mDisplayHeight / 2,
1574 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1575 1));
1576 }
1577 }
1578};
1579
1580TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1581 test(ui::Transform::ROT_0);
1582}
1583
1584TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1585 test(ui::Transform::FLIP_H);
1586}
1587
1588TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1589 test(ui::Transform::FLIP_V);
1590}
1591
1592TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1593 test(ui::Transform::ROT_90);
1594}
1595
1596TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1597 test(ui::Transform::ROT_180);
1598}
1599
1600TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1601 test(ui::Transform::ROT_270);
1602}
Valerie Hau871d6352020-01-29 08:44:02 -08001603
1604class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1605public:
1606 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001607 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001608 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001609 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001610 int slot;
1611 sp<Fence> fence;
1612 sp<GraphicBuffer> buf;
1613 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1614 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1615 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001616 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1617 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1618 }
Valerie Hau871d6352020-01-29 08:44:02 -08001619
Vishnu Nairde66dc72021-06-17 17:54:41 -07001620 *outRequestedPresentTime = requestedPresentTime;
1621 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1622 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001623 Rect(mDisplayWidth, mDisplayHeight),
1624 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1625 Fence::NO_FENCE, /*sticky*/ 0,
1626 getFrameTimestamps);
1627 if (postedTime) *postedTime = systemTime();
1628 igbProducer->queueBuffer(slot, input, qbOutput);
1629 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001630 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001631};
1632
1633TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1634 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1635 sp<IGraphicBufferProducer> igbProducer;
1636 ProducerFrameEventHistory history;
1637 setUpProducer(adapter, igbProducer);
1638
1639 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1640 nsecs_t requestedPresentTimeA = 0;
1641 nsecs_t postedTimeA = 0;
1642 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1643 history.applyDelta(qbOutput.frameTimestamps);
1644
1645 FrameEvents* events = nullptr;
1646 events = history.getFrame(1);
1647 ASSERT_NE(nullptr, events);
1648 ASSERT_EQ(1, events->frameNumber);
1649 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1650 ASSERT_GE(events->postedTime, postedTimeA);
1651
Vishnu Nair1506b182021-02-22 14:35:15 -08001652 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001653
1654 // queue another buffer so we query for frame event deltas
1655 nsecs_t requestedPresentTimeB = 0;
1656 nsecs_t postedTimeB = 0;
1657 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1658 history.applyDelta(qbOutput.frameTimestamps);
1659 events = history.getFrame(1);
1660 ASSERT_NE(nullptr, events);
1661
1662 // frame number, requestedPresentTime, and postTime should not have changed
1663 ASSERT_EQ(1, events->frameNumber);
1664 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1665 ASSERT_GE(events->postedTime, postedTimeA);
1666
1667 ASSERT_GE(events->latchTime, postedTimeA);
1668 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1669 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1670 ASSERT_NE(nullptr, events->displayPresentFence);
1671 ASSERT_NE(nullptr, events->releaseFence);
1672
1673 // we should also have gotten the initial values for the next frame
1674 events = history.getFrame(2);
1675 ASSERT_NE(nullptr, events);
1676 ASSERT_EQ(2, events->frameNumber);
1677 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1678 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001679
1680 // wait for any callbacks that have not been received
1681 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001682}
Vishnu Nair083efd32021-02-12 09:32:30 -08001683
Vishnu Nair083efd32021-02-12 09:32:30 -08001684TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1685 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1686 sp<IGraphicBufferProducer> igbProducer;
1687 setUpProducer(adapter, igbProducer);
1688
1689 ProducerFrameEventHistory history;
1690 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1691 nsecs_t requestedPresentTimeA = 0;
1692 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001693 // Present the frame sometime in the future so we can add two frames to the queue so the older
1694 // one will be dropped.
1695 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001696 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001697 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001698 history.applyDelta(qbOutput.frameTimestamps);
1699
1700 FrameEvents* events = nullptr;
1701 events = history.getFrame(1);
1702 ASSERT_NE(nullptr, events);
1703 ASSERT_EQ(1, events->frameNumber);
1704 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1705 ASSERT_GE(events->postedTime, postedTimeA);
1706
1707 // queue another buffer so the first can be dropped
1708 nsecs_t requestedPresentTimeB = 0;
1709 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001710 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1711 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1712 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001713 history.applyDelta(qbOutput.frameTimestamps);
1714 events = history.getFrame(1);
1715 ASSERT_NE(nullptr, events);
1716
1717 // 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
Vishnu Nairde66dc72021-06-17 17:54:41 -07001722 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001723 ASSERT_FALSE(events->hasLatchInfo());
1724 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001725 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1726 ASSERT_FALSE(events->hasDisplayPresentInfo());
1727 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001728
Vishnu Nairde66dc72021-06-17 17:54:41 -07001729 // wait for the last transaction to be completed.
1730 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001731
Vishnu Nairde66dc72021-06-17 17:54:41 -07001732 // queue another buffer so we query for frame event deltas
1733 nsecs_t requestedPresentTimeC = 0;
1734 nsecs_t postedTimeC = 0;
1735 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1736 history.applyDelta(qbOutput.frameTimestamps);
1737
1738 // frame number, requestedPresentTime, and postTime should not have changed
1739 ASSERT_EQ(1, events->frameNumber);
1740 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1741 ASSERT_GE(events->postedTime, postedTimeA);
1742
1743 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1744 ASSERT_FALSE(events->hasLatchInfo());
1745 ASSERT_FALSE(events->hasDequeueReadyInfo());
1746 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1747 ASSERT_FALSE(events->hasDisplayPresentInfo());
1748 ASSERT_FALSE(events->hasReleaseInfo());
1749
1750 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001751 events = history.getFrame(2);
1752 ASSERT_NE(nullptr, events);
1753 ASSERT_EQ(2, events->frameNumber);
1754 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1755 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001756 ASSERT_GE(events->latchTime, postedTimeB);
1757 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1758 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1759 ASSERT_NE(nullptr, events->displayPresentFence);
1760 ASSERT_NE(nullptr, events->releaseFence);
1761
1762 // wait for any callbacks that have not been received
1763 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001764}
1765
Vishnu Nair9a69a042021-06-18 13:19:49 -07001766TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1767 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1768 sp<IGraphicBufferProducer> igbProducer;
1769 ProducerFrameEventHistory history;
1770 setUpProducer(adapter, igbProducer);
1771
1772 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1773 nsecs_t requestedPresentTimeA = 0;
1774 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001775 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1776 history.applyDelta(qbOutput.frameTimestamps);
1777 adapter.waitForCallback(1);
1778
1779 // queue another buffer so we query for frame event deltas
1780 nsecs_t requestedPresentTimeB = 0;
1781 nsecs_t postedTimeB = 0;
1782 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1783 history.applyDelta(qbOutput.frameTimestamps);
1784
1785 // check for a valid compositor deadline
1786 ASSERT_NE(0, history.getReportedCompositeDeadline());
1787
1788 // wait for any callbacks that have not been received
1789 adapter.waitForCallbacks();
1790}
1791
Valerie Hauc5011f92019-10-11 09:52:07 -07001792} // namespace android