blob: 5a5da97599297830dfee69da1089174efd32c0ee [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>
Valerie Haud3b90d22019-11-06 09:37:31 -080022#include <gui/BufferQueueCore.h>
23#include <gui/BufferQueueProducer.h>
Valerie Hau871d6352020-01-29 08:44:02 -080024#include <gui/FrameTimestamps.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070025#include <gui/IGraphicBufferProducer.h>
26#include <gui/IProducerListener.h>
Vishnu Nair17dde612020-12-28 11:39:59 -080027#include <gui/Surface.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070028#include <gui/SurfaceComposerClient.h>
chaviwe7b9f272020-08-18 16:08:59 -070029#include <gui/SyncScreenCaptureListener.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070030#include <private/gui/ComposerService.h>
Marin Shalamanova7fe3042021-01-29 21:02:08 +010031#include <ui/DisplayMode.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070032#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070033#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080034#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070035
36#include <gtest/gtest.h>
37
38using namespace std::chrono_literals;
39
40namespace android {
41
Valerie Hauc5011f92019-10-11 09:52:07 -070042using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070043using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070044
45class BLASTBufferQueueHelper {
46public:
47 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -080048 mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height,
49 PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -070050 }
51
52 void update(const sp<SurfaceControl>& sc, int width, int height) {
chaviw565ee542021-01-14 10:21:23 -080053 mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
Valerie Hauc5011f92019-10-11 09:52:07 -070054 }
55
56 void setNextTransaction(Transaction* next) {
57 mBlastBufferQueueAdapter->setNextTransaction(next);
58 }
59
Vishnu Nairea0de002020-11-17 17:42:37 -080060 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -070061
Vishnu Nairea0de002020-11-17 17:42:37 -080062 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -070063
Valerie Hauc5011f92019-10-11 09:52:07 -070064 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -070065
66 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
67 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
68 }
69
Valerie Hauc5011f92019-10-11 09:52:07 -070070 const sp<SurfaceControl> getSurfaceControl() {
71 return mBlastBufferQueueAdapter->mSurfaceControl;
72 }
73
Valerie Haud3b90d22019-11-06 09:37:31 -080074 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -070075 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Vishnu Nair1506b182021-02-22 14:35:15 -080076 // Wait until all but one of the submitted buffers have been released.
77 while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
Valerie Haud3b90d22019-11-06 09:37:31 -080078 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
79 }
Valerie Hauda3446e2019-10-14 15:49:22 -070080 }
81
Vishnu Nair1506b182021-02-22 14:35:15 -080082 void setTransactionCompleteCallback(int64_t frameNumber) {
83 mBlastBufferQueueAdapter->setTransactionCompleteCallback(frameNumber, [&](int64_t frame) {
84 std::unique_lock lock{mMutex};
85 mLastTransactionCompleteFrameNumber = frame;
86 mCallbackCV.notify_all();
87 });
88 }
89
90 void waitForCallback(int64_t frameNumber) {
91 std::unique_lock lock{mMutex};
92 // Wait until all but one of the submitted buffers have been released.
93 while (mLastTransactionCompleteFrameNumber < frameNumber) {
94 mCallbackCV.wait(lock);
95 }
96 }
97
Valerie Hauc5011f92019-10-11 09:52:07 -070098private:
99 sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
Vishnu Nair1506b182021-02-22 14:35:15 -0800100
101 std::mutex mMutex;
102 std::condition_variable mCallbackCV;
103 int64_t mLastTransactionCompleteFrameNumber = -1;
Valerie Hauc5011f92019-10-11 09:52:07 -0700104};
105
106class BLASTBufferQueueTest : public ::testing::Test {
107public:
108protected:
109 BLASTBufferQueueTest() {
110 const ::testing::TestInfo* const testInfo =
111 ::testing::UnitTest::GetInstance()->current_test_info();
112 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
113 }
114
115 ~BLASTBufferQueueTest() {
116 const ::testing::TestInfo* const testInfo =
117 ::testing::UnitTest::GetInstance()->current_test_info();
118 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
119 }
120
121 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700122 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700123 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700124 mDisplayToken = mClient->getInternalDisplayToken();
125 ASSERT_NE(nullptr, mDisplayToken.get());
126 Transaction t;
127 t.setDisplayLayerStack(mDisplayToken, 0);
128 t.apply();
129 t.clear();
130
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100131 ui::DisplayMode mode;
132 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
133 const ui::Size& resolution = mode.resolution;
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800134 mDisplayWidth = resolution.getWidth();
135 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700136
137 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
138 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
139 ISurfaceComposerClient::eFXSurfaceBufferState,
140 /*parent*/ nullptr);
141 t.setLayerStack(mSurfaceControl, 0)
142 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Valerie Hauda3446e2019-10-14 15:49:22 -0700143 .show(mSurfaceControl)
144 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
145 .apply();
chaviwd2432892020-07-24 17:42:39 -0700146
147 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800148 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700149 }
150
Vishnu Nair1506b182021-02-22 14:35:15 -0800151 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800152 producer = adapter.getIGraphicBufferProducer();
153 setUpProducer(producer);
154 }
155
156 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800157 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800158 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800159 IGraphicBufferProducer::QueueBufferOutput qbOutput;
160 ASSERT_EQ(NO_ERROR,
Peiyong Lind8460c82020-07-28 16:04:22 -0700161 igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
Valerie Haud3b90d22019-11-06 09:37:31 -0800162 &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800163 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800164 }
165
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800166 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
167 uint8_t b) {
168 for (uint32_t row = rect.top; row < rect.bottom; row++) {
169 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700170 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
171 *pixel = r;
172 *(pixel + 1) = g;
173 *(pixel + 2) = b;
174 *(pixel + 3) = 255;
175 }
176 }
177 }
178
Valerie Hau5977fc82019-12-05 15:56:39 -0800179 void fillQuadrants(sp<GraphicBuffer>& buf) {
180 const auto bufWidth = buf->getWidth();
181 const auto bufHeight = buf->getHeight();
182 uint32_t* bufData;
183 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
184 reinterpret_cast<void**>(&bufData));
185 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
186 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
187 0, 0);
188 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
189 buf->getStride(), 0, 255, 0);
190 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
191 255);
192 buf->unlock();
193 }
194
195 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
196 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700197 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800198 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700199 const auto width = captureBuf->getWidth();
200 const auto height = captureBuf->getHeight();
201 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700202
203 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700204 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
205 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700206
207 for (uint32_t row = 0; row < height; row++) {
208 for (uint32_t col = 0; col < width; col++) {
209 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800210 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800211 bool inRegion;
212 if (!outsideRegion) {
213 inRegion = row >= region.top + border && row < region.bottom - border &&
214 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800215 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800216 inRegion = row >= region.top - border && row < region.bottom + border &&
217 col >= region.left - border && col < region.right + border;
218 }
219 if (!outsideRegion && inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000220 ASSERT_GE(epsilon, abs(r - *(pixel)));
221 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
222 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau5977fc82019-12-05 15:56:39 -0800223 } else if (outsideRegion && !inRegion) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000224 ASSERT_GE(epsilon, abs(r - *(pixel)));
225 ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
226 ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800227 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800228 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700229 }
230 }
chaviwd2432892020-07-24 17:42:39 -0700231 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700232 }
233
chaviw8ffc7b82020-08-18 11:25:37 -0700234 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
235 ScreenCaptureResults& captureResults) {
236 const auto sf = ComposerService::getComposerService();
237 SurfaceComposerClient::Transaction().apply(true);
238
239 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
240 status_t status = sf->captureDisplay(captureArgs, captureListener);
241 if (status != NO_ERROR) {
242 return status;
243 }
244 captureResults = captureListener->waitForResults();
245 return captureResults.result;
246 }
247
Vishnu Nair277142c2021-01-05 18:35:29 -0800248 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
249 nsecs_t presentTimeDelay) {
250 int slot;
251 sp<Fence> fence;
252 sp<GraphicBuffer> buf;
253 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
254 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
255 nullptr, nullptr);
256 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
257 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
258
259 uint32_t* bufData;
260 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
261 reinterpret_cast<void**>(&bufData));
262 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
263 buf->unlock();
264
265 IGraphicBufferProducer::QueueBufferOutput qbOutput;
266 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
267 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
268 Rect(mDisplayWidth, mDisplayHeight / 2),
269 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
270 Fence::NO_FENCE);
271 igbp->queueBuffer(slot, input, &qbOutput);
272 }
273
Valerie Hauc5011f92019-10-11 09:52:07 -0700274 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700275 sp<ISurfaceComposer> mComposer;
276
277 sp<IBinder> mDisplayToken;
278
Valerie Hauc5011f92019-10-11 09:52:07 -0700279 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700280
281 uint32_t mDisplayWidth;
282 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700283
284 DisplayCaptureArgs mCaptureArgs;
285 ScreenCaptureResults mCaptureResults;
Valerie Hauc5011f92019-10-11 09:52:07 -0700286};
287
288TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
289 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700290 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700291 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700292 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
293 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700294 ASSERT_EQ(nullptr, adapter.getNextTransaction());
295}
296
297TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700298 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700299 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700300 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
301 PIXEL_FORMAT_RGBA_8888);
302 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700303 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800304 sp<IGraphicBufferProducer> igbProducer;
305 setUpProducer(adapter, igbProducer);
306
307 int32_t width;
308 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
309 ASSERT_EQ(mDisplayWidth / 2, width);
310 int32_t height;
311 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
312 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700313}
314
315TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700316 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700317 Transaction next;
318 adapter.setNextTransaction(&next);
319 ASSERT_EQ(&next, adapter.getNextTransaction());
320}
Valerie Hauda3446e2019-10-14 15:49:22 -0700321
Valerie Haubf29e042020-02-06 11:40:38 -0800322TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800323 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
324 sp<IGraphicBufferProducer> igbProducer;
325 setUpProducer(adapter, igbProducer);
326
327 int slot;
328 sp<Fence> fence;
329 sp<GraphicBuffer> buf;
330 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
331 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
332 nullptr, nullptr);
333 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
334 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
335
336 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
337 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800338 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
339 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800340 Rect(mDisplayWidth, mDisplayHeight),
341 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
342 Fence::NO_FENCE);
343 igbProducer->queueBuffer(slot, input, &qbOutput);
344 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
345
346 adapter.waitForCallbacks();
347 ASSERT_GE(systemTime(), desiredPresentTime);
348}
349
Valerie Hauda3446e2019-10-14 15:49:22 -0700350TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
351 uint8_t r = 255;
352 uint8_t g = 0;
353 uint8_t b = 0;
354
355 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800356 sp<IGraphicBufferProducer> igbProducer;
357 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700358
359 int slot;
360 sp<Fence> fence;
361 sp<GraphicBuffer> buf;
362 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
363 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
364 nullptr, nullptr);
365 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
366 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
367
368 uint32_t* bufData;
369 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
370 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800371 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700372 buf->unlock();
373
Valerie Haud3b90d22019-11-06 09:37:31 -0800374 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800375 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
376 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700377 Rect(mDisplayWidth, mDisplayHeight),
378 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
379 Fence::NO_FENCE);
380 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800381 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700382
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800383 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700384
385 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700386 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800387 ASSERT_NO_FATAL_FAILURE(
388 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700389}
Valerie Haud3b90d22019-11-06 09:37:31 -0800390
391TEST_F(BLASTBufferQueueTest, TripleBuffering) {
392 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
393 sp<IGraphicBufferProducer> igbProducer;
394 setUpProducer(adapter, igbProducer);
395
396 std::vector<std::pair<int, sp<Fence>>> allocated;
397 for (int i = 0; i < 3; i++) {
398 int slot;
399 sp<Fence> fence;
400 sp<GraphicBuffer> buf;
401 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
402 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
403 nullptr, nullptr);
404 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
405 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
406 allocated.push_back({slot, fence});
407 }
408 for (int i = 0; i < allocated.size(); i++) {
409 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
410 }
411
Valerie Haua32c5522019-12-09 10:11:08 -0800412 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800413 int slot;
414 sp<Fence> fence;
415 sp<GraphicBuffer> buf;
416 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
417 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
418 nullptr, nullptr);
419 ASSERT_EQ(NO_ERROR, ret);
420 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800421 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
422 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800423 Rect(mDisplayWidth, mDisplayHeight),
424 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
425 Fence::NO_FENCE);
426 igbProducer->queueBuffer(slot, input, &qbOutput);
427 }
428 adapter.waitForCallbacks();
429}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800430
431TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
432 uint8_t r = 255;
433 uint8_t g = 0;
434 uint8_t b = 0;
435
436 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
437 sp<IGraphicBufferProducer> igbProducer;
438 setUpProducer(adapter, igbProducer);
439 int slot;
440 sp<Fence> fence;
441 sp<GraphicBuffer> buf;
442 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
443 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
444 nullptr, nullptr);
445 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
446 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
447
448 uint32_t* bufData;
449 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
450 reinterpret_cast<void**>(&bufData));
451 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
452 buf->unlock();
453
454 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800455 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
456 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800457 Rect(mDisplayWidth, mDisplayHeight / 2),
458 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
459 Fence::NO_FENCE);
460 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800461 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800462
463 adapter.waitForCallbacks();
464 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700465 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700466
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800467 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000468 checkScreenCapture(r, g, b,
469 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800470}
471
472TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
473 uint8_t r = 255;
474 uint8_t g = 0;
475 uint8_t b = 0;
476
477 int32_t bufferSideLength =
478 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
479 int32_t finalCropSideLength = bufferSideLength / 2;
480
481 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800482 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800483 ASSERT_NE(nullptr, bg.get());
484 Transaction t;
485 t.setLayerStack(bg, 0)
chaviw25714502021-02-11 10:01:08 -0800486 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800487 .setColor(bg, half3{0, 0, 0})
488 .setLayer(bg, 0)
489 .apply();
490
491 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
492 sp<IGraphicBufferProducer> igbProducer;
493 setUpProducer(adapter, igbProducer);
494 int slot;
495 sp<Fence> fence;
496 sp<GraphicBuffer> buf;
497 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
498 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
499 nullptr, nullptr);
500 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
501 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
502
503 uint32_t* bufData;
504 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
505 reinterpret_cast<void**>(&bufData));
506 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
507 fillBuffer(bufData,
508 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
509 buf->getHeight()),
510 buf->getStride(), r, g, b);
511 buf->unlock();
512
513 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800514 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
515 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800516 Rect(bufferSideLength, finalCropSideLength),
517 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
518 Fence::NO_FENCE);
519 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800520 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800521
522 adapter.waitForCallbacks();
523 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700524 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700525 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
526 {10, 10, (int32_t)bufferSideLength - 10,
527 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800528 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700529 checkScreenCapture(0, 0, 0,
530 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
531 /*border*/ 0, /*outsideRegion*/ true));
532}
533
534TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
535 // add black background
536 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
537 ISurfaceComposerClient::eFXSurfaceEffect);
538 ASSERT_NE(nullptr, bg.get());
539 Transaction t;
540 t.setLayerStack(bg, 0)
541 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
542 .setColor(bg, half3{0, 0, 0})
543 .setLayer(bg, 0)
544 .apply();
545
546 Rect windowSize(1000, 1000);
547 Rect bufferSize(windowSize);
548 Rect bufferCrop(200, 200, 700, 700);
549
550 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
551 sp<IGraphicBufferProducer> igbProducer;
552 setUpProducer(adapter, igbProducer);
553 int slot;
554 sp<Fence> fence;
555 sp<GraphicBuffer> buf;
556 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
557 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
558 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
559 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
560 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
561
562 uint32_t* bufData;
563 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
564 reinterpret_cast<void**>(&bufData));
565 // fill buffer with grey
566 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
567
568 // fill crop area with different colors so we can verify the cropped region has been scaled
569 // correctly.
570 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
571 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
572 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
573 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
574 buf->unlock();
575
576 IGraphicBufferProducer::QueueBufferOutput qbOutput;
577 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
578 HAL_DATASPACE_UNKNOWN,
579 bufferCrop /* Rect::INVALID_RECT */,
580 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
581 Fence::NO_FENCE);
582 igbProducer->queueBuffer(slot, input, &qbOutput);
583 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
584
585 adapter.waitForCallbacks();
586
587 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
588
589 // Verify cropped region is scaled correctly.
590 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
591 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
592 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
593 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
594 // Verify outside region is black.
595 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
596 {0, 0, (int32_t)windowSize.getWidth(),
597 (int32_t)windowSize.getHeight()},
598 /*border*/ 0, /*outsideRegion*/ true));
599}
600
601TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
602 // add black background
603 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
604 ISurfaceComposerClient::eFXSurfaceEffect);
605 ASSERT_NE(nullptr, bg.get());
606 Transaction t;
607 t.setLayerStack(bg, 0)
608 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
609 .setColor(bg, half3{0, 0, 0})
610 .setLayer(bg, 0)
611 .apply();
612
613 Rect windowSize(1000, 1000);
614 Rect bufferSize(500, 500);
615 Rect bufferCrop(100, 100, 350, 350);
616
617 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
618 sp<IGraphicBufferProducer> igbProducer;
619 setUpProducer(adapter, igbProducer);
620 int slot;
621 sp<Fence> fence;
622 sp<GraphicBuffer> buf;
623 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
624 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
625 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
626 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
627 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
628
629 uint32_t* bufData;
630 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
631 reinterpret_cast<void**>(&bufData));
632 // fill buffer with grey
633 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
634
635 // fill crop area with different colors so we can verify the cropped region has been scaled
636 // correctly.
637 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
638 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
639 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
640 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
641 buf->unlock();
642
643 IGraphicBufferProducer::QueueBufferOutput qbOutput;
644 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
645 HAL_DATASPACE_UNKNOWN,
646 bufferCrop /* Rect::INVALID_RECT */,
647 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
648 Fence::NO_FENCE);
649 igbProducer->queueBuffer(slot, input, &qbOutput);
650 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
651
652 adapter.waitForCallbacks();
653
654 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
655 // Verify cropped region is scaled correctly.
656 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
657 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
658 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
659 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
660 // Verify outside region is black.
661 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
662 {0, 0, (int32_t)windowSize.getWidth(),
663 (int32_t)windowSize.getHeight()},
664 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800665}
666
Vishnu Nair89496122020-12-14 17:14:53 -0800667class TestProducerListener : public BnProducerListener {
668public:
669 sp<IGraphicBufferProducer> mIgbp;
670 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
671 void onBufferReleased() override {
672 sp<GraphicBuffer> buffer;
673 sp<Fence> fence;
674 mIgbp->detachNextBuffer(&buffer, &fence);
675 }
676};
677
678TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
679 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
680 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
681 ASSERT_NE(nullptr, igbProducer.get());
682 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
683 IGraphicBufferProducer::QueueBufferOutput qbOutput;
684 ASSERT_EQ(NO_ERROR,
685 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
686 false, &qbOutput));
687 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
688 for (int i = 0; i < 3; i++) {
689 int slot;
690 sp<Fence> fence;
691 sp<GraphicBuffer> buf;
692 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
693 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
694 nullptr, nullptr);
695 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
696 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
697 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800698 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
699 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -0800700 Rect(mDisplayWidth, mDisplayHeight),
701 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
702 Fence::NO_FENCE);
703 igbProducer->queueBuffer(slot, input, &qbOutput);
704 }
705 adapter.waitForCallbacks();
706}
707
Vishnu Nair17dde612020-12-28 11:39:59 -0800708TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
709 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
710
711 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
712 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
713 int queuesToNativeWindow = 0;
714 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
715 &queuesToNativeWindow);
716 ASSERT_EQ(NO_ERROR, err);
717 ASSERT_EQ(queuesToNativeWindow, 1);
718}
719
Vishnu Nair083efd32021-02-12 09:32:30 -0800720// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
721// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -0800722TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
723 sp<SurfaceControl> bgSurface =
724 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
725 ISurfaceComposerClient::eFXSurfaceBufferState);
726 ASSERT_NE(nullptr, bgSurface.get());
727 Transaction t;
728 t.setLayerStack(bgSurface, 0)
729 .show(bgSurface)
730 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -0800731 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
732 .apply();
733
734 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
735 sp<IGraphicBufferProducer> slowIgbProducer;
736 setUpProducer(slowAdapter, slowIgbProducer);
737 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -0800738 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -0800739
740 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
741 sp<IGraphicBufferProducer> fastIgbProducer;
742 setUpProducer(fastAdapter, fastIgbProducer);
743 uint8_t r = 255;
744 uint8_t g = 0;
745 uint8_t b = 0;
746 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
747 fastAdapter.waitForCallbacks();
748
749 // capture screen and verify that it is red
750 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
751
752 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000753 checkScreenCapture(r, g, b,
754 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -0800755}
756
Valerie Hau5977fc82019-12-05 15:56:39 -0800757class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
758public:
759 void test(uint32_t tr) {
760 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
761 sp<IGraphicBufferProducer> igbProducer;
762 setUpProducer(adapter, igbProducer);
763
764 auto bufWidth = mDisplayWidth;
765 auto bufHeight = mDisplayHeight;
766 int slot;
767 sp<Fence> fence;
768 sp<GraphicBuffer> buf;
769
770 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
771 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
772 nullptr, nullptr);
773 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
774 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
775
776 fillQuadrants(buf);
777
778 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800779 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
780 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -0800781 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -0700782 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
783 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -0800784 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800785 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800786
787 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700788 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700789
Valerie Hau5977fc82019-12-05 15:56:39 -0800790 switch (tr) {
791 case ui::Transform::ROT_0:
792 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
793 {0, 0, (int32_t)mDisplayWidth / 2,
794 (int32_t)mDisplayHeight / 2},
795 1));
796 ASSERT_NO_FATAL_FAILURE(
797 checkScreenCapture(255, 0, 0,
798 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
799 (int32_t)mDisplayHeight / 2},
800 1));
801 ASSERT_NO_FATAL_FAILURE(
802 checkScreenCapture(0, 255, 0,
803 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
804 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
805 1));
806 ASSERT_NO_FATAL_FAILURE(
807 checkScreenCapture(0, 0, 255,
808 {0, (int32_t)mDisplayHeight / 2,
809 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
810 1));
811 break;
812 case ui::Transform::FLIP_H:
813 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
814 {0, 0, (int32_t)mDisplayWidth / 2,
815 (int32_t)mDisplayHeight / 2},
816 1));
817 ASSERT_NO_FATAL_FAILURE(
818 checkScreenCapture(0, 0, 0,
819 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
820 (int32_t)mDisplayHeight / 2},
821 1));
822 ASSERT_NO_FATAL_FAILURE(
823 checkScreenCapture(0, 0, 255,
824 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
825 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
826 1));
827 ASSERT_NO_FATAL_FAILURE(
828 checkScreenCapture(0, 255, 0,
829 {0, (int32_t)mDisplayHeight / 2,
830 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
831 1));
832 break;
833 case ui::Transform::FLIP_V:
834 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
835 {0, 0, (int32_t)mDisplayWidth / 2,
836 (int32_t)mDisplayHeight / 2},
837 1));
838 ASSERT_NO_FATAL_FAILURE(
839 checkScreenCapture(0, 255, 0,
840 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
841 (int32_t)mDisplayHeight / 2},
842 1));
843 ASSERT_NO_FATAL_FAILURE(
844 checkScreenCapture(255, 0, 0,
845 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
846 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
847 1));
848 ASSERT_NO_FATAL_FAILURE(
849 checkScreenCapture(0, 0, 0,
850 {0, (int32_t)mDisplayHeight / 2,
851 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
852 1));
853 break;
854 case ui::Transform::ROT_90:
855 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
856 {0, 0, (int32_t)mDisplayWidth / 2,
857 (int32_t)mDisplayHeight / 2},
858 1));
859 ASSERT_NO_FATAL_FAILURE(
860 checkScreenCapture(0, 0, 0,
861 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
862 (int32_t)mDisplayHeight / 2},
863 1));
864 ASSERT_NO_FATAL_FAILURE(
865 checkScreenCapture(255, 0, 0,
866 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
867 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
868 1));
869 ASSERT_NO_FATAL_FAILURE(
870 checkScreenCapture(0, 255, 0,
871 {0, (int32_t)mDisplayHeight / 2,
872 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
873 1));
874 break;
875 case ui::Transform::ROT_180:
876 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
877 {0, 0, (int32_t)mDisplayWidth / 2,
878 (int32_t)mDisplayHeight / 2},
879 1));
880 ASSERT_NO_FATAL_FAILURE(
881 checkScreenCapture(0, 0, 255,
882 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
883 (int32_t)mDisplayHeight / 2},
884 1));
885 ASSERT_NO_FATAL_FAILURE(
886 checkScreenCapture(0, 0, 0,
887 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
888 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
889 1));
890 ASSERT_NO_FATAL_FAILURE(
891 checkScreenCapture(255, 0, 0,
892 {0, (int32_t)mDisplayHeight / 2,
893 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
894 1));
895 break;
896 case ui::Transform::ROT_270:
897 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
898 {0, 0, (int32_t)mDisplayWidth / 2,
899 (int32_t)mDisplayHeight / 2},
900 1));
901 ASSERT_NO_FATAL_FAILURE(
902 checkScreenCapture(0, 255, 0,
903 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
904 (int32_t)mDisplayHeight / 2},
905 1));
906 ASSERT_NO_FATAL_FAILURE(
907 checkScreenCapture(0, 0, 255,
908 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
909 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
910 1));
911 ASSERT_NO_FATAL_FAILURE(
912 checkScreenCapture(0, 0, 0,
913 {0, (int32_t)mDisplayHeight / 2,
914 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
915 1));
916 }
917 }
918};
919
920TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
921 test(ui::Transform::ROT_0);
922}
923
924TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
925 test(ui::Transform::FLIP_H);
926}
927
928TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
929 test(ui::Transform::FLIP_V);
930}
931
932TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
933 test(ui::Transform::ROT_90);
934}
935
936TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
937 test(ui::Transform::ROT_180);
938}
939
940TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
941 test(ui::Transform::ROT_270);
942}
Valerie Hau871d6352020-01-29 08:44:02 -0800943
944class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
945public:
946 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
947 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
948 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nair083efd32021-02-12 09:32:30 -0800949 bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
Valerie Hau871d6352020-01-29 08:44:02 -0800950 int slot;
951 sp<Fence> fence;
952 sp<GraphicBuffer> buf;
953 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
954 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
955 nullptr, nullptr);
956 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
957 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
958
Vishnu Nair083efd32021-02-12 09:32:30 -0800959 nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
Valerie Hau871d6352020-01-29 08:44:02 -0800960 if (requestedPresentTime) *requestedPresentTime = requestedTime;
961 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
962 Rect(mDisplayWidth, mDisplayHeight),
963 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
964 Fence::NO_FENCE, /*sticky*/ 0,
965 getFrameTimestamps);
966 if (postedTime) *postedTime = systemTime();
967 igbProducer->queueBuffer(slot, input, qbOutput);
968 }
Vishnu Nair083efd32021-02-12 09:32:30 -0800969 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -0800970};
971
972TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
973 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
974 sp<IGraphicBufferProducer> igbProducer;
975 ProducerFrameEventHistory history;
976 setUpProducer(adapter, igbProducer);
977
978 IGraphicBufferProducer::QueueBufferOutput qbOutput;
979 nsecs_t requestedPresentTimeA = 0;
980 nsecs_t postedTimeA = 0;
Vishnu Nair1506b182021-02-22 14:35:15 -0800981 adapter.setTransactionCompleteCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800982 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
983 history.applyDelta(qbOutput.frameTimestamps);
984
985 FrameEvents* events = nullptr;
986 events = history.getFrame(1);
987 ASSERT_NE(nullptr, events);
988 ASSERT_EQ(1, events->frameNumber);
989 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
990 ASSERT_GE(events->postedTime, postedTimeA);
991
Vishnu Nair1506b182021-02-22 14:35:15 -0800992 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800993
994 // queue another buffer so we query for frame event deltas
995 nsecs_t requestedPresentTimeB = 0;
996 nsecs_t postedTimeB = 0;
997 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
998 history.applyDelta(qbOutput.frameTimestamps);
999 events = history.getFrame(1);
1000 ASSERT_NE(nullptr, events);
1001
1002 // frame number, requestedPresentTime, and postTime should not have changed
1003 ASSERT_EQ(1, events->frameNumber);
1004 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1005 ASSERT_GE(events->postedTime, postedTimeA);
1006
1007 ASSERT_GE(events->latchTime, postedTimeA);
1008 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1009 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1010 ASSERT_NE(nullptr, events->displayPresentFence);
1011 ASSERT_NE(nullptr, events->releaseFence);
1012
1013 // we should also have gotten the initial values for the next frame
1014 events = history.getFrame(2);
1015 ASSERT_NE(nullptr, events);
1016 ASSERT_EQ(2, events->frameNumber);
1017 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1018 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001019
1020 // wait for any callbacks that have not been received
1021 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001022}
Vishnu Nair083efd32021-02-12 09:32:30 -08001023
Vishnu Nair083efd32021-02-12 09:32:30 -08001024TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1025 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1026 sp<IGraphicBufferProducer> igbProducer;
1027 setUpProducer(adapter, igbProducer);
1028
1029 ProducerFrameEventHistory history;
1030 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1031 nsecs_t requestedPresentTimeA = 0;
1032 nsecs_t postedTimeA = 0;
1033 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1034 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
1035 presentTimeDelay);
1036 history.applyDelta(qbOutput.frameTimestamps);
1037
1038 FrameEvents* events = nullptr;
1039 events = history.getFrame(1);
1040 ASSERT_NE(nullptr, events);
1041 ASSERT_EQ(1, events->frameNumber);
1042 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1043 ASSERT_GE(events->postedTime, postedTimeA);
1044
1045 // queue another buffer so the first can be dropped
1046 nsecs_t requestedPresentTimeB = 0;
1047 nsecs_t postedTimeB = 0;
1048 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1049 history.applyDelta(qbOutput.frameTimestamps);
1050 events = history.getFrame(1);
1051 ASSERT_NE(nullptr, events);
1052
1053 // frame number, requestedPresentTime, and postTime should not have changed
1054 ASSERT_EQ(1, events->frameNumber);
1055 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1056 ASSERT_GE(events->postedTime, postedTimeA);
1057
1058 // a valid latchtime should not be set
1059 ASSERT_FALSE(events->hasLatchInfo());
1060 ASSERT_FALSE(events->hasDequeueReadyInfo());
1061
1062 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1063 ASSERT_NE(nullptr, events->displayPresentFence);
1064 ASSERT_NE(nullptr, events->releaseFence);
1065
1066 // we should also have gotten the initial values for the next frame
1067 events = history.getFrame(2);
1068 ASSERT_NE(nullptr, events);
1069 ASSERT_EQ(2, events->frameNumber);
1070 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1071 ASSERT_GE(events->postedTime, postedTimeB);
1072}
1073
Valerie Hauc5011f92019-10-11 09:52:07 -07001074} // namespace android