blob: 06660b8b504c0142e23637efc42cbce5fc1a1fb3 [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;
Ady Abraham0bde6b52021-05-18 13:57:02 -0700397 int minUndequeuedBuffers = 0;
398 ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
399 const auto bufferCount = minUndequeuedBuffers + 2;
400
401 for (int i = 0; i < bufferCount; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800402 int slot;
403 sp<Fence> fence;
404 sp<GraphicBuffer> buf;
405 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
406 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
407 nullptr, nullptr);
408 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
409 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
410 allocated.push_back({slot, fence});
411 }
412 for (int i = 0; i < allocated.size(); i++) {
413 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
414 }
415
Valerie Haua32c5522019-12-09 10:11:08 -0800416 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800417 int slot;
418 sp<Fence> fence;
419 sp<GraphicBuffer> buf;
420 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
421 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
422 nullptr, nullptr);
423 ASSERT_EQ(NO_ERROR, ret);
424 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800425 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
426 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800427 Rect(mDisplayWidth, mDisplayHeight),
428 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
429 Fence::NO_FENCE);
430 igbProducer->queueBuffer(slot, input, &qbOutput);
431 }
432 adapter.waitForCallbacks();
433}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800434
435TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
436 uint8_t r = 255;
437 uint8_t g = 0;
438 uint8_t b = 0;
439
440 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
441 sp<IGraphicBufferProducer> igbProducer;
442 setUpProducer(adapter, igbProducer);
443 int slot;
444 sp<Fence> fence;
445 sp<GraphicBuffer> buf;
446 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
447 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
448 nullptr, nullptr);
449 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
450 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
451
452 uint32_t* bufData;
453 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
454 reinterpret_cast<void**>(&bufData));
455 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
456 buf->unlock();
457
458 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800459 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
460 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800461 Rect(mDisplayWidth, mDisplayHeight / 2),
462 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
463 Fence::NO_FENCE);
464 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800465 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800466
467 adapter.waitForCallbacks();
468 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700469 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700470
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800471 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000472 checkScreenCapture(r, g, b,
473 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800474}
475
476TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
477 uint8_t r = 255;
478 uint8_t g = 0;
479 uint8_t b = 0;
480
481 int32_t bufferSideLength =
482 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
483 int32_t finalCropSideLength = bufferSideLength / 2;
484
485 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800486 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800487 ASSERT_NE(nullptr, bg.get());
488 Transaction t;
489 t.setLayerStack(bg, 0)
chaviw25714502021-02-11 10:01:08 -0800490 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800491 .setColor(bg, half3{0, 0, 0})
492 .setLayer(bg, 0)
493 .apply();
494
495 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
496 sp<IGraphicBufferProducer> igbProducer;
497 setUpProducer(adapter, igbProducer);
498 int slot;
499 sp<Fence> fence;
500 sp<GraphicBuffer> buf;
501 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
502 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
503 nullptr, nullptr);
504 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
505 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
506
507 uint32_t* bufData;
508 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
509 reinterpret_cast<void**>(&bufData));
510 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
511 fillBuffer(bufData,
512 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
513 buf->getHeight()),
514 buf->getStride(), r, g, b);
515 buf->unlock();
516
517 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800518 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
519 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800520 Rect(bufferSideLength, finalCropSideLength),
521 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
522 Fence::NO_FENCE);
523 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800524 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800525
526 adapter.waitForCallbacks();
527 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700528 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700529 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
530 {10, 10, (int32_t)bufferSideLength - 10,
531 (int32_t)bufferSideLength - 10}));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800532 ASSERT_NO_FATAL_FAILURE(
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700533 checkScreenCapture(0, 0, 0,
534 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
535 /*border*/ 0, /*outsideRegion*/ true));
536}
537
538TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
539 // add black background
540 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
541 ISurfaceComposerClient::eFXSurfaceEffect);
542 ASSERT_NE(nullptr, bg.get());
543 Transaction t;
544 t.setLayerStack(bg, 0)
545 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
546 .setColor(bg, half3{0, 0, 0})
547 .setLayer(bg, 0)
548 .apply();
549
550 Rect windowSize(1000, 1000);
551 Rect bufferSize(windowSize);
552 Rect bufferCrop(200, 200, 700, 700);
553
554 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
555 sp<IGraphicBufferProducer> igbProducer;
556 setUpProducer(adapter, igbProducer);
557 int slot;
558 sp<Fence> fence;
559 sp<GraphicBuffer> buf;
560 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
561 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
562 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
563 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
564 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
565
566 uint32_t* bufData;
567 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
568 reinterpret_cast<void**>(&bufData));
569 // fill buffer with grey
570 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
571
572 // fill crop area with different colors so we can verify the cropped region has been scaled
573 // correctly.
574 fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
575 fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
576 fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
577 fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
578 buf->unlock();
579
580 IGraphicBufferProducer::QueueBufferOutput qbOutput;
581 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
582 HAL_DATASPACE_UNKNOWN,
583 bufferCrop /* Rect::INVALID_RECT */,
584 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
585 Fence::NO_FENCE);
586 igbProducer->queueBuffer(slot, input, &qbOutput);
587 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
588
589 adapter.waitForCallbacks();
590
591 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
592
593 // Verify cropped region is scaled correctly.
594 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
595 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
596 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
597 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
598 // Verify outside region is black.
599 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
600 {0, 0, (int32_t)windowSize.getWidth(),
601 (int32_t)windowSize.getHeight()},
602 /*border*/ 0, /*outsideRegion*/ true));
603}
604
605TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
606 // add black background
607 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
608 ISurfaceComposerClient::eFXSurfaceEffect);
609 ASSERT_NE(nullptr, bg.get());
610 Transaction t;
611 t.setLayerStack(bg, 0)
612 .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
613 .setColor(bg, half3{0, 0, 0})
614 .setLayer(bg, 0)
615 .apply();
616
617 Rect windowSize(1000, 1000);
618 Rect bufferSize(500, 500);
619 Rect bufferCrop(100, 100, 350, 350);
620
621 BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
622 sp<IGraphicBufferProducer> igbProducer;
623 setUpProducer(adapter, igbProducer);
624 int slot;
625 sp<Fence> fence;
626 sp<GraphicBuffer> buf;
627 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
628 bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
629 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
630 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
631 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
632
633 uint32_t* bufData;
634 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
635 reinterpret_cast<void**>(&bufData));
636 // fill buffer with grey
637 fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
638
639 // fill crop area with different colors so we can verify the cropped region has been scaled
640 // correctly.
641 fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
642 fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
643 fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
644 fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
645 buf->unlock();
646
647 IGraphicBufferProducer::QueueBufferOutput qbOutput;
648 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
649 HAL_DATASPACE_UNKNOWN,
650 bufferCrop /* Rect::INVALID_RECT */,
651 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
652 Fence::NO_FENCE);
653 igbProducer->queueBuffer(slot, input, &qbOutput);
654 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
655
656 adapter.waitForCallbacks();
657
658 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
659 // Verify cropped region is scaled correctly.
660 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
661 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
662 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
663 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
664 // Verify outside region is black.
665 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
666 {0, 0, (int32_t)windowSize.getWidth(),
667 (int32_t)windowSize.getHeight()},
668 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800669}
670
Vishnu Nair89496122020-12-14 17:14:53 -0800671class TestProducerListener : public BnProducerListener {
672public:
673 sp<IGraphicBufferProducer> mIgbp;
674 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
675 void onBufferReleased() override {
676 sp<GraphicBuffer> buffer;
677 sp<Fence> fence;
678 mIgbp->detachNextBuffer(&buffer, &fence);
679 }
680};
681
682TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
683 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
684 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
685 ASSERT_NE(nullptr, igbProducer.get());
686 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
687 IGraphicBufferProducer::QueueBufferOutput qbOutput;
688 ASSERT_EQ(NO_ERROR,
689 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
690 false, &qbOutput));
691 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
692 for (int i = 0; i < 3; i++) {
693 int slot;
694 sp<Fence> fence;
695 sp<GraphicBuffer> buf;
696 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
697 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
698 nullptr, nullptr);
699 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
700 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
701 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800702 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
703 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -0800704 Rect(mDisplayWidth, mDisplayHeight),
705 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
706 Fence::NO_FENCE);
707 igbProducer->queueBuffer(slot, input, &qbOutput);
708 }
709 adapter.waitForCallbacks();
710}
711
Vishnu Nair17dde612020-12-28 11:39:59 -0800712TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
713 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
714
715 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
716 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
717 int queuesToNativeWindow = 0;
718 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
719 &queuesToNativeWindow);
720 ASSERT_EQ(NO_ERROR, err);
721 ASSERT_EQ(queuesToNativeWindow, 1);
722}
723
Vishnu Nair083efd32021-02-12 09:32:30 -0800724// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
725// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -0800726TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
727 sp<SurfaceControl> bgSurface =
728 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
729 ISurfaceComposerClient::eFXSurfaceBufferState);
730 ASSERT_NE(nullptr, bgSurface.get());
731 Transaction t;
732 t.setLayerStack(bgSurface, 0)
733 .show(bgSurface)
734 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -0800735 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
736 .apply();
737
738 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
739 sp<IGraphicBufferProducer> slowIgbProducer;
740 setUpProducer(slowAdapter, slowIgbProducer);
741 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -0800742 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -0800743
744 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
745 sp<IGraphicBufferProducer> fastIgbProducer;
746 setUpProducer(fastAdapter, fastIgbProducer);
747 uint8_t r = 255;
748 uint8_t g = 0;
749 uint8_t b = 0;
750 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
751 fastAdapter.waitForCallbacks();
752
753 // capture screen and verify that it is red
754 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
755
756 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000757 checkScreenCapture(r, g, b,
758 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -0800759}
760
Valerie Hau5977fc82019-12-05 15:56:39 -0800761class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
762public:
763 void test(uint32_t tr) {
764 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
765 sp<IGraphicBufferProducer> igbProducer;
766 setUpProducer(adapter, igbProducer);
767
768 auto bufWidth = mDisplayWidth;
769 auto bufHeight = mDisplayHeight;
770 int slot;
771 sp<Fence> fence;
772 sp<GraphicBuffer> buf;
773
774 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
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 fillQuadrants(buf);
781
782 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800783 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
784 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -0800785 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -0700786 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
787 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -0800788 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800789 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800790
791 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700792 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700793
Valerie Hau5977fc82019-12-05 15:56:39 -0800794 switch (tr) {
795 case ui::Transform::ROT_0:
796 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
797 {0, 0, (int32_t)mDisplayWidth / 2,
798 (int32_t)mDisplayHeight / 2},
799 1));
800 ASSERT_NO_FATAL_FAILURE(
801 checkScreenCapture(255, 0, 0,
802 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
803 (int32_t)mDisplayHeight / 2},
804 1));
805 ASSERT_NO_FATAL_FAILURE(
806 checkScreenCapture(0, 255, 0,
807 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
808 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
809 1));
810 ASSERT_NO_FATAL_FAILURE(
811 checkScreenCapture(0, 0, 255,
812 {0, (int32_t)mDisplayHeight / 2,
813 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
814 1));
815 break;
816 case ui::Transform::FLIP_H:
817 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
818 {0, 0, (int32_t)mDisplayWidth / 2,
819 (int32_t)mDisplayHeight / 2},
820 1));
821 ASSERT_NO_FATAL_FAILURE(
822 checkScreenCapture(0, 0, 0,
823 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
824 (int32_t)mDisplayHeight / 2},
825 1));
826 ASSERT_NO_FATAL_FAILURE(
827 checkScreenCapture(0, 0, 255,
828 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
829 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
830 1));
831 ASSERT_NO_FATAL_FAILURE(
832 checkScreenCapture(0, 255, 0,
833 {0, (int32_t)mDisplayHeight / 2,
834 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
835 1));
836 break;
837 case ui::Transform::FLIP_V:
838 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
839 {0, 0, (int32_t)mDisplayWidth / 2,
840 (int32_t)mDisplayHeight / 2},
841 1));
842 ASSERT_NO_FATAL_FAILURE(
843 checkScreenCapture(0, 255, 0,
844 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
845 (int32_t)mDisplayHeight / 2},
846 1));
847 ASSERT_NO_FATAL_FAILURE(
848 checkScreenCapture(255, 0, 0,
849 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
850 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
851 1));
852 ASSERT_NO_FATAL_FAILURE(
853 checkScreenCapture(0, 0, 0,
854 {0, (int32_t)mDisplayHeight / 2,
855 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
856 1));
857 break;
858 case ui::Transform::ROT_90:
859 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
860 {0, 0, (int32_t)mDisplayWidth / 2,
861 (int32_t)mDisplayHeight / 2},
862 1));
863 ASSERT_NO_FATAL_FAILURE(
864 checkScreenCapture(0, 0, 0,
865 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
866 (int32_t)mDisplayHeight / 2},
867 1));
868 ASSERT_NO_FATAL_FAILURE(
869 checkScreenCapture(255, 0, 0,
870 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
871 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
872 1));
873 ASSERT_NO_FATAL_FAILURE(
874 checkScreenCapture(0, 255, 0,
875 {0, (int32_t)mDisplayHeight / 2,
876 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
877 1));
878 break;
879 case ui::Transform::ROT_180:
880 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
881 {0, 0, (int32_t)mDisplayWidth / 2,
882 (int32_t)mDisplayHeight / 2},
883 1));
884 ASSERT_NO_FATAL_FAILURE(
885 checkScreenCapture(0, 0, 255,
886 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
887 (int32_t)mDisplayHeight / 2},
888 1));
889 ASSERT_NO_FATAL_FAILURE(
890 checkScreenCapture(0, 0, 0,
891 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
892 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
893 1));
894 ASSERT_NO_FATAL_FAILURE(
895 checkScreenCapture(255, 0, 0,
896 {0, (int32_t)mDisplayHeight / 2,
897 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
898 1));
899 break;
900 case ui::Transform::ROT_270:
901 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
902 {0, 0, (int32_t)mDisplayWidth / 2,
903 (int32_t)mDisplayHeight / 2},
904 1));
905 ASSERT_NO_FATAL_FAILURE(
906 checkScreenCapture(0, 255, 0,
907 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
908 (int32_t)mDisplayHeight / 2},
909 1));
910 ASSERT_NO_FATAL_FAILURE(
911 checkScreenCapture(0, 0, 255,
912 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
913 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
914 1));
915 ASSERT_NO_FATAL_FAILURE(
916 checkScreenCapture(0, 0, 0,
917 {0, (int32_t)mDisplayHeight / 2,
918 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
919 1));
920 }
921 }
922};
923
924TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
925 test(ui::Transform::ROT_0);
926}
927
928TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
929 test(ui::Transform::FLIP_H);
930}
931
932TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
933 test(ui::Transform::FLIP_V);
934}
935
936TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
937 test(ui::Transform::ROT_90);
938}
939
940TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
941 test(ui::Transform::ROT_180);
942}
943
944TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
945 test(ui::Transform::ROT_270);
946}
Valerie Hau871d6352020-01-29 08:44:02 -0800947
948class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
949public:
950 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
951 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
952 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nair083efd32021-02-12 09:32:30 -0800953 bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
Valerie Hau871d6352020-01-29 08:44:02 -0800954 int slot;
955 sp<Fence> fence;
956 sp<GraphicBuffer> buf;
957 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
958 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
959 nullptr, nullptr);
960 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
961 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
962
Vishnu Nair083efd32021-02-12 09:32:30 -0800963 nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
Valerie Hau871d6352020-01-29 08:44:02 -0800964 if (requestedPresentTime) *requestedPresentTime = requestedTime;
965 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
966 Rect(mDisplayWidth, mDisplayHeight),
967 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
968 Fence::NO_FENCE, /*sticky*/ 0,
969 getFrameTimestamps);
970 if (postedTime) *postedTime = systemTime();
971 igbProducer->queueBuffer(slot, input, qbOutput);
972 }
Vishnu Nair083efd32021-02-12 09:32:30 -0800973 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -0800974};
975
976TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
977 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
978 sp<IGraphicBufferProducer> igbProducer;
979 ProducerFrameEventHistory history;
980 setUpProducer(adapter, igbProducer);
981
982 IGraphicBufferProducer::QueueBufferOutput qbOutput;
983 nsecs_t requestedPresentTimeA = 0;
984 nsecs_t postedTimeA = 0;
Vishnu Nair1506b182021-02-22 14:35:15 -0800985 adapter.setTransactionCompleteCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800986 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
987 history.applyDelta(qbOutput.frameTimestamps);
988
989 FrameEvents* events = nullptr;
990 events = history.getFrame(1);
991 ASSERT_NE(nullptr, events);
992 ASSERT_EQ(1, events->frameNumber);
993 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
994 ASSERT_GE(events->postedTime, postedTimeA);
995
Vishnu Nair1506b182021-02-22 14:35:15 -0800996 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800997
998 // queue another buffer so we query for frame event deltas
999 nsecs_t requestedPresentTimeB = 0;
1000 nsecs_t postedTimeB = 0;
1001 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1002 history.applyDelta(qbOutput.frameTimestamps);
1003 events = history.getFrame(1);
1004 ASSERT_NE(nullptr, events);
1005
1006 // frame number, requestedPresentTime, and postTime should not have changed
1007 ASSERT_EQ(1, events->frameNumber);
1008 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1009 ASSERT_GE(events->postedTime, postedTimeA);
1010
1011 ASSERT_GE(events->latchTime, postedTimeA);
1012 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1013 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1014 ASSERT_NE(nullptr, events->displayPresentFence);
1015 ASSERT_NE(nullptr, events->releaseFence);
1016
1017 // we should also have gotten the initial values for the next frame
1018 events = history.getFrame(2);
1019 ASSERT_NE(nullptr, events);
1020 ASSERT_EQ(2, events->frameNumber);
1021 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1022 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -07001023
1024 // wait for any callbacks that have not been received
1025 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -08001026}
Vishnu Nair083efd32021-02-12 09:32:30 -08001027
Vishnu Nair083efd32021-02-12 09:32:30 -08001028TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1029 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1030 sp<IGraphicBufferProducer> igbProducer;
1031 setUpProducer(adapter, igbProducer);
1032
1033 ProducerFrameEventHistory history;
1034 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1035 nsecs_t requestedPresentTimeA = 0;
1036 nsecs_t postedTimeA = 0;
1037 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1038 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
1039 presentTimeDelay);
1040 history.applyDelta(qbOutput.frameTimestamps);
1041
1042 FrameEvents* events = nullptr;
1043 events = history.getFrame(1);
1044 ASSERT_NE(nullptr, events);
1045 ASSERT_EQ(1, events->frameNumber);
1046 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1047 ASSERT_GE(events->postedTime, postedTimeA);
1048
1049 // queue another buffer so the first can be dropped
1050 nsecs_t requestedPresentTimeB = 0;
1051 nsecs_t postedTimeB = 0;
1052 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1053 history.applyDelta(qbOutput.frameTimestamps);
1054 events = history.getFrame(1);
1055 ASSERT_NE(nullptr, events);
1056
1057 // frame number, requestedPresentTime, and postTime should not have changed
1058 ASSERT_EQ(1, events->frameNumber);
1059 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1060 ASSERT_GE(events->postedTime, postedTimeA);
1061
1062 // a valid latchtime should not be set
1063 ASSERT_FALSE(events->hasLatchInfo());
1064 ASSERT_FALSE(events->hasDequeueReadyInfo());
1065
1066 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1067 ASSERT_NE(nullptr, events->displayPresentFence);
1068 ASSERT_NE(nullptr, events->releaseFence);
1069
1070 // we should also have gotten the initial values for the next frame
1071 events = history.getFrame(2);
1072 ASSERT_NE(nullptr, events);
1073 ASSERT_EQ(2, events->frameNumber);
1074 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1075 ASSERT_GE(events->postedTime, postedTimeB);
1076}
1077
Valerie Hauc5011f92019-10-11 09:52:07 -07001078} // namespace android