blob: fd69702843af131fdc9667899d768f96913f72cb [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>
Valerie Hauc5011f92019-10-11 09:52:07 -070035#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070036#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080037#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070038
39#include <gtest/gtest.h>
40
41using namespace std::chrono_literals;
42
43namespace android {
44
Valerie Hauc5011f92019-10-11 09:52:07 -070045using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070046using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070047
chaviwd7deef72021-10-06 11:53:40 -050048class CountProducerListener : public BnProducerListener {
49public:
50 void onBufferReleased() override {
51 std::scoped_lock<std::mutex> lock(mMutex);
52 mNumReleased++;
53 mReleaseCallback.notify_one();
54 }
55
56 void waitOnNumberReleased(int32_t expectedNumReleased) {
57 std::unique_lock<std::mutex> lock(mMutex);
58 while (mNumReleased < expectedNumReleased) {
59 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
60 std::cv_status::timeout)
61 << "did not receive release";
62 }
63 }
64
65private:
66 std::mutex mMutex;
67 std::condition_variable mReleaseCallback;
68 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
69};
70
chaviwf10b9042021-10-13 15:48:59 -050071class TestBLASTBufferQueue : public BLASTBufferQueue {
72public:
73 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
74 int height, int32_t format)
75 : BLASTBufferQueue(name, surface, width, height, format) {}
76
chaviw6b9ffea2021-11-08 09:25:48 -060077 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
78 const std::vector<SurfaceControlStats>& stats) override {
79 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050080 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
81
82 {
83 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060084 mLastTransactionFrameNumber = frameNumber;
85 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050086 }
87 }
88
89 void waitForCallback(int64_t frameNumber) {
90 std::unique_lock lock{frameNumberMutex};
91 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -060092 while (mLastTransactionFrameNumber < frameNumber) {
93 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -050094 }
95 }
96
97private:
98 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -060099 std::condition_variable mWaitForCallbackCV;
100 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500101};
102
Valerie Hauc5011f92019-10-11 09:52:07 -0700103class BLASTBufferQueueHelper {
104public:
105 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500106 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
107 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700108 }
109
110 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800111 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700112 }
113
Tianhao Yao4861b102022-02-03 20:18:35 +0000114 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
115 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
116 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
117 }
118
Chavi Weingartenc398c012023-04-12 17:26:02 +0000119 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000120 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000121 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000122 }
123
124 void stopContinuousSyncTransaction() {
125 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700126 }
127
Chavi Weingartenc398c012023-04-12 17:26:02 +0000128 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
129
Vishnu Nairea0de002020-11-17 17:42:37 -0800130 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700131
Vishnu Nairea0de002020-11-17 17:42:37 -0800132 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -0700133
Tianhao Yao4861b102022-02-03 20:18:35 +0000134 std::function<void(Transaction*)> getTransactionReadyCallback() {
135 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
136 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700137
138 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
139 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
140 }
141
Valerie Hauc5011f92019-10-11 09:52:07 -0700142 const sp<SurfaceControl> getSurfaceControl() {
143 return mBlastBufferQueueAdapter->mSurfaceControl;
144 }
145
Vishnu Naira4fbca52021-07-07 16:52:34 -0700146 sp<Surface> getSurface() {
147 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
148 }
149
Valerie Haud3b90d22019-11-06 09:37:31 -0800150 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700151 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -0800152 // Wait until all but one of the submitted buffers have been released.
153 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800154 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
155 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700156 }
157
Vishnu Nair1506b182021-02-22 14:35:15 -0800158 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500159 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800160 }
161
chaviw0acd33a2021-11-02 11:55:37 -0500162 void validateNumFramesSubmitted(int64_t numFramesSubmitted) {
163 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
164 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
165 }
166
chaviwc1cf4022022-06-03 13:32:33 -0500167 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
168 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
169 }
170
Valerie Hauc5011f92019-10-11 09:52:07 -0700171private:
chaviwf10b9042021-10-13 15:48:59 -0500172 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700173};
174
175class BLASTBufferQueueTest : public ::testing::Test {
176public:
177protected:
178 BLASTBufferQueueTest() {
179 const ::testing::TestInfo* const testInfo =
180 ::testing::UnitTest::GetInstance()->current_test_info();
181 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
182 }
183
184 ~BLASTBufferQueueTest() {
185 const ::testing::TestInfo* const testInfo =
186 ::testing::UnitTest::GetInstance()->current_test_info();
187 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
188 }
189
190 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700191 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700192 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700193 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
194 ASSERT_FALSE(ids.empty());
195 // display 0 is picked as this test is not much display depedent
196 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700197 ASSERT_NE(nullptr, mDisplayToken.get());
198 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700199 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700200 t.apply();
201 t.clear();
202
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100203 ui::DisplayMode mode;
204 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
205 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800206 mDisplayWidth = resolution.getWidth();
207 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700208
209 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
210 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
211 ISurfaceComposerClient::eFXSurfaceBufferState,
212 /*parent*/ nullptr);
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700213 t.setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
Valerie Hauda3446e2019-10-14 15:49:22 -0700214 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700215 .show(mSurfaceControl)
216 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
217 .apply();
chaviwd2432892020-07-24 17:42:39 -0700218
219 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800220 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700221 }
222
chaviwd7deef72021-10-06 11:53:40 -0500223 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
224 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800225 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500226 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800227 }
228
chaviwd7deef72021-10-06 11:53:40 -0500229 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800230 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500231 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800232 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500233 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800234 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500235 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800236 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800237 }
238
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800239 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
240 uint8_t b) {
241 for (uint32_t row = rect.top; row < rect.bottom; row++) {
242 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700243 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
244 *pixel = r;
245 *(pixel + 1) = g;
246 *(pixel + 2) = b;
247 *(pixel + 3) = 255;
248 }
249 }
250 }
251
Valerie Hau5977fc82019-12-05 15:56:39 -0800252 void fillQuadrants(sp<GraphicBuffer>& buf) {
253 const auto bufWidth = buf->getWidth();
254 const auto bufHeight = buf->getHeight();
255 uint32_t* bufData;
256 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
257 reinterpret_cast<void**>(&bufData));
258 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
259 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
260 0, 0);
261 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
262 buf->getStride(), 0, 255, 0);
263 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
264 255);
265 buf->unlock();
266 }
267
268 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
269 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700270 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800271 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700272 const auto width = captureBuf->getWidth();
273 const auto height = captureBuf->getHeight();
274 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700275
276 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700277 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
278 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700279
280 for (uint32_t row = 0; row < height; row++) {
281 for (uint32_t col = 0; col < width; col++) {
282 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800283 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800284 bool inRegion;
285 if (!outsideRegion) {
286 inRegion = row >= region.top + border && row < region.bottom - border &&
287 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800288 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800289 inRegion = row >= region.top - border && row < region.bottom + border &&
290 col >= region.left - border && col < region.right + border;
291 }
292 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000293 ASSERT_GE(epsilon, abs(r - *(pixel)));
294 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
295 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800296 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000297 ASSERT_GE(epsilon, abs(r - *(pixel)));
298 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
299 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800300 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800301 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700302 }
303 }
chaviwd2432892020-07-24 17:42:39 -0700304 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700305 }
306
chaviw8ffc7b82020-08-18 11:25:37 -0700307 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
308 ScreenCaptureResults& captureResults) {
Huihong Luo9e84f332021-12-16 14:33:46 -0800309 const auto sf = ComposerServiceAIDL::getComposerService();
chaviw8ffc7b82020-08-18 11:25:37 -0700310 SurfaceComposerClient::Transaction().apply(true);
311
312 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
Huihong Luo9e84f332021-12-16 14:33:46 -0800313 binder::Status status = sf->captureDisplay(captureArgs, captureListener);
Huihong Luo3bdef862022-03-03 11:57:19 -0800314 status_t err = gui::aidl_utils::statusTFromBinderStatus(status);
315 if (err != NO_ERROR) {
316 return err;
chaviw8ffc7b82020-08-18 11:25:37 -0700317 }
318 captureResults = captureListener->waitForResults();
Patrick Williamsfdb57bb2022-08-09 22:48:18 +0000319 return fenceStatus(captureResults.fenceResult);
chaviw8ffc7b82020-08-18 11:25:37 -0700320 }
321
Vishnu Nair277142c2021-01-05 18:35:29 -0800322 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
323 nsecs_t presentTimeDelay) {
324 int slot;
325 sp<Fence> fence;
326 sp<GraphicBuffer> buf;
327 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
328 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
329 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500330 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800331 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
332
333 uint32_t* bufData;
334 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
335 reinterpret_cast<void**>(&bufData));
336 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
337 buf->unlock();
338
339 IGraphicBufferProducer::QueueBufferOutput qbOutput;
340 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
341 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
342 Rect(mDisplayWidth, mDisplayHeight / 2),
343 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
344 Fence::NO_FENCE);
345 igbp->queueBuffer(slot, input, &qbOutput);
346 }
347
Valerie Hauc5011f92019-10-11 09:52:07 -0700348 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700349 sp<ISurfaceComposer> mComposer;
350
351 sp<IBinder> mDisplayToken;
352
Valerie Hauc5011f92019-10-11 09:52:07 -0700353 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700354
355 uint32_t mDisplayWidth;
356 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700357
358 DisplayCaptureArgs mCaptureArgs;
359 ScreenCaptureResults mCaptureResults;
chaviwd7deef72021-10-06 11:53:40 -0500360 sp<CountProducerListener> mProducerListener;
Valerie Hauc5011f92019-10-11 09:52:07 -0700361};
362
363TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
364 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700365 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700366 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700367 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
368 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Tianhao Yao4861b102022-02-03 20:18:35 +0000369 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700370}
371
372TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700373 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700374 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700375 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
376 PIXEL_FORMAT_RGBA_8888);
377 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700378 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800379 sp<IGraphicBufferProducer> igbProducer;
380 setUpProducer(adapter, igbProducer);
381
382 int32_t width;
383 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
384 ASSERT_EQ(mDisplayWidth / 2, width);
385 int32_t height;
386 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
387 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700388}
389
Tianhao Yao4861b102022-02-03 20:18:35 +0000390TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700391 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000392 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
393 auto callback = [](Transaction*) {};
394 adapter.syncNextTransaction(callback);
395 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700396}
Valerie Hauda3446e2019-10-14 15:49:22 -0700397
Valerie Haubf29e042020-02-06 11:40:38 -0800398TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800399 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
400 sp<IGraphicBufferProducer> igbProducer;
401 setUpProducer(adapter, igbProducer);
402
403 int slot;
404 sp<Fence> fence;
405 sp<GraphicBuffer> buf;
406 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
407 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
408 nullptr, nullptr);
409 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
410 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
411
412 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
413 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800414 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
415 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800416 Rect(mDisplayWidth, mDisplayHeight),
417 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
418 Fence::NO_FENCE);
419 igbProducer->queueBuffer(slot, input, &qbOutput);
420 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
421
422 adapter.waitForCallbacks();
423 ASSERT_GE(systemTime(), desiredPresentTime);
424}
425
Valerie Hauda3446e2019-10-14 15:49:22 -0700426TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
427 uint8_t r = 255;
428 uint8_t g = 0;
429 uint8_t b = 0;
430
431 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800432 sp<IGraphicBufferProducer> igbProducer;
433 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700434
435 int slot;
436 sp<Fence> fence;
437 sp<GraphicBuffer> buf;
438 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
439 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
440 nullptr, nullptr);
441 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
442 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
443
444 uint32_t* bufData;
445 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
446 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800447 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700448 buf->unlock();
449
Valerie Haud3b90d22019-11-06 09:37:31 -0800450 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800451 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
452 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700453 Rect(mDisplayWidth, mDisplayHeight),
454 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
455 Fence::NO_FENCE);
456 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800457 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700458
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800459 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700460
461 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700462 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800463 ASSERT_NO_FATAL_FAILURE(
464 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700465}
Valerie Haud3b90d22019-11-06 09:37:31 -0800466
467TEST_F(BLASTBufferQueueTest, TripleBuffering) {
468 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
469 sp<IGraphicBufferProducer> igbProducer;
470 setUpProducer(adapter, igbProducer);
471
472 std::vector<std::pair<int, sp<Fence>>> allocated;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700473 int minUndequeuedBuffers = 0;
474 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
475 const auto bufferCount = minUndequeuedBuffers + 2;
476
477 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800478 int slot;
479 sp<Fence> fence;
480 sp<GraphicBuffer> buf;
481 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
482 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
483 nullptr, nullptr);
484 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
485 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
486 allocated.push_back({slot, fence});
487 }
488 for (int i = 0; i < allocated.size(); i++) {
489 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
490 }
491
Valerie Haua32c5522019-12-09 10:11:08 -0800492 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800493 int slot;
494 sp<Fence> fence;
495 sp<GraphicBuffer> buf;
496 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
497 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
498 nullptr, nullptr);
499 ASSERT_EQ(NO_ERROR, ret);
500 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800501 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
502 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800503 Rect(mDisplayWidth, mDisplayHeight),
504 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
505 Fence::NO_FENCE);
506 igbProducer->queueBuffer(slot, input, &qbOutput);
507 }
508 adapter.waitForCallbacks();
509}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800510
511TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
512 uint8_t r = 255;
513 uint8_t g = 0;
514 uint8_t b = 0;
515
516 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
517 sp<IGraphicBufferProducer> igbProducer;
518 setUpProducer(adapter, igbProducer);
519 int slot;
520 sp<Fence> fence;
521 sp<GraphicBuffer> buf;
522 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
523 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
524 nullptr, nullptr);
525 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
526 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
527
528 uint32_t* bufData;
529 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
530 reinterpret_cast<void**>(&bufData));
531 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
532 buf->unlock();
533
534 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800535 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
536 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800537 Rect(mDisplayWidth, mDisplayHeight / 2),
538 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
539 Fence::NO_FENCE);
540 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800541 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800542
543 adapter.waitForCallbacks();
544 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700545 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700546
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800547 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000548 checkScreenCapture(r, g, b,
549 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800550}
551
552TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
553 uint8_t r = 255;
554 uint8_t g = 0;
555 uint8_t b = 0;
556
557 int32_t bufferSideLength =
558 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
559 int32_t finalCropSideLength = bufferSideLength / 2;
560
561 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800562 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800563 ASSERT_NE(nullptr, bg.get());
564 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700565 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
chaviw25714502021-02-11 10:01:08 -0800566 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800567 .setColor(bg, half3{0, 0, 0})
568 .setLayer(bg, 0)
569 .apply();
570
571 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
572 sp<IGraphicBufferProducer> igbProducer;
573 setUpProducer(adapter, igbProducer);
574 int slot;
575 sp<Fence> fence;
576 sp<GraphicBuffer> buf;
577 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
578 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
579 nullptr, nullptr);
580 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
581 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
582
583 uint32_t* bufData;
584 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
585 reinterpret_cast<void**>(&bufData));
586 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
587 fillBuffer(bufData,
588 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
589 buf->getHeight()),
590 buf->getStride(), r, g, b);
591 buf->unlock();
592
593 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800594 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
595 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800596 Rect(bufferSideLength, finalCropSideLength),
597 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
598 Fence::NO_FENCE);
599 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800600 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800601
602 adapter.waitForCallbacks();
603 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700604 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700605 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
606 {10, 10, (int32_t)bufferSideLength - 10,
607 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800608 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700609 checkScreenCapture(0, 0, 0,
610 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
611 /*border*/ 0, /*outsideRegion*/ true));
612}
613
614TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
615 // add black background
616 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
617 ISurfaceComposerClient::eFXSurfaceEffect);
618 ASSERT_NE(nullptr, bg.get());
619 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700620 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700621 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
622 .setColor(bg, half3{0, 0, 0})
623 .setLayer(bg, 0)
624 .apply();
625
626 Rect windowSize(1000, 1000);
627 Rect bufferSize(windowSize);
628 Rect bufferCrop(200, 200, 700, 700);
629
630 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
631 sp<IGraphicBufferProducer> igbProducer;
632 setUpProducer(adapter, igbProducer);
633 int slot;
634 sp<Fence> fence;
635 sp<GraphicBuffer> buf;
636 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
637 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
638 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
639 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
640 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
641
642 uint32_t* bufData;
643 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
644 reinterpret_cast<void**>(&bufData));
645 // fill buffer with grey
646 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
647
648 // fill crop area with different colors so we can verify the cropped region has been scaled
649 // correctly.
650 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
651 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
652 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
653 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
654 buf->unlock();
655
656 IGraphicBufferProducer::QueueBufferOutput qbOutput;
657 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
658 HAL_DATASPACE_UNKNOWN,
659 bufferCrop /* Rect::INVALID_RECT */,
660 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
661 Fence::NO_FENCE);
662 igbProducer->queueBuffer(slot, input, &qbOutput);
663 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
664
665 adapter.waitForCallbacks();
666
667 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
668
669 // Verify cropped region is scaled correctly.
670 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
671 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
672 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
673 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
674 // Verify outside region is black.
675 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
676 {0, 0, (int32_t)windowSize.getWidth(),
677 (int32_t)windowSize.getHeight()},
678 /*border*/ 0, /*outsideRegion*/ true));
679}
680
681TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
682 // add black background
683 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
684 ISurfaceComposerClient::eFXSurfaceEffect);
685 ASSERT_NE(nullptr, bg.get());
686 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700687 t.setLayerStack(bg, ui::DEFAULT_LAYER_STACK)
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700688 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
689 .setColor(bg, half3{0, 0, 0})
690 .setLayer(bg, 0)
691 .apply();
692
693 Rect windowSize(1000, 1000);
694 Rect bufferSize(500, 500);
695 Rect bufferCrop(100, 100, 350, 350);
696
697 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
698 sp<IGraphicBufferProducer> igbProducer;
699 setUpProducer(adapter, igbProducer);
700 int slot;
701 sp<Fence> fence;
702 sp<GraphicBuffer> buf;
703 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
704 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
705 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
706 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
707 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
708
709 uint32_t* bufData;
710 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
711 reinterpret_cast<void**>(&bufData));
712 // fill buffer with grey
713 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
714
715 // fill crop area with different colors so we can verify the cropped region has been scaled
716 // correctly.
717 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
718 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
719 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
720 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
721 buf->unlock();
722
723 IGraphicBufferProducer::QueueBufferOutput qbOutput;
724 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
725 HAL_DATASPACE_UNKNOWN,
726 bufferCrop /* Rect::INVALID_RECT */,
727 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
728 Fence::NO_FENCE);
729 igbProducer->queueBuffer(slot, input, &qbOutput);
730 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
731
732 adapter.waitForCallbacks();
733
734 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
735 // Verify cropped region is scaled correctly.
736 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
737 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
738 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
739 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
740 // Verify outside region is black.
741 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
742 {0, 0, (int32_t)windowSize.getWidth(),
743 (int32_t)windowSize.getHeight()},
744 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800745}
746
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700747// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
748// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
749TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
750 uint8_t r = 255;
751 uint8_t g = 0;
752 uint8_t b = 0;
753
754 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
755 sp<IGraphicBufferProducer> igbProducer;
756 setUpProducer(adapter, igbProducer);
757 {
758 int slot;
759 sp<Fence> fence;
760 sp<GraphicBuffer> buf;
761 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
762 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
763 nullptr, nullptr);
764 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
765 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
766
767 uint32_t* bufData;
768 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
769 reinterpret_cast<void**>(&bufData));
770 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
771 buf->unlock();
772
773 IGraphicBufferProducer::QueueBufferOutput qbOutput;
774 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
775 HAL_DATASPACE_UNKNOWN, {},
776 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
777 Fence::NO_FENCE);
778 igbProducer->queueBuffer(slot, input, &qbOutput);
779 adapter.waitForCallbacks();
780 }
781 // capture screen and verify that it is red
782 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
783
784 ASSERT_NO_FATAL_FAILURE(
785 checkScreenCapture(r, g, b,
786 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
787
788 // update the size to half the display and dequeue a buffer quarter of the display.
789 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
790
791 {
792 int slot;
793 sp<Fence> fence;
794 sp<GraphicBuffer> buf;
795 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
796 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
797 nullptr, nullptr);
798 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
799 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
800
801 uint32_t* bufData;
802 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
803 reinterpret_cast<void**>(&bufData));
804 g = 255;
805 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
806 buf->unlock();
807
808 IGraphicBufferProducer::QueueBufferOutput qbOutput;
809 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
810 HAL_DATASPACE_UNKNOWN, {},
811 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
812 0, Fence::NO_FENCE);
813 igbProducer->queueBuffer(slot, input, &qbOutput);
814 adapter.waitForCallbacks();
815 }
816 // capture screen and verify that it is red
817 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
818 // verify we still scale the buffer to the new size (half the screen height)
819 ASSERT_NO_FATAL_FAILURE(
820 checkScreenCapture(r, g, b,
821 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
822}
823
chaviwd7deef72021-10-06 11:53:40 -0500824TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
825 uint8_t r = 255;
826 uint8_t g = 0;
827 uint8_t b = 0;
828
829 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
830
831 sp<IGraphicBufferProducer> igbProducer;
832 setUpProducer(adapter, igbProducer);
833
chaviwa1c4c822021-11-10 18:11:58 -0600834 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000835 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500836 queueBuffer(igbProducer, 0, 255, 0, 0);
837
838 // queue non sync buffer, so this one should get blocked
839 // Add a present delay to allow the first screenshot to get taken.
840 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
841 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
842
843 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600844 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500845 transactionCallback.getContext())
846 .apply();
847
848 CallbackData callbackData;
849 transactionCallback.getCallbackData(&callbackData);
850
chaviw0acd33a2021-11-02 11:55:37 -0500851 // capture screen and verify that it is green
chaviwd7deef72021-10-06 11:53:40 -0500852 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
853 ASSERT_NO_FATAL_FAILURE(
854 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
855
856 mProducerListener->waitOnNumberReleased(1);
857 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
858 ASSERT_NO_FATAL_FAILURE(
859 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
860}
861
862TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
863 uint8_t r = 255;
864 uint8_t g = 0;
865 uint8_t b = 0;
866
867 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
868
869 sp<IGraphicBufferProducer> igbProducer;
870 setUpProducer(adapter, igbProducer);
871
872 Transaction mainTransaction;
873
chaviwa1c4c822021-11-10 18:11:58 -0600874 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000875 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500876 queueBuffer(igbProducer, 0, 255, 0, 0);
877
chaviwa1c4c822021-11-10 18:11:58 -0600878 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500879
Tianhao Yao4861b102022-02-03 20:18:35 +0000880 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500881 queueBuffer(igbProducer, r, g, b, 0);
882
chaviwa1c4c822021-11-10 18:11:58 -0600883 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500884 // Expect 1 buffer to be released even before sending to SurfaceFlinger
885 mProducerListener->waitOnNumberReleased(1);
886
887 CallbackHelper transactionCallback;
888 mainTransaction
889 .addTransactionCompletedCallback(transactionCallback.function,
890 transactionCallback.getContext())
891 .apply();
892
893 CallbackData callbackData;
894 transactionCallback.getCallbackData(&callbackData);
895
896 // capture screen and verify that it is red
897 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
898 ASSERT_NO_FATAL_FAILURE(
899 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
900}
901
902TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
903 uint8_t r = 255;
904 uint8_t g = 0;
905 uint8_t b = 0;
906
907 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
908
909 sp<IGraphicBufferProducer> igbProducer;
910 setUpProducer(adapter, igbProducer);
911
912 Transaction mainTransaction;
913
chaviwa1c4c822021-11-10 18:11:58 -0600914 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500915 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000916 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500917 queueBuffer(igbProducer, 0, 255, 0, 0);
918
chaviwa1c4c822021-11-10 18:11:58 -0600919 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500920
chaviwa1c4c822021-11-10 18:11:58 -0600921 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500922 queueBuffer(igbProducer, 0, 0, 255, 0);
923
924 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000925 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500926 queueBuffer(igbProducer, r, g, b, 0);
927 // Expect 1 buffer to be released because the non sync transaction should merge
928 // with the sync
929 mProducerListener->waitOnNumberReleased(1);
930
chaviwa1c4c822021-11-10 18:11:58 -0600931 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500932 // Expect 2 buffers to be released due to merging the two syncs.
933 mProducerListener->waitOnNumberReleased(2);
934
935 CallbackHelper transactionCallback;
936 mainTransaction
937 .addTransactionCompletedCallback(transactionCallback.function,
938 transactionCallback.getContext())
939 .apply();
940
941 CallbackData callbackData;
942 transactionCallback.getCallbackData(&callbackData);
943
944 // capture screen and verify that it is red
945 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
946 ASSERT_NO_FATAL_FAILURE(
947 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
948}
949
950TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
951 uint8_t r = 255;
952 uint8_t g = 0;
953 uint8_t b = 0;
954
955 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
956
957 sp<IGraphicBufferProducer> igbProducer;
958 setUpProducer(adapter, igbProducer, 3);
959
960 Transaction mainTransaction;
961
chaviwa1c4c822021-11-10 18:11:58 -0600962 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500963 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000964 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500965 queueBuffer(igbProducer, 0, 255, 0, 0);
966
chaviwa1c4c822021-11-10 18:11:58 -0600967 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500968
chaviwa1c4c822021-11-10 18:11:58 -0600969 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500970 queueBuffer(igbProducer, 0, 0, 255, 0);
971 queueBuffer(igbProducer, 0, 0, 255, 0);
972 queueBuffer(igbProducer, 0, 0, 255, 0);
973
974 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000975 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500976 queueBuffer(igbProducer, r, g, b, 0);
977 // Expect 3 buffers to be released because the non sync transactions should merge
978 // with the sync
979 mProducerListener->waitOnNumberReleased(3);
980
chaviwa1c4c822021-11-10 18:11:58 -0600981 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500982 // Expect 4 buffers to be released due to merging the two syncs.
983 mProducerListener->waitOnNumberReleased(4);
984
985 CallbackHelper transactionCallback;
986 mainTransaction
987 .addTransactionCompletedCallback(transactionCallback.function,
988 transactionCallback.getContext())
989 .apply();
990
991 CallbackData callbackData;
992 transactionCallback.getCallbackData(&callbackData);
993
994 // capture screen and verify that it is red
995 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
996 ASSERT_NO_FATAL_FAILURE(
997 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
998}
999
1000// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
1001// continue processing is for a release callback from SurfaceFlinger.
1002// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
1003// continue acquiring buffers.
1004TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
1005 uint8_t r = 255;
1006 uint8_t g = 0;
1007 uint8_t b = 0;
1008
1009 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1010
1011 sp<IGraphicBufferProducer> igbProducer;
1012 setUpProducer(adapter, igbProducer, 4);
1013
1014 Transaction mainTransaction;
1015
1016 // Send a buffer to SF
1017 queueBuffer(igbProducer, 0, 255, 0, 0);
1018
chaviwa1c4c822021-11-10 18:11:58 -06001019 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001020 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001021 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001022 queueBuffer(igbProducer, 0, 255, 0, 0);
1023
chaviwa1c4c822021-11-10 18:11:58 -06001024 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001025
chaviwa1c4c822021-11-10 18:11:58 -06001026 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001027 queueBuffer(igbProducer, 0, 0, 255, 0);
1028 queueBuffer(igbProducer, 0, 0, 255, 0);
1029 queueBuffer(igbProducer, 0, 0, 255, 0);
1030
1031 // apply the first synced buffer to ensure we have to wait on SF
1032 mainTransaction.apply();
1033
1034 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001035 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001036 queueBuffer(igbProducer, r, g, b, 0);
1037 // Expect 2 buffers to be released because the non sync transactions should merge
1038 // with the sync
1039 mProducerListener->waitOnNumberReleased(3);
1040
chaviwa1c4c822021-11-10 18:11:58 -06001041 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001042
1043 CallbackHelper transactionCallback;
1044 mainTransaction
1045 .addTransactionCompletedCallback(transactionCallback.function,
1046 transactionCallback.getContext())
1047 .apply();
1048
1049 CallbackData callbackData;
1050 transactionCallback.getCallbackData(&callbackData);
1051
1052 // capture screen and verify that it is red
1053 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1054 ASSERT_NO_FATAL_FAILURE(
1055 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1056}
1057
Tianhao Yao4861b102022-02-03 20:18:35 +00001058TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001059 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1060
1061 sp<IGraphicBufferProducer> igbProducer;
1062 setUpProducer(adapter, igbProducer);
1063
1064 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001065 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001066 queueBuffer(igbProducer, 0, 255, 0, 0);
1067 queueBuffer(igbProducer, 0, 0, 255, 0);
1068 // There should only be one frame submitted since the first frame will be released.
1069 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001070 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001071
1072 // queue non sync buffer, so this one should get blocked
1073 // Add a present delay to allow the first screenshot to get taken.
1074 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1075 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1076
1077 CallbackHelper transactionCallback;
1078 next.addTransactionCompletedCallback(transactionCallback.function,
1079 transactionCallback.getContext())
1080 .apply();
1081
1082 CallbackData callbackData;
1083 transactionCallback.getCallbackData(&callbackData);
1084
1085 // capture screen and verify that it is blue
1086 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1087 ASSERT_NO_FATAL_FAILURE(
1088 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1089
1090 mProducerListener->waitOnNumberReleased(2);
1091 // capture screen and verify that it is red
1092 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1093 ASSERT_NO_FATAL_FAILURE(
1094 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1095}
1096
chaviw3b4bdcf2022-03-17 09:27:03 -05001097TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
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 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001113 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1114
1115 sp<IGraphicBufferProducer> igbProducer;
1116 setUpProducer(adapter, igbProducer);
1117 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001118
1119 std::unique_lock<std::mutex> lock(mutex);
1120 if (!receivedCallback) {
1121 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1122 std::cv_status::timeout)
1123 << "did not receive callback";
1124 }
1125
1126 ASSERT_TRUE(receivedCallback);
1127}
1128
Chavi Weingartenc398c012023-04-12 17:26:02 +00001129TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1130 std::mutex mutex;
1131 std::condition_variable callbackReceivedCv;
1132 bool receivedCallback = false;
1133
1134 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1135 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1136 auto callback = [&](Transaction*) {
1137 std::unique_lock<std::mutex> lock(mutex);
1138 receivedCallback = true;
1139 callbackReceivedCv.notify_one();
1140 };
1141 adapter.syncNextTransaction(callback);
1142 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1143
1144 adapter.clearSyncTransaction();
1145
1146 sp<IGraphicBufferProducer> igbProducer;
1147 setUpProducer(adapter, igbProducer);
1148 queueBuffer(igbProducer, 0, 255, 0, 0);
1149
1150 std::unique_lock<std::mutex> lock(mutex);
1151 if (!receivedCallback) {
1152 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1153 std::cv_status::timeout)
1154 << "did not receive callback";
1155 }
1156
1157 ASSERT_FALSE(receivedCallback);
1158}
1159
chaviwc1cf4022022-06-03 13:32:33 -05001160TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1161 uint8_t r = 255;
1162 uint8_t g = 0;
1163 uint8_t b = 0;
1164
1165 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1166
1167 sp<IGraphicBufferProducer> igbProducer;
1168 setUpProducer(adapter, igbProducer);
1169
1170 Transaction sync;
1171 adapter.setSyncTransaction(sync);
1172 queueBuffer(igbProducer, 0, 255, 0, 0);
1173
1174 // Merge a transaction that has a complete callback into the next frame so we can get notified
1175 // when to take a screenshot
1176 CallbackHelper transactionCallback;
1177 Transaction t;
1178 t.addTransactionCompletedCallback(transactionCallback.function,
1179 transactionCallback.getContext());
1180 adapter.mergeWithNextTransaction(&t, 2);
1181 queueBuffer(igbProducer, r, g, b, 0);
1182
1183 // Drop the buffer, but ensure the next one continues to get processed.
1184 sync.setBuffer(mSurfaceControl, nullptr);
1185
1186 CallbackData callbackData;
1187 transactionCallback.getCallbackData(&callbackData);
1188 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1189 ASSERT_NO_FATAL_FAILURE(
1190 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001191 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001192}
1193
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001194// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1195// until the old surface control is destroyed. This is not necessarily a bug but to document a
1196// limitation with the update API and to test any changes to make the api more robust. The current
1197// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1198TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1199 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1200 std::vector<sp<SurfaceControl>> surfaceControls;
1201 sp<IGraphicBufferProducer> igbProducer;
1202 for (int i = 0; i < 10; i++) {
1203 sp<SurfaceControl> sc =
1204 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1205 PIXEL_FORMAT_RGBA_8888,
1206 ISurfaceComposerClient::eFXSurfaceBufferState,
1207 /*parent*/ nullptr);
1208 Transaction()
1209 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1210 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1211 .show(mSurfaceControl)
1212 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1213 .apply(true);
1214 surfaceControls.push_back(sc);
1215 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1216
1217 setUpProducer(adapter, igbProducer);
1218 Transaction next;
1219 queueBuffer(igbProducer, 0, 255, 0, 0);
1220 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001221 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001222 queueBuffer(igbProducer, 255, 0, 0, 0);
1223
1224 CallbackHelper transactionCallback;
1225 next.addTransactionCompletedCallback(transactionCallback.function,
1226 transactionCallback.getContext())
1227 .apply();
1228
1229 CallbackData callbackData;
1230 transactionCallback.getCallbackData(&callbackData);
1231 // capture screen and verify that it is red
1232 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1233 ASSERT_NO_FATAL_FAILURE(
1234 checkScreenCapture(255, 0, 0,
1235 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1236 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1237 }
1238}
1239
1240// See DISABLED_DisconnectProducerTest
1241TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1242 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1243 std::vector<sp<SurfaceControl>> surfaceControls;
1244 sp<IGraphicBufferProducer> igbProducer;
1245 for (int i = 0; i < 10; i++) {
1246 sp<SurfaceControl> sc =
1247 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1248 PIXEL_FORMAT_RGBA_8888,
1249 ISurfaceComposerClient::eFXSurfaceBufferState,
1250 /*parent*/ nullptr);
1251 Transaction()
1252 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1253 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1254 .show(mSurfaceControl)
1255 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1256 .apply(true);
1257 surfaceControls.push_back(sc);
1258 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1259 setUpProducer(adapter, igbProducer);
1260
1261 Transaction next;
1262 queueBuffer(igbProducer, 0, 255, 0, 0);
1263 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001264 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001265 queueBuffer(igbProducer, 255, 0, 0, 0);
1266
1267 CallbackHelper transactionCallback;
1268 next.addTransactionCompletedCallback(transactionCallback.function,
1269 transactionCallback.getContext())
1270 .apply();
1271
1272 CallbackData callbackData;
1273 transactionCallback.getCallbackData(&callbackData);
1274 // capture screen and verify that it is red
1275 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1276 ASSERT_NO_FATAL_FAILURE(
1277 checkScreenCapture(255, 0, 0,
1278 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1279 }
1280}
1281
Vishnu Nair89496122020-12-14 17:14:53 -08001282class TestProducerListener : public BnProducerListener {
1283public:
1284 sp<IGraphicBufferProducer> mIgbp;
1285 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1286 void onBufferReleased() override {
1287 sp<GraphicBuffer> buffer;
1288 sp<Fence> fence;
1289 mIgbp->detachNextBuffer(&buffer, &fence);
1290 }
1291};
1292
1293TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1294 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1295 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1296 ASSERT_NE(nullptr, igbProducer.get());
1297 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1298 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1299 ASSERT_EQ(NO_ERROR,
1300 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1301 false, &qbOutput));
1302 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1303 for (int i = 0; i < 3; i++) {
1304 int slot;
1305 sp<Fence> fence;
1306 sp<GraphicBuffer> buf;
1307 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1308 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1309 nullptr, nullptr);
1310 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1311 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1312 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001313 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1314 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001315 Rect(mDisplayWidth, mDisplayHeight),
1316 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1317 Fence::NO_FENCE);
1318 igbProducer->queueBuffer(slot, input, &qbOutput);
1319 }
1320 adapter.waitForCallbacks();
1321}
1322
Vishnu Nair17dde612020-12-28 11:39:59 -08001323TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1324 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1325
1326 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1327 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1328 int queuesToNativeWindow = 0;
1329 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1330 &queuesToNativeWindow);
1331 ASSERT_EQ(NO_ERROR, err);
1332 ASSERT_EQ(queuesToNativeWindow, 1);
1333}
1334
Vishnu Nair083efd32021-02-12 09:32:30 -08001335// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1336// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -08001337TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1338 sp<SurfaceControl> bgSurface =
1339 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1340 ISurfaceComposerClient::eFXSurfaceBufferState);
1341 ASSERT_NE(nullptr, bgSurface.get());
1342 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001343 t.setLayerStack(bgSurface, ui::DEFAULT_LAYER_STACK)
Vishnu Nair277142c2021-01-05 18:35:29 -08001344 .show(bgSurface)
1345 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -08001346 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1347 .apply();
1348
1349 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1350 sp<IGraphicBufferProducer> slowIgbProducer;
1351 setUpProducer(slowAdapter, slowIgbProducer);
1352 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -08001353 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -08001354
1355 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1356 sp<IGraphicBufferProducer> fastIgbProducer;
1357 setUpProducer(fastAdapter, fastIgbProducer);
1358 uint8_t r = 255;
1359 uint8_t g = 0;
1360 uint8_t b = 0;
1361 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1362 fastAdapter.waitForCallbacks();
1363
1364 // capture screen and verify that it is red
1365 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1366
1367 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +00001368 checkScreenCapture(r, g, b,
1369 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -08001370}
1371
Vishnu Naira4fbca52021-07-07 16:52:34 -07001372TEST_F(BLASTBufferQueueTest, TransformHint) {
1373 // Transform hint is provided to BBQ via the surface control passed by WM
1374 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1375
1376 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1377 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1378 ASSERT_NE(nullptr, igbProducer.get());
1379 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1380 sp<Surface> surface = adapter.getSurface();
1381
1382 // Before connecting to the surface, we do not get a valid transform hint
1383 int transformHint;
1384 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1385 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1386
1387 ASSERT_EQ(NO_ERROR,
1388 surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1389
1390 // After connecting to the surface, we should get the correct hint.
1391 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1392 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1393
1394 ANativeWindow_Buffer buffer;
1395 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1396
1397 // Transform hint is updated via callbacks or surface control updates
1398 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1399 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1400
1401 // The hint does not change and matches the value used when dequeueing the buffer.
1402 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1403 ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1404
1405 surface->unlockAndPost();
1406
1407 // After queuing the buffer, we get the updated transform hint
1408 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1409 ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1410
1411 adapter.waitForCallbacks();
1412}
1413
Valerie Hau5977fc82019-12-05 15:56:39 -08001414class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1415public:
1416 void test(uint32_t tr) {
1417 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1418 sp<IGraphicBufferProducer> igbProducer;
1419 setUpProducer(adapter, igbProducer);
1420
1421 auto bufWidth = mDisplayWidth;
1422 auto bufHeight = mDisplayHeight;
1423 int slot;
1424 sp<Fence> fence;
1425 sp<GraphicBuffer> buf;
1426
1427 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1428 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1429 nullptr, nullptr);
1430 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1431 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1432
1433 fillQuadrants(buf);
1434
1435 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001436 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1437 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001438 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001439 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1440 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001441 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001442 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001443
1444 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -07001445 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001446
Valerie Hau5977fc82019-12-05 15:56:39 -08001447 switch (tr) {
1448 case ui::Transform::ROT_0:
1449 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1450 {0, 0, (int32_t)mDisplayWidth / 2,
1451 (int32_t)mDisplayHeight / 2},
1452 1));
1453 ASSERT_NO_FATAL_FAILURE(
1454 checkScreenCapture(255, 0, 0,
1455 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1456 (int32_t)mDisplayHeight / 2},
1457 1));
1458 ASSERT_NO_FATAL_FAILURE(
1459 checkScreenCapture(0, 255, 0,
1460 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1461 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1462 1));
1463 ASSERT_NO_FATAL_FAILURE(
1464 checkScreenCapture(0, 0, 255,
1465 {0, (int32_t)mDisplayHeight / 2,
1466 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1467 1));
1468 break;
1469 case ui::Transform::FLIP_H:
1470 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1471 {0, 0, (int32_t)mDisplayWidth / 2,
1472 (int32_t)mDisplayHeight / 2},
1473 1));
1474 ASSERT_NO_FATAL_FAILURE(
1475 checkScreenCapture(0, 0, 0,
1476 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1477 (int32_t)mDisplayHeight / 2},
1478 1));
1479 ASSERT_NO_FATAL_FAILURE(
1480 checkScreenCapture(0, 0, 255,
1481 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1482 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1483 1));
1484 ASSERT_NO_FATAL_FAILURE(
1485 checkScreenCapture(0, 255, 0,
1486 {0, (int32_t)mDisplayHeight / 2,
1487 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1488 1));
1489 break;
1490 case ui::Transform::FLIP_V:
1491 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1492 {0, 0, (int32_t)mDisplayWidth / 2,
1493 (int32_t)mDisplayHeight / 2},
1494 1));
1495 ASSERT_NO_FATAL_FAILURE(
1496 checkScreenCapture(0, 255, 0,
1497 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1498 (int32_t)mDisplayHeight / 2},
1499 1));
1500 ASSERT_NO_FATAL_FAILURE(
1501 checkScreenCapture(255, 0, 0,
1502 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1503 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1504 1));
1505 ASSERT_NO_FATAL_FAILURE(
1506 checkScreenCapture(0, 0, 0,
1507 {0, (int32_t)mDisplayHeight / 2,
1508 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1509 1));
1510 break;
1511 case ui::Transform::ROT_90:
1512 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1513 {0, 0, (int32_t)mDisplayWidth / 2,
1514 (int32_t)mDisplayHeight / 2},
1515 1));
1516 ASSERT_NO_FATAL_FAILURE(
1517 checkScreenCapture(0, 0, 0,
1518 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1519 (int32_t)mDisplayHeight / 2},
1520 1));
1521 ASSERT_NO_FATAL_FAILURE(
1522 checkScreenCapture(255, 0, 0,
1523 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1524 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1525 1));
1526 ASSERT_NO_FATAL_FAILURE(
1527 checkScreenCapture(0, 255, 0,
1528 {0, (int32_t)mDisplayHeight / 2,
1529 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1530 1));
1531 break;
1532 case ui::Transform::ROT_180:
1533 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1534 {0, 0, (int32_t)mDisplayWidth / 2,
1535 (int32_t)mDisplayHeight / 2},
1536 1));
1537 ASSERT_NO_FATAL_FAILURE(
1538 checkScreenCapture(0, 0, 255,
1539 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1540 (int32_t)mDisplayHeight / 2},
1541 1));
1542 ASSERT_NO_FATAL_FAILURE(
1543 checkScreenCapture(0, 0, 0,
1544 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1545 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1546 1));
1547 ASSERT_NO_FATAL_FAILURE(
1548 checkScreenCapture(255, 0, 0,
1549 {0, (int32_t)mDisplayHeight / 2,
1550 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1551 1));
1552 break;
1553 case ui::Transform::ROT_270:
1554 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1555 {0, 0, (int32_t)mDisplayWidth / 2,
1556 (int32_t)mDisplayHeight / 2},
1557 1));
1558 ASSERT_NO_FATAL_FAILURE(
1559 checkScreenCapture(0, 255, 0,
1560 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1561 (int32_t)mDisplayHeight / 2},
1562 1));
1563 ASSERT_NO_FATAL_FAILURE(
1564 checkScreenCapture(0, 0, 255,
1565 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1566 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1567 1));
1568 ASSERT_NO_FATAL_FAILURE(
1569 checkScreenCapture(0, 0, 0,
1570 {0, (int32_t)mDisplayHeight / 2,
1571 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1572 1));
1573 }
1574 }
1575};
1576
1577TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1578 test(ui::Transform::ROT_0);
1579}
1580
1581TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1582 test(ui::Transform::FLIP_H);
1583}
1584
1585TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1586 test(ui::Transform::FLIP_V);
1587}
1588
1589TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1590 test(ui::Transform::ROT_90);
1591}
1592
1593TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1594 test(ui::Transform::ROT_180);
1595}
1596
1597TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1598 test(ui::Transform::ROT_270);
1599}
Valerie Hau871d6352020-01-29 08:44:02 -08001600
1601class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1602public:
1603 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001604 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001605 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001606 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001607 int slot;
1608 sp<Fence> fence;
1609 sp<GraphicBuffer> buf;
1610 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1611 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1612 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001613 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1614 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1615 }
Valerie Hau871d6352020-01-29 08:44:02 -08001616
Vishnu Nairde66dc72021-06-17 17:54:41 -07001617 *outRequestedPresentTime = requestedPresentTime;
1618 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1619 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001620 Rect(mDisplayWidth, mDisplayHeight),
1621 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1622 Fence::NO_FENCE, /*sticky*/ 0,
1623 getFrameTimestamps);
1624 if (postedTime) *postedTime = systemTime();
1625 igbProducer->queueBuffer(slot, input, qbOutput);
1626 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001627 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001628};
1629
1630TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1631 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1632 sp<IGraphicBufferProducer> igbProducer;
1633 ProducerFrameEventHistory history;
1634 setUpProducer(adapter, igbProducer);
1635
1636 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1637 nsecs_t requestedPresentTimeA = 0;
1638 nsecs_t postedTimeA = 0;
1639 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1640 history.applyDelta(qbOutput.frameTimestamps);
1641
1642 FrameEvents* events = nullptr;
1643 events = history.getFrame(1);
1644 ASSERT_NE(nullptr, events);
1645 ASSERT_EQ(1, events->frameNumber);
1646 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1647 ASSERT_GE(events->postedTime, postedTimeA);
1648
Vishnu Nair1506b182021-02-22 14:35:15 -08001649 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001650
1651 // queue another buffer so we query for frame event deltas
1652 nsecs_t requestedPresentTimeB = 0;
1653 nsecs_t postedTimeB = 0;
1654 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1655 history.applyDelta(qbOutput.frameTimestamps);
1656 events = history.getFrame(1);
1657 ASSERT_NE(nullptr, events);
1658
1659 // frame number, requestedPresentTime, and postTime should not have changed
1660 ASSERT_EQ(1, events->frameNumber);
1661 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1662 ASSERT_GE(events->postedTime, postedTimeA);
1663
1664 ASSERT_GE(events->latchTime, postedTimeA);
1665 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1666 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1667 ASSERT_NE(nullptr, events->displayPresentFence);
1668 ASSERT_NE(nullptr, events->releaseFence);
1669
1670 // we should also have gotten the initial values for the next frame
1671 events = history.getFrame(2);
1672 ASSERT_NE(nullptr, events);
1673 ASSERT_EQ(2, events->frameNumber);
1674 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1675 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001676
1677 // wait for any callbacks that have not been received
1678 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001679}
Vishnu Nair083efd32021-02-12 09:32:30 -08001680
Vishnu Nair083efd32021-02-12 09:32:30 -08001681TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1682 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1683 sp<IGraphicBufferProducer> igbProducer;
1684 setUpProducer(adapter, igbProducer);
1685
1686 ProducerFrameEventHistory history;
1687 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1688 nsecs_t requestedPresentTimeA = 0;
1689 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001690 // Present the frame sometime in the future so we can add two frames to the queue so the older
1691 // one will be dropped.
1692 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001693 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001694 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001695 history.applyDelta(qbOutput.frameTimestamps);
1696
1697 FrameEvents* events = nullptr;
1698 events = history.getFrame(1);
1699 ASSERT_NE(nullptr, events);
1700 ASSERT_EQ(1, events->frameNumber);
1701 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1702 ASSERT_GE(events->postedTime, postedTimeA);
1703
1704 // queue another buffer so the first can be dropped
1705 nsecs_t requestedPresentTimeB = 0;
1706 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001707 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1708 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1709 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001710 history.applyDelta(qbOutput.frameTimestamps);
1711 events = history.getFrame(1);
1712 ASSERT_NE(nullptr, events);
1713
1714 // frame number, requestedPresentTime, and postTime should not have changed
1715 ASSERT_EQ(1, events->frameNumber);
1716 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1717 ASSERT_GE(events->postedTime, postedTimeA);
1718
Vishnu Nairde66dc72021-06-17 17:54:41 -07001719 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001720 ASSERT_FALSE(events->hasLatchInfo());
1721 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001722 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1723 ASSERT_FALSE(events->hasDisplayPresentInfo());
1724 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001725
Vishnu Nairde66dc72021-06-17 17:54:41 -07001726 // wait for the last transaction to be completed.
1727 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001728
Vishnu Nairde66dc72021-06-17 17:54:41 -07001729 // queue another buffer so we query for frame event deltas
1730 nsecs_t requestedPresentTimeC = 0;
1731 nsecs_t postedTimeC = 0;
1732 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1733 history.applyDelta(qbOutput.frameTimestamps);
1734
1735 // frame number, requestedPresentTime, and postTime should not have changed
1736 ASSERT_EQ(1, events->frameNumber);
1737 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1738 ASSERT_GE(events->postedTime, postedTimeA);
1739
1740 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1741 ASSERT_FALSE(events->hasLatchInfo());
1742 ASSERT_FALSE(events->hasDequeueReadyInfo());
1743 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1744 ASSERT_FALSE(events->hasDisplayPresentInfo());
1745 ASSERT_FALSE(events->hasReleaseInfo());
1746
1747 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001748 events = history.getFrame(2);
1749 ASSERT_NE(nullptr, events);
1750 ASSERT_EQ(2, events->frameNumber);
1751 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1752 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001753 ASSERT_GE(events->latchTime, postedTimeB);
1754 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1755 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1756 ASSERT_NE(nullptr, events->displayPresentFence);
1757 ASSERT_NE(nullptr, events->releaseFence);
1758
1759 // wait for any callbacks that have not been received
1760 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001761}
1762
Vishnu Nair9a69a042021-06-18 13:19:49 -07001763TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1764 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1765 sp<IGraphicBufferProducer> igbProducer;
1766 ProducerFrameEventHistory history;
1767 setUpProducer(adapter, igbProducer);
1768
1769 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1770 nsecs_t requestedPresentTimeA = 0;
1771 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001772 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1773 history.applyDelta(qbOutput.frameTimestamps);
1774 adapter.waitForCallback(1);
1775
1776 // queue another buffer so we query for frame event deltas
1777 nsecs_t requestedPresentTimeB = 0;
1778 nsecs_t postedTimeB = 0;
1779 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1780 history.applyDelta(qbOutput.frameTimestamps);
1781
1782 // check for a valid compositor deadline
1783 ASSERT_NE(0, history.getReportedCompositeDeadline());
1784
1785 // wait for any callbacks that have not been received
1786 adapter.waitForCallbacks();
1787}
1788
Valerie Hauc5011f92019-10-11 09:52:07 -07001789} // namespace android