blob: 4a186b1e97dcb33776b12e109803cdcdae194853 [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();
chaviwd2432892020-07-24 17:42:39 -0700123
124 mCaptureArgs.displayToken = mDisplayToken;
Valerie Hauda3446e2019-10-14 15:49:22 -0700125 }
126
Valerie Haud3b90d22019-11-06 09:37:31 -0800127 void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
128 auto igbProducer = adapter.getIGraphicBufferProducer();
129 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800130 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800131 IGraphicBufferProducer::QueueBufferOutput qbOutput;
132 ASSERT_EQ(NO_ERROR,
Peiyong Lind8460c82020-07-28 16:04:22 -0700133 igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false,
Valerie Haud3b90d22019-11-06 09:37:31 -0800134 &qbOutput));
Dominik Laskowski718f9602019-11-09 20:01:35 -0800135 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Haud3b90d22019-11-06 09:37:31 -0800136 producer = igbProducer;
137 }
138
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800139 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
140 uint8_t b) {
141 for (uint32_t row = rect.top; row < rect.bottom; row++) {
142 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700143 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
144 *pixel = r;
145 *(pixel + 1) = g;
146 *(pixel + 2) = b;
147 *(pixel + 3) = 255;
148 }
149 }
150 }
151
Valerie Hau5977fc82019-12-05 15:56:39 -0800152 void fillQuadrants(sp<GraphicBuffer>& buf) {
153 const auto bufWidth = buf->getWidth();
154 const auto bufHeight = buf->getHeight();
155 uint32_t* bufData;
156 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
157 reinterpret_cast<void**>(&bufData));
158 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
159 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
160 0, 0);
161 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
162 buf->getStride(), 0, 255, 0);
163 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
164 255);
165 buf->unlock();
166 }
167
168 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
169 bool outsideRegion = false) {
chaviwd2432892020-07-24 17:42:39 -0700170 sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
Valerie Hau5977fc82019-12-05 15:56:39 -0800171 const auto epsilon = 3;
chaviwd2432892020-07-24 17:42:39 -0700172 const auto width = captureBuf->getWidth();
173 const auto height = captureBuf->getHeight();
174 const auto stride = captureBuf->getStride();
Valerie Hauda3446e2019-10-14 15:49:22 -0700175
176 uint32_t* bufData;
chaviwd2432892020-07-24 17:42:39 -0700177 captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
178 reinterpret_cast<void**>(&bufData));
Valerie Hauda3446e2019-10-14 15:49:22 -0700179
180 for (uint32_t row = 0; row < height; row++) {
181 for (uint32_t col = 0; col < width; col++) {
182 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
Valerie Hau5977fc82019-12-05 15:56:39 -0800183 bool inRegion;
184 if (!outsideRegion) {
185 inRegion = row >= region.top + border && row < region.bottom - border &&
186 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800187 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800188 inRegion = row >= region.top - border && row < region.bottom + border &&
189 col >= region.left - border && col < region.right + border;
190 }
191 if (!outsideRegion && inRegion) {
192 EXPECT_GE(epsilon, abs(r - *(pixel)));
193 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
194 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
195 } else 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)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800199 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700200 }
201 }
chaviwd2432892020-07-24 17:42:39 -0700202 captureBuf->unlock();
Valerie Hauda3446e2019-10-14 15:49:22 -0700203 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauc5011f92019-10-11 09:52:07 -0700204 }
205
chaviw8ffc7b82020-08-18 11:25:37 -0700206 static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
207 ScreenCaptureResults& captureResults) {
208 const auto sf = ComposerService::getComposerService();
209 SurfaceComposerClient::Transaction().apply(true);
210
211 const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
212 status_t status = sf->captureDisplay(captureArgs, captureListener);
213 if (status != NO_ERROR) {
214 return status;
215 }
216 captureResults = captureListener->waitForResults();
217 return captureResults.result;
218 }
219
Valerie Hauc5011f92019-10-11 09:52:07 -0700220 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700221 sp<ISurfaceComposer> mComposer;
222
223 sp<IBinder> mDisplayToken;
224
Valerie Hauc5011f92019-10-11 09:52:07 -0700225 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700226
227 uint32_t mDisplayWidth;
228 uint32_t mDisplayHeight;
chaviwd2432892020-07-24 17:42:39 -0700229
230 DisplayCaptureArgs mCaptureArgs;
231 ScreenCaptureResults mCaptureResults;
Valerie Hauc5011f92019-10-11 09:52:07 -0700232};
233
234TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
235 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700236 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700237 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700238 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
239 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700240 ASSERT_EQ(nullptr, adapter.getNextTransaction());
241}
242
243TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700244 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700245 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700246 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
247 PIXEL_FORMAT_RGBA_8888);
248 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700249 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700250 ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth());
251 ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700252}
253
254TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700255 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700256 Transaction next;
257 adapter.setNextTransaction(&next);
258 ASSERT_EQ(&next, adapter.getNextTransaction());
259}
Valerie Hauda3446e2019-10-14 15:49:22 -0700260
Valerie Haubf29e042020-02-06 11:40:38 -0800261TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
Valerie Hau181abd32020-01-27 14:18:28 -0800262 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
263 sp<IGraphicBufferProducer> igbProducer;
264 setUpProducer(adapter, igbProducer);
265
266 int slot;
267 sp<Fence> fence;
268 sp<GraphicBuffer> buf;
269 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
270 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
271 nullptr, nullptr);
272 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
273 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
274
275 nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
276 IGraphicBufferProducer::QueueBufferOutput qbOutput;
277 IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, false, HAL_DATASPACE_UNKNOWN,
278 Rect(mDisplayWidth, mDisplayHeight),
279 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
280 Fence::NO_FENCE);
281 igbProducer->queueBuffer(slot, input, &qbOutput);
282 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
283
284 adapter.waitForCallbacks();
285 ASSERT_GE(systemTime(), desiredPresentTime);
286}
287
Valerie Hauda3446e2019-10-14 15:49:22 -0700288TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
289 uint8_t r = 255;
290 uint8_t g = 0;
291 uint8_t b = 0;
292
293 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800294 sp<IGraphicBufferProducer> igbProducer;
295 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700296
297 int slot;
298 sp<Fence> fence;
299 sp<GraphicBuffer> buf;
300 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
301 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
302 nullptr, nullptr);
303 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
304 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
305
306 uint32_t* bufData;
307 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
308 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800309 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700310 buf->unlock();
311
Valerie Haud3b90d22019-11-06 09:37:31 -0800312 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Valerie Hauda3446e2019-10-14 15:49:22 -0700313 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
314 Rect(mDisplayWidth, mDisplayHeight),
315 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
316 Fence::NO_FENCE);
317 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800318 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700319
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800320 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700321
322 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700323 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800324 ASSERT_NO_FATAL_FAILURE(
325 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700326}
Valerie Haud3b90d22019-11-06 09:37:31 -0800327
328TEST_F(BLASTBufferQueueTest, TripleBuffering) {
329 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
330 sp<IGraphicBufferProducer> igbProducer;
331 setUpProducer(adapter, igbProducer);
332
333 std::vector<std::pair<int, sp<Fence>>> allocated;
334 for (int i = 0; i < 3; i++) {
335 int slot;
336 sp<Fence> fence;
337 sp<GraphicBuffer> buf;
338 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
339 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
340 nullptr, nullptr);
341 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
342 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
343 allocated.push_back({slot, fence});
344 }
345 for (int i = 0; i < allocated.size(); i++) {
346 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
347 }
348
Valerie Haua32c5522019-12-09 10:11:08 -0800349 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800350 int slot;
351 sp<Fence> fence;
352 sp<GraphicBuffer> buf;
353 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
354 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
355 nullptr, nullptr);
356 ASSERT_EQ(NO_ERROR, ret);
357 IGraphicBufferProducer::QueueBufferOutput qbOutput;
358 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
359 Rect(mDisplayWidth, mDisplayHeight),
360 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
361 Fence::NO_FENCE);
362 igbProducer->queueBuffer(slot, input, &qbOutput);
363 }
364 adapter.waitForCallbacks();
365}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800366
367TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
368 uint8_t r = 255;
369 uint8_t g = 0;
370 uint8_t b = 0;
371
372 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
373 sp<IGraphicBufferProducer> igbProducer;
374 setUpProducer(adapter, igbProducer);
375 int slot;
376 sp<Fence> fence;
377 sp<GraphicBuffer> buf;
378 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
379 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
380 nullptr, nullptr);
381 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
382 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
383
384 uint32_t* bufData;
385 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
386 reinterpret_cast<void**>(&bufData));
387 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
388 buf->unlock();
389
390 IGraphicBufferProducer::QueueBufferOutput qbOutput;
391 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
392 Rect(mDisplayWidth, mDisplayHeight / 2),
393 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
394 Fence::NO_FENCE);
395 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800396 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800397
398 adapter.waitForCallbacks();
399 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700400 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700401
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800402 ASSERT_NO_FATAL_FAILURE(
403 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
404}
405
406TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
407 uint8_t r = 255;
408 uint8_t g = 0;
409 uint8_t b = 0;
410
411 int32_t bufferSideLength =
412 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
413 int32_t finalCropSideLength = bufferSideLength / 2;
414
415 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800416 ISurfaceComposerClient::eFXSurfaceEffect);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800417 ASSERT_NE(nullptr, bg.get());
418 Transaction t;
419 t.setLayerStack(bg, 0)
420 .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
421 .setColor(bg, half3{0, 0, 0})
422 .setLayer(bg, 0)
423 .apply();
424
425 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
426 sp<IGraphicBufferProducer> igbProducer;
427 setUpProducer(adapter, igbProducer);
428 int slot;
429 sp<Fence> fence;
430 sp<GraphicBuffer> buf;
431 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
432 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
433 nullptr, nullptr);
434 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
435 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
436
437 uint32_t* bufData;
438 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
439 reinterpret_cast<void**>(&bufData));
440 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
441 fillBuffer(bufData,
442 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
443 buf->getHeight()),
444 buf->getStride(), r, g, b);
445 buf->unlock();
446
447 IGraphicBufferProducer::QueueBufferOutput qbOutput;
448 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
449 Rect(bufferSideLength, finalCropSideLength),
450 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
451 Fence::NO_FENCE);
452 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800453 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800454
455 adapter.waitForCallbacks();
456 // capture screen and verify that it is red
chaviw8ffc7b82020-08-18 11:25:37 -0700457 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700458
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800459 ASSERT_NO_FATAL_FAILURE(
460 checkScreenCapture(r, g, b,
461 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}));
Valerie Hau5977fc82019-12-05 15:56:39 -0800462 ASSERT_NO_FATAL_FAILURE(
463 checkScreenCapture(0, 0, 0,
464 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
465 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800466}
467
Valerie Hau5977fc82019-12-05 15:56:39 -0800468class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
469public:
470 void test(uint32_t tr) {
471 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
472 sp<IGraphicBufferProducer> igbProducer;
473 setUpProducer(adapter, igbProducer);
474
475 auto bufWidth = mDisplayWidth;
476 auto bufHeight = mDisplayHeight;
477 int slot;
478 sp<Fence> fence;
479 sp<GraphicBuffer> buf;
480
481 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
482 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
483 nullptr, nullptr);
484 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
485 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
486
487 fillQuadrants(buf);
488
489 IGraphicBufferProducer::QueueBufferOutput qbOutput;
490 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
491 Rect(bufWidth, bufHeight),
492 NATIVE_WINDOW_SCALING_MODE_FREEZE, tr,
493 Fence::NO_FENCE);
494 igbProducer->queueBuffer(slot, input, &qbOutput);
Dominik Laskowski718f9602019-11-09 20:01:35 -0800495 ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
Valerie Hau5977fc82019-12-05 15:56:39 -0800496
497 adapter.waitForCallbacks();
chaviw8ffc7b82020-08-18 11:25:37 -0700498 ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
chaviwd2432892020-07-24 17:42:39 -0700499
Valerie Hau5977fc82019-12-05 15:56:39 -0800500 switch (tr) {
501 case ui::Transform::ROT_0:
502 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
503 {0, 0, (int32_t)mDisplayWidth / 2,
504 (int32_t)mDisplayHeight / 2},
505 1));
506 ASSERT_NO_FATAL_FAILURE(
507 checkScreenCapture(255, 0, 0,
508 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
509 (int32_t)mDisplayHeight / 2},
510 1));
511 ASSERT_NO_FATAL_FAILURE(
512 checkScreenCapture(0, 255, 0,
513 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
514 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
515 1));
516 ASSERT_NO_FATAL_FAILURE(
517 checkScreenCapture(0, 0, 255,
518 {0, (int32_t)mDisplayHeight / 2,
519 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
520 1));
521 break;
522 case ui::Transform::FLIP_H:
523 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
524 {0, 0, (int32_t)mDisplayWidth / 2,
525 (int32_t)mDisplayHeight / 2},
526 1));
527 ASSERT_NO_FATAL_FAILURE(
528 checkScreenCapture(0, 0, 0,
529 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
530 (int32_t)mDisplayHeight / 2},
531 1));
532 ASSERT_NO_FATAL_FAILURE(
533 checkScreenCapture(0, 0, 255,
534 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
535 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
536 1));
537 ASSERT_NO_FATAL_FAILURE(
538 checkScreenCapture(0, 255, 0,
539 {0, (int32_t)mDisplayHeight / 2,
540 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
541 1));
542 break;
543 case ui::Transform::FLIP_V:
544 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
545 {0, 0, (int32_t)mDisplayWidth / 2,
546 (int32_t)mDisplayHeight / 2},
547 1));
548 ASSERT_NO_FATAL_FAILURE(
549 checkScreenCapture(0, 255, 0,
550 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
551 (int32_t)mDisplayHeight / 2},
552 1));
553 ASSERT_NO_FATAL_FAILURE(
554 checkScreenCapture(255, 0, 0,
555 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
556 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
557 1));
558 ASSERT_NO_FATAL_FAILURE(
559 checkScreenCapture(0, 0, 0,
560 {0, (int32_t)mDisplayHeight / 2,
561 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
562 1));
563 break;
564 case ui::Transform::ROT_90:
565 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
566 {0, 0, (int32_t)mDisplayWidth / 2,
567 (int32_t)mDisplayHeight / 2},
568 1));
569 ASSERT_NO_FATAL_FAILURE(
570 checkScreenCapture(0, 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(255, 0, 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, 255, 0,
581 {0, (int32_t)mDisplayHeight / 2,
582 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
583 1));
584 break;
585 case ui::Transform::ROT_180:
586 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
587 {0, 0, (int32_t)mDisplayWidth / 2,
588 (int32_t)mDisplayHeight / 2},
589 1));
590 ASSERT_NO_FATAL_FAILURE(
591 checkScreenCapture(0, 0, 255,
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, 0,
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(255, 0, 0,
602 {0, (int32_t)mDisplayHeight / 2,
603 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
604 1));
605 break;
606 case ui::Transform::ROT_270:
607 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
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(0, 0, 255,
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 }
627 }
628};
629
630TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
631 test(ui::Transform::ROT_0);
632}
633
634TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
635 test(ui::Transform::FLIP_H);
636}
637
638TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
639 test(ui::Transform::FLIP_V);
640}
641
642TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
643 test(ui::Transform::ROT_90);
644}
645
646TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
647 test(ui::Transform::ROT_180);
648}
649
650TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
651 test(ui::Transform::ROT_270);
652}
Valerie Hau871d6352020-01-29 08:44:02 -0800653
654class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
655public:
656 void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
657 nsecs_t* requestedPresentTime, nsecs_t* postedTime,
658 IGraphicBufferProducer::QueueBufferOutput* qbOutput,
659 bool getFrameTimestamps) {
660 int slot;
661 sp<Fence> fence;
662 sp<GraphicBuffer> buf;
663 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
664 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
665 nullptr, nullptr);
666 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
667 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
668
669 nsecs_t requestedTime = systemTime();
670 if (requestedPresentTime) *requestedPresentTime = requestedTime;
671 IGraphicBufferProducer::QueueBufferInput input(requestedTime, false, HAL_DATASPACE_UNKNOWN,
672 Rect(mDisplayWidth, mDisplayHeight),
673 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
674 Fence::NO_FENCE, /*sticky*/ 0,
675 getFrameTimestamps);
676 if (postedTime) *postedTime = systemTime();
677 igbProducer->queueBuffer(slot, input, qbOutput);
678 }
679};
680
681TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
682 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
683 sp<IGraphicBufferProducer> igbProducer;
684 ProducerFrameEventHistory history;
685 setUpProducer(adapter, igbProducer);
686
687 IGraphicBufferProducer::QueueBufferOutput qbOutput;
688 nsecs_t requestedPresentTimeA = 0;
689 nsecs_t postedTimeA = 0;
690 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
691 history.applyDelta(qbOutput.frameTimestamps);
692
693 FrameEvents* events = nullptr;
694 events = history.getFrame(1);
695 ASSERT_NE(nullptr, events);
696 ASSERT_EQ(1, events->frameNumber);
697 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
698 ASSERT_GE(events->postedTime, postedTimeA);
699
700 adapter.waitForCallbacks();
701
702 // queue another buffer so we query for frame event deltas
703 nsecs_t requestedPresentTimeB = 0;
704 nsecs_t postedTimeB = 0;
705 setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
706 history.applyDelta(qbOutput.frameTimestamps);
707 events = history.getFrame(1);
708 ASSERT_NE(nullptr, events);
709
710 // frame number, requestedPresentTime, and postTime should not have changed
711 ASSERT_EQ(1, events->frameNumber);
712 ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
713 ASSERT_GE(events->postedTime, postedTimeA);
714
715 ASSERT_GE(events->latchTime, postedTimeA);
716 ASSERT_GE(events->dequeueReadyTime, events->latchTime);
717 ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
718 ASSERT_NE(nullptr, events->displayPresentFence);
719 ASSERT_NE(nullptr, events->releaseFence);
720
721 // we should also have gotten the initial values for the next frame
722 events = history.getFrame(2);
723 ASSERT_NE(nullptr, events);
724 ASSERT_EQ(2, events->frameNumber);
725 ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
726 ASSERT_GE(events->postedTime, postedTimeB);
Valerie Hau78491e92020-04-15 13:10:56 -0700727
728 // wait for any callbacks that have not been received
729 adapter.waitForCallbacks();
Valerie Hau871d6352020-01-29 08:44:02 -0800730}
Valerie Hauc5011f92019-10-11 09:52:07 -0700731} // namespace android