blob: 9b1f0db83bef0c88a67e44d56c24046dcf7c83c6 [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));
chaviwd2432892020-07-24 17:42:39 -0700525
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000526 Rect bounds;
527 bounds.left = finalCropSideLength / 2;
528 bounds.top = 0;
529 bounds.right = bounds.left + finalCropSideLength;
530 bounds.bottom = finalCropSideLength;
531
532 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b, bounds));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800533 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000534 checkScreenCapture(0, 0, 0, bounds, /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800535}
536
Vishnu Nair89496122020-12-14 17:14:53 -0800537class TestProducerListener : public BnProducerListener {
538public:
539 sp<IGraphicBufferProducer> mIgbp;
540 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
541 void onBufferReleased() override {
542 sp<GraphicBuffer> buffer;
543 sp<Fence> fence;
544 mIgbp->detachNextBuffer(&buffer, &fence);
545 }
546};
547
548TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
549 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
550 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
551 ASSERT_NE(nullptr, igbProducer.get());
552 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
553 IGraphicBufferProducer::QueueBufferOutput qbOutput;
554 ASSERT_EQ(NO_ERROR,
555 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
556 false, &qbOutput));
557 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
558 for (int i = 0; i < 3; i++) {
559 int slot;
560 sp<Fence> fence;
561 sp<GraphicBuffer> buf;
562 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
563 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
564 nullptr, nullptr);
565 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
566 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
567 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800568 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
569 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -0800570 Rect(mDisplayWidth, mDisplayHeight),
571 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
572 Fence::NO_FENCE);
573 igbProducer->queueBuffer(slot, input, &qbOutput);
574 }
575 adapter.waitForCallbacks();
576}
577
Vishnu Nair17dde612020-12-28 11:39:59 -0800578TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
579 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
580
581 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
582 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
583 int queuesToNativeWindow = 0;
584 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
585 &queuesToNativeWindow);
586 ASSERT_EQ(NO_ERROR, err);
587 ASSERT_EQ(queuesToNativeWindow, 1);
588}
589
Vishnu Nair083efd32021-02-12 09:32:30 -0800590// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
591// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -0800592TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
593 sp<SurfaceControl> bgSurface =
594 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
595 ISurfaceComposerClient::eFXSurfaceBufferState);
596 ASSERT_NE(nullptr, bgSurface.get());
597 Transaction t;
598 t.setLayerStack(bgSurface, 0)
599 .show(bgSurface)
600 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
Vishnu Nair277142c2021-01-05 18:35:29 -0800601 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
602 .apply();
603
604 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
605 sp<IGraphicBufferProducer> slowIgbProducer;
606 setUpProducer(slowAdapter, slowIgbProducer);
607 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -0800608 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -0800609
610 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
611 sp<IGraphicBufferProducer> fastIgbProducer;
612 setUpProducer(fastAdapter, fastIgbProducer);
613 uint8_t r = 255;
614 uint8_t g = 0;
615 uint8_t b = 0;
616 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
617 fastAdapter.waitForCallbacks();
618
619 // capture screen and verify that it is red
620 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
621
622 ASSERT_NO_FATAL_FAILURE(
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000623 checkScreenCapture(r, g, b,
624 {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
Vishnu Nair277142c2021-01-05 18:35:29 -0800625}
626
Valerie Hau5977fc82019-12-05 15:56:39 -0800627class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
628public:
629 void test(uint32_t tr) {
630 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
631 sp<IGraphicBufferProducer> igbProducer;
632 setUpProducer(adapter, igbProducer);
633
634 auto bufWidth = mDisplayWidth;
635 auto bufHeight = mDisplayHeight;
636 int slot;
637 sp<Fence> fence;
638 sp<GraphicBuffer> buf;
639
640 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
641 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
642 nullptr, nullptr);
643 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
644 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
645
646 fillQuadrants(buf);
647
648 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800649 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
650 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -0800651 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -0700652 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
653 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -0800654 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800655 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800656
657 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700658 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700659
Valerie Hau5977fc82019-12-05 15:56:39 -0800660 switch (tr) {
661 case ui::Transform::ROT_0:
662 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
663 {0, 0, (int32_t)mDisplayWidth / 2,
664 (int32_t)mDisplayHeight / 2},
665 1));
666 ASSERT_NO_FATAL_FAILURE(
667 checkScreenCapture(255, 0, 0,
668 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
669 (int32_t)mDisplayHeight / 2},
670 1));
671 ASSERT_NO_FATAL_FAILURE(
672 checkScreenCapture(0, 255, 0,
673 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
674 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
675 1));
676 ASSERT_NO_FATAL_FAILURE(
677 checkScreenCapture(0, 0, 255,
678 {0, (int32_t)mDisplayHeight / 2,
679 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
680 1));
681 break;
682 case ui::Transform::FLIP_H:
683 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
684 {0, 0, (int32_t)mDisplayWidth / 2,
685 (int32_t)mDisplayHeight / 2},
686 1));
687 ASSERT_NO_FATAL_FAILURE(
688 checkScreenCapture(0, 0, 0,
689 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
690 (int32_t)mDisplayHeight / 2},
691 1));
692 ASSERT_NO_FATAL_FAILURE(
693 checkScreenCapture(0, 0, 255,
694 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
695 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
696 1));
697 ASSERT_NO_FATAL_FAILURE(
698 checkScreenCapture(0, 255, 0,
699 {0, (int32_t)mDisplayHeight / 2,
700 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
701 1));
702 break;
703 case ui::Transform::FLIP_V:
704 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
705 {0, 0, (int32_t)mDisplayWidth / 2,
706 (int32_t)mDisplayHeight / 2},
707 1));
708 ASSERT_NO_FATAL_FAILURE(
709 checkScreenCapture(0, 255, 0,
710 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
711 (int32_t)mDisplayHeight / 2},
712 1));
713 ASSERT_NO_FATAL_FAILURE(
714 checkScreenCapture(255, 0, 0,
715 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
716 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
717 1));
718 ASSERT_NO_FATAL_FAILURE(
719 checkScreenCapture(0, 0, 0,
720 {0, (int32_t)mDisplayHeight / 2,
721 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
722 1));
723 break;
724 case ui::Transform::ROT_90:
725 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
726 {0, 0, (int32_t)mDisplayWidth / 2,
727 (int32_t)mDisplayHeight / 2},
728 1));
729 ASSERT_NO_FATAL_FAILURE(
730 checkScreenCapture(0, 0, 0,
731 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
732 (int32_t)mDisplayHeight / 2},
733 1));
734 ASSERT_NO_FATAL_FAILURE(
735 checkScreenCapture(255, 0, 0,
736 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
737 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
738 1));
739 ASSERT_NO_FATAL_FAILURE(
740 checkScreenCapture(0, 255, 0,
741 {0, (int32_t)mDisplayHeight / 2,
742 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
743 1));
744 break;
745 case ui::Transform::ROT_180:
746 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
747 {0, 0, (int32_t)mDisplayWidth / 2,
748 (int32_t)mDisplayHeight / 2},
749 1));
750 ASSERT_NO_FATAL_FAILURE(
751 checkScreenCapture(0, 0, 255,
752 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
753 (int32_t)mDisplayHeight / 2},
754 1));
755 ASSERT_NO_FATAL_FAILURE(
756 checkScreenCapture(0, 0, 0,
757 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
758 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
759 1));
760 ASSERT_NO_FATAL_FAILURE(
761 checkScreenCapture(255, 0, 0,
762 {0, (int32_t)mDisplayHeight / 2,
763 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
764 1));
765 break;
766 case ui::Transform::ROT_270:
767 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
768 {0, 0, (int32_t)mDisplayWidth / 2,
769 (int32_t)mDisplayHeight / 2},
770 1));
771 ASSERT_NO_FATAL_FAILURE(
772 checkScreenCapture(0, 255, 0,
773 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
774 (int32_t)mDisplayHeight / 2},
775 1));
776 ASSERT_NO_FATAL_FAILURE(
777 checkScreenCapture(0, 0, 255,
778 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
779 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
780 1));
781 ASSERT_NO_FATAL_FAILURE(
782 checkScreenCapture(0, 0, 0,
783 {0, (int32_t)mDisplayHeight / 2,
784 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
785 1));
786 }
787 }
788};
789
790TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
791 test(ui::Transform::ROT_0);
792}
793
794TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
795 test(ui::Transform::FLIP_H);
796}
797
798TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
799 test(ui::Transform::FLIP_V);
800}
801
802TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
803 test(ui::Transform::ROT_90);
804}
805
806TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
807 test(ui::Transform::ROT_180);
808}
809
810TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
811 test(ui::Transform::ROT_270);
812}
Valerie Hau871d6352020-01-29 08:44:02 -0800813
814class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
815public:
816 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
817 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
818 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nair083efd32021-02-12 09:32:30 -0800819 bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
Valerie Hau871d6352020-01-29 08:44:02 -0800820 int slot;
821 sp<Fence> fence;
822 sp<GraphicBuffer> buf;
823 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
824 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
825 nullptr, nullptr);
826 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
827 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
828
Vishnu Nair083efd32021-02-12 09:32:30 -0800829 nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
Valerie Hau871d6352020-01-29 08:44:02 -0800830 if (requestedPresentTime) *requestedPresentTime = requestedTime;
831 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
832 Rect(mDisplayWidth, mDisplayHeight),
833 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
834 Fence::NO_FENCE, /*sticky*/ 0,
835 getFrameTimestamps);
836 if (postedTime) *postedTime = systemTime();
837 igbProducer->queueBuffer(slot, input, qbOutput);
838 }
Vishnu Nair083efd32021-02-12 09:32:30 -0800839
840 void createBufferQueueProducer(sp<IGraphicBufferProducer>* bqIgbp) {
841 mBufferQueueSurfaceControl =
842 mClient->createSurface(String8("BqSurface"), 0, 0, PIXEL_FORMAT_RGBA_8888,
843 ISurfaceComposerClient::eFXSurfaceBufferQueue);
844 ASSERT_NE(nullptr, mBufferQueueSurfaceControl.get());
845 Transaction()
846 .setLayerStack(mBufferQueueSurfaceControl, 0)
847 .show(mBufferQueueSurfaceControl)
848 .setDataspace(mBufferQueueSurfaceControl, ui::Dataspace::V0_SRGB)
849 .setSize(mBufferQueueSurfaceControl, mDisplayWidth, mDisplayHeight)
850 .setLayer(mBufferQueueSurfaceControl, std::numeric_limits<int32_t>::max())
851 .apply();
852
853 sp<Surface> bqSurface = mBufferQueueSurfaceControl->getSurface();
854 ASSERT_NE(nullptr, bqSurface.get());
855
856 *bqIgbp = bqSurface->getIGraphicBufferProducer();
857 setUpProducer(*bqIgbp);
858 }
859 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -0800860};
861
862TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
863 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
864 sp<IGraphicBufferProducer> igbProducer;
865 ProducerFrameEventHistory history;
866 setUpProducer(adapter, igbProducer);
867
868 IGraphicBufferProducer::QueueBufferOutput qbOutput;
869 nsecs_t requestedPresentTimeA = 0;
870 nsecs_t postedTimeA = 0;
Vishnu Nair1506b182021-02-22 14:35:15 -0800871 adapter.setTransactionCompleteCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800872 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
873 history.applyDelta(qbOutput.frameTimestamps);
874
875 FrameEvents* events = nullptr;
876 events = history.getFrame(1);
877 ASSERT_NE(nullptr, events);
878 ASSERT_EQ(1, events->frameNumber);
879 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
880 ASSERT_GE(events->postedTime, postedTimeA);
881
Vishnu Nair1506b182021-02-22 14:35:15 -0800882 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800883
884 // queue another buffer so we query for frame event deltas
885 nsecs_t requestedPresentTimeB = 0;
886 nsecs_t postedTimeB = 0;
887 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
888 history.applyDelta(qbOutput.frameTimestamps);
889 events = history.getFrame(1);
890 ASSERT_NE(nullptr, events);
891
892 // frame number, requestedPresentTime, and postTime should not have changed
893 ASSERT_EQ(1, events->frameNumber);
894 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
895 ASSERT_GE(events->postedTime, postedTimeA);
896
897 ASSERT_GE(events->latchTime, postedTimeA);
898 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
899 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
900 ASSERT_NE(nullptr, events->displayPresentFence);
901 ASSERT_NE(nullptr, events->releaseFence);
902
903 // we should also have gotten the initial values for the next frame
904 events = history.getFrame(2);
905 ASSERT_NE(nullptr, events);
906 ASSERT_EQ(2, events->frameNumber);
907 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
908 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -0700909
910 // wait for any callbacks that have not been received
911 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -0800912}
Vishnu Nair083efd32021-02-12 09:32:30 -0800913
914// Runs the same Frame Event History test
915TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic_BufferQueue) {
916 sp<IGraphicBufferProducer> bqIgbp;
917 createBufferQueueProducer(&bqIgbp);
918
919 ProducerFrameEventHistory history;
920 IGraphicBufferProducer::QueueBufferOutput qbOutput;
921 nsecs_t requestedPresentTimeA = 0;
922 nsecs_t postedTimeA = 0;
923 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
924 history.applyDelta(qbOutput.frameTimestamps);
925
926 FrameEvents* events = nullptr;
927 events = history.getFrame(1);
928 ASSERT_NE(nullptr, events);
929 ASSERT_EQ(1, events->frameNumber);
930 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
931 ASSERT_GE(events->postedTime, postedTimeA);
932
933 // wait for buffer to be presented
934 std::this_thread::sleep_for(200ms);
935
936 nsecs_t requestedPresentTimeB = 0;
937 nsecs_t postedTimeB = 0;
938 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
939 history.applyDelta(qbOutput.frameTimestamps);
940 events = history.getFrame(1);
941 ASSERT_NE(nullptr, events);
942
943 // frame number, requestedPresentTime, and postTime should not have changed
944 ASSERT_EQ(1, events->frameNumber);
945 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
946 ASSERT_GE(events->postedTime, postedTimeA);
947
948 ASSERT_GE(events->latchTime, postedTimeA);
949 ASSERT_FALSE(events->hasDequeueReadyInfo());
950
951 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
952 ASSERT_NE(nullptr, events->displayPresentFence);
953 ASSERT_NE(nullptr, events->releaseFence);
954
955 // we should also have gotten the initial values for the next frame
956 events = history.getFrame(2);
957 ASSERT_NE(nullptr, events);
958 ASSERT_EQ(2, events->frameNumber);
959 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
960 ASSERT_GE(events->postedTime, postedTimeB);
961}
962
963TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
964 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
965 sp<IGraphicBufferProducer> igbProducer;
966 setUpProducer(adapter, igbProducer);
967
968 ProducerFrameEventHistory history;
969 IGraphicBufferProducer::QueueBufferOutput qbOutput;
970 nsecs_t requestedPresentTimeA = 0;
971 nsecs_t postedTimeA = 0;
972 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
973 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
974 presentTimeDelay);
975 history.applyDelta(qbOutput.frameTimestamps);
976
977 FrameEvents* events = nullptr;
978 events = history.getFrame(1);
979 ASSERT_NE(nullptr, events);
980 ASSERT_EQ(1, events->frameNumber);
981 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
982 ASSERT_GE(events->postedTime, postedTimeA);
983
984 // queue another buffer so the first can be dropped
985 nsecs_t requestedPresentTimeB = 0;
986 nsecs_t postedTimeB = 0;
987 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
988 history.applyDelta(qbOutput.frameTimestamps);
989 events = history.getFrame(1);
990 ASSERT_NE(nullptr, events);
991
992 // frame number, requestedPresentTime, and postTime should not have changed
993 ASSERT_EQ(1, events->frameNumber);
994 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
995 ASSERT_GE(events->postedTime, postedTimeA);
996
997 // a valid latchtime should not be set
998 ASSERT_FALSE(events->hasLatchInfo());
999 ASSERT_FALSE(events->hasDequeueReadyInfo());
1000
1001 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1002 ASSERT_NE(nullptr, events->displayPresentFence);
1003 ASSERT_NE(nullptr, events->releaseFence);
1004
1005 // we should also have gotten the initial values for the next frame
1006 events = history.getFrame(2);
1007 ASSERT_NE(nullptr, events);
1008 ASSERT_EQ(2, events->frameNumber);
1009 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1010 ASSERT_GE(events->postedTime, postedTimeB);
1011}
1012
1013TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame_BufferQueue) {
1014 sp<IGraphicBufferProducer> bqIgbp;
1015 createBufferQueueProducer(&bqIgbp);
1016
1017 ProducerFrameEventHistory history;
1018 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1019 nsecs_t requestedPresentTimeA = 0;
1020 nsecs_t postedTimeA = 0;
1021 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1022 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
1023 presentTimeDelay);
1024 history.applyDelta(qbOutput.frameTimestamps);
1025
1026 FrameEvents* events = nullptr;
1027 events = history.getFrame(1);
1028 ASSERT_NE(nullptr, events);
1029 ASSERT_EQ(1, events->frameNumber);
1030 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1031 ASSERT_GE(events->postedTime, postedTimeA);
1032
1033 // queue another buffer so the first can be dropped
1034 nsecs_t requestedPresentTimeB = 0;
1035 nsecs_t postedTimeB = 0;
1036 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1037 history.applyDelta(qbOutput.frameTimestamps);
1038 events = history.getFrame(1);
1039 ASSERT_NE(nullptr, events);
1040
1041 // frame number, requestedPresentTime, and postTime should not have changed
1042 ASSERT_EQ(1, events->frameNumber);
1043 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1044 ASSERT_GE(events->postedTime, postedTimeA);
1045
1046 // a valid latchtime should not be set
1047 ASSERT_FALSE(events->hasLatchInfo());
1048 ASSERT_FALSE(events->hasDequeueReadyInfo());
1049
1050 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1051 ASSERT_NE(nullptr, events->displayPresentFence);
1052 ASSERT_NE(nullptr, events->releaseFence);
1053
1054 // we should also have gotten the initial values for the next frame
1055 events = history.getFrame(2);
1056 ASSERT_NE(nullptr, events);
1057 ASSERT_EQ(2, events->frameNumber);
1058 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1059 ASSERT_GE(events->postedTime, postedTimeB);
1060}
1061
Valerie Hauc5011f92019-10-11 09:52:07 -07001062} // namespace android