blob: fe48d88376299cbaa2550997fe95f27f07449f40 [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())
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800143 .setFrame(mSurfaceControl, Rect(resolution))
Valerie Hauda3446e2019-10-14 15:49:22 -0700144 .show(mSurfaceControl)
145 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
146 .apply();
chaviwd2432892020-07-24 17:42:39 -0700147
148 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800149 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700150 }
151
Vishnu Nair1506b182021-02-22 14:35:15 -0800152 void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer) {
Vishnu Nair083efd32021-02-12 09:32:30 -0800153 producer = adapter.getIGraphicBufferProducer();
154 setUpProducer(producer);
155 }
156
157 void setUpProducer(sp<IGraphicBufferProducer>& igbProducer) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800158 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800159 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800160 IGraphicBufferProducer::QueueBufferOutput qbOutput;
161 ASSERT_EQ(NO_ERROR,
Peiyong Lind8460c82020-07-28 16:04:22 -0700162 igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
Valerie Haud3b90d22019-11-06 09:37:31 -0800163 &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800164 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800165 }
166
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800167 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
168 uint8_t b) {
169 for (uint32_t row = rect.top; row < rect.bottom; row++) {
170 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700171 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
172 *pixel = r;
173 *(pixel + 1) = g;
174 *(pixel + 2) = b;
175 *(pixel + 3) = 255;
176 }
177 }
178 }
179
Valerie Hau5977fc82019-12-05 15:56:39 -0800180 void fillQuadrants(sp<GraphicBuffer>& buf) {
181 const auto bufWidth = buf->getWidth();
182 const auto bufHeight = buf->getHeight();
183 uint32_t* bufData;
184 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
185 reinterpret_cast<void**>(&bufData));
186 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
187 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
188 0, 0);
189 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
190 buf->getStride(), 0, 255, 0);
191 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
192 255);
193 buf->unlock();
194 }
195
196 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
197 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700198 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800199 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700200 const auto width = captureBuf->getWidth();
201 const auto height = captureBuf->getHeight();
202 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700203
204 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700205 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
206 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700207
208 for (uint32_t row = 0; row < height; row++) {
209 for (uint32_t col = 0; col < width; col++) {
210 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800211 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800212 bool inRegion;
213 if (!outsideRegion) {
214 inRegion = row >= region.top + border && row < region.bottom - border &&
215 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800216 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800217 inRegion = row >= region.top - border && row < region.bottom + border &&
218 col >= region.left - border && col < region.right + border;
219 }
220 if (!outsideRegion && inRegion) {
221 EXPECT_GE(epsilon, abs(r - *(pixel)));
222 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
223 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
224 } else if (outsideRegion && !inRegion) {
225 EXPECT_GE(epsilon, abs(r - *(pixel)));
226 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
227 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800228 }
Vishnu Nair1506b182021-02-22 14:35:15 -0800229 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauda3446e2019-10-14 15:49:22 -0700230 }
231 }
chaviwd2432892020-07-24 17:42:39 -0700232 captureBuf->unlock();
Valerie Hauc5011f92019-10-11 09:52:07 -0700233 }
234
chaviw8ffc7b82020-08-18 11:25:37 -0700235 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
236 ScreenCaptureResults& captureResults) {
237 const auto sf = ComposerService::getComposerService();
238 SurfaceComposerClient::Transaction().apply(true);
239
240 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
241 status_t status = sf->captureDisplay(captureArgs, captureListener);
242 if (status != NO_ERROR) {
243 return status;
244 }
245 captureResults = captureListener->waitForResults();
246 return captureResults.result;
247 }
248
Vishnu Nair277142c2021-01-05 18:35:29 -0800249 void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
250 nsecs_t presentTimeDelay) {
251 int slot;
252 sp<Fence> fence;
253 sp<GraphicBuffer> buf;
254 auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
255 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
256 nullptr, nullptr);
257 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
258 ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
259
260 uint32_t* bufData;
261 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
262 reinterpret_cast<void**>(&bufData));
263 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
264 buf->unlock();
265
266 IGraphicBufferProducer::QueueBufferOutput qbOutput;
267 nsecs_t timestampNanos = systemTime() + presentTimeDelay;
268 IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
269 Rect(mDisplayWidth, mDisplayHeight / 2),
270 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
271 Fence::NO_FENCE);
272 igbp->queueBuffer(slot, input, &qbOutput);
273 }
274
Valerie Hauc5011f92019-10-11 09:52:07 -0700275 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700276 sp<ISurfaceComposer> mComposer;
277
278 sp<IBinder> mDisplayToken;
279
Valerie Hauc5011f92019-10-11 09:52:07 -0700280 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700281
282 uint32_t mDisplayWidth;
283 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700284
285 DisplayCaptureArgs mCaptureArgs;
286 ScreenCaptureResults mCaptureResults;
Valerie Hauc5011f92019-10-11 09:52:07 -0700287};
288
289TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
290 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700291 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700292 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700293 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
294 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700295 ASSERT_EQ(nullptr, adapter.getNextTransaction());
296}
297
298TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700299 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700300 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700301 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
302 PIXEL_FORMAT_RGBA_8888);
303 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700304 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800305 sp<IGraphicBufferProducer> igbProducer;
306 setUpProducer(adapter, igbProducer);
307
308 int32_t width;
309 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
310 ASSERT_EQ(mDisplayWidth / 2, width);
311 int32_t height;
312 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
313 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700314}
315
316TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700317 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700318 Transaction next;
319 adapter.setNextTransaction(&next);
320 ASSERT_EQ(&next, adapter.getNextTransaction());
321}
Valerie Hauda3446e2019-10-14 15:49:22 -0700322
Valerie Haubf29e042020-02-06 11:40:38 -0800323TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800324 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
325 sp<IGraphicBufferProducer> igbProducer;
326 setUpProducer(adapter, igbProducer);
327
328 int slot;
329 sp<Fence> fence;
330 sp<GraphicBuffer> buf;
331 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
332 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
333 nullptr, nullptr);
334 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
335 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
336
337 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
338 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800339 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
340 HAL_DATASPACE_UNKNOWN,
Valerie Hau181abd32020-01-27 14:18:28 -0800341 Rect(mDisplayWidth, mDisplayHeight),
342 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
343 Fence::NO_FENCE);
344 igbProducer->queueBuffer(slot, input, &qbOutput);
345 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
346
347 adapter.waitForCallbacks();
348 ASSERT_GE(systemTime(), desiredPresentTime);
349}
350
Valerie Hauda3446e2019-10-14 15:49:22 -0700351TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
352 uint8_t r = 255;
353 uint8_t g = 0;
354 uint8_t b = 0;
355
356 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800357 sp<IGraphicBufferProducer> igbProducer;
358 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700359
360 int slot;
361 sp<Fence> fence;
362 sp<GraphicBuffer> buf;
363 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
364 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
365 nullptr, nullptr);
366 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
367 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
368
369 uint32_t* bufData;
370 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
371 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800372 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700373 buf->unlock();
374
Valerie Haud3b90d22019-11-06 09:37:31 -0800375 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800376 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
377 HAL_DATASPACE_UNKNOWN,
Valerie Hauda3446e2019-10-14 15:49:22 -0700378 Rect(mDisplayWidth, mDisplayHeight),
379 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
380 Fence::NO_FENCE);
381 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800382 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700383
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800384 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700385
386 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700387 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800388 ASSERT_NO_FATAL_FAILURE(
389 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700390}
Valerie Haud3b90d22019-11-06 09:37:31 -0800391
392TEST_F(BLASTBufferQueueTest, TripleBuffering) {
393 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
394 sp<IGraphicBufferProducer> igbProducer;
395 setUpProducer(adapter, igbProducer);
396
397 std::vector<std::pair<int, sp<Fence>>> allocated;
398 for (int i = 0; i < 3; i++) {
399 int slot;
400 sp<Fence> fence;
401 sp<GraphicBuffer> buf;
402 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
403 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
404 nullptr, nullptr);
405 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
406 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
407 allocated.push_back({slot, fence});
408 }
409 for (int i = 0; i < allocated.size(); i++) {
410 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
411 }
412
Valerie Haua32c5522019-12-09 10:11:08 -0800413 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800414 int slot;
415 sp<Fence> fence;
416 sp<GraphicBuffer> buf;
417 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
418 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
419 nullptr, nullptr);
420 ASSERT_EQ(NO_ERROR, ret);
421 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800422 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
423 HAL_DATASPACE_UNKNOWN,
Valerie Haud3b90d22019-11-06 09:37:31 -0800424 Rect(mDisplayWidth, mDisplayHeight),
425 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
426 Fence::NO_FENCE);
427 igbProducer->queueBuffer(slot, input, &qbOutput);
428 }
429 adapter.waitForCallbacks();
430}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800431
432TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
433 uint8_t r = 255;
434 uint8_t g = 0;
435 uint8_t b = 0;
436
437 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
438 sp<IGraphicBufferProducer> igbProducer;
439 setUpProducer(adapter, igbProducer);
440 int slot;
441 sp<Fence> fence;
442 sp<GraphicBuffer> buf;
443 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
444 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
445 nullptr, nullptr);
446 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
447 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
448
449 uint32_t* bufData;
450 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
451 reinterpret_cast<void**>(&bufData));
452 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
453 buf->unlock();
454
455 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800456 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
457 HAL_DATASPACE_UNKNOWN,
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800458 Rect(mDisplayWidth, mDisplayHeight / 2),
459 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
460 Fence::NO_FENCE);
461 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800462 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800463
464 adapter.waitForCallbacks();
465 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700466 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700467
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800468 ASSERT_NO_FATAL_FAILURE(
469 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
470}
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
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800526 ASSERT_NO_FATAL_FAILURE(
527 checkScreenCapture(r, g, b,
528 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}));
Valerie Hau5977fc82019-12-05 15:56:39 -0800529 ASSERT_NO_FATAL_FAILURE(
530 checkScreenCapture(0, 0, 0,
531 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
532 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800533}
534
Vishnu Nair89496122020-12-14 17:14:53 -0800535class TestProducerListener : public BnProducerListener {
536public:
537 sp<IGraphicBufferProducer> mIgbp;
538 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
539 void onBufferReleased() override {
540 sp<GraphicBuffer> buffer;
541 sp<Fence> fence;
542 mIgbp->detachNextBuffer(&buffer, &fence);
543 }
544};
545
546TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
547 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
548 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
549 ASSERT_NE(nullptr, igbProducer.get());
550 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
551 IGraphicBufferProducer::QueueBufferOutput qbOutput;
552 ASSERT_EQ(NO_ERROR,
553 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
554 false, &qbOutput));
555 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
556 for (int i = 0; i < 3; i++) {
557 int slot;
558 sp<Fence> fence;
559 sp<GraphicBuffer> buf;
560 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
561 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
562 nullptr, nullptr);
563 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
564 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
565 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800566 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
567 HAL_DATASPACE_UNKNOWN,
Vishnu Nair89496122020-12-14 17:14:53 -0800568 Rect(mDisplayWidth, mDisplayHeight),
569 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
570 Fence::NO_FENCE);
571 igbProducer->queueBuffer(slot, input, &qbOutput);
572 }
573 adapter.waitForCallbacks();
574}
575
Vishnu Nair17dde612020-12-28 11:39:59 -0800576TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
577 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
578
579 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
580 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
581 int queuesToNativeWindow = 0;
582 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
583 &queuesToNativeWindow);
584 ASSERT_EQ(NO_ERROR, err);
585 ASSERT_EQ(queuesToNativeWindow, 1);
586}
587
Vishnu Nair083efd32021-02-12 09:32:30 -0800588// Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
589// BBQ uses separate transaction queues.
Vishnu Nair277142c2021-01-05 18:35:29 -0800590TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
591 sp<SurfaceControl> bgSurface =
592 mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
593 ISurfaceComposerClient::eFXSurfaceBufferState);
594 ASSERT_NE(nullptr, bgSurface.get());
595 Transaction t;
596 t.setLayerStack(bgSurface, 0)
597 .show(bgSurface)
598 .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
599 .setFrame(bgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight))
600 .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
601 .apply();
602
603 BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
604 sp<IGraphicBufferProducer> slowIgbProducer;
605 setUpProducer(slowAdapter, slowIgbProducer);
606 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
Vishnu Nair1506b182021-02-22 14:35:15 -0800607 queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
Vishnu Nair277142c2021-01-05 18:35:29 -0800608
609 BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
610 sp<IGraphicBufferProducer> fastIgbProducer;
611 setUpProducer(fastAdapter, fastIgbProducer);
612 uint8_t r = 255;
613 uint8_t g = 0;
614 uint8_t b = 0;
615 queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
616 fastAdapter.waitForCallbacks();
617
618 // capture screen and verify that it is red
619 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
620
621 ASSERT_NO_FATAL_FAILURE(
622 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
623}
624
Valerie Hau5977fc82019-12-05 15:56:39 -0800625class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
626public:
627 void test(uint32_t tr) {
628 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
629 sp<IGraphicBufferProducer> igbProducer;
630 setUpProducer(adapter, igbProducer);
631
632 auto bufWidth = mDisplayWidth;
633 auto bufHeight = mDisplayHeight;
634 int slot;
635 sp<Fence> fence;
636 sp<GraphicBuffer> buf;
637
638 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
639 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
640 nullptr, nullptr);
641 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
642 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
643
644 fillQuadrants(buf);
645
646 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Vishnu Nair1506b182021-02-22 14:35:15 -0800647 IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
648 HAL_DATASPACE_UNKNOWN,
Valerie Hau5977fc82019-12-05 15:56:39 -0800649 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -0700650 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
651 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -0800652 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800653 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800654
655 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700656 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700657
Valerie Hau5977fc82019-12-05 15:56:39 -0800658 switch (tr) {
659 case ui::Transform::ROT_0:
660 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
661 {0, 0, (int32_t)mDisplayWidth / 2,
662 (int32_t)mDisplayHeight / 2},
663 1));
664 ASSERT_NO_FATAL_FAILURE(
665 checkScreenCapture(255, 0, 0,
666 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
667 (int32_t)mDisplayHeight / 2},
668 1));
669 ASSERT_NO_FATAL_FAILURE(
670 checkScreenCapture(0, 255, 0,
671 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
672 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
673 1));
674 ASSERT_NO_FATAL_FAILURE(
675 checkScreenCapture(0, 0, 255,
676 {0, (int32_t)mDisplayHeight / 2,
677 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
678 1));
679 break;
680 case ui::Transform::FLIP_H:
681 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
682 {0, 0, (int32_t)mDisplayWidth / 2,
683 (int32_t)mDisplayHeight / 2},
684 1));
685 ASSERT_NO_FATAL_FAILURE(
686 checkScreenCapture(0, 0, 0,
687 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
688 (int32_t)mDisplayHeight / 2},
689 1));
690 ASSERT_NO_FATAL_FAILURE(
691 checkScreenCapture(0, 0, 255,
692 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
693 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
694 1));
695 ASSERT_NO_FATAL_FAILURE(
696 checkScreenCapture(0, 255, 0,
697 {0, (int32_t)mDisplayHeight / 2,
698 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
699 1));
700 break;
701 case ui::Transform::FLIP_V:
702 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
703 {0, 0, (int32_t)mDisplayWidth / 2,
704 (int32_t)mDisplayHeight / 2},
705 1));
706 ASSERT_NO_FATAL_FAILURE(
707 checkScreenCapture(0, 255, 0,
708 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
709 (int32_t)mDisplayHeight / 2},
710 1));
711 ASSERT_NO_FATAL_FAILURE(
712 checkScreenCapture(255, 0, 0,
713 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
714 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
715 1));
716 ASSERT_NO_FATAL_FAILURE(
717 checkScreenCapture(0, 0, 0,
718 {0, (int32_t)mDisplayHeight / 2,
719 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
720 1));
721 break;
722 case ui::Transform::ROT_90:
723 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
724 {0, 0, (int32_t)mDisplayWidth / 2,
725 (int32_t)mDisplayHeight / 2},
726 1));
727 ASSERT_NO_FATAL_FAILURE(
728 checkScreenCapture(0, 0, 0,
729 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
730 (int32_t)mDisplayHeight / 2},
731 1));
732 ASSERT_NO_FATAL_FAILURE(
733 checkScreenCapture(255, 0, 0,
734 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
735 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
736 1));
737 ASSERT_NO_FATAL_FAILURE(
738 checkScreenCapture(0, 255, 0,
739 {0, (int32_t)mDisplayHeight / 2,
740 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
741 1));
742 break;
743 case ui::Transform::ROT_180:
744 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
745 {0, 0, (int32_t)mDisplayWidth / 2,
746 (int32_t)mDisplayHeight / 2},
747 1));
748 ASSERT_NO_FATAL_FAILURE(
749 checkScreenCapture(0, 0, 255,
750 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
751 (int32_t)mDisplayHeight / 2},
752 1));
753 ASSERT_NO_FATAL_FAILURE(
754 checkScreenCapture(0, 0, 0,
755 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
756 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
757 1));
758 ASSERT_NO_FATAL_FAILURE(
759 checkScreenCapture(255, 0, 0,
760 {0, (int32_t)mDisplayHeight / 2,
761 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
762 1));
763 break;
764 case ui::Transform::ROT_270:
765 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
766 {0, 0, (int32_t)mDisplayWidth / 2,
767 (int32_t)mDisplayHeight / 2},
768 1));
769 ASSERT_NO_FATAL_FAILURE(
770 checkScreenCapture(0, 255, 0,
771 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
772 (int32_t)mDisplayHeight / 2},
773 1));
774 ASSERT_NO_FATAL_FAILURE(
775 checkScreenCapture(0, 0, 255,
776 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
777 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
778 1));
779 ASSERT_NO_FATAL_FAILURE(
780 checkScreenCapture(0, 0, 0,
781 {0, (int32_t)mDisplayHeight / 2,
782 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
783 1));
784 }
785 }
786};
787
788TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
789 test(ui::Transform::ROT_0);
790}
791
792TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
793 test(ui::Transform::FLIP_H);
794}
795
796TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
797 test(ui::Transform::FLIP_V);
798}
799
800TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
801 test(ui::Transform::ROT_90);
802}
803
804TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
805 test(ui::Transform::ROT_180);
806}
807
808TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
809 test(ui::Transform::ROT_270);
810}
Valerie Hau871d6352020-01-29 08:44:02 -0800811
812class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
813public:
814 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
815 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
816 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
Vishnu Nair083efd32021-02-12 09:32:30 -0800817 bool getFrameTimestamps, nsecs_t requestedPresentTimeDelay = 0) {
Valerie Hau871d6352020-01-29 08:44:02 -0800818 int slot;
819 sp<Fence> fence;
820 sp<GraphicBuffer> buf;
821 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
822 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
823 nullptr, nullptr);
824 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
825 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
826
Vishnu Nair083efd32021-02-12 09:32:30 -0800827 nsecs_t requestedTime = systemTime() + requestedPresentTimeDelay;
Valerie Hau871d6352020-01-29 08:44:02 -0800828 if (requestedPresentTime) *requestedPresentTime = requestedTime;
829 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
830 Rect(mDisplayWidth, mDisplayHeight),
831 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
832 Fence::NO_FENCE, /*sticky*/ 0,
833 getFrameTimestamps);
834 if (postedTime) *postedTime = systemTime();
835 igbProducer->queueBuffer(slot, input, qbOutput);
836 }
Vishnu Nair083efd32021-02-12 09:32:30 -0800837
838 void createBufferQueueProducer(sp<IGraphicBufferProducer>* bqIgbp) {
839 mBufferQueueSurfaceControl =
840 mClient->createSurface(String8("BqSurface"), 0, 0, PIXEL_FORMAT_RGBA_8888,
841 ISurfaceComposerClient::eFXSurfaceBufferQueue);
842 ASSERT_NE(nullptr, mBufferQueueSurfaceControl.get());
843 Transaction()
844 .setLayerStack(mBufferQueueSurfaceControl, 0)
845 .show(mBufferQueueSurfaceControl)
846 .setDataspace(mBufferQueueSurfaceControl, ui::Dataspace::V0_SRGB)
847 .setSize(mBufferQueueSurfaceControl, mDisplayWidth, mDisplayHeight)
848 .setLayer(mBufferQueueSurfaceControl, std::numeric_limits<int32_t>::max())
849 .apply();
850
851 sp<Surface> bqSurface = mBufferQueueSurfaceControl->getSurface();
852 ASSERT_NE(nullptr, bqSurface.get());
853
854 *bqIgbp = bqSurface->getIGraphicBufferProducer();
855 setUpProducer(*bqIgbp);
856 }
857 sp<SurfaceControl> mBufferQueueSurfaceControl;
Valerie Hau871d6352020-01-29 08:44:02 -0800858};
859
860TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
861 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
862 sp<IGraphicBufferProducer> igbProducer;
863 ProducerFrameEventHistory history;
864 setUpProducer(adapter, igbProducer);
865
866 IGraphicBufferProducer::QueueBufferOutput qbOutput;
867 nsecs_t requestedPresentTimeA = 0;
868 nsecs_t postedTimeA = 0;
Vishnu Nair1506b182021-02-22 14:35:15 -0800869 adapter.setTransactionCompleteCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800870 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
871 history.applyDelta(qbOutput.frameTimestamps);
872
873 FrameEvents* events = nullptr;
874 events = history.getFrame(1);
875 ASSERT_NE(nullptr, events);
876 ASSERT_EQ(1, events->frameNumber);
877 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
878 ASSERT_GE(events->postedTime, postedTimeA);
879
Vishnu Nair1506b182021-02-22 14:35:15 -0800880 adapter.waitForCallback(1);
Valerie Hau871d6352020-01-29 08:44:02 -0800881
882 // queue another buffer so we query for frame event deltas
883 nsecs_t requestedPresentTimeB = 0;
884 nsecs_t postedTimeB = 0;
885 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
886 history.applyDelta(qbOutput.frameTimestamps);
887 events = history.getFrame(1);
888 ASSERT_NE(nullptr, events);
889
890 // frame number, requestedPresentTime, and postTime should not have changed
891 ASSERT_EQ(1, events->frameNumber);
892 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
893 ASSERT_GE(events->postedTime, postedTimeA);
894
895 ASSERT_GE(events->latchTime, postedTimeA);
896 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
897 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
898 ASSERT_NE(nullptr, events->displayPresentFence);
899 ASSERT_NE(nullptr, events->releaseFence);
900
901 // we should also have gotten the initial values for the next frame
902 events = history.getFrame(2);
903 ASSERT_NE(nullptr, events);
904 ASSERT_EQ(2, events->frameNumber);
905 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
906 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -0700907
908 // wait for any callbacks that have not been received
909 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -0800910}
Vishnu Nair083efd32021-02-12 09:32:30 -0800911
912// Runs the same Frame Event History test
913TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic_BufferQueue) {
914 sp<IGraphicBufferProducer> bqIgbp;
915 createBufferQueueProducer(&bqIgbp);
916
917 ProducerFrameEventHistory history;
918 IGraphicBufferProducer::QueueBufferOutput qbOutput;
919 nsecs_t requestedPresentTimeA = 0;
920 nsecs_t postedTimeA = 0;
921 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
922 history.applyDelta(qbOutput.frameTimestamps);
923
924 FrameEvents* events = nullptr;
925 events = history.getFrame(1);
926 ASSERT_NE(nullptr, events);
927 ASSERT_EQ(1, events->frameNumber);
928 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
929 ASSERT_GE(events->postedTime, postedTimeA);
930
931 // wait for buffer to be presented
932 std::this_thread::sleep_for(200ms);
933
934 nsecs_t requestedPresentTimeB = 0;
935 nsecs_t postedTimeB = 0;
936 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
937 history.applyDelta(qbOutput.frameTimestamps);
938 events = history.getFrame(1);
939 ASSERT_NE(nullptr, events);
940
941 // frame number, requestedPresentTime, and postTime should not have changed
942 ASSERT_EQ(1, events->frameNumber);
943 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
944 ASSERT_GE(events->postedTime, postedTimeA);
945
946 ASSERT_GE(events->latchTime, postedTimeA);
947 ASSERT_FALSE(events->hasDequeueReadyInfo());
948
949 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
950 ASSERT_NE(nullptr, events->displayPresentFence);
951 ASSERT_NE(nullptr, events->releaseFence);
952
953 // we should also have gotten the initial values for the next frame
954 events = history.getFrame(2);
955 ASSERT_NE(nullptr, events);
956 ASSERT_EQ(2, events->frameNumber);
957 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
958 ASSERT_GE(events->postedTime, postedTimeB);
959}
960
961TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
962 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
963 sp<IGraphicBufferProducer> igbProducer;
964 setUpProducer(adapter, igbProducer);
965
966 ProducerFrameEventHistory history;
967 IGraphicBufferProducer::QueueBufferOutput qbOutput;
968 nsecs_t requestedPresentTimeA = 0;
969 nsecs_t postedTimeA = 0;
970 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
971 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
972 presentTimeDelay);
973 history.applyDelta(qbOutput.frameTimestamps);
974
975 FrameEvents* events = nullptr;
976 events = history.getFrame(1);
977 ASSERT_NE(nullptr, events);
978 ASSERT_EQ(1, events->frameNumber);
979 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
980 ASSERT_GE(events->postedTime, postedTimeA);
981
982 // queue another buffer so the first can be dropped
983 nsecs_t requestedPresentTimeB = 0;
984 nsecs_t postedTimeB = 0;
985 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
986 history.applyDelta(qbOutput.frameTimestamps);
987 events = history.getFrame(1);
988 ASSERT_NE(nullptr, events);
989
990 // frame number, requestedPresentTime, and postTime should not have changed
991 ASSERT_EQ(1, events->frameNumber);
992 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
993 ASSERT_GE(events->postedTime, postedTimeA);
994
995 // a valid latchtime should not be set
996 ASSERT_FALSE(events->hasLatchInfo());
997 ASSERT_FALSE(events->hasDequeueReadyInfo());
998
999 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1000 ASSERT_NE(nullptr, events->displayPresentFence);
1001 ASSERT_NE(nullptr, events->releaseFence);
1002
1003 // we should also have gotten the initial values for the next frame
1004 events = history.getFrame(2);
1005 ASSERT_NE(nullptr, events);
1006 ASSERT_EQ(2, events->frameNumber);
1007 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1008 ASSERT_GE(events->postedTime, postedTimeB);
1009}
1010
1011TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame_BufferQueue) {
1012 sp<IGraphicBufferProducer> bqIgbp;
1013 createBufferQueueProducer(&bqIgbp);
1014
1015 ProducerFrameEventHistory history;
1016 IGraphicBufferProducer::QueueBufferOutput qbOutput;
1017 nsecs_t requestedPresentTimeA = 0;
1018 nsecs_t postedTimeA = 0;
1019 nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1020 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
1021 presentTimeDelay);
1022 history.applyDelta(qbOutput.frameTimestamps);
1023
1024 FrameEvents* events = nullptr;
1025 events = history.getFrame(1);
1026 ASSERT_NE(nullptr, events);
1027 ASSERT_EQ(1, events->frameNumber);
1028 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1029 ASSERT_GE(events->postedTime, postedTimeA);
1030
1031 // queue another buffer so the first can be dropped
1032 nsecs_t requestedPresentTimeB = 0;
1033 nsecs_t postedTimeB = 0;
1034 setUpAndQueueBuffer(bqIgbp, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1035 history.applyDelta(qbOutput.frameTimestamps);
1036 events = history.getFrame(1);
1037 ASSERT_NE(nullptr, events);
1038
1039 // frame number, requestedPresentTime, and postTime should not have changed
1040 ASSERT_EQ(1, events->frameNumber);
1041 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1042 ASSERT_GE(events->postedTime, postedTimeA);
1043
1044 // a valid latchtime should not be set
1045 ASSERT_FALSE(events->hasLatchInfo());
1046 ASSERT_FALSE(events->hasDequeueReadyInfo());
1047
1048 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1049 ASSERT_NE(nullptr, events->displayPresentFence);
1050 ASSERT_NE(nullptr, events->releaseFence);
1051
1052 // we should also have gotten the initial values for the next frame
1053 events = history.getFrame(2);
1054 ASSERT_NE(nullptr, events);
1055 ASSERT_EQ(2, events->frameNumber);
1056 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1057 ASSERT_GE(events->postedTime, postedTimeB);
1058}
1059
Valerie Hauc5011f92019-10-11 09:52:07 -07001060} // namespace android