1 /*
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 
21 #include <android/hardware/graphics/common/1.2/types.h>
22 #include <gui/BufferQueueCore.h>
23 #include <gui/BufferQueueProducer.h>
24 #include <gui/FrameTimestamps.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/IProducerListener.h>
27 #include <gui/SurfaceComposerClient.h>
28 #include <private/gui/ComposerService.h>
29 #include <ui/DisplayConfig.h>
30 #include <ui/GraphicBuffer.h>
31 #include <ui/GraphicTypes.h>
32 #include <ui/Transform.h>
33 
34 #include <gtest/gtest.h>
35 
36 using namespace std::chrono_literals;
37 
38 namespace android {
39 
40 using Transaction = SurfaceComposerClient::Transaction;
41 using android::hardware::graphics::common::V1_2::BufferUsage;
42 
43 class BLASTBufferQueueHelper {
44 public:
BLASTBufferQueueHelper(const sp<SurfaceControl> & sc,int width,int height)45     BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
46         mBlastBufferQueueAdapter = new BLASTBufferQueue(sc, width, height);
47     }
48 
update(const sp<SurfaceControl> & sc,int width,int height)49     void update(const sp<SurfaceControl>& sc, int width, int height) {
50         mBlastBufferQueueAdapter->update(sc, width, height);
51     }
52 
setNextTransaction(Transaction * next)53     void setNextTransaction(Transaction* next) {
54         mBlastBufferQueueAdapter->setNextTransaction(next);
55     }
56 
getWidth()57     int getWidth() { return mBlastBufferQueueAdapter->mWidth; }
58 
getHeight()59     int getHeight() { return mBlastBufferQueueAdapter->mHeight; }
60 
getNextTransaction()61     Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
62 
getIGraphicBufferProducer()63     sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
64         return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
65     }
66 
getSurfaceControl()67     const sp<SurfaceControl> getSurfaceControl() {
68         return mBlastBufferQueueAdapter->mSurfaceControl;
69     }
70 
waitForCallbacks()71     void waitForCallbacks() {
72         std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
73         while (mBlastBufferQueueAdapter->mSubmitted.size() > 0) {
74             mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
75         }
76     }
77 
78 private:
79     sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
80 };
81 
82 class BLASTBufferQueueTest : public ::testing::Test {
83 public:
84 protected:
BLASTBufferQueueTest()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 
~BLASTBufferQueueTest()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 
SetUp()97     void SetUp() {
98         mComposer = ComposerService::getComposerService();
99         mClient = new SurfaceComposerClient();
100         mDisplayToken = mClient->getInternalDisplayToken();
101         ASSERT_NE(nullptr, mDisplayToken.get());
102         Transaction t;
103         t.setDisplayLayerStack(mDisplayToken, 0);
104         t.apply();
105         t.clear();
106 
107         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();
112 
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())
119                 .setFrame(mSurfaceControl, Rect(resolution))
120                 .show(mSurfaceControl)
121                 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
122                 .apply();
123     }
124 
setUpProducer(BLASTBufferQueueHelper adapter,sp<IGraphicBufferProducer> & producer)125     void setUpProducer(BLASTBufferQueueHelper adapter, sp<IGraphicBufferProducer>& producer) {
126         auto igbProducer = adapter.getIGraphicBufferProducer();
127         ASSERT_NE(nullptr, igbProducer.get());
128         ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
129         IGraphicBufferProducer::QueueBufferOutput qbOutput;
130         ASSERT_EQ(NO_ERROR,
131                   igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
132                                        &qbOutput));
133         ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
134         producer = igbProducer;
135     }
136 
fillBuffer(uint32_t * bufData,Rect rect,uint32_t stride,uint8_t r,uint8_t g,uint8_t b)137     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++) {
141                 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 
fillQuadrants(sp<GraphicBuffer> & buf)150     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 
checkScreenCapture(uint8_t r,uint8_t g,uint8_t b,Rect region,int32_t border=0,bool outsideRegion=false)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;
169         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);
180                 bool inRegion;
181                 if (!outsideRegion) {
182                     inRegion = row >= region.top + border && row < region.bottom - border &&
183                             col >= region.left + border && col < region.right - border;
184                 } else {
185                     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)));
196                 }
197             }
198         }
199         mScreenCaptureBuf->unlock();
200         ASSERT_EQ(false, ::testing::Test::HasFailure());
201     }
202 
203     sp<SurfaceComposerClient> mClient;
204     sp<ISurfaceComposer> mComposer;
205 
206     sp<IBinder> mDisplayToken;
207 
208     sp<SurfaceControl> mSurfaceControl;
209     sp<GraphicBuffer> mScreenCaptureBuf;
210 
211     uint32_t mDisplayWidth;
212     uint32_t mDisplayHeight;
213 };
214 
TEST_F(BLASTBufferQueueTest,CreateBLASTBufferQueue)215 TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
216     // create BLASTBufferQueue adapter associated with this surface
217     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
218     ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
219     ASSERT_EQ(mDisplayWidth, adapter.getWidth());
220     ASSERT_EQ(mDisplayHeight, adapter.getHeight());
221     ASSERT_EQ(nullptr, adapter.getNextTransaction());
222 }
223 
TEST_F(BLASTBufferQueueTest,Update)224 TEST_F(BLASTBufferQueueTest, Update) {
225     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
226     sp<SurfaceControl> updateSurface =
227             mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
228                                    PIXEL_FORMAT_RGBA_8888);
229     adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
230     ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
231     ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth());
232     ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight());
233 }
234 
TEST_F(BLASTBufferQueueTest,SetNextTransaction)235 TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
236     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
237     Transaction next;
238     adapter.setNextTransaction(&next);
239     ASSERT_EQ(&next, adapter.getNextTransaction());
240 }
241 
TEST_F(BLASTBufferQueueTest,DISABLED_onFrameAvailable_ApplyDesiredPresentTime)242 TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
243     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 
TEST_F(BLASTBufferQueueTest,onFrameAvailable_Apply)269 TEST_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);
275     sp<IGraphicBufferProducer> igbProducer;
276     setUpProducer(adapter, igbProducer);
277 
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));
290     fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
291     buf->unlock();
292 
293     IGraphicBufferProducer::QueueBufferOutput qbOutput;
294     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);
299     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
300 
301     adapter.waitForCallbacks();
302 
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));
310     ASSERT_NO_FATAL_FAILURE(
311             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
312 }
313 
TEST_F(BLASTBufferQueueTest,TripleBuffering)314 TEST_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 
335     for (int i = 0; i < 100; i++) {
336         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 }
352 
TEST_F(BLASTBufferQueueTest,SetCrop_Item)353 TEST_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);
382     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
383 
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 
TEST_F(BLASTBufferQueueTest,SetCrop_ScalingModeScaleCrop)396 TEST_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,
406                                      ISurfaceComposerClient::eFXSurfaceEffect);
407     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);
443     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
444 
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}));
456     ASSERT_NO_FATAL_FAILURE(
457             checkScreenCapture(0, 0, 0,
458                                {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
459                                /*border*/ 0, /*outsideRegion*/ true));
460 }
461 
462 class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
463 public:
test(uint32_t tr)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);
489         ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
490 
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 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_0)628 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
629     test(ui::Transform::ROT_0);
630 }
631 
TEST_F(BLASTBufferQueueTransformTest,setTransform_FLIP_H)632 TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
633     test(ui::Transform::FLIP_H);
634 }
635 
TEST_F(BLASTBufferQueueTransformTest,setTransform_FLIP_V)636 TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
637     test(ui::Transform::FLIP_V);
638 }
639 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_90)640 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
641     test(ui::Transform::ROT_90);
642 }
643 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_180)644 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
645     test(ui::Transform::ROT_180);
646 }
647 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_270)648 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
649     test(ui::Transform::ROT_270);
650 }
651 
652 class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
653 public:
setUpAndQueueBuffer(const sp<IGraphicBufferProducer> & igbProducer,nsecs_t * requestedPresentTime,nsecs_t * postedTime,IGraphicBufferProducer::QueueBufferOutput * qbOutput,bool getFrameTimestamps)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 
TEST_F(BLASTFrameEventHistoryTest,FrameEventHistory_Basic)679 TEST_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);
725 
726     // wait for any callbacks that have not been received
727     adapter.waitForCallbacks();
728 }
729 } // namespace android
730