blob: 48b3908bd488e350348a2278ba08892a2d408cca [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 Hauda3446e2019-10-14 15:49:22 -070024#include <gui/IGraphicBufferProducer.h>
25#include <gui/IProducerListener.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070026#include <gui/SurfaceComposerClient.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070027#include <private/gui/ComposerService.h>
28#include <ui/DisplayInfo.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070029#include <ui/GraphicBuffer.h>
Valerie Hauda3446e2019-10-14 15:49:22 -070030#include <ui/GraphicTypes.h>
Valerie Hau8cee3f92019-11-06 10:06:28 -080031#include <ui/Transform.h>
Valerie Hauc5011f92019-10-11 09:52:07 -070032
33#include <gtest/gtest.h>
34
35using namespace std::chrono_literals;
36
37namespace android {
38
Valerie Hauc5011f92019-10-11 09:52:07 -070039using Transaction = SurfaceComposerClient::Transaction;
Valerie Hauda3446e2019-10-14 15:49:22 -070040using android::hardware::graphics::common::V1_2::BufferUsage;
Valerie Hauc5011f92019-10-11 09:52:07 -070041
42class BLASTBufferQueueHelper {
43public:
44 BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
45 mBlastBufferQueueAdapter = new BLASTBufferQueue(sc, width, height);
46 }
47
48 void update(const sp<SurfaceControl>& sc, int width, int height) {
49 mBlastBufferQueueAdapter->update(sc, width, height);
50 }
51
52 void setNextTransaction(Transaction* next) {
53 mBlastBufferQueueAdapter->setNextTransaction(next);
54 }
55
56 int getWidth() { return mBlastBufferQueueAdapter->mWidth; }
Valerie Hauda3446e2019-10-14 15:49:22 -070057
Valerie Hauc5011f92019-10-11 09:52:07 -070058 int getHeight() { return mBlastBufferQueueAdapter->mHeight; }
Valerie Hauda3446e2019-10-14 15:49:22 -070059
Valerie Hauc5011f92019-10-11 09:52:07 -070060 Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
Valerie Hauda3446e2019-10-14 15:49:22 -070061
62 sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
63 return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
64 }
65
Valerie Hauc5011f92019-10-11 09:52:07 -070066 const sp<SurfaceControl> getSurfaceControl() {
67 return mBlastBufferQueueAdapter->mSurfaceControl;
68 }
69
Valerie Haud3b90d22019-11-06 09:37:31 -080070 void waitForCallbacks() {
Valerie Hauda3446e2019-10-14 15:49:22 -070071 std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
Valerie Haua32c5522019-12-09 10:11:08 -080072 while (mBlastBufferQueueAdapter->mSubmitted.size() > 0) {
Valerie Haud3b90d22019-11-06 09:37:31 -080073 mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
74 }
Valerie Hauda3446e2019-10-14 15:49:22 -070075 }
76
Valerie Hauc5011f92019-10-11 09:52:07 -070077private:
78 sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
79};
80
81class BLASTBufferQueueTest : public ::testing::Test {
82public:
83protected:
84 BLASTBufferQueueTest() {
85 const ::testing::TestInfo* const testInfo =
86 ::testing::UnitTest::GetInstance()->current_test_info();
87 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
88 }
89
90 ~BLASTBufferQueueTest() {
91 const ::testing::TestInfo* const testInfo =
92 ::testing::UnitTest::GetInstance()->current_test_info();
93 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
94 }
95
96 void SetUp() {
Valerie Hauda3446e2019-10-14 15:49:22 -070097 mComposer = ComposerService::getComposerService();
Valerie Hauc5011f92019-10-11 09:52:07 -070098 mClient = new SurfaceComposerClient();
Valerie Hauda3446e2019-10-14 15:49:22 -070099 mDisplayToken = mClient->getInternalDisplayToken();
100 ASSERT_NE(nullptr, mDisplayToken.get());
101 Transaction t;
102 t.setDisplayLayerStack(mDisplayToken, 0);
103 t.apply();
104 t.clear();
105
106 DisplayInfo info;
107 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplayToken, &info));
108 mDisplayWidth = info.w;
109 mDisplayHeight = info.h;
110
111 mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
112 mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
113 ISurfaceComposerClient::eFXSurfaceBufferState,
114 /*parent*/ nullptr);
115 t.setLayerStack(mSurfaceControl, 0)
116 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
117 .setFrame(mSurfaceControl, Rect(0, 0, mDisplayWidth, mDisplayHeight))
118 .show(mSurfaceControl)
119 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
120 .apply();
121 }
122
Valerie Haud3b90d22019-11-06 09:37:31 -0800123 void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
124 auto igbProducer = adapter.getIGraphicBufferProducer();
125 ASSERT_NE(nullptr, igbProducer.get());
Valerie Hauc78c43a2020-01-09 17:34:14 -0800126 ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
Valerie Haud3b90d22019-11-06 09:37:31 -0800127 IGraphicBufferProducer::QueueBufferOutput qbOutput;
128 ASSERT_EQ(NO_ERROR,
129 igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
130 &qbOutput));
131 ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
132 producer = igbProducer;
133 }
134
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800135 void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
136 uint8_t b) {
137 for (uint32_t row = rect.top; row < rect.bottom; row++) {
138 for (uint32_t col = rect.left; col < rect.right; col++) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700139 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
140 *pixel = r;
141 *(pixel + 1) = g;
142 *(pixel + 2) = b;
143 *(pixel + 3) = 255;
144 }
145 }
146 }
147
Valerie Hau5977fc82019-12-05 15:56:39 -0800148 void fillQuadrants(sp<GraphicBuffer>& buf) {
149 const auto bufWidth = buf->getWidth();
150 const auto bufHeight = buf->getHeight();
151 uint32_t* bufData;
152 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
153 reinterpret_cast<void**>(&bufData));
154 fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
155 fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
156 0, 0);
157 fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
158 buf->getStride(), 0, 255, 0);
159 fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
160 255);
161 buf->unlock();
162 }
163
164 void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
165 bool outsideRegion = false) {
166 const auto epsilon = 3;
Valerie Hauda3446e2019-10-14 15:49:22 -0700167 const auto width = mScreenCaptureBuf->getWidth();
168 const auto height = mScreenCaptureBuf->getHeight();
169 const auto stride = mScreenCaptureBuf->getStride();
170
171 uint32_t* bufData;
172 mScreenCaptureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
173 reinterpret_cast<void**>(&bufData));
174
175 for (uint32_t row = 0; row < height; row++) {
176 for (uint32_t col = 0; col < width; col++) {
177 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
Valerie Hau5977fc82019-12-05 15:56:39 -0800178 bool inRegion;
179 if (!outsideRegion) {
180 inRegion = row >= region.top + border && row < region.bottom - border &&
181 col >= region.left + border && col < region.right - border;
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800182 } else {
Valerie Hau5977fc82019-12-05 15:56:39 -0800183 inRegion = row >= region.top - border && row < region.bottom + border &&
184 col >= region.left - border && col < region.right + border;
185 }
186 if (!outsideRegion && inRegion) {
187 EXPECT_GE(epsilon, abs(r - *(pixel)));
188 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
189 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
190 } else if (outsideRegion && !inRegion) {
191 EXPECT_GE(epsilon, abs(r - *(pixel)));
192 EXPECT_GE(epsilon, abs(g - *(pixel + 1)));
193 EXPECT_GE(epsilon, abs(b - *(pixel + 2)));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800194 }
Valerie Hauda3446e2019-10-14 15:49:22 -0700195 }
196 }
197 mScreenCaptureBuf->unlock();
198 ASSERT_EQ(false, ::testing::Test::HasFailure());
Valerie Hauc5011f92019-10-11 09:52:07 -0700199 }
200
201 sp<SurfaceComposerClient> mClient;
Valerie Hauda3446e2019-10-14 15:49:22 -0700202 sp<ISurfaceComposer> mComposer;
203
204 sp<IBinder> mDisplayToken;
205
Valerie Hauc5011f92019-10-11 09:52:07 -0700206 sp<SurfaceControl> mSurfaceControl;
Valerie Hauda3446e2019-10-14 15:49:22 -0700207 sp<GraphicBuffer> mScreenCaptureBuf;
208
209 uint32_t mDisplayWidth;
210 uint32_t mDisplayHeight;
Valerie Hauc5011f92019-10-11 09:52:07 -0700211};
212
213TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
214 // create BLASTBufferQueue adapter associated with this surface
Valerie Hauda3446e2019-10-14 15:49:22 -0700215 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700216 ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700217 ASSERT_EQ(mDisplayWidth, adapter.getWidth());
218 ASSERT_EQ(mDisplayHeight, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700219 ASSERT_EQ(nullptr, adapter.getNextTransaction());
220}
221
222TEST_F(BLASTBufferQueueTest, Update) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700223 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700224 sp<SurfaceControl> updateSurface =
Valerie Hauda3446e2019-10-14 15:49:22 -0700225 mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
226 PIXEL_FORMAT_RGBA_8888);
227 adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
Valerie Hauc5011f92019-10-11 09:52:07 -0700228 ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
Valerie Hauda3446e2019-10-14 15:49:22 -0700229 ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth());
230 ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight());
Valerie Hauc5011f92019-10-11 09:52:07 -0700231}
232
233TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
Valerie Hauda3446e2019-10-14 15:49:22 -0700234 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Hauc5011f92019-10-11 09:52:07 -0700235 Transaction next;
236 adapter.setNextTransaction(&next);
237 ASSERT_EQ(&next, adapter.getNextTransaction());
238}
Valerie Hauda3446e2019-10-14 15:49:22 -0700239
240TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
241 uint8_t r = 255;
242 uint8_t g = 0;
243 uint8_t b = 0;
244
245 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
Valerie Haud3b90d22019-11-06 09:37:31 -0800246 sp<IGraphicBufferProducer> igbProducer;
247 setUpProducer(adapter, igbProducer);
Valerie Hauda3446e2019-10-14 15:49:22 -0700248
249 int slot;
250 sp<Fence> fence;
251 sp<GraphicBuffer> buf;
252 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
253 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
254 nullptr, nullptr);
255 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
256 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
257
258 uint32_t* bufData;
259 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
260 reinterpret_cast<void**>(&bufData));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800261 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
Valerie Hauda3446e2019-10-14 15:49:22 -0700262 buf->unlock();
263
Valerie Haud3b90d22019-11-06 09:37:31 -0800264 IGraphicBufferProducer::QueueBufferOutput qbOutput;
Valerie Hauda3446e2019-10-14 15:49:22 -0700265 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
266 Rect(mDisplayWidth, mDisplayHeight),
267 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
268 Fence::NO_FENCE);
269 igbProducer->queueBuffer(slot, input, &qbOutput);
Valerie Hau8cee3f92019-11-06 10:06:28 -0800270 ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
Valerie Hauda3446e2019-10-14 15:49:22 -0700271
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800272 adapter.waitForCallbacks();
Valerie Hauda3446e2019-10-14 15:49:22 -0700273
274 // capture screen and verify that it is red
275 bool capturedSecureLayers;
276 ASSERT_EQ(NO_ERROR,
277 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
278 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
279 mDisplayWidth, mDisplayHeight,
280 /*useIdentityTransform*/ false));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800281 ASSERT_NO_FATAL_FAILURE(
282 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
Valerie Hauda3446e2019-10-14 15:49:22 -0700283}
Valerie Haud3b90d22019-11-06 09:37:31 -0800284
285TEST_F(BLASTBufferQueueTest, TripleBuffering) {
286 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
287 sp<IGraphicBufferProducer> igbProducer;
288 setUpProducer(adapter, igbProducer);
289
290 std::vector<std::pair<int, sp<Fence>>> allocated;
291 for (int i = 0; i < 3; i++) {
292 int slot;
293 sp<Fence> fence;
294 sp<GraphicBuffer> buf;
295 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
296 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
297 nullptr, nullptr);
298 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
299 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
300 allocated.push_back({slot, fence});
301 }
302 for (int i = 0; i < allocated.size(); i++) {
303 igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
304 }
305
Valerie Haua32c5522019-12-09 10:11:08 -0800306 for (int i = 0; i < 100; i++) {
Valerie Haud3b90d22019-11-06 09:37:31 -0800307 int slot;
308 sp<Fence> fence;
309 sp<GraphicBuffer> buf;
310 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
311 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
312 nullptr, nullptr);
313 ASSERT_EQ(NO_ERROR, ret);
314 IGraphicBufferProducer::QueueBufferOutput qbOutput;
315 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
316 Rect(mDisplayWidth, mDisplayHeight),
317 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
318 Fence::NO_FENCE);
319 igbProducer->queueBuffer(slot, input, &qbOutput);
320 }
321 adapter.waitForCallbacks();
322}
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800323
324TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
325 uint8_t r = 255;
326 uint8_t g = 0;
327 uint8_t b = 0;
328
329 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
330 sp<IGraphicBufferProducer> igbProducer;
331 setUpProducer(adapter, igbProducer);
332 int slot;
333 sp<Fence> fence;
334 sp<GraphicBuffer> buf;
335 auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
336 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
337 nullptr, nullptr);
338 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
339 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
340
341 uint32_t* bufData;
342 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
343 reinterpret_cast<void**>(&bufData));
344 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
345 buf->unlock();
346
347 IGraphicBufferProducer::QueueBufferOutput qbOutput;
348 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
349 Rect(mDisplayWidth, mDisplayHeight / 2),
350 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
351 Fence::NO_FENCE);
352 igbProducer->queueBuffer(slot, input, &qbOutput);
353 ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
354
355 adapter.waitForCallbacks();
356 // capture screen and verify that it is red
357 bool capturedSecureLayers;
358 ASSERT_EQ(NO_ERROR,
359 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
360 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
361 mDisplayWidth, mDisplayHeight,
362 /*useIdentityTransform*/ false));
363 ASSERT_NO_FATAL_FAILURE(
364 checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
365}
366
367TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
368 uint8_t r = 255;
369 uint8_t g = 0;
370 uint8_t b = 0;
371
372 int32_t bufferSideLength =
373 (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
374 int32_t finalCropSideLength = bufferSideLength / 2;
375
376 auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
377 ISurfaceComposerClient::eFXSurfaceColor);
378 ASSERT_NE(nullptr, bg.get());
379 Transaction t;
380 t.setLayerStack(bg, 0)
381 .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
382 .setColor(bg, half3{0, 0, 0})
383 .setLayer(bg, 0)
384 .apply();
385
386 BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
387 sp<IGraphicBufferProducer> igbProducer;
388 setUpProducer(adapter, igbProducer);
389 int slot;
390 sp<Fence> fence;
391 sp<GraphicBuffer> buf;
392 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
393 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
394 nullptr, nullptr);
395 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
396 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
397
398 uint32_t* bufData;
399 buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
400 reinterpret_cast<void**>(&bufData));
401 fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
402 fillBuffer(bufData,
403 Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
404 buf->getHeight()),
405 buf->getStride(), r, g, b);
406 buf->unlock();
407
408 IGraphicBufferProducer::QueueBufferOutput qbOutput;
409 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
410 Rect(bufferSideLength, finalCropSideLength),
411 NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
412 Fence::NO_FENCE);
413 igbProducer->queueBuffer(slot, input, &qbOutput);
414 ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
415
416 adapter.waitForCallbacks();
417 // capture screen and verify that it is red
418 bool capturedSecureLayers;
419 ASSERT_EQ(NO_ERROR,
420 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
421 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888, Rect(),
422 mDisplayWidth, mDisplayHeight,
423 /*useIdentityTransform*/ false));
424 ASSERT_NO_FATAL_FAILURE(
425 checkScreenCapture(r, g, b,
426 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}));
Valerie Hau5977fc82019-12-05 15:56:39 -0800427 ASSERT_NO_FATAL_FAILURE(
428 checkScreenCapture(0, 0, 0,
429 {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
430 /*border*/ 0, /*outsideRegion*/ true));
Valerie Hau45e4b3b2019-12-03 10:49:17 -0800431}
432
Valerie Hau5977fc82019-12-05 15:56:39 -0800433class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
434public:
435 void test(uint32_t tr) {
436 BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
437 sp<IGraphicBufferProducer> igbProducer;
438 setUpProducer(adapter, igbProducer);
439
440 auto bufWidth = mDisplayWidth;
441 auto bufHeight = mDisplayHeight;
442 int slot;
443 sp<Fence> fence;
444 sp<GraphicBuffer> buf;
445
446 auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
447 PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
448 nullptr, nullptr);
449 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
450 ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
451
452 fillQuadrants(buf);
453
454 IGraphicBufferProducer::QueueBufferOutput qbOutput;
455 IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN,
456 Rect(bufWidth, bufHeight),
457 NATIVE_WINDOW_SCALING_MODE_FREEZE, tr,
458 Fence::NO_FENCE);
459 igbProducer->queueBuffer(slot, input, &qbOutput);
460 ASSERT_NE(ui::Transform::orientation_flags::ROT_INVALID, qbOutput.transformHint);
461
462 adapter.waitForCallbacks();
463 bool capturedSecureLayers;
464 ASSERT_EQ(NO_ERROR,
465 mComposer->captureScreen(mDisplayToken, &mScreenCaptureBuf, capturedSecureLayers,
466 ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
467 Rect(), mDisplayWidth, mDisplayHeight,
468 /*useIdentityTransform*/ false));
469 switch (tr) {
470 case ui::Transform::ROT_0:
471 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
472 {0, 0, (int32_t)mDisplayWidth / 2,
473 (int32_t)mDisplayHeight / 2},
474 1));
475 ASSERT_NO_FATAL_FAILURE(
476 checkScreenCapture(255, 0, 0,
477 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
478 (int32_t)mDisplayHeight / 2},
479 1));
480 ASSERT_NO_FATAL_FAILURE(
481 checkScreenCapture(0, 255, 0,
482 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
483 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
484 1));
485 ASSERT_NO_FATAL_FAILURE(
486 checkScreenCapture(0, 0, 255,
487 {0, (int32_t)mDisplayHeight / 2,
488 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
489 1));
490 break;
491 case ui::Transform::FLIP_H:
492 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
493 {0, 0, (int32_t)mDisplayWidth / 2,
494 (int32_t)mDisplayHeight / 2},
495 1));
496 ASSERT_NO_FATAL_FAILURE(
497 checkScreenCapture(0, 0, 0,
498 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
499 (int32_t)mDisplayHeight / 2},
500 1));
501 ASSERT_NO_FATAL_FAILURE(
502 checkScreenCapture(0, 0, 255,
503 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
504 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
505 1));
506 ASSERT_NO_FATAL_FAILURE(
507 checkScreenCapture(0, 255, 0,
508 {0, (int32_t)mDisplayHeight / 2,
509 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
510 1));
511 break;
512 case ui::Transform::FLIP_V:
513 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
514 {0, 0, (int32_t)mDisplayWidth / 2,
515 (int32_t)mDisplayHeight / 2},
516 1));
517 ASSERT_NO_FATAL_FAILURE(
518 checkScreenCapture(0, 255, 0,
519 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
520 (int32_t)mDisplayHeight / 2},
521 1));
522 ASSERT_NO_FATAL_FAILURE(
523 checkScreenCapture(255, 0, 0,
524 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
525 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
526 1));
527 ASSERT_NO_FATAL_FAILURE(
528 checkScreenCapture(0, 0, 0,
529 {0, (int32_t)mDisplayHeight / 2,
530 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
531 1));
532 break;
533 case ui::Transform::ROT_90:
534 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
535 {0, 0, (int32_t)mDisplayWidth / 2,
536 (int32_t)mDisplayHeight / 2},
537 1));
538 ASSERT_NO_FATAL_FAILURE(
539 checkScreenCapture(0, 0, 0,
540 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
541 (int32_t)mDisplayHeight / 2},
542 1));
543 ASSERT_NO_FATAL_FAILURE(
544 checkScreenCapture(255, 0, 0,
545 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
546 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
547 1));
548 ASSERT_NO_FATAL_FAILURE(
549 checkScreenCapture(0, 255, 0,
550 {0, (int32_t)mDisplayHeight / 2,
551 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
552 1));
553 break;
554 case ui::Transform::ROT_180:
555 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
556 {0, 0, (int32_t)mDisplayWidth / 2,
557 (int32_t)mDisplayHeight / 2},
558 1));
559 ASSERT_NO_FATAL_FAILURE(
560 checkScreenCapture(0, 0, 255,
561 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
562 (int32_t)mDisplayHeight / 2},
563 1));
564 ASSERT_NO_FATAL_FAILURE(
565 checkScreenCapture(0, 0, 0,
566 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
567 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
568 1));
569 ASSERT_NO_FATAL_FAILURE(
570 checkScreenCapture(255, 0, 0,
571 {0, (int32_t)mDisplayHeight / 2,
572 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
573 1));
574 break;
575 case ui::Transform::ROT_270:
576 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
577 {0, 0, (int32_t)mDisplayWidth / 2,
578 (int32_t)mDisplayHeight / 2},
579 1));
580 ASSERT_NO_FATAL_FAILURE(
581 checkScreenCapture(0, 255, 0,
582 {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
583 (int32_t)mDisplayHeight / 2},
584 1));
585 ASSERT_NO_FATAL_FAILURE(
586 checkScreenCapture(0, 0, 255,
587 {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
588 (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
589 1));
590 ASSERT_NO_FATAL_FAILURE(
591 checkScreenCapture(0, 0, 0,
592 {0, (int32_t)mDisplayHeight / 2,
593 (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
594 1));
595 }
596 }
597};
598
599TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
600 test(ui::Transform::ROT_0);
601}
602
603TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
604 test(ui::Transform::FLIP_H);
605}
606
607TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
608 test(ui::Transform::FLIP_V);
609}
610
611TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
612 test(ui::Transform::ROT_90);
613}
614
615TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
616 test(ui::Transform::ROT_180);
617}
618
619TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
620 test(ui::Transform::ROT_270);
621}
Valerie Hauc5011f92019-10-11 09:52:07 -0700622} // namespace android