blob: da5bbdd2e6ea2e927e1b312fbf4f13401af8f545 [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>
Valerie Hauc5011f92019-10-11 09:52:07 -070027#include <gui/SurfaceComposerClient.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070028#include <private/gui/ComposerService.h>
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080029#include <ui/DisplayConfig.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070030#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070031#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080032#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070033
34#include <gtest/gtest.h>
35
36using namespace std::chrono_literals;
37
38namespace android {
39
Valerie Hauc5011f92019-10-11 09:52:07 -070040using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070041using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070042
43class BLASTBufferQueueHelper {
44public:
45 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
46 mBlastBufferQueueAdapter = new BLASTBufferQueue(sc, width, height);
47 }
48
49 void update(const sp<SurfaceControl>& sc, int width, int height) {
50 mBlastBufferQueueAdapter->update(sc, width, height);
51 }
52
53 void setNextTransaction(Transaction* next) {
54 mBlastBufferQueueAdapter->setNextTransaction(next);
55 }
56
57 int getWidth() { return mBlastBufferQueueAdapter->mWidth; }
Valerie Hauda3446e2019-10-14 15:49:22 -070058
Valerie Hauc5011f92019-10-11 09:52:07 -070059 int getHeight() { return mBlastBufferQueueAdapter->mHeight; }
Valerie Hauda3446e2019-10-14 15:49:22 -070060
Valerie Hauc5011f92019-10-11 09:52:07 -070061 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -070062
63 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
64 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
65 }
66
Valerie Hauc5011f92019-10-11 09:52:07 -070067 const sp<SurfaceControl> getSurfaceControl() {
68 return mBlastBufferQueueAdapter->mSurfaceControl;
69 }
70
Valerie Haud3b90d22019-11-06 09:37:31 -080071 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -070072 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Valerie Haua32c5522019-12-09 10:11:08 -080073 while (mBlastBufferQueueAdapter->mSubmitted.size() > 0) {
Valerie Haud3b90d22019-11-06 09:37:31 -080074 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
75 }
Valerie Hauda3446e2019-10-14 15:49:22 -070076 }
77
Valerie Hauc5011f92019-10-11 09:52:07 -070078private:
79 sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
80};
81
82class BLASTBufferQueueTest : public ::testing::Test {
83public:
84protected:
85 BLASTBufferQueueTest() {
86 const ::testing::TestInfo* const testInfo =
87 ::testing::UnitTest::GetInstance()->current_test_info();
88 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
89 }
90
91 ~BLASTBufferQueueTest() {
92 const ::testing::TestInfo* const testInfo =
93 ::testing::UnitTest::GetInstance()->current_test_info();
94 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
95 }
96
97 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -070098 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -070099 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -0700100 mDisplayToken = mClient->getInternalDisplayToken();
101 ASSERT_NE(nullptr, mDisplayToken.get());
102 Transaction t;
103 t.setDisplayLayerStack(mDisplayToken, 0);
104 t.apply();
105 t.clear();
106
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800107 DisplayConfig config;
108 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(mDisplayToken, &config));
109 const ui::Size& resolution = config.resolution;
110 mDisplayWidth = resolution.getWidth();
111 mDisplayHeight = resolution.getHeight();
Valerie Hauda3446e2019-10-14 15:49:22 -0700112
113 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
114 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
115 ISurfaceComposerClient::eFXSurfaceBufferState,
116 /*parent*/ nullptr);
117 t.setLayerStack(mSurfaceControl, 0)
118 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -0800119 .setFrame(mSurfaceControl, Rect(resolution))
Valerie Hauda3446e2019-10-14 15:49:22 -0700120 .show(mSurfaceControl)
121 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
122 .apply();
123 }
124
Valerie Haud3b90d22019-11-06 09:37:31 -0800125 void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
126 auto igbProducer = adapter.getIGraphicBufferProducer();
127 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800128 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800129 IGraphicBufferProducer::QueueBufferOutput qbOutput;
130 ASSERT_EQ(NO_ERROR,
Peiyong Lind8460c82020-07-28 16:04:22 -0700131 igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
Valerie Haud3b90d22019-11-06 09:37:31 -0800132 &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800133 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800134 producer = igbProducer;
135 }
136
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800137 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
138 uint8_t b) {
139 for (uint32_t row = rect.top; row < rect.bottom; row++) {
140 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700141 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
142 *pixel = r;
143 *(pixel + 1) = g;
144 *(pixel + 2) = b;
145 *(pixel + 3) = 255;
146 }
147 }
148 }
149
Valerie Hau5977fc82019-12-05 15:56:39 -0800150 void fillQuadrants(sp<GraphicBuffer>& buf) {
151 const auto bufWidth = buf->getWidth();
152 const auto bufHeight = buf->getHeight();
153 uint32_t* bufData;
154 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
155 reinterpret_cast<void**>(&bufData));
156 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
157 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
158 0, 0);
159 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
160 buf->getStride(), 0, 255, 0);
161 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
162 255);
163 buf->unlock();
164 }
165
166 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
167 bool outsideRegion = false) {
168 const auto epsilon = 3;
Valerie Hauda3446e2019-10-14 15:49:22 -0700169 const auto width = mScreenCaptureBuf->getWidth();
170 const auto height = mScreenCaptureBuf->getHeight();
171 const auto stride = mScreenCaptureBuf->getStride();
172
173 uint32_t* bufData;
174 mScreenCaptureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
175 reinterpret_cast<void**>(&bufData));
176
177 for (uint32_t row = 0; row < height; row++) {
178 for (uint32_t col = 0; col < width; col++) {
179 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
Valerie Hau5977fc82019-12-05 15:56:39 -0800180 bool inRegion;
181 if (!outsideRegion) {
182 inRegion = row >= region.top + border && row < region.bottom - border &&
183 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800184 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800185 inRegion = row >= region.top - border && row < region.bottom + border &&
186 col >= region.left - border && col < region.right + border;
187 }
188 if (!outsideRegion && inRegion) {
189 EXPECT_GE(epsilon, abs(r - *(pixel)));
190 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
191 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
192 } else if (outsideRegion && !inRegion) {
193 EXPECT_GE(epsilon, abs(r - *(pixel)));
194 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
195 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800196 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700197 }
198 }
199 mScreenCaptureBuf->unlock();
200 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauc5011f92019-10-11 09:52:07 -0700201 }
202
203 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700204 sp<ISurfaceComposer> mComposer;
205
206 sp<IBinder> mDisplayToken;
207
Valerie Hauc5011f92019-10-11 09:52:07 -0700208 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700209 sp<GraphicBuffer> mScreenCaptureBuf;
210
211 uint32_t mDisplayWidth;
212 uint32_t mDisplayHeight;
Valerie Hauc5011f92019-10-11 09:52:07 -0700213};
214
215TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
216 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700217 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700218 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700219 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
220 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700221 ASSERT_EQ(nullptr, adapter.getNextTransaction());
222}
223
224TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700225 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700226 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700227 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
228 PIXEL_FORMAT_RGBA_8888);
229 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700230 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700231 ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth());
232 ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700233}
234
235TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700236 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700237 Transaction next;
238 adapter.setNextTransaction(&next);
239 ASSERT_EQ(&next, adapter.getNextTransaction());
240}
Valerie Hauda3446e2019-10-14 15:49:22 -0700241
Valerie Haubf29e042020-02-06 11:40:38 -0800242TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800243 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
244 sp<IGraphicBufferProducer> igbProducer;
245 setUpProducer(adapter, igbProducer);
246
247 int slot;
248 sp<Fence> fence;
249 sp<GraphicBuffer> buf;
250 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
251 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
252 nullptr, nullptr);
253 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
254 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
255
256 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
257 IGraphicBufferProducer::QueueBufferOutput qbOutput;
258 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, false, HAL_DATASPACE_UNKNOWN,
259 Rect(mDisplayWidth, mDisplayHeight),
260 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
261 Fence::NO_FENCE);
262 igbProducer->queueBuffer(slot, input, &qbOutput);
263 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
264
265 adapter.waitForCallbacks();
266 ASSERT_GE(systemTime(), desiredPresentTime);
267}
268
Valerie Hauda3446e2019-10-14 15:49:22 -0700269TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
270 uint8_t r = 255;
271 uint8_t g = 0;
272 uint8_t b = 0;
273
274 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800275 sp<IGraphicBufferProducer> igbProducer;
276 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700277
278 int slot;
279 sp<Fence> fence;
280 sp<GraphicBuffer> buf;
281 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
282 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
283 nullptr, nullptr);
284 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
285 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
286
287 uint32_t* bufData;
288 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
289 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800290 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700291 buf->unlock();
292
Valerie Haud3b90d22019-11-06 09:37:31 -0800293 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Valerie Hauda3446e2019-10-14 15:49:22 -0700294 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
295 Rect(mDisplayWidth, mDisplayHeight),
296 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
297 Fence::NO_FENCE);
298 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800299 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700300
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800301 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700302
303 // capture screen and verify that it is red
304 bool capturedSecureLayers;
305 ASSERT_EQ(NO_ERROR,
306 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
307 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
308 mDisplayWidth, mDisplayHeight,
309 /*useIdentityTransform*/ false));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800310 ASSERT_NO_FATAL_FAILURE(
311 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700312}
Valerie Haud3b90d22019-11-06 09:37:31 -0800313
314TEST_F(BLASTBufferQueueTest, TripleBuffering) {
315 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
316 sp<IGraphicBufferProducer> igbProducer;
317 setUpProducer(adapter, igbProducer);
318
319 std::vector<std::pair<int, sp<Fence>>> allocated;
320 for (int i = 0; i < 3; i++) {
321 int slot;
322 sp<Fence> fence;
323 sp<GraphicBuffer> buf;
324 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
325 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
326 nullptr, nullptr);
327 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
328 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
329 allocated.push_back({slot, fence});
330 }
331 for (int i = 0; i < allocated.size(); i++) {
332 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
333 }
334
Valerie Haua32c5522019-12-09 10:11:08 -0800335 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800336 int slot;
337 sp<Fence> fence;
338 sp<GraphicBuffer> buf;
339 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
340 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
341 nullptr, nullptr);
342 ASSERT_EQ(NO_ERROR, ret);
343 IGraphicBufferProducer::QueueBufferOutput qbOutput;
344 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
345 Rect(mDisplayWidth, mDisplayHeight),
346 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
347 Fence::NO_FENCE);
348 igbProducer->queueBuffer(slot, input, &qbOutput);
349 }
350 adapter.waitForCallbacks();
351}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800352
353TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
354 uint8_t r = 255;
355 uint8_t g = 0;
356 uint8_t b = 0;
357
358 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
359 sp<IGraphicBufferProducer> igbProducer;
360 setUpProducer(adapter, igbProducer);
361 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(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
368 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
369
370 uint32_t* bufData;
371 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
372 reinterpret_cast<void**>(&bufData));
373 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
374 buf->unlock();
375
376 IGraphicBufferProducer::QueueBufferOutput qbOutput;
377 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
378 Rect(mDisplayWidth, mDisplayHeight / 2),
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 Hau45e4b3b2019-12-03 10:49:17 -0800383
384 adapter.waitForCallbacks();
385 // capture screen and verify that it is red
386 bool capturedSecureLayers;
387 ASSERT_EQ(NO_ERROR,
388 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
389 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
390 mDisplayWidth, mDisplayHeight,
391 /*useIdentityTransform*/ false));
392 ASSERT_NO_FATAL_FAILURE(
393 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
394}
395
396TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
397 uint8_t r = 255;
398 uint8_t g = 0;
399 uint8_t b = 0;
400
401 int32_t bufferSideLength =
402 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
403 int32_t finalCropSideLength = bufferSideLength / 2;
404
405 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800406 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800407 ASSERT_NE(nullptr, bg.get());
408 Transaction t;
409 t.setLayerStack(bg, 0)
410 .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
411 .setColor(bg, half3{0, 0, 0})
412 .setLayer(bg, 0)
413 .apply();
414
415 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
416 sp<IGraphicBufferProducer> igbProducer;
417 setUpProducer(adapter, igbProducer);
418 int slot;
419 sp<Fence> fence;
420 sp<GraphicBuffer> buf;
421 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
422 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
423 nullptr, nullptr);
424 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
425 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
426
427 uint32_t* bufData;
428 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
429 reinterpret_cast<void**>(&bufData));
430 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
431 fillBuffer(bufData,
432 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
433 buf->getHeight()),
434 buf->getStride(), r, g, b);
435 buf->unlock();
436
437 IGraphicBufferProducer::QueueBufferOutput qbOutput;
438 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
439 Rect(bufferSideLength, finalCropSideLength),
440 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
441 Fence::NO_FENCE);
442 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800443 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800444
445 adapter.waitForCallbacks();
446 // capture screen and verify that it is red
447 bool capturedSecureLayers;
448 ASSERT_EQ(NO_ERROR,
449 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
450 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
451 mDisplayWidth, mDisplayHeight,
452 /*useIdentityTransform*/ false));
453 ASSERT_NO_FATAL_FAILURE(
454 checkScreenCapture(r, g, b,
455 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}));
Valerie Hau5977fc82019-12-05 15:56:39 -0800456 ASSERT_NO_FATAL_FAILURE(
457 checkScreenCapture(0, 0, 0,
458 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
459 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800460}
461
Valerie Hau5977fc82019-12-05 15:56:39 -0800462class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
463public:
464 void test(uint32_t tr) {
465 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
466 sp<IGraphicBufferProducer> igbProducer;
467 setUpProducer(adapter, igbProducer);
468
469 auto bufWidth = mDisplayWidth;
470 auto bufHeight = mDisplayHeight;
471 int slot;
472 sp<Fence> fence;
473 sp<GraphicBuffer> buf;
474
475 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
476 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
477 nullptr, nullptr);
478 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
479 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
480
481 fillQuadrants(buf);
482
483 IGraphicBufferProducer::QueueBufferOutput qbOutput;
484 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
485 Rect(bufWidth, bufHeight),
486 NATIVE_WINDOW_SCALING_MODE_FREEZE, tr,
487 Fence::NO_FENCE);
488 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800489 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800490
491 adapter.waitForCallbacks();
492 bool capturedSecureLayers;
493 ASSERT_EQ(NO_ERROR,
494 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
495 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
496 Rect(), mDisplayWidth, mDisplayHeight,
497 /*useIdentityTransform*/ false));
498 switch (tr) {
499 case ui::Transform::ROT_0:
500 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
501 {0, 0, (int32_t)mDisplayWidth / 2,
502 (int32_t)mDisplayHeight / 2},
503 1));
504 ASSERT_NO_FATAL_FAILURE(
505 checkScreenCapture(255, 0, 0,
506 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
507 (int32_t)mDisplayHeight / 2},
508 1));
509 ASSERT_NO_FATAL_FAILURE(
510 checkScreenCapture(0, 255, 0,
511 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
512 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
513 1));
514 ASSERT_NO_FATAL_FAILURE(
515 checkScreenCapture(0, 0, 255,
516 {0, (int32_t)mDisplayHeight / 2,
517 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
518 1));
519 break;
520 case ui::Transform::FLIP_H:
521 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
522 {0, 0, (int32_t)mDisplayWidth / 2,
523 (int32_t)mDisplayHeight / 2},
524 1));
525 ASSERT_NO_FATAL_FAILURE(
526 checkScreenCapture(0, 0, 0,
527 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
528 (int32_t)mDisplayHeight / 2},
529 1));
530 ASSERT_NO_FATAL_FAILURE(
531 checkScreenCapture(0, 0, 255,
532 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
533 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
534 1));
535 ASSERT_NO_FATAL_FAILURE(
536 checkScreenCapture(0, 255, 0,
537 {0, (int32_t)mDisplayHeight / 2,
538 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
539 1));
540 break;
541 case ui::Transform::FLIP_V:
542 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
543 {0, 0, (int32_t)mDisplayWidth / 2,
544 (int32_t)mDisplayHeight / 2},
545 1));
546 ASSERT_NO_FATAL_FAILURE(
547 checkScreenCapture(0, 255, 0,
548 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
549 (int32_t)mDisplayHeight / 2},
550 1));
551 ASSERT_NO_FATAL_FAILURE(
552 checkScreenCapture(255, 0, 0,
553 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
554 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
555 1));
556 ASSERT_NO_FATAL_FAILURE(
557 checkScreenCapture(0, 0, 0,
558 {0, (int32_t)mDisplayHeight / 2,
559 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
560 1));
561 break;
562 case ui::Transform::ROT_90:
563 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
564 {0, 0, (int32_t)mDisplayWidth / 2,
565 (int32_t)mDisplayHeight / 2},
566 1));
567 ASSERT_NO_FATAL_FAILURE(
568 checkScreenCapture(0, 0, 0,
569 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
570 (int32_t)mDisplayHeight / 2},
571 1));
572 ASSERT_NO_FATAL_FAILURE(
573 checkScreenCapture(255, 0, 0,
574 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
575 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
576 1));
577 ASSERT_NO_FATAL_FAILURE(
578 checkScreenCapture(0, 255, 0,
579 {0, (int32_t)mDisplayHeight / 2,
580 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
581 1));
582 break;
583 case ui::Transform::ROT_180:
584 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
585 {0, 0, (int32_t)mDisplayWidth / 2,
586 (int32_t)mDisplayHeight / 2},
587 1));
588 ASSERT_NO_FATAL_FAILURE(
589 checkScreenCapture(0, 0, 255,
590 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
591 (int32_t)mDisplayHeight / 2},
592 1));
593 ASSERT_NO_FATAL_FAILURE(
594 checkScreenCapture(0, 0, 0,
595 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
596 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
597 1));
598 ASSERT_NO_FATAL_FAILURE(
599 checkScreenCapture(255, 0, 0,
600 {0, (int32_t)mDisplayHeight / 2,
601 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
602 1));
603 break;
604 case ui::Transform::ROT_270:
605 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
606 {0, 0, (int32_t)mDisplayWidth / 2,
607 (int32_t)mDisplayHeight / 2},
608 1));
609 ASSERT_NO_FATAL_FAILURE(
610 checkScreenCapture(0, 255, 0,
611 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
612 (int32_t)mDisplayHeight / 2},
613 1));
614 ASSERT_NO_FATAL_FAILURE(
615 checkScreenCapture(0, 0, 255,
616 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
617 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
618 1));
619 ASSERT_NO_FATAL_FAILURE(
620 checkScreenCapture(0, 0, 0,
621 {0, (int32_t)mDisplayHeight / 2,
622 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
623 1));
624 }
625 }
626};
627
628TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
629 test(ui::Transform::ROT_0);
630}
631
632TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
633 test(ui::Transform::FLIP_H);
634}
635
636TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
637 test(ui::Transform::FLIP_V);
638}
639
640TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
641 test(ui::Transform::ROT_90);
642}
643
644TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
645 test(ui::Transform::ROT_180);
646}
647
648TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
649 test(ui::Transform::ROT_270);
650}
Valerie Hau871d6352020-01-29 08:44:02 -0800651
652class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
653public:
654 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
655 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
656 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
657 bool getFrameTimestamps) {
658 int slot;
659 sp<Fence> fence;
660 sp<GraphicBuffer> buf;
661 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
662 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
663 nullptr, nullptr);
664 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
665 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
666
667 nsecs_t requestedTime = systemTime();
668 if (requestedPresentTime) *requestedPresentTime = requestedTime;
669 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
670 Rect(mDisplayWidth, mDisplayHeight),
671 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
672 Fence::NO_FENCE, /*sticky*/ 0,
673 getFrameTimestamps);
674 if (postedTime) *postedTime = systemTime();
675 igbProducer->queueBuffer(slot, input, qbOutput);
676 }
677};
678
679TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
680 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
681 sp<IGraphicBufferProducer> igbProducer;
682 ProducerFrameEventHistory history;
683 setUpProducer(adapter, igbProducer);
684
685 IGraphicBufferProducer::QueueBufferOutput qbOutput;
686 nsecs_t requestedPresentTimeA = 0;
687 nsecs_t postedTimeA = 0;
688 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
689 history.applyDelta(qbOutput.frameTimestamps);
690
691 FrameEvents* events = nullptr;
692 events = history.getFrame(1);
693 ASSERT_NE(nullptr, events);
694 ASSERT_EQ(1, events->frameNumber);
695 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
696 ASSERT_GE(events->postedTime, postedTimeA);
697
698 adapter.waitForCallbacks();
699
700 // queue another buffer so we query for frame event deltas
701 nsecs_t requestedPresentTimeB = 0;
702 nsecs_t postedTimeB = 0;
703 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
704 history.applyDelta(qbOutput.frameTimestamps);
705 events = history.getFrame(1);
706 ASSERT_NE(nullptr, events);
707
708 // frame number, requestedPresentTime, and postTime should not have changed
709 ASSERT_EQ(1, events->frameNumber);
710 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
711 ASSERT_GE(events->postedTime, postedTimeA);
712
713 ASSERT_GE(events->latchTime, postedTimeA);
714 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
715 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
716 ASSERT_NE(nullptr, events->displayPresentFence);
717 ASSERT_NE(nullptr, events->releaseFence);
718
719 // we should also have gotten the initial values for the next frame
720 events = history.getFrame(2);
721 ASSERT_NE(nullptr, events);
722 ASSERT_EQ(2, events->frameNumber);
723 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
724 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -0700725
726 // wait for any callbacks that have not been received
727 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -0800728}
Valerie Hauc5011f92019-10-11 09:52:07 -0700729} // namespace android