blob: 46a19c273de966d31d4cee285807fc24db88fba9 [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
Vishnu Nair2e8ae852024-03-30 00:02:30 +000021#include <android-base/thread_annotations.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070022#include <android/hardware/graphics/common/1.2/types.h>
Huihong Luo3bdef862022-03-03 11:57:19 -080023#include <gui/AidlStatusUtil.h>
Valerie Haud3b90d22019-11-06 09:37:31 -080024#include <gui/BufferQueueCore.h>
25#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080026#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070027#include <gui/IGraphicBufferProducer.h>
28#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080029#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070030#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070031#include <gui/SyncScreenCaptureListener.h>
chaviwd7deef72021-10-06 11:53:40 -050032#include <gui/test/CallbackUtils.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070033#include <private/gui/ComposerService.h>
Huihong Luo9e84f332021-12-16 14:33:46 -080034#include <private/gui/ComposerServiceAIDL.h>
Melody Hsub9578222023-10-02 23:09:36 +000035#include <tests/utils/ScreenshotUtils.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010036#include <ui/DisplayMode.h>
Vishnu Nair5b5f6932023-04-12 16:28:19 -070037#include <ui/DisplayState.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070038#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070039#include <ui/GraphicTypes.h>
Melody Hsub9578222023-10-02 23:09:36 +000040#include <ui/Rect.h>
41#include <ui/Size.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080042#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070043
44#include <gtest/gtest.h>
45
Alec Mouri21d94322023-10-17 19:51:39 +000046#include <com_android_graphics_libgui_flags.h>
47
Valerie Hauc5011f92019-10-11 09:52:07 -070048using namespace std::chrono_literals;
49
50namespace android {
Alec Mouri21d94322023-10-17 19:51:39 +000051using namespace com::android::graphics::libgui;
Valerie Hauc5011f92019-10-11 09:52:07 -070052
Valerie Hauc5011f92019-10-11 09:52:07 -070053using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070054using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070055
chaviwd7deef72021-10-06 11:53:40 -050056class CountProducerListener : public BnProducerListener {
57public:
58 void onBufferReleased() override {
59 std::scoped_lock<std::mutex> lock(mMutex);
60 mNumReleased++;
61 mReleaseCallback.notify_one();
62 }
63
64 void waitOnNumberReleased(int32_t expectedNumReleased) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +000065 std::unique_lock lock{mMutex};
66 base::ScopedLockAssertion assumeLocked(mMutex);
chaviwd7deef72021-10-06 11:53:40 -050067 while (mNumReleased < expectedNumReleased) {
68 ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
69 std::cv_status::timeout)
70 << "did not receive release";
71 }
72 }
73
74private:
75 std::mutex mMutex;
76 std::condition_variable mReleaseCallback;
77 int32_t mNumReleased GUARDED_BY(mMutex) = 0;
78};
79
chaviwf10b9042021-10-13 15:48:59 -050080class TestBLASTBufferQueue : public BLASTBufferQueue {
81public:
82 TestBLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
83 int height, int32_t format)
84 : BLASTBufferQueue(name, surface, width, height, format) {}
85
chaviw6b9ffea2021-11-08 09:25:48 -060086 void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
87 const std::vector<SurfaceControlStats>& stats) override {
88 BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
chaviwf10b9042021-10-13 15:48:59 -050089 uint64_t frameNumber = stats[0].frameEventStats.frameNumber;
90
91 {
92 std::unique_lock lock{frameNumberMutex};
chaviw6b9ffea2021-11-08 09:25:48 -060093 mLastTransactionFrameNumber = frameNumber;
94 mWaitForCallbackCV.notify_all();
chaviwf10b9042021-10-13 15:48:59 -050095 }
96 }
97
98 void waitForCallback(int64_t frameNumber) {
99 std::unique_lock lock{frameNumberMutex};
100 // Wait until all but one of the submitted buffers have been released.
chaviw6b9ffea2021-11-08 09:25:48 -0600101 while (mLastTransactionFrameNumber < frameNumber) {
102 mWaitForCallbackCV.wait(lock);
chaviwf10b9042021-10-13 15:48:59 -0500103 }
104 }
105
106private:
107 std::mutex frameNumberMutex;
chaviw6b9ffea2021-11-08 09:25:48 -0600108 std::condition_variable mWaitForCallbackCV;
109 int64_t mLastTransactionFrameNumber = -1;
chaviwf10b9042021-10-13 15:48:59 -0500110};
111
Valerie Hauc5011f92019-10-11 09:52:07 -0700112class BLASTBufferQueueHelper {
113public:
114 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviwf10b9042021-10-13 15:48:59 -0500115 mBlastBufferQueueAdapter = new TestBLASTBufferQueue("TestBLASTBufferQueue", sc, width,
116 height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700117 }
118
119 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -0800120 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -0700121 }
122
Tianhao Yao4861b102022-02-03 20:18:35 +0000123 void setSyncTransaction(Transaction& next, bool acquireSingleBuffer = true) {
124 auto callback = [&next](Transaction* t) { next.merge(std::move(*t)); };
125 mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
126 }
127
Chavi Weingartenc398c012023-04-12 17:26:02 +0000128 bool syncNextTransaction(std::function<void(Transaction*)> callback,
Tianhao Yao4861b102022-02-03 20:18:35 +0000129 bool acquireSingleBuffer = true) {
Chavi Weingartenc398c012023-04-12 17:26:02 +0000130 return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
Tianhao Yao4861b102022-02-03 20:18:35 +0000131 }
132
133 void stopContinuousSyncTransaction() {
134 mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
Valerie Hauc5011f92019-10-11 09:52:07 -0700135 }
136
Chavi Weingartenc398c012023-04-12 17:26:02 +0000137 void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
138
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000139 int getWidth() {
140 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
141 return mBlastBufferQueueAdapter->mSize.width;
142 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700143
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000144 int getHeight() {
145 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
146 return mBlastBufferQueueAdapter->mSize.height;
147 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700148
Tianhao Yao4861b102022-02-03 20:18:35 +0000149 std::function<void(Transaction*)> getTransactionReadyCallback() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000150 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Tianhao Yao4861b102022-02-03 20:18:35 +0000151 return mBlastBufferQueueAdapter->mTransactionReadyCallback;
152 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700153
154 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
155 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
156 }
157
Valerie Hauc5011f92019-10-11 09:52:07 -0700158 const sp<SurfaceControl> getSurfaceControl() {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000159 std::scoped_lock lock(mBlastBufferQueueAdapter->mMutex);
Valerie Hauc5011f92019-10-11 09:52:07 -0700160 return mBlastBufferQueueAdapter->mSurfaceControl;
161 }
162
Vishnu Naira4fbca52021-07-07 16:52:34 -0700163 sp<Surface> getSurface() {
164 return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
165 }
166
Valerie Haud3b90d22019-11-06 09:37:31 -0800167 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700168 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000169 base::ScopedLockAssertion assumeLocked(mBlastBufferQueueAdapter->mMutex);
Vishnu Nair1506b182021-02-22 14:35:15 -0800170 // Wait until all but one of the submitted buffers have been released.
171 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800172 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
173 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700174 }
175
Vishnu Nair1506b182021-02-22 14:35:15 -0800176 void waitForCallback(int64_t frameNumber) {
chaviwf10b9042021-10-13 15:48:59 -0500177 mBlastBufferQueueAdapter->waitForCallback(frameNumber);
Vishnu Nair1506b182021-02-22 14:35:15 -0800178 }
179
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000180 void validateNumFramesSubmitted(size_t numFramesSubmitted) {
181 std::scoped_lock lock{mBlastBufferQueueAdapter->mMutex};
chaviw0acd33a2021-11-02 11:55:37 -0500182 ASSERT_EQ(numFramesSubmitted, mBlastBufferQueueAdapter->mSubmitted.size());
183 }
184
chaviwc1cf4022022-06-03 13:32:33 -0500185 void mergeWithNextTransaction(Transaction* merge, uint64_t frameNumber) {
186 mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
187 }
188
Valerie Hauc5011f92019-10-11 09:52:07 -0700189private:
chaviwf10b9042021-10-13 15:48:59 -0500190 sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
Valerie Hauc5011f92019-10-11 09:52:07 -0700191};
192
193class BLASTBufferQueueTest : public ::testing::Test {
194public:
195protected:
Valerie Hauc5011f92019-10-11 09:52:07 -0700196 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700197 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700198 mClient = new SurfaceComposerClient();
Huihong Luo31b5ac22022-08-15 20:38:10 -0700199 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
200 ASSERT_FALSE(ids.empty());
201 // display 0 is picked as this test is not much display depedent
202 mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Valerie Hauda3446e2019-10-14 15:49:22 -0700203 ASSERT_NE(nullptr, mDisplayToken.get());
204 Transaction t;
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700205 t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
Valerie Hauda3446e2019-10-14 15:49:22 -0700206 t.apply();
207 t.clear();
208
Vishnu Nair5b5f6932023-04-12 16:28:19 -0700209 ui::DisplayState displayState;
210 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
211 const ui::Size& resolution = displayState.layerStackSpaceRect;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800212 mDisplayWidth = resolution.getWidth();
213 mDisplayHeight = resolution.getHeight();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000214 ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000215 static_cast<int32_t>(displayState.orientation));
Valerie Hauda3446e2019-10-14 15:49:22 -0700216
Melody Hsub9578222023-10-02 23:09:36 +0000217 mRootSurfaceControl = mClient->createSurface(String8("RootTestSurface"), mDisplayWidth,
218 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
219 ISurfaceComposerClient::eFXSurfaceBufferState,
220 /*parent*/ nullptr);
221
222 t.setLayerStack(mRootSurfaceControl, ui::DEFAULT_LAYER_STACK)
223 .setLayer(mRootSurfaceControl, std::numeric_limits<int32_t>::max())
224 .show(mRootSurfaceControl)
225 .apply();
226
Valerie Hauda3446e2019-10-14 15:49:22 -0700227 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
228 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
229 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +0000230 /*parent*/ mRootSurfaceControl->getHandle());
chaviwd2432892020-07-24 17:42:39 -0700231
Alec Mouribae67862024-08-06 14:53:46 +0000232 mCaptureArgs.captureArgs.sourceCrop =
233 gui::aidl_utils::toARect(mDisplayWidth, mDisplayHeight);
Melody Hsub9578222023-10-02 23:09:36 +0000234 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
Valerie Hauda3446e2019-10-14 15:49:22 -0700235 }
236
chaviwd7deef72021-10-06 11:53:40 -0500237 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
238 int32_t maxBufferCount = 2) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800239 producer = adapter.getIGraphicBufferProducer();
chaviwd7deef72021-10-06 11:53:40 -0500240 setUpProducer(producer, maxBufferCount);
Vishnu Nair083efd32021-02-12 09:32:30 -0800241 }
242
chaviwd7deef72021-10-06 11:53:40 -0500243 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800244 ASSERT_NE(nullptr, igbProducer.get());
chaviwd7deef72021-10-06 11:53:40 -0500245 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
Valerie Haud3b90d22019-11-06 09:37:31 -0800246 IGraphicBufferProducer::QueueBufferOutput qbOutput;
chaviwd7deef72021-10-06 11:53:40 -0500247 mProducerListener = new CountProducerListener();
Valerie Haud3b90d22019-11-06 09:37:31 -0800248 ASSERT_EQ(NO_ERROR,
chaviwd7deef72021-10-06 11:53:40 -0500249 igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800250 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800251 }
252
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800253 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
254 uint8_t b) {
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000255 for (int32_t row = rect.top; row < rect.bottom; row++) {
256 for (int32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700257 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
258 *pixel = r;
259 *(pixel + 1) = g;
260 *(pixel + 2) = b;
261 *(pixel + 3) = 255;
262 }
263 }
264 }
265
Valerie Hau5977fc82019-12-05 15:56:39 -0800266 void fillQuadrants(sp<GraphicBuffer>& buf) {
267 const auto bufWidth = buf->getWidth();
268 const auto bufHeight = buf->getHeight();
269 uint32_t* bufData;
270 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
271 reinterpret_cast<void**>(&bufData));
272 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
273 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
274 0, 0);
275 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
276 buf->getStride(), 0, 255, 0);
277 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
278 255);
279 buf->unlock();
280 }
281
282 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
283 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700284 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800285 const auto epsilon = 3;
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000286 const int32_t width = static_cast<int32_t>(captureBuf->getWidth());
287 const int32_t height = static_cast<int32_t>(captureBuf->getHeight());
chaviwd2432892020-07-24 17:42:39 -0700288 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700289
290 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700291 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
292 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700293
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000294 for (int32_t row = 0; row < height; row++) {
295 for (int32_t col = 0; col < width; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700296 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800297 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800298 bool inRegion;
299 if (!outsideRegion) {
300 inRegion = row >= region.top + border && row < region.bottom - border &&
301 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800302 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800303 inRegion = row >= region.top - border && row < region.bottom + border &&
304 col >= region.left - border && col < region.right + border;
305 }
306 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000307 ASSERT_GE(epsilon, abs(r - *(pixel)));
308 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
309 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800310 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000311 ASSERT_GE(epsilon, abs(r - *(pixel)));
312 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
313 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800314 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800315 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700316 }
317 }
chaviwd2432892020-07-24 17:42:39 -0700318 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700319 }
320
Vishnu Nair277142c2021-01-05 18:35:29 -0800321 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
322 nsecs_t presentTimeDelay) {
323 int slot;
324 sp<Fence> fence;
325 sp<GraphicBuffer> buf;
326 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
327 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
328 nullptr, nullptr);
chaviw0acd33a2021-11-02 11:55:37 -0500329 ASSERT_TRUE(ret == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION || ret == NO_ERROR);
Vishnu Nair277142c2021-01-05 18:35:29 -0800330 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
331
332 uint32_t* bufData;
333 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
334 reinterpret_cast<void**>(&bufData));
335 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
336 buf->unlock();
337
338 IGraphicBufferProducer::QueueBufferOutput qbOutput;
339 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
340 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
341 Rect(mDisplayWidth, mDisplayHeight / 2),
342 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
343 Fence::NO_FENCE);
344 igbp->queueBuffer(slot, input, &qbOutput);
345 }
346
Valerie Hauc5011f92019-10-11 09:52:07 -0700347 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700348 sp<ISurfaceComposer> mComposer;
349
350 sp<IBinder> mDisplayToken;
351
Valerie Hauc5011f92019-10-11 09:52:07 -0700352 sp<SurfaceControl> mSurfaceControl;
Melody Hsub9578222023-10-02 23:09:36 +0000353 sp<SurfaceControl> mRootSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700354
355 uint32_t mDisplayWidth;
356 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700357
Melody Hsub9578222023-10-02 23:09:36 +0000358 LayerCaptureArgs mCaptureArgs;
chaviwd2432892020-07-24 17:42:39 -0700359 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());
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000367 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth), adapter.getWidth());
368 ASSERT_EQ(static_cast<int32_t>(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,
Melody Hsub9578222023-10-02 23:09:36 +0000376 PIXEL_FORMAT_RGBA_8888,
377 ISurfaceComposerClient::eFXSurfaceBufferState,
378 /*parent*/ mRootSurfaceControl->getHandle());
Valerie Hauda3446e2019-10-14 15:49:22 -0700379 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700380 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800381 sp<IGraphicBufferProducer> igbProducer;
382 setUpProducer(adapter, igbProducer);
383
384 int32_t width;
385 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000386 ASSERT_EQ(static_cast<int32_t>(mDisplayWidth) / 2, width);
Vishnu Nairea0de002020-11-17 17:42:37 -0800387 int32_t height;
388 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
Vishnu Nair2e8ae852024-03-30 00:02:30 +0000389 ASSERT_EQ(static_cast<int32_t>(mDisplayHeight) / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700390}
391
Tianhao Yao4861b102022-02-03 20:18:35 +0000392TEST_F(BLASTBufferQueueTest, SyncNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700393 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Tianhao Yao4861b102022-02-03 20:18:35 +0000394 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
395 auto callback = [](Transaction*) {};
396 adapter.syncNextTransaction(callback);
397 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
Valerie Hauc5011f92019-10-11 09:52:07 -0700398}
Valerie Hauda3446e2019-10-14 15:49:22 -0700399
Valerie Haubf29e042020-02-06 11:40:38 -0800400TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800401 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
402 sp<IGraphicBufferProducer> igbProducer;
403 setUpProducer(adapter, igbProducer);
404
405 int slot;
406 sp<Fence> fence;
407 sp<GraphicBuffer> buf;
408 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
409 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
410 nullptr, nullptr);
411 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
412 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
413
414 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
415 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800416 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
417 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800418 Rect(mDisplayWidth, mDisplayHeight),
419 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
420 Fence::NO_FENCE);
421 igbProducer->queueBuffer(slot, input, &qbOutput);
422 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
423
424 adapter.waitForCallbacks();
425 ASSERT_GE(systemTime(), desiredPresentTime);
426}
427
Valerie Hauda3446e2019-10-14 15:49:22 -0700428TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
429 uint8_t r = 255;
430 uint8_t g = 0;
431 uint8_t b = 0;
432
433 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800434 sp<IGraphicBufferProducer> igbProducer;
435 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700436
437 int slot;
438 sp<Fence> fence;
439 sp<GraphicBuffer> buf;
440 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
441 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
442 nullptr, nullptr);
443 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
444 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
445
446 uint32_t* bufData;
447 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
448 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800449 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700450 buf->unlock();
451
Valerie Haud3b90d22019-11-06 09:37:31 -0800452 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800453 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
454 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700455 Rect(mDisplayWidth, mDisplayHeight),
456 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
457 Fence::NO_FENCE);
458 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800459 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700460
Patrick Williams0eb09c62023-07-28 11:24:35 -0500461 // ensure the buffer queue transaction has been committed
462 Transaction().apply(true /* synchronous */);
Valerie Hauda3446e2019-10-14 15:49:22 -0700463
464 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000465 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(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 }
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700491 for (size_t i = 0; i < allocated.size(); i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800492 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
Patrick Williams0eb09c62023-07-28 11:24:35 -0500546 // ensure the buffer queue transaction has been committed
547 Transaction().apply(true /* synchronous */);
548
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800549 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000550 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700551
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800552 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000553 checkScreenCapture(r, g, b,
554 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800555}
556
557TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
558 uint8_t r = 255;
559 uint8_t g = 0;
560 uint8_t b = 0;
561
562 int32_t bufferSideLength =
563 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
564 int32_t finalCropSideLength = bufferSideLength / 2;
565
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800566 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
567 sp<IGraphicBufferProducer> igbProducer;
568 setUpProducer(adapter, igbProducer);
569 int slot;
570 sp<Fence> fence;
571 sp<GraphicBuffer> buf;
572 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
573 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
574 nullptr, nullptr);
575 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
576 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
577
578 uint32_t* bufData;
579 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
580 reinterpret_cast<void**>(&bufData));
581 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
582 fillBuffer(bufData,
583 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
584 buf->getHeight()),
585 buf->getStride(), r, g, b);
586 buf->unlock();
587
588 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800589 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
590 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800591 Rect(bufferSideLength, finalCropSideLength),
592 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
593 Fence::NO_FENCE);
594 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800595 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800596
Patrick Williams0eb09c62023-07-28 11:24:35 -0500597 // ensure the buffer queue transaction has been committed
598 Transaction().apply(true /* synchronous */);
599
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800600 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000601 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700602 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
603 {10, 10, (int32_t)bufferSideLength - 10,
604 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800605 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700606 checkScreenCapture(0, 0, 0,
607 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
608 /*border*/ 0, /*outsideRegion*/ true));
609}
610
611TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700612 Rect windowSize(1000, 1000);
613 Rect bufferSize(windowSize);
614 Rect bufferCrop(200, 200, 700, 700);
615
616 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
617 sp<IGraphicBufferProducer> igbProducer;
618 setUpProducer(adapter, igbProducer);
619 int slot;
620 sp<Fence> fence;
621 sp<GraphicBuffer> buf;
622 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
623 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
624 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
625 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
626 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
627
628 uint32_t* bufData;
629 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
630 reinterpret_cast<void**>(&bufData));
631 // fill buffer with grey
632 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
633
634 // fill crop area with different colors so we can verify the cropped region has been scaled
635 // correctly.
636 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
637 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
638 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
639 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
640 buf->unlock();
641
642 IGraphicBufferProducer::QueueBufferOutput qbOutput;
643 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
644 HAL_DATASPACE_UNKNOWN,
645 bufferCrop /* Rect::INVALID_RECT */,
646 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
647 Fence::NO_FENCE);
648 igbProducer->queueBuffer(slot, input, &qbOutput);
649 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
650
Patrick Williams0eb09c62023-07-28 11:24:35 -0500651 // ensure the buffer queue transaction has been committed
652 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700653
Melody Hsub9578222023-10-02 23:09:36 +0000654 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700655
656 // Verify cropped region is scaled correctly.
657 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
658 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
659 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
660 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
661 // Verify outside region is black.
662 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
663 {0, 0, (int32_t)windowSize.getWidth(),
664 (int32_t)windowSize.getHeight()},
665 /*border*/ 0, /*outsideRegion*/ true));
666}
667
668TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700669 Rect windowSize(1000, 1000);
670 Rect bufferSize(500, 500);
671 Rect bufferCrop(100, 100, 350, 350);
672
673 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
674 sp<IGraphicBufferProducer> igbProducer;
675 setUpProducer(adapter, igbProducer);
676 int slot;
677 sp<Fence> fence;
678 sp<GraphicBuffer> buf;
679 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
680 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
681 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
682 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
683 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
684
685 uint32_t* bufData;
686 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
687 reinterpret_cast<void**>(&bufData));
688 // fill buffer with grey
689 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
690
691 // fill crop area with different colors so we can verify the cropped region has been scaled
692 // correctly.
693 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
694 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
695 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
696 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
697 buf->unlock();
698
699 IGraphicBufferProducer::QueueBufferOutput qbOutput;
700 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
701 HAL_DATASPACE_UNKNOWN,
702 bufferCrop /* Rect::INVALID_RECT */,
703 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
704 Fence::NO_FENCE);
705 igbProducer->queueBuffer(slot, input, &qbOutput);
706 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
707
Patrick Williams0eb09c62023-07-28 11:24:35 -0500708 // ensure the buffer queue transaction has been committed
709 Transaction().apply(true /* synchronous */);
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700710
Melody Hsub9578222023-10-02 23:09:36 +0000711 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700712 // Verify cropped region is scaled correctly.
713 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
714 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
715 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
716 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
717 // Verify outside region is black.
718 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
719 {0, 0, (int32_t)windowSize.getWidth(),
720 (int32_t)windowSize.getHeight()},
721 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800722}
723
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700724// b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
725// scale the buffer properly when the mode changes to SCALE_TO_WINDOW
726TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
727 uint8_t r = 255;
728 uint8_t g = 0;
729 uint8_t b = 0;
730
731 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
732 sp<IGraphicBufferProducer> igbProducer;
733 setUpProducer(adapter, igbProducer);
734 {
735 int slot;
736 sp<Fence> fence;
737 sp<GraphicBuffer> buf;
738 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
739 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
740 nullptr, nullptr);
741 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
742 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
743
744 uint32_t* bufData;
745 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
746 reinterpret_cast<void**>(&bufData));
747 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
748 buf->unlock();
749
750 IGraphicBufferProducer::QueueBufferOutput qbOutput;
751 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
752 HAL_DATASPACE_UNKNOWN, {},
753 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
754 Fence::NO_FENCE);
755 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500756
757 // ensure the buffer queue transaction has been committed
758 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700759 }
760 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000761 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700762
763 ASSERT_NO_FATAL_FAILURE(
764 checkScreenCapture(r, g, b,
765 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
766
767 // update the size to half the display and dequeue a buffer quarter of the display.
768 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
769
770 {
771 int slot;
772 sp<Fence> fence;
773 sp<GraphicBuffer> buf;
774 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
775 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
776 nullptr, nullptr);
777 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
778 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
779
780 uint32_t* bufData;
781 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
782 reinterpret_cast<void**>(&bufData));
783 g = 255;
784 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
785 buf->unlock();
786
787 IGraphicBufferProducer::QueueBufferOutput qbOutput;
788 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
789 HAL_DATASPACE_UNKNOWN, {},
790 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
791 0, Fence::NO_FENCE);
792 igbProducer->queueBuffer(slot, input, &qbOutput);
Patrick Williams0eb09c62023-07-28 11:24:35 -0500793 // ensure the buffer queue transaction has been committed
794 Transaction().apply(true /* synchronous */);
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700795 }
796 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000797 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair932f6ae2021-09-29 17:33:10 -0700798 // verify we still scale the buffer to the new size (half the screen height)
799 ASSERT_NO_FATAL_FAILURE(
800 checkScreenCapture(r, g, b,
801 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
802}
803
chaviwd7deef72021-10-06 11:53:40 -0500804TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
805 uint8_t r = 255;
806 uint8_t g = 0;
807 uint8_t b = 0;
808
809 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
810
811 sp<IGraphicBufferProducer> igbProducer;
812 setUpProducer(adapter, igbProducer);
813
chaviwa1c4c822021-11-10 18:11:58 -0600814 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000815 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500816 queueBuffer(igbProducer, 0, 255, 0, 0);
817
818 // queue non sync buffer, so this one should get blocked
819 // Add a present delay to allow the first screenshot to get taken.
820 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
821 queueBuffer(igbProducer, r, g, b, presentTimeDelay);
822
823 CallbackHelper transactionCallback;
chaviwa1c4c822021-11-10 18:11:58 -0600824 sync.addTransactionCompletedCallback(transactionCallback.function,
chaviwd7deef72021-10-06 11:53:40 -0500825 transactionCallback.getContext())
826 .apply();
827
828 CallbackData callbackData;
829 transactionCallback.getCallbackData(&callbackData);
830
chaviw0acd33a2021-11-02 11:55:37 -0500831 // capture screen and verify that it is green
Melody Hsub9578222023-10-02 23:09:36 +0000832 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500833 ASSERT_NO_FATAL_FAILURE(
834 checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
835
836 mProducerListener->waitOnNumberReleased(1);
Melody Hsub9578222023-10-02 23:09:36 +0000837 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500838 ASSERT_NO_FATAL_FAILURE(
839 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
840}
841
842TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
843 uint8_t r = 255;
844 uint8_t g = 0;
845 uint8_t b = 0;
846
847 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
848
849 sp<IGraphicBufferProducer> igbProducer;
850 setUpProducer(adapter, igbProducer);
851
852 Transaction mainTransaction;
853
chaviwa1c4c822021-11-10 18:11:58 -0600854 Transaction sync;
Tianhao Yao4861b102022-02-03 20:18:35 +0000855 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500856 queueBuffer(igbProducer, 0, 255, 0, 0);
857
chaviwa1c4c822021-11-10 18:11:58 -0600858 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500859
Tianhao Yao4861b102022-02-03 20:18:35 +0000860 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500861 queueBuffer(igbProducer, r, g, b, 0);
862
chaviwa1c4c822021-11-10 18:11:58 -0600863 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500864 // Expect 1 buffer to be released even before sending to SurfaceFlinger
865 mProducerListener->waitOnNumberReleased(1);
866
867 CallbackHelper transactionCallback;
868 mainTransaction
869 .addTransactionCompletedCallback(transactionCallback.function,
870 transactionCallback.getContext())
871 .apply();
872
873 CallbackData callbackData;
874 transactionCallback.getCallbackData(&callbackData);
875
876 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000877 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500878 ASSERT_NO_FATAL_FAILURE(
879 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
880}
881
882TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
883 uint8_t r = 255;
884 uint8_t g = 0;
885 uint8_t b = 0;
886
887 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
888
889 sp<IGraphicBufferProducer> igbProducer;
890 setUpProducer(adapter, igbProducer);
891
892 Transaction mainTransaction;
893
chaviwa1c4c822021-11-10 18:11:58 -0600894 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500895 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000896 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500897 queueBuffer(igbProducer, 0, 255, 0, 0);
898
chaviwa1c4c822021-11-10 18:11:58 -0600899 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500900
chaviwa1c4c822021-11-10 18:11:58 -0600901 // queue another buffer without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500902 queueBuffer(igbProducer, 0, 0, 255, 0);
903
904 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000905 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500906 queueBuffer(igbProducer, r, g, b, 0);
907 // Expect 1 buffer to be released because the non sync transaction should merge
908 // with the sync
909 mProducerListener->waitOnNumberReleased(1);
910
chaviwa1c4c822021-11-10 18:11:58 -0600911 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500912 // Expect 2 buffers to be released due to merging the two syncs.
913 mProducerListener->waitOnNumberReleased(2);
914
915 CallbackHelper transactionCallback;
916 mainTransaction
917 .addTransactionCompletedCallback(transactionCallback.function,
918 transactionCallback.getContext())
919 .apply();
920
921 CallbackData callbackData;
922 transactionCallback.getCallbackData(&callbackData);
923
924 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000925 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500926 ASSERT_NO_FATAL_FAILURE(
927 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
928}
929
930TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
931 uint8_t r = 255;
932 uint8_t g = 0;
933 uint8_t b = 0;
934
935 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
936
937 sp<IGraphicBufferProducer> igbProducer;
938 setUpProducer(adapter, igbProducer, 3);
939
940 Transaction mainTransaction;
941
chaviwa1c4c822021-11-10 18:11:58 -0600942 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -0500943 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000944 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500945 queueBuffer(igbProducer, 0, 255, 0, 0);
946
chaviwa1c4c822021-11-10 18:11:58 -0600947 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500948
chaviwa1c4c822021-11-10 18:11:58 -0600949 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -0500950 queueBuffer(igbProducer, 0, 0, 255, 0);
951 queueBuffer(igbProducer, 0, 0, 255, 0);
952 queueBuffer(igbProducer, 0, 0, 255, 0);
953
954 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +0000955 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -0500956 queueBuffer(igbProducer, r, g, b, 0);
957 // Expect 3 buffers to be released because the non sync transactions should merge
958 // with the sync
959 mProducerListener->waitOnNumberReleased(3);
960
chaviwa1c4c822021-11-10 18:11:58 -0600961 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -0500962 // Expect 4 buffers to be released due to merging the two syncs.
963 mProducerListener->waitOnNumberReleased(4);
964
965 CallbackHelper transactionCallback;
966 mainTransaction
967 .addTransactionCompletedCallback(transactionCallback.function,
968 transactionCallback.getContext())
969 .apply();
970
971 CallbackData callbackData;
972 transactionCallback.getCallbackData(&callbackData);
973
974 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +0000975 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -0500976 ASSERT_NO_FATAL_FAILURE(
977 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
978}
979
980// Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
981// continue processing is for a release callback from SurfaceFlinger.
982// This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
983// continue acquiring buffers.
984TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
985 uint8_t r = 255;
986 uint8_t g = 0;
987 uint8_t b = 0;
988
989 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
990
991 sp<IGraphicBufferProducer> igbProducer;
992 setUpProducer(adapter, igbProducer, 4);
993
994 Transaction mainTransaction;
995
996 // Send a buffer to SF
997 queueBuffer(igbProducer, 0, 255, 0, 0);
998
chaviwa1c4c822021-11-10 18:11:58 -0600999 Transaction sync;
chaviwd7deef72021-10-06 11:53:40 -05001000 // queue a sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001001 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001002 queueBuffer(igbProducer, 0, 255, 0, 0);
1003
chaviwa1c4c822021-11-10 18:11:58 -06001004 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001005
chaviwa1c4c822021-11-10 18:11:58 -06001006 // queue a few buffers without setting sync transaction
chaviwd7deef72021-10-06 11:53:40 -05001007 queueBuffer(igbProducer, 0, 0, 255, 0);
1008 queueBuffer(igbProducer, 0, 0, 255, 0);
1009 queueBuffer(igbProducer, 0, 0, 255, 0);
1010
1011 // apply the first synced buffer to ensure we have to wait on SF
1012 mainTransaction.apply();
1013
1014 // queue another sync transaction
Tianhao Yao4861b102022-02-03 20:18:35 +00001015 adapter.setSyncTransaction(sync);
chaviwd7deef72021-10-06 11:53:40 -05001016 queueBuffer(igbProducer, r, g, b, 0);
1017 // Expect 2 buffers to be released because the non sync transactions should merge
1018 // with the sync
1019 mProducerListener->waitOnNumberReleased(3);
1020
chaviwa1c4c822021-11-10 18:11:58 -06001021 mainTransaction.merge(std::move(sync));
chaviwd7deef72021-10-06 11:53:40 -05001022
1023 CallbackHelper transactionCallback;
1024 mainTransaction
1025 .addTransactionCompletedCallback(transactionCallback.function,
1026 transactionCallback.getContext())
1027 .apply();
1028
1029 CallbackData callbackData;
1030 transactionCallback.getCallbackData(&callbackData);
1031
1032 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001033 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd7deef72021-10-06 11:53:40 -05001034 ASSERT_NO_FATAL_FAILURE(
1035 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1036}
1037
Tianhao Yao4861b102022-02-03 20:18:35 +00001038TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
chaviw0acd33a2021-11-02 11:55:37 -05001039 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1040
1041 sp<IGraphicBufferProducer> igbProducer;
1042 setUpProducer(adapter, igbProducer);
1043
1044 Transaction next;
Tianhao Yao4861b102022-02-03 20:18:35 +00001045 adapter.setSyncTransaction(next, false);
chaviw0acd33a2021-11-02 11:55:37 -05001046 queueBuffer(igbProducer, 0, 255, 0, 0);
1047 queueBuffer(igbProducer, 0, 0, 255, 0);
1048 // There should only be one frame submitted since the first frame will be released.
1049 adapter.validateNumFramesSubmitted(1);
Tianhao Yao4861b102022-02-03 20:18:35 +00001050 adapter.stopContinuousSyncTransaction();
chaviw0acd33a2021-11-02 11:55:37 -05001051
1052 // queue non sync buffer, so this one should get blocked
1053 // Add a present delay to allow the first screenshot to get taken.
1054 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1055 queueBuffer(igbProducer, 255, 0, 0, presentTimeDelay);
1056
1057 CallbackHelper transactionCallback;
1058 next.addTransactionCompletedCallback(transactionCallback.function,
1059 transactionCallback.getContext())
1060 .apply();
1061
1062 CallbackData callbackData;
1063 transactionCallback.getCallbackData(&callbackData);
1064
1065 // capture screen and verify that it is blue
Melody Hsub9578222023-10-02 23:09:36 +00001066 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001067 ASSERT_NO_FATAL_FAILURE(
1068 checkScreenCapture(0, 0, 255, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1069
1070 mProducerListener->waitOnNumberReleased(2);
1071 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001072 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw0acd33a2021-11-02 11:55:37 -05001073 ASSERT_NO_FATAL_FAILURE(
1074 checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1075}
1076
chaviw3b4bdcf2022-03-17 09:27:03 -05001077TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
1078 std::mutex mutex;
1079 std::condition_variable callbackReceivedCv;
1080 bool receivedCallback = false;
1081
1082 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1083 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1084 auto callback = [&](Transaction*) {
1085 std::unique_lock<std::mutex> lock(mutex);
1086 receivedCallback = true;
1087 callbackReceivedCv.notify_one();
1088 };
1089 adapter.syncNextTransaction(callback);
1090 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1091
1092 auto callback2 = [](Transaction*) {};
Chavi Weingartenc398c012023-04-12 17:26:02 +00001093 ASSERT_FALSE(adapter.syncNextTransaction(callback2));
1094
1095 sp<IGraphicBufferProducer> igbProducer;
1096 setUpProducer(adapter, igbProducer);
1097 queueBuffer(igbProducer, 0, 255, 0, 0);
chaviw3b4bdcf2022-03-17 09:27:03 -05001098
1099 std::unique_lock<std::mutex> lock(mutex);
1100 if (!receivedCallback) {
1101 ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1102 std::cv_status::timeout)
1103 << "did not receive callback";
1104 }
1105
1106 ASSERT_TRUE(receivedCallback);
1107}
1108
Chavi Weingartenc398c012023-04-12 17:26:02 +00001109TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
1110 std::mutex mutex;
1111 std::condition_variable callbackReceivedCv;
1112 bool receivedCallback = false;
1113
1114 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1115 ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
1116 auto callback = [&](Transaction*) {
1117 std::unique_lock<std::mutex> lock(mutex);
1118 receivedCallback = true;
1119 callbackReceivedCv.notify_one();
1120 };
1121 adapter.syncNextTransaction(callback);
1122 ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
1123
1124 adapter.clearSyncTransaction();
1125
1126 sp<IGraphicBufferProducer> igbProducer;
1127 setUpProducer(adapter, igbProducer);
1128 queueBuffer(igbProducer, 0, 255, 0, 0);
1129
1130 std::unique_lock<std::mutex> lock(mutex);
1131 if (!receivedCallback) {
1132 ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
1133 std::cv_status::timeout)
1134 << "did not receive callback";
1135 }
1136
1137 ASSERT_FALSE(receivedCallback);
1138}
1139
chaviwc1cf4022022-06-03 13:32:33 -05001140TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
1141 uint8_t r = 255;
1142 uint8_t g = 0;
1143 uint8_t b = 0;
1144
1145 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1146
1147 sp<IGraphicBufferProducer> igbProducer;
1148 setUpProducer(adapter, igbProducer);
1149
1150 Transaction sync;
1151 adapter.setSyncTransaction(sync);
1152 queueBuffer(igbProducer, 0, 255, 0, 0);
1153
1154 // Merge a transaction that has a complete callback into the next frame so we can get notified
1155 // when to take a screenshot
1156 CallbackHelper transactionCallback;
1157 Transaction t;
1158 t.addTransactionCompletedCallback(transactionCallback.function,
1159 transactionCallback.getContext());
1160 adapter.mergeWithNextTransaction(&t, 2);
1161 queueBuffer(igbProducer, r, g, b, 0);
1162
1163 // Drop the buffer, but ensure the next one continues to get processed.
1164 sync.setBuffer(mSurfaceControl, nullptr);
1165
1166 CallbackData callbackData;
1167 transactionCallback.getCallbackData(&callbackData);
Melody Hsub9578222023-10-02 23:09:36 +00001168 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwc1cf4022022-06-03 13:32:33 -05001169 ASSERT_NO_FATAL_FAILURE(
1170 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Rob Carr4f797ab2022-07-07 18:29:22 +00001171 sync.apply();
chaviwc1cf4022022-06-03 13:32:33 -05001172}
1173
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001174// This test will currently fail because the old surfacecontrol will steal the last presented buffer
1175// until the old surface control is destroyed. This is not necessarily a bug but to document a
1176// limitation with the update API and to test any changes to make the api more robust. The current
1177// approach for the client is to recreate the blastbufferqueue when the surfacecontrol updates.
1178TEST_F(BLASTBufferQueueTest, DISABLED_DisconnectProducerTest) {
1179 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1180 std::vector<sp<SurfaceControl>> surfaceControls;
1181 sp<IGraphicBufferProducer> igbProducer;
1182 for (int i = 0; i < 10; i++) {
1183 sp<SurfaceControl> sc =
1184 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1185 PIXEL_FORMAT_RGBA_8888,
1186 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001187 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001188 Transaction()
1189 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1190 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1191 .show(mSurfaceControl)
1192 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1193 .apply(true);
1194 surfaceControls.push_back(sc);
1195 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1196
1197 setUpProducer(adapter, igbProducer);
1198 Transaction next;
1199 queueBuffer(igbProducer, 0, 255, 0, 0);
1200 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001201 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001202 queueBuffer(igbProducer, 255, 0, 0, 0);
1203
1204 CallbackHelper transactionCallback;
1205 next.addTransactionCompletedCallback(transactionCallback.function,
1206 transactionCallback.getContext())
1207 .apply();
1208
1209 CallbackData callbackData;
1210 transactionCallback.getCallbackData(&callbackData);
1211 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001212 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001213 ASSERT_NO_FATAL_FAILURE(
1214 checkScreenCapture(255, 0, 0,
1215 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1216 igbProducer->disconnect(NATIVE_WINDOW_API_CPU);
1217 }
1218}
1219
1220// See DISABLED_DisconnectProducerTest
1221TEST_F(BLASTBufferQueueTest, DISABLED_UpdateSurfaceControlTest) {
1222 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1223 std::vector<sp<SurfaceControl>> surfaceControls;
1224 sp<IGraphicBufferProducer> igbProducer;
1225 for (int i = 0; i < 10; i++) {
1226 sp<SurfaceControl> sc =
1227 mClient->createSurface(String8("TestSurface"), mDisplayWidth, mDisplayHeight,
1228 PIXEL_FORMAT_RGBA_8888,
1229 ISurfaceComposerClient::eFXSurfaceBufferState,
Melody Hsub9578222023-10-02 23:09:36 +00001230 /*parent*/ mRootSurfaceControl->getHandle());
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001231 Transaction()
1232 .setLayerStack(mSurfaceControl, ui::DEFAULT_LAYER_STACK)
1233 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
1234 .show(mSurfaceControl)
1235 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
1236 .apply(true);
1237 surfaceControls.push_back(sc);
1238 adapter.update(sc, mDisplayWidth, mDisplayHeight);
1239 setUpProducer(adapter, igbProducer);
1240
1241 Transaction next;
1242 queueBuffer(igbProducer, 0, 255, 0, 0);
1243 queueBuffer(igbProducer, 0, 0, 255, 0);
Tianhao Yao4861b102022-02-03 20:18:35 +00001244 adapter.setSyncTransaction(next, true);
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001245 queueBuffer(igbProducer, 255, 0, 0, 0);
1246
1247 CallbackHelper transactionCallback;
1248 next.addTransactionCompletedCallback(transactionCallback.function,
1249 transactionCallback.getContext())
1250 .apply();
1251
1252 CallbackData callbackData;
1253 transactionCallback.getCallbackData(&callbackData);
1254 // capture screen and verify that it is red
Melody Hsub9578222023-10-02 23:09:36 +00001255 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Vishnu Nair1e8bf102021-12-28 14:36:59 -08001256 ASSERT_NO_FATAL_FAILURE(
1257 checkScreenCapture(255, 0, 0,
1258 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1259 }
1260}
1261
Vishnu Nair89496122020-12-14 17:14:53 -08001262class TestProducerListener : public BnProducerListener {
1263public:
1264 sp<IGraphicBufferProducer> mIgbp;
1265 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1266 void onBufferReleased() override {
1267 sp<GraphicBuffer> buffer;
1268 sp<Fence> fence;
1269 mIgbp->detachNextBuffer(&buffer, &fence);
1270 }
1271};
1272
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001273class TestSurfaceListener : public SurfaceListener {
1274public:
1275 sp<IGraphicBufferProducer> mIgbp;
1276 TestSurfaceListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
1277 void onBufferReleased() override {
1278 sp<GraphicBuffer> buffer;
1279 sp<Fence> fence;
1280 mIgbp->detachNextBuffer(&buffer, &fence);
1281 }
1282 bool needsReleaseNotify() override { return true; }
1283 void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
1284 void onBufferDetached(int /*slot*/) {}
1285};
1286
Vishnu Nair89496122020-12-14 17:14:53 -08001287TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1288 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1289 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1290 ASSERT_NE(nullptr, igbProducer.get());
1291 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1292 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1293 ASSERT_EQ(NO_ERROR,
1294 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1295 false, &qbOutput));
1296 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1297 for (int i = 0; i < 3; i++) {
1298 int slot;
1299 sp<Fence> fence;
1300 sp<GraphicBuffer> buf;
1301 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1302 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1303 nullptr, nullptr);
1304 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1305 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1306 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001307 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1308 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -08001309 Rect(mDisplayWidth, mDisplayHeight),
1310 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1311 Fence::NO_FENCE);
1312 igbProducer->queueBuffer(slot, input, &qbOutput);
1313 }
1314 adapter.waitForCallbacks();
1315}
1316
Vishnu Nair17dde612020-12-28 11:39:59 -08001317TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1318 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1319
1320 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1321 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1322 int queuesToNativeWindow = 0;
1323 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1324 &queuesToNativeWindow);
1325 ASSERT_EQ(NO_ERROR, err);
1326 ASSERT_EQ(queuesToNativeWindow, 1);
1327}
1328
Vishnu Naira4fbca52021-07-07 16:52:34 -07001329TEST_F(BLASTBufferQueueTest, TransformHint) {
1330 // Transform hint is provided to BBQ via the surface control passed by WM
1331 mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1332
1333 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1334 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1335 ASSERT_NE(nullptr, igbProducer.get());
1336 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1337 sp<Surface> surface = adapter.getSurface();
1338
1339 // Before connecting to the surface, we do not get a valid transform hint
1340 int transformHint;
1341 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001342 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001343
1344 ASSERT_EQ(NO_ERROR,
Carlos Martinez Romeroab8443c2024-07-03 13:50:10 -07001345 surface->connect(NATIVE_WINDOW_API_CPU, new TestSurfaceListener(igbProducer)));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001346
1347 // After connecting to the surface, we should get the correct hint.
1348 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001349 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001350
1351 ANativeWindow_Buffer buffer;
1352 surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1353
1354 // Transform hint is updated via callbacks or surface control updates
1355 mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1356 adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1357
1358 // The hint does not change and matches the value used when dequeueing the buffer.
1359 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001360 ASSERT_EQ(ui::Transform::ROT_90, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001361
1362 surface->unlockAndPost();
1363
1364 // After queuing the buffer, we get the updated transform hint
1365 surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001366 ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
Vishnu Naira4fbca52021-07-07 16:52:34 -07001367
1368 adapter.waitForCallbacks();
1369}
1370
Valerie Hau5977fc82019-12-05 15:56:39 -08001371class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1372public:
1373 void test(uint32_t tr) {
1374 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1375 sp<IGraphicBufferProducer> igbProducer;
1376 setUpProducer(adapter, igbProducer);
1377
1378 auto bufWidth = mDisplayWidth;
1379 auto bufHeight = mDisplayHeight;
1380 int slot;
1381 sp<Fence> fence;
1382 sp<GraphicBuffer> buf;
1383
1384 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1385 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1386 nullptr, nullptr);
1387 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1388 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1389
1390 fillQuadrants(buf);
1391
1392 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -08001393 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1394 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -08001395 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -07001396 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1397 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -08001398 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -08001399 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -08001400
Patrick Williams0eb09c62023-07-28 11:24:35 -05001401 Transaction().apply(true /* synchronous */);
Melody Hsub9578222023-10-02 23:09:36 +00001402 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -07001403
Valerie Hau5977fc82019-12-05 15:56:39 -08001404 switch (tr) {
1405 case ui::Transform::ROT_0:
1406 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1407 {0, 0, (int32_t)mDisplayWidth / 2,
1408 (int32_t)mDisplayHeight / 2},
1409 1));
1410 ASSERT_NO_FATAL_FAILURE(
1411 checkScreenCapture(255, 0, 0,
1412 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1413 (int32_t)mDisplayHeight / 2},
1414 1));
1415 ASSERT_NO_FATAL_FAILURE(
1416 checkScreenCapture(0, 255, 0,
1417 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1418 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1419 1));
1420 ASSERT_NO_FATAL_FAILURE(
1421 checkScreenCapture(0, 0, 255,
1422 {0, (int32_t)mDisplayHeight / 2,
1423 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1424 1));
1425 break;
1426 case ui::Transform::FLIP_H:
1427 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1428 {0, 0, (int32_t)mDisplayWidth / 2,
1429 (int32_t)mDisplayHeight / 2},
1430 1));
1431 ASSERT_NO_FATAL_FAILURE(
1432 checkScreenCapture(0, 0, 0,
1433 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1434 (int32_t)mDisplayHeight / 2},
1435 1));
1436 ASSERT_NO_FATAL_FAILURE(
1437 checkScreenCapture(0, 0, 255,
1438 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1439 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1440 1));
1441 ASSERT_NO_FATAL_FAILURE(
1442 checkScreenCapture(0, 255, 0,
1443 {0, (int32_t)mDisplayHeight / 2,
1444 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1445 1));
1446 break;
1447 case ui::Transform::FLIP_V:
1448 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1449 {0, 0, (int32_t)mDisplayWidth / 2,
1450 (int32_t)mDisplayHeight / 2},
1451 1));
1452 ASSERT_NO_FATAL_FAILURE(
1453 checkScreenCapture(0, 255, 0,
1454 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1455 (int32_t)mDisplayHeight / 2},
1456 1));
1457 ASSERT_NO_FATAL_FAILURE(
1458 checkScreenCapture(255, 0, 0,
1459 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1460 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1461 1));
1462 ASSERT_NO_FATAL_FAILURE(
1463 checkScreenCapture(0, 0, 0,
1464 {0, (int32_t)mDisplayHeight / 2,
1465 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1466 1));
1467 break;
1468 case ui::Transform::ROT_90:
1469 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1470 {0, 0, (int32_t)mDisplayWidth / 2,
1471 (int32_t)mDisplayHeight / 2},
1472 1));
1473 ASSERT_NO_FATAL_FAILURE(
1474 checkScreenCapture(0, 0, 0,
1475 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1476 (int32_t)mDisplayHeight / 2},
1477 1));
1478 ASSERT_NO_FATAL_FAILURE(
1479 checkScreenCapture(255, 0, 0,
1480 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1481 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1482 1));
1483 ASSERT_NO_FATAL_FAILURE(
1484 checkScreenCapture(0, 255, 0,
1485 {0, (int32_t)mDisplayHeight / 2,
1486 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1487 1));
1488 break;
1489 case ui::Transform::ROT_180:
1490 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1491 {0, 0, (int32_t)mDisplayWidth / 2,
1492 (int32_t)mDisplayHeight / 2},
1493 1));
1494 ASSERT_NO_FATAL_FAILURE(
1495 checkScreenCapture(0, 0, 255,
1496 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1497 (int32_t)mDisplayHeight / 2},
1498 1));
1499 ASSERT_NO_FATAL_FAILURE(
1500 checkScreenCapture(0, 0, 0,
1501 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1502 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1503 1));
1504 ASSERT_NO_FATAL_FAILURE(
1505 checkScreenCapture(255, 0, 0,
1506 {0, (int32_t)mDisplayHeight / 2,
1507 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1508 1));
1509 break;
1510 case ui::Transform::ROT_270:
1511 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1512 {0, 0, (int32_t)mDisplayWidth / 2,
1513 (int32_t)mDisplayHeight / 2},
1514 1));
1515 ASSERT_NO_FATAL_FAILURE(
1516 checkScreenCapture(0, 255, 0,
1517 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1518 (int32_t)mDisplayHeight / 2},
1519 1));
1520 ASSERT_NO_FATAL_FAILURE(
1521 checkScreenCapture(0, 0, 255,
1522 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1523 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1524 1));
1525 ASSERT_NO_FATAL_FAILURE(
1526 checkScreenCapture(0, 0, 0,
1527 {0, (int32_t)mDisplayHeight / 2,
1528 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1529 1));
1530 }
1531 }
1532};
1533
1534TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1535 test(ui::Transform::ROT_0);
1536}
1537
1538TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1539 test(ui::Transform::FLIP_H);
1540}
1541
1542TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1543 test(ui::Transform::FLIP_V);
1544}
1545
1546TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1547 test(ui::Transform::ROT_90);
1548}
1549
1550TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1551 test(ui::Transform::ROT_180);
1552}
1553
1554TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1555 test(ui::Transform::ROT_270);
1556}
Valerie Hau871d6352020-01-29 08:44:02 -08001557
1558class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1559public:
1560 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001561 nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
Valerie Hau871d6352020-01-29 08:44:02 -08001562 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001563 bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
Valerie Hau871d6352020-01-29 08:44:02 -08001564 int slot;
1565 sp<Fence> fence;
1566 sp<GraphicBuffer> buf;
1567 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1568 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1569 nullptr, nullptr);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001570 if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1571 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1572 }
Valerie Hau871d6352020-01-29 08:44:02 -08001573
Vishnu Nairde66dc72021-06-17 17:54:41 -07001574 *outRequestedPresentTime = requestedPresentTime;
1575 IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1576 HAL_DATASPACE_UNKNOWN,
Valerie Hau871d6352020-01-29 08:44:02 -08001577 Rect(mDisplayWidth, mDisplayHeight),
1578 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1579 Fence::NO_FENCE, /*sticky*/ 0,
1580 getFrameTimestamps);
1581 if (postedTime) *postedTime = systemTime();
1582 igbProducer->queueBuffer(slot, input, qbOutput);
1583 }
Vishnu Nair083efd32021-02-12 09:32:30 -08001584 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -08001585};
1586
1587TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1588 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1589 sp<IGraphicBufferProducer> igbProducer;
1590 ProducerFrameEventHistory history;
1591 setUpProducer(adapter, igbProducer);
1592
1593 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1594 nsecs_t requestedPresentTimeA = 0;
1595 nsecs_t postedTimeA = 0;
1596 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1597 history.applyDelta(qbOutput.frameTimestamps);
1598
1599 FrameEvents* events = nullptr;
1600 events = history.getFrame(1);
1601 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001602 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001603 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1604 ASSERT_GE(events->postedTime, postedTimeA);
1605
Vishnu Nair1506b182021-02-22 14:35:15 -08001606 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -08001607
1608 // queue another buffer so we query for frame event deltas
1609 nsecs_t requestedPresentTimeB = 0;
1610 nsecs_t postedTimeB = 0;
1611 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1612 history.applyDelta(qbOutput.frameTimestamps);
Alec Mouri21d94322023-10-17 19:51:39 +00001613
1614 adapter.waitForCallback(2);
1615
Valerie Hau871d6352020-01-29 08:44:02 -08001616 events = history.getFrame(1);
1617 ASSERT_NE(nullptr, events);
1618
1619 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001620 ASSERT_EQ(1u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001621 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1622 ASSERT_GE(events->postedTime, postedTimeA);
1623
1624 ASSERT_GE(events->latchTime, postedTimeA);
Alec Mouri21d94322023-10-17 19:51:39 +00001625 if (flags::frametimestamps_previousrelease()) {
1626 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1627 }
Valerie Hau871d6352020-01-29 08:44:02 -08001628 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1629 ASSERT_NE(nullptr, events->displayPresentFence);
1630 ASSERT_NE(nullptr, events->releaseFence);
1631
1632 // we should also have gotten the initial values for the next frame
1633 events = history.getFrame(2);
1634 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001635 ASSERT_EQ(2u, events->frameNumber);
Valerie Hau871d6352020-01-29 08:44:02 -08001636 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1637 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001638
Alec Mouri21d94322023-10-17 19:51:39 +00001639 // Now do the same as above with a third buffer, so that timings related to
1640 // buffer releases make it back to the first frame.
1641 nsecs_t requestedPresentTimeC = 0;
1642 nsecs_t postedTimeC = 0;
1643 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1644 history.applyDelta(qbOutput.frameTimestamps);
1645
1646 adapter.waitForCallback(3);
1647
1648 // Check the first frame...
1649 events = history.getFrame(1);
1650 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001651 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001652 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1653 ASSERT_GE(events->postedTime, postedTimeA);
1654 ASSERT_GE(events->latchTime, postedTimeA);
1655 // Now dequeueReadyTime is valid, because the release timings finally
1656 // propaged to queueBuffer()
1657 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1658 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1659 ASSERT_NE(nullptr, events->displayPresentFence);
1660 ASSERT_NE(nullptr, events->releaseFence);
1661
1662 // ...and the second
1663 events = history.getFrame(2);
1664 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001665 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001666 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1667 ASSERT_GE(events->postedTime, postedTimeB);
1668 ASSERT_GE(events->latchTime, postedTimeB);
1669 if (flags::frametimestamps_previousrelease()) {
1670 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1671 }
1672 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1673 ASSERT_NE(nullptr, events->displayPresentFence);
1674 ASSERT_NE(nullptr, events->releaseFence);
1675
1676 // ...and finally the third!
1677 events = history.getFrame(3);
1678 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001679 ASSERT_EQ(3u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001680 ASSERT_EQ(requestedPresentTimeC, events->requestedPresentTime);
1681 ASSERT_GE(events->postedTime, postedTimeC);
1682
Valerie Hau78491e92020-04-15 13:10:56 -07001683 // wait for any callbacks that have not been received
1684 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001685}
Vishnu Nair083efd32021-02-12 09:32:30 -08001686
Vishnu Nair083efd32021-02-12 09:32:30 -08001687TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1688 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1689 sp<IGraphicBufferProducer> igbProducer;
1690 setUpProducer(adapter, igbProducer);
1691
1692 ProducerFrameEventHistory history;
1693 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1694 nsecs_t requestedPresentTimeA = 0;
1695 nsecs_t postedTimeA = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001696 // Present the frame sometime in the future so we can add two frames to the queue so the older
1697 // one will be dropped.
1698 nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
Vishnu Nair083efd32021-02-12 09:32:30 -08001699 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
Vishnu Nairde66dc72021-06-17 17:54:41 -07001700 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001701 history.applyDelta(qbOutput.frameTimestamps);
1702
1703 FrameEvents* events = nullptr;
1704 events = history.getFrame(1);
1705 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001706 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001707 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1708 ASSERT_GE(events->postedTime, postedTimeA);
1709
1710 // queue another buffer so the first can be dropped
1711 nsecs_t requestedPresentTimeB = 0;
1712 nsecs_t postedTimeB = 0;
Vishnu Nairde66dc72021-06-17 17:54:41 -07001713 presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1714 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1715 presentTime);
Vishnu Nair083efd32021-02-12 09:32:30 -08001716 history.applyDelta(qbOutput.frameTimestamps);
1717 events = history.getFrame(1);
1718 ASSERT_NE(nullptr, events);
1719
1720 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001721 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001722 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1723 ASSERT_GE(events->postedTime, postedTimeA);
1724
Vishnu Nairde66dc72021-06-17 17:54:41 -07001725 // a valid latchtime and pre and post composition info should not be set for the dropped frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001726 ASSERT_FALSE(events->hasLatchInfo());
1727 ASSERT_FALSE(events->hasDequeueReadyInfo());
Vishnu Nairde66dc72021-06-17 17:54:41 -07001728 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1729 ASSERT_FALSE(events->hasDisplayPresentInfo());
1730 ASSERT_FALSE(events->hasReleaseInfo());
Vishnu Nair083efd32021-02-12 09:32:30 -08001731
Vishnu Nairde66dc72021-06-17 17:54:41 -07001732 // wait for the last transaction to be completed.
1733 adapter.waitForCallback(2);
Vishnu Nair083efd32021-02-12 09:32:30 -08001734
Vishnu Nairde66dc72021-06-17 17:54:41 -07001735 // queue another buffer so we query for frame event deltas
1736 nsecs_t requestedPresentTimeC = 0;
1737 nsecs_t postedTimeC = 0;
1738 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1739 history.applyDelta(qbOutput.frameTimestamps);
1740
Alec Mouri21d94322023-10-17 19:51:39 +00001741 adapter.waitForCallback(3);
1742
Vishnu Nairde66dc72021-06-17 17:54:41 -07001743 // frame number, requestedPresentTime, and postTime should not have changed
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001744 ASSERT_EQ(1u, events->frameNumber);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001745 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1746 ASSERT_GE(events->postedTime, postedTimeA);
1747
1748 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1749 ASSERT_FALSE(events->hasLatchInfo());
1750 ASSERT_FALSE(events->hasDequeueReadyInfo());
1751 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1752 ASSERT_FALSE(events->hasDisplayPresentInfo());
1753 ASSERT_FALSE(events->hasReleaseInfo());
1754
1755 // we should also have gotten values for the presented frame
Vishnu Nair083efd32021-02-12 09:32:30 -08001756 events = history.getFrame(2);
1757 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001758 ASSERT_EQ(2u, events->frameNumber);
Vishnu Nair083efd32021-02-12 09:32:30 -08001759 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1760 ASSERT_GE(events->postedTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001761 ASSERT_GE(events->latchTime, postedTimeB);
Alec Mouri21d94322023-10-17 19:51:39 +00001762
1763 if (flags::frametimestamps_previousrelease()) {
1764 ASSERT_EQ(events->dequeueReadyTime, FrameEvents::TIMESTAMP_PENDING);
1765 }
1766 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1767 ASSERT_NE(nullptr, events->displayPresentFence);
1768 ASSERT_NE(nullptr, events->releaseFence);
1769
1770 // Queue another buffer to check for timestamps that came late
1771 nsecs_t requestedPresentTimeD = 0;
1772 nsecs_t postedTimeD = 0;
1773 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeD, &postedTimeD, &qbOutput, true);
1774 history.applyDelta(qbOutput.frameTimestamps);
1775
1776 adapter.waitForCallback(4);
1777
1778 // frame number, requestedPresentTime, and postTime should not have changed
1779 events = history.getFrame(1);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001780 ASSERT_EQ(1u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001781 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1782 ASSERT_GE(events->postedTime, postedTimeA);
1783
1784 // a valid latchtime and pre and post composition info should not be set for the dropped frame
1785 ASSERT_FALSE(events->hasLatchInfo());
1786 ASSERT_FALSE(events->hasDequeueReadyInfo());
1787 ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1788 ASSERT_FALSE(events->hasDisplayPresentInfo());
1789 ASSERT_FALSE(events->hasReleaseInfo());
1790
1791 // we should also have gotten values for the presented frame
1792 events = history.getFrame(2);
1793 ASSERT_NE(nullptr, events);
Vishnu Nair2e8ae852024-03-30 00:02:30 +00001794 ASSERT_EQ(2u, events->frameNumber);
Alec Mouri21d94322023-10-17 19:51:39 +00001795 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1796 ASSERT_GE(events->postedTime, postedTimeB);
1797 ASSERT_GE(events->latchTime, postedTimeB);
Vishnu Nairde66dc72021-06-17 17:54:41 -07001798 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1799 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1800 ASSERT_NE(nullptr, events->displayPresentFence);
1801 ASSERT_NE(nullptr, events->releaseFence);
1802
1803 // wait for any callbacks that have not been received
1804 adapter.waitForCallbacks();
Vishnu Nair083efd32021-02-12 09:32:30 -08001805}
1806
Vishnu Nair9a69a042021-06-18 13:19:49 -07001807TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1808 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1809 sp<IGraphicBufferProducer> igbProducer;
1810 ProducerFrameEventHistory history;
1811 setUpProducer(adapter, igbProducer);
1812
1813 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1814 nsecs_t requestedPresentTimeA = 0;
1815 nsecs_t postedTimeA = 0;
Vishnu Nair9a69a042021-06-18 13:19:49 -07001816 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1817 history.applyDelta(qbOutput.frameTimestamps);
1818 adapter.waitForCallback(1);
1819
1820 // queue another buffer so we query for frame event deltas
1821 nsecs_t requestedPresentTimeB = 0;
1822 nsecs_t postedTimeB = 0;
1823 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1824 history.applyDelta(qbOutput.frameTimestamps);
1825
1826 // check for a valid compositor deadline
1827 ASSERT_NE(0, history.getReportedCompositeDeadline());
1828
1829 // wait for any callbacks that have not been received
1830 adapter.waitForCallbacks();
1831}
1832
Valerie Hauc5011f92019-10-11 09:52:07 -07001833} // namespace android