blob: 170ad879935c0ccaa7a4f98fd406aef2a29b5997 [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>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080031#include <ui/DisplayConfig.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) {
Vishnu Nairdab94092020-09-29 16:09:04 -070048 mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height);
Valerie Hauc5011f92019-10-11 09:52:07 -070049 }
50
51 void update(const sp<SurfaceControl>& sc, int width, int height) {
52 mBlastBufferQueueAdapter->update(sc, width, height);
53 }
54
55 void setNextTransaction(Transaction* next) {
56 mBlastBufferQueueAdapter->setNextTransaction(next);
57 }
58
Vishnu Nairea0de002020-11-17 17:42:37 -080059 int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
Valerie Hauda3446e2019-10-14 15:49:22 -070060
Vishnu Nairea0de002020-11-17 17:42:37 -080061 int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Valerie Hauda3446e2019-10-14 15:49:22 -070062
Valerie Hauc5011f92019-10-11 09:52:07 -070063 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -070064
65 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
66 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
67 }
68
Valerie Hauc5011f92019-10-11 09:52:07 -070069 const sp<SurfaceControl> getSurfaceControl() {
70 return mBlastBufferQueueAdapter->mSurfaceControl;
71 }
72
Valerie Haud3b90d22019-11-06 09:37:31 -080073 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -070074 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Valerie Haua32c5522019-12-09 10:11:08 -080075 while (mBlastBufferQueueAdapter->mSubmitted.size() > 0) {
Valerie Haud3b90d22019-11-06 09:37:31 -080076 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
77 }
Valerie Hauda3446e2019-10-14 15:49:22 -070078 }
79
Valerie Hauc5011f92019-10-11 09:52:07 -070080private:
81 sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
82};
83
84class BLASTBufferQueueTest : public ::testing::Test {
85public:
86protected:
87 BLASTBufferQueueTest() {
88 const ::testing::TestInfo* const testInfo =
89 ::testing::UnitTest::GetInstance()->current_test_info();
90 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
91 }
92
93 ~BLASTBufferQueueTest() {
94 const ::testing::TestInfo* const testInfo =
95 ::testing::UnitTest::GetInstance()->current_test_info();
96 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
97 }
98
99 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -0700100 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -0700101 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700102 mDisplayToken = mClient->getInternalDisplayToken();
103 ASSERT_NE(nullptr, mDisplayToken.get());
104 Transaction t;
105 t.setDisplayLayerStack(mDisplayToken, 0);
106 t.apply();
107 t.clear();
108
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800109 DisplayConfig config;
110 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(mDisplayToken, &config));
111 const ui::Size& resolution = config.resolution;
112 mDisplayWidth = resolution.getWidth();
113 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700114
115 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
116 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
117 ISurfaceComposerClient::eFXSurfaceBufferState,
118 /*parent*/ nullptr);
119 t.setLayerStack(mSurfaceControl, 0)
120 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800121 .setFrame(mSurfaceControl, Rect(resolution))
Valerie Hauda3446e2019-10-14 15:49:22 -0700122 .show(mSurfaceControl)
123 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
124 .apply();
chaviwd2432892020-07-24 17:42:39 -0700125
126 mCaptureArgs.displayToken = mDisplayToken;
arthurhung6fa58b72020-11-05 11:56:00 +0800127 mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
Valerie Hauda3446e2019-10-14 15:49:22 -0700128 }
129
Valerie Haud3b90d22019-11-06 09:37:31 -0800130 void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
131 auto igbProducer = adapter.getIGraphicBufferProducer();
132 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800133 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800134 IGraphicBufferProducer::QueueBufferOutput qbOutput;
135 ASSERT_EQ(NO_ERROR,
Peiyong Lind8460c82020-07-28 16:04:22 -0700136 igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
Valerie Haud3b90d22019-11-06 09:37:31 -0800137 &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800138 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800139 producer = igbProducer;
140 }
141
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800142 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
143 uint8_t b) {
144 for (uint32_t row = rect.top; row < rect.bottom; row++) {
145 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700146 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
147 *pixel = r;
148 *(pixel + 1) = g;
149 *(pixel + 2) = b;
150 *(pixel + 3) = 255;
151 }
152 }
153 }
154
Valerie Hau5977fc82019-12-05 15:56:39 -0800155 void fillQuadrants(sp<GraphicBuffer>& buf) {
156 const auto bufWidth = buf->getWidth();
157 const auto bufHeight = buf->getHeight();
158 uint32_t* bufData;
159 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
160 reinterpret_cast<void**>(&bufData));
161 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
162 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
163 0, 0);
164 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
165 buf->getStride(), 0, 255, 0);
166 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
167 255);
168 buf->unlock();
169 }
170
171 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
172 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700173 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800174 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700175 const auto width = captureBuf->getWidth();
176 const auto height = captureBuf->getHeight();
177 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700178
179 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700180 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
181 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700182
183 for (uint32_t row = 0; row < height; row++) {
184 for (uint32_t col = 0; col < width; col++) {
185 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
arthurhung6fa58b72020-11-05 11:56:00 +0800186 ASSERT_NE(nullptr, pixel);
Valerie Hau5977fc82019-12-05 15:56:39 -0800187 bool inRegion;
188 if (!outsideRegion) {
189 inRegion = row >= region.top + border && row < region.bottom - border &&
190 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800191 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800192 inRegion = row >= region.top - border && row < region.bottom + border &&
193 col >= region.left - border && col < region.right + border;
194 }
195 if (!outsideRegion && inRegion) {
196 EXPECT_GE(epsilon, abs(r - *(pixel)));
197 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
198 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
199 } else if (outsideRegion && !inRegion) {
200 EXPECT_GE(epsilon, abs(r - *(pixel)));
201 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
202 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800203 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700204 }
205 }
chaviwd2432892020-07-24 17:42:39 -0700206 captureBuf->unlock();
Valerie Hauda3446e2019-10-14 15:49:22 -0700207 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauc5011f92019-10-11 09:52:07 -0700208 }
209
chaviw8ffc7b82020-08-18 11:25:37 -0700210 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
211 ScreenCaptureResults& captureResults) {
212 const auto sf = ComposerService::getComposerService();
213 SurfaceComposerClient::Transaction().apply(true);
214
215 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
216 status_t status = sf->captureDisplay(captureArgs, captureListener);
217 if (status != NO_ERROR) {
218 return status;
219 }
220 captureResults = captureListener->waitForResults();
221 return captureResults.result;
222 }
223
Valerie Hauc5011f92019-10-11 09:52:07 -0700224 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700225 sp<ISurfaceComposer> mComposer;
226
227 sp<IBinder> mDisplayToken;
228
Valerie Hauc5011f92019-10-11 09:52:07 -0700229 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700230
231 uint32_t mDisplayWidth;
232 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700233
234 DisplayCaptureArgs mCaptureArgs;
235 ScreenCaptureResults mCaptureResults;
Valerie Hauc5011f92019-10-11 09:52:07 -0700236};
237
238TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
239 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700240 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700241 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700242 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
243 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700244 ASSERT_EQ(nullptr, adapter.getNextTransaction());
245}
246
247TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700248 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700249 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700250 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
251 PIXEL_FORMAT_RGBA_8888);
252 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700253 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Vishnu Nairea0de002020-11-17 17:42:37 -0800254 sp<IGraphicBufferProducer> igbProducer;
255 setUpProducer(adapter, igbProducer);
256
257 int32_t width;
258 igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
259 ASSERT_EQ(mDisplayWidth / 2, width);
260 int32_t height;
261 igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
262 ASSERT_EQ(mDisplayHeight / 2, height);
Valerie Hauc5011f92019-10-11 09:52:07 -0700263}
264
265TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700266 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700267 Transaction next;
268 adapter.setNextTransaction(&next);
269 ASSERT_EQ(&next, adapter.getNextTransaction());
270}
Valerie Hauda3446e2019-10-14 15:49:22 -0700271
Valerie Haubf29e042020-02-06 11:40:38 -0800272TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800273 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
274 sp<IGraphicBufferProducer> igbProducer;
275 setUpProducer(adapter, igbProducer);
276
277 int slot;
278 sp<Fence> fence;
279 sp<GraphicBuffer> buf;
280 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
281 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
282 nullptr, nullptr);
283 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
284 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
285
286 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
287 IGraphicBufferProducer::QueueBufferOutput qbOutput;
288 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, false, HAL_DATASPACE_UNKNOWN,
289 Rect(mDisplayWidth, mDisplayHeight),
290 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
291 Fence::NO_FENCE);
292 igbProducer->queueBuffer(slot, input, &qbOutput);
293 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
294
295 adapter.waitForCallbacks();
296 ASSERT_GE(systemTime(), desiredPresentTime);
297}
298
Valerie Hauda3446e2019-10-14 15:49:22 -0700299TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
300 uint8_t r = 255;
301 uint8_t g = 0;
302 uint8_t b = 0;
303
304 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800305 sp<IGraphicBufferProducer> igbProducer;
306 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700307
308 int slot;
309 sp<Fence> fence;
310 sp<GraphicBuffer> buf;
311 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
312 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
313 nullptr, nullptr);
314 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
315 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
316
317 uint32_t* bufData;
318 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
319 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800320 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700321 buf->unlock();
322
Valerie Haud3b90d22019-11-06 09:37:31 -0800323 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Valerie Hauda3446e2019-10-14 15:49:22 -0700324 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
325 Rect(mDisplayWidth, mDisplayHeight),
326 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
327 Fence::NO_FENCE);
328 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800329 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700330
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800331 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700332
333 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700334 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800335 ASSERT_NO_FATAL_FAILURE(
336 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700337}
Valerie Haud3b90d22019-11-06 09:37:31 -0800338
339TEST_F(BLASTBufferQueueTest, TripleBuffering) {
340 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
341 sp<IGraphicBufferProducer> igbProducer;
342 setUpProducer(adapter, igbProducer);
343
344 std::vector<std::pair<int, sp<Fence>>> allocated;
345 for (int i = 0; i < 3; i++) {
346 int slot;
347 sp<Fence> fence;
348 sp<GraphicBuffer> buf;
349 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
350 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
351 nullptr, nullptr);
352 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
353 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
354 allocated.push_back({slot, fence});
355 }
356 for (int i = 0; i < allocated.size(); i++) {
357 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
358 }
359
Valerie Haua32c5522019-12-09 10:11:08 -0800360 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800361 int slot;
362 sp<Fence> fence;
363 sp<GraphicBuffer> buf;
364 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
365 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
366 nullptr, nullptr);
367 ASSERT_EQ(NO_ERROR, ret);
368 IGraphicBufferProducer::QueueBufferOutput qbOutput;
369 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
370 Rect(mDisplayWidth, mDisplayHeight),
371 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
372 Fence::NO_FENCE);
373 igbProducer->queueBuffer(slot, input, &qbOutput);
374 }
375 adapter.waitForCallbacks();
376}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800377
378TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
379 uint8_t r = 255;
380 uint8_t g = 0;
381 uint8_t b = 0;
382
383 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
384 sp<IGraphicBufferProducer> igbProducer;
385 setUpProducer(adapter, igbProducer);
386 int slot;
387 sp<Fence> fence;
388 sp<GraphicBuffer> buf;
389 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
390 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
391 nullptr, nullptr);
392 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
393 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
394
395 uint32_t* bufData;
396 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
397 reinterpret_cast<void**>(&bufData));
398 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
399 buf->unlock();
400
401 IGraphicBufferProducer::QueueBufferOutput qbOutput;
402 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
403 Rect(mDisplayWidth, mDisplayHeight / 2),
404 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
405 Fence::NO_FENCE);
406 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800407 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800408
409 adapter.waitForCallbacks();
410 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700411 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700412
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800413 ASSERT_NO_FATAL_FAILURE(
414 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
415}
416
417TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
418 uint8_t r = 255;
419 uint8_t g = 0;
420 uint8_t b = 0;
421
422 int32_t bufferSideLength =
423 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
424 int32_t finalCropSideLength = bufferSideLength / 2;
425
426 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800427 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800428 ASSERT_NE(nullptr, bg.get());
429 Transaction t;
430 t.setLayerStack(bg, 0)
431 .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
432 .setColor(bg, half3{0, 0, 0})
433 .setLayer(bg, 0)
434 .apply();
435
436 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
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, bufferSideLength, bufferSideLength,
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()), buf->getStride(), 0, 0, 0);
452 fillBuffer(bufData,
453 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
454 buf->getHeight()),
455 buf->getStride(), r, g, b);
456 buf->unlock();
457
458 IGraphicBufferProducer::QueueBufferOutput qbOutput;
459 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
460 Rect(bufferSideLength, finalCropSideLength),
461 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
462 Fence::NO_FENCE);
463 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800464 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800465
466 adapter.waitForCallbacks();
467 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700468 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700469
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800470 ASSERT_NO_FATAL_FAILURE(
471 checkScreenCapture(r, g, b,
472 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}));
Valerie Hau5977fc82019-12-05 15:56:39 -0800473 ASSERT_NO_FATAL_FAILURE(
474 checkScreenCapture(0, 0, 0,
475 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
476 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800477}
478
Vishnu Nair89496122020-12-14 17:14:53 -0800479class TestProducerListener : public BnProducerListener {
480public:
481 sp<IGraphicBufferProducer> mIgbp;
482 TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
483 void onBufferReleased() override {
484 sp<GraphicBuffer> buffer;
485 sp<Fence> fence;
486 mIgbp->detachNextBuffer(&buffer, &fence);
487 }
488};
489
490TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
491 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
492 sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
493 ASSERT_NE(nullptr, igbProducer.get());
494 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
495 IGraphicBufferProducer::QueueBufferOutput qbOutput;
496 ASSERT_EQ(NO_ERROR,
497 igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
498 false, &qbOutput));
499 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
500 for (int i = 0; i < 3; i++) {
501 int slot;
502 sp<Fence> fence;
503 sp<GraphicBuffer> buf;
504 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
505 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
506 nullptr, nullptr);
507 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
508 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
509 IGraphicBufferProducer::QueueBufferOutput qbOutput;
510 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
511 Rect(mDisplayWidth, mDisplayHeight),
512 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
513 Fence::NO_FENCE);
514 igbProducer->queueBuffer(slot, input, &qbOutput);
515 }
516 adapter.waitForCallbacks();
517}
518
Vishnu Nair17dde612020-12-28 11:39:59 -0800519TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
520 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
521
522 sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
523 ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
524 int queuesToNativeWindow = 0;
525 int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
526 &queuesToNativeWindow);
527 ASSERT_EQ(NO_ERROR, err);
528 ASSERT_EQ(queuesToNativeWindow, 1);
529}
530
Valerie Hau5977fc82019-12-05 15:56:39 -0800531class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
532public:
533 void test(uint32_t tr) {
534 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
535 sp<IGraphicBufferProducer> igbProducer;
536 setUpProducer(adapter, igbProducer);
537
538 auto bufWidth = mDisplayWidth;
539 auto bufHeight = mDisplayHeight;
540 int slot;
541 sp<Fence> fence;
542 sp<GraphicBuffer> buf;
543
544 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
545 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
546 nullptr, nullptr);
547 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
548 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
549
550 fillQuadrants(buf);
551
552 IGraphicBufferProducer::QueueBufferOutput qbOutput;
553 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
554 Rect(bufWidth, bufHeight),
Vishnu Naire1a42322020-10-02 17:42:04 -0700555 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
556 tr, Fence::NO_FENCE);
Valerie Hau5977fc82019-12-05 15:56:39 -0800557 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800558 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800559
560 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700561 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700562
Valerie Hau5977fc82019-12-05 15:56:39 -0800563 switch (tr) {
564 case ui::Transform::ROT_0:
565 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
566 {0, 0, (int32_t)mDisplayWidth / 2,
567 (int32_t)mDisplayHeight / 2},
568 1));
569 ASSERT_NO_FATAL_FAILURE(
570 checkScreenCapture(255, 0, 0,
571 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
572 (int32_t)mDisplayHeight / 2},
573 1));
574 ASSERT_NO_FATAL_FAILURE(
575 checkScreenCapture(0, 255, 0,
576 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
577 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
578 1));
579 ASSERT_NO_FATAL_FAILURE(
580 checkScreenCapture(0, 0, 255,
581 {0, (int32_t)mDisplayHeight / 2,
582 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
583 1));
584 break;
585 case ui::Transform::FLIP_H:
586 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
587 {0, 0, (int32_t)mDisplayWidth / 2,
588 (int32_t)mDisplayHeight / 2},
589 1));
590 ASSERT_NO_FATAL_FAILURE(
591 checkScreenCapture(0, 0, 0,
592 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
593 (int32_t)mDisplayHeight / 2},
594 1));
595 ASSERT_NO_FATAL_FAILURE(
596 checkScreenCapture(0, 0, 255,
597 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
598 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
599 1));
600 ASSERT_NO_FATAL_FAILURE(
601 checkScreenCapture(0, 255, 0,
602 {0, (int32_t)mDisplayHeight / 2,
603 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
604 1));
605 break;
606 case ui::Transform::FLIP_V:
607 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
608 {0, 0, (int32_t)mDisplayWidth / 2,
609 (int32_t)mDisplayHeight / 2},
610 1));
611 ASSERT_NO_FATAL_FAILURE(
612 checkScreenCapture(0, 255, 0,
613 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
614 (int32_t)mDisplayHeight / 2},
615 1));
616 ASSERT_NO_FATAL_FAILURE(
617 checkScreenCapture(255, 0, 0,
618 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
619 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
620 1));
621 ASSERT_NO_FATAL_FAILURE(
622 checkScreenCapture(0, 0, 0,
623 {0, (int32_t)mDisplayHeight / 2,
624 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
625 1));
626 break;
627 case ui::Transform::ROT_90:
628 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
629 {0, 0, (int32_t)mDisplayWidth / 2,
630 (int32_t)mDisplayHeight / 2},
631 1));
632 ASSERT_NO_FATAL_FAILURE(
633 checkScreenCapture(0, 0, 0,
634 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
635 (int32_t)mDisplayHeight / 2},
636 1));
637 ASSERT_NO_FATAL_FAILURE(
638 checkScreenCapture(255, 0, 0,
639 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
640 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
641 1));
642 ASSERT_NO_FATAL_FAILURE(
643 checkScreenCapture(0, 255, 0,
644 {0, (int32_t)mDisplayHeight / 2,
645 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
646 1));
647 break;
648 case ui::Transform::ROT_180:
649 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
650 {0, 0, (int32_t)mDisplayWidth / 2,
651 (int32_t)mDisplayHeight / 2},
652 1));
653 ASSERT_NO_FATAL_FAILURE(
654 checkScreenCapture(0, 0, 255,
655 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
656 (int32_t)mDisplayHeight / 2},
657 1));
658 ASSERT_NO_FATAL_FAILURE(
659 checkScreenCapture(0, 0, 0,
660 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
661 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
662 1));
663 ASSERT_NO_FATAL_FAILURE(
664 checkScreenCapture(255, 0, 0,
665 {0, (int32_t)mDisplayHeight / 2,
666 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
667 1));
668 break;
669 case ui::Transform::ROT_270:
670 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
671 {0, 0, (int32_t)mDisplayWidth / 2,
672 (int32_t)mDisplayHeight / 2},
673 1));
674 ASSERT_NO_FATAL_FAILURE(
675 checkScreenCapture(0, 255, 0,
676 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
677 (int32_t)mDisplayHeight / 2},
678 1));
679 ASSERT_NO_FATAL_FAILURE(
680 checkScreenCapture(0, 0, 255,
681 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
682 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
683 1));
684 ASSERT_NO_FATAL_FAILURE(
685 checkScreenCapture(0, 0, 0,
686 {0, (int32_t)mDisplayHeight / 2,
687 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
688 1));
689 }
690 }
691};
692
693TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
694 test(ui::Transform::ROT_0);
695}
696
697TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
698 test(ui::Transform::FLIP_H);
699}
700
701TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
702 test(ui::Transform::FLIP_V);
703}
704
705TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
706 test(ui::Transform::ROT_90);
707}
708
709TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
710 test(ui::Transform::ROT_180);
711}
712
713TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
714 test(ui::Transform::ROT_270);
715}
Valerie Hau871d6352020-01-29 08:44:02 -0800716
717class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
718public:
719 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
720 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
721 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
722 bool getFrameTimestamps) {
723 int slot;
724 sp<Fence> fence;
725 sp<GraphicBuffer> buf;
726 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
727 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
728 nullptr, nullptr);
729 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
730 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
731
732 nsecs_t requestedTime = systemTime();
733 if (requestedPresentTime) *requestedPresentTime = requestedTime;
734 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
735 Rect(mDisplayWidth, mDisplayHeight),
736 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
737 Fence::NO_FENCE, /*sticky*/ 0,
738 getFrameTimestamps);
739 if (postedTime) *postedTime = systemTime();
740 igbProducer->queueBuffer(slot, input, qbOutput);
741 }
742};
743
744TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
745 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
746 sp<IGraphicBufferProducer> igbProducer;
747 ProducerFrameEventHistory history;
748 setUpProducer(adapter, igbProducer);
749
750 IGraphicBufferProducer::QueueBufferOutput qbOutput;
751 nsecs_t requestedPresentTimeA = 0;
752 nsecs_t postedTimeA = 0;
753 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
754 history.applyDelta(qbOutput.frameTimestamps);
755
756 FrameEvents* events = nullptr;
757 events = history.getFrame(1);
758 ASSERT_NE(nullptr, events);
759 ASSERT_EQ(1, events->frameNumber);
760 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
761 ASSERT_GE(events->postedTime, postedTimeA);
762
763 adapter.waitForCallbacks();
764
765 // queue another buffer so we query for frame event deltas
766 nsecs_t requestedPresentTimeB = 0;
767 nsecs_t postedTimeB = 0;
768 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
769 history.applyDelta(qbOutput.frameTimestamps);
770 events = history.getFrame(1);
771 ASSERT_NE(nullptr, events);
772
773 // frame number, requestedPresentTime, and postTime should not have changed
774 ASSERT_EQ(1, events->frameNumber);
775 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
776 ASSERT_GE(events->postedTime, postedTimeA);
777
778 ASSERT_GE(events->latchTime, postedTimeA);
779 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
780 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
781 ASSERT_NE(nullptr, events->displayPresentFence);
782 ASSERT_NE(nullptr, events->releaseFence);
783
784 // we should also have gotten the initial values for the next frame
785 events = history.getFrame(2);
786 ASSERT_NE(nullptr, events);
787 ASSERT_EQ(2, events->frameNumber);
788 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
789 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -0700790
791 // wait for any callbacks that have not been received
792 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -0800793}
Valerie Hauc5011f92019-10-11 09:52:07 -0700794} // namespace android