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/Surface.h>
28 #include <gui/SurfaceComposerClient.h>
29 #include <gui/SyncScreenCaptureListener.h>
30 #include <gui/test/CallbackUtils.h>
31 #include <private/gui/ComposerService.h>
32 #include <ui/DisplayMode.h>
33 #include <ui/GraphicBuffer.h>
34 #include <ui/GraphicTypes.h>
35 #include <ui/Transform.h>
36 
37 #include <gtest/gtest.h>
38 
39 using namespace std::chrono_literals;
40 
41 namespace android {
42 
43 using Transaction = SurfaceComposerClient::Transaction;
44 using android::hardware::graphics::common::V1_2::BufferUsage;
45 
46 class CountProducerListener : public BnProducerListener {
47 public:
onBufferReleased()48     void onBufferReleased() override {
49         std::scoped_lock<std::mutex> lock(mMutex);
50         mNumReleased++;
51         mReleaseCallback.notify_one();
52     }
53 
waitOnNumberReleased(int32_t expectedNumReleased)54     void waitOnNumberReleased(int32_t expectedNumReleased) {
55         std::unique_lock<std::mutex> lock(mMutex);
56         while (mNumReleased < expectedNumReleased) {
57             ASSERT_NE(mReleaseCallback.wait_for(lock, std::chrono::seconds(3)),
58                       std::cv_status::timeout)
59                     << "did not receive release";
60         }
61     }
62 
63 private:
64     std::mutex mMutex;
65     std::condition_variable mReleaseCallback;
66     int32_t mNumReleased GUARDED_BY(mMutex) = 0;
67 };
68 
69 class BLASTBufferQueueHelper {
70 public:
BLASTBufferQueueHelper(const sp<SurfaceControl> & sc,int width,int height)71     BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
72         mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height,
73                                                         PIXEL_FORMAT_RGBA_8888);
74     }
75 
update(const sp<SurfaceControl> & sc,int width,int height)76     void update(const sp<SurfaceControl>& sc, int width, int height) {
77         mBlastBufferQueueAdapter->update(sc, width, height, PIXEL_FORMAT_RGBA_8888);
78     }
79 
setNextTransaction(Transaction * next)80     void setNextTransaction(Transaction* next) {
81         mBlastBufferQueueAdapter->setNextTransaction(next);
82     }
83 
getWidth()84     int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
85 
getHeight()86     int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
87 
getNextTransaction()88     Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
89 
getIGraphicBufferProducer()90     sp<IGraphicBufferProducer> getIGraphicBufferProducer() {
91         return mBlastBufferQueueAdapter->getIGraphicBufferProducer();
92     }
93 
getSurfaceControl()94     const sp<SurfaceControl> getSurfaceControl() {
95         return mBlastBufferQueueAdapter->mSurfaceControl;
96     }
97 
getSurface()98     sp<Surface> getSurface() {
99         return mBlastBufferQueueAdapter->getSurface(false /* includeSurfaceControlHandle */);
100     }
101 
waitForCallbacks()102     void waitForCallbacks() {
103         std::unique_lock lock{mBlastBufferQueueAdapter->mMutex};
104         // Wait until all but one of the submitted buffers have been released.
105         while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) {
106             mBlastBufferQueueAdapter->mCallbackCV.wait(lock);
107         }
108     }
109 
setTransactionCompleteCallback(int64_t frameNumber)110     void setTransactionCompleteCallback(int64_t frameNumber) {
111         mBlastBufferQueueAdapter->setTransactionCompleteCallback(frameNumber, [&](int64_t frame) {
112             std::unique_lock lock{mMutex};
113             mLastTransactionCompleteFrameNumber = frame;
114             mCallbackCV.notify_all();
115         });
116     }
117 
waitForCallback(int64_t frameNumber)118     void waitForCallback(int64_t frameNumber) {
119         std::unique_lock lock{mMutex};
120         // Wait until all but one of the submitted buffers have been released.
121         while (mLastTransactionCompleteFrameNumber < frameNumber) {
122             mCallbackCV.wait(lock);
123         }
124     }
125 
126 private:
127     sp<BLASTBufferQueue> mBlastBufferQueueAdapter;
128 
129     std::mutex mMutex;
130     std::condition_variable mCallbackCV;
131     int64_t mLastTransactionCompleteFrameNumber = -1;
132 };
133 
134 class BLASTBufferQueueTest : public ::testing::Test {
135 public:
136 protected:
BLASTBufferQueueTest()137     BLASTBufferQueueTest() {
138         const ::testing::TestInfo* const testInfo =
139                 ::testing::UnitTest::GetInstance()->current_test_info();
140         ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
141     }
142 
~BLASTBufferQueueTest()143     ~BLASTBufferQueueTest() {
144         const ::testing::TestInfo* const testInfo =
145                 ::testing::UnitTest::GetInstance()->current_test_info();
146         ALOGV("End test:   %s.%s", testInfo->test_case_name(), testInfo->name());
147     }
148 
SetUp()149     void SetUp() {
150         mComposer = ComposerService::getComposerService();
151         mClient = new SurfaceComposerClient();
152         mDisplayToken = mClient->getInternalDisplayToken();
153         ASSERT_NE(nullptr, mDisplayToken.get());
154         Transaction t;
155         t.setDisplayLayerStack(mDisplayToken, 0);
156         t.apply();
157         t.clear();
158 
159         ui::DisplayMode mode;
160         ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
161         const ui::Size& resolution = mode.resolution;
162         mDisplayWidth = resolution.getWidth();
163         mDisplayHeight = resolution.getHeight();
164 
165         mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
166                                                  mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
167                                                  ISurfaceComposerClient::eFXSurfaceBufferState,
168                                                  /*parent*/ nullptr);
169         t.setLayerStack(mSurfaceControl, 0)
170                 .setLayer(mSurfaceControl, std::numeric_limits<int32_t>::max())
171                 .show(mSurfaceControl)
172                 .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB)
173                 .apply();
174 
175         mCaptureArgs.displayToken = mDisplayToken;
176         mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB;
177     }
178 
setUpProducer(BLASTBufferQueueHelper & adapter,sp<IGraphicBufferProducer> & producer,int32_t maxBufferCount=2)179     void setUpProducer(BLASTBufferQueueHelper& adapter, sp<IGraphicBufferProducer>& producer,
180                        int32_t maxBufferCount = 2) {
181         producer = adapter.getIGraphicBufferProducer();
182         setUpProducer(producer, maxBufferCount);
183     }
184 
setUpProducer(sp<IGraphicBufferProducer> & igbProducer,int32_t maxBufferCount)185     void setUpProducer(sp<IGraphicBufferProducer>& igbProducer, int32_t maxBufferCount) {
186         ASSERT_NE(nullptr, igbProducer.get());
187         ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(maxBufferCount));
188         IGraphicBufferProducer::QueueBufferOutput qbOutput;
189         mProducerListener = new CountProducerListener();
190         ASSERT_EQ(NO_ERROR,
191                   igbProducer->connect(mProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput));
192         ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
193     }
194 
fillBuffer(uint32_t * bufData,Rect rect,uint32_t stride,uint8_t r,uint8_t g,uint8_t b)195     void fillBuffer(uint32_t* bufData, Rect rect, uint32_t stride, uint8_t r, uint8_t g,
196                     uint8_t b) {
197         for (uint32_t row = rect.top; row < rect.bottom; row++) {
198             for (uint32_t col = rect.left; col < rect.right; col++) {
199                 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
200                 *pixel = r;
201                 *(pixel + 1) = g;
202                 *(pixel + 2) = b;
203                 *(pixel + 3) = 255;
204             }
205         }
206     }
207 
fillQuadrants(sp<GraphicBuffer> & buf)208     void fillQuadrants(sp<GraphicBuffer>& buf) {
209         const auto bufWidth = buf->getWidth();
210         const auto bufHeight = buf->getHeight();
211         uint32_t* bufData;
212         buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
213                   reinterpret_cast<void**>(&bufData));
214         fillBuffer(bufData, Rect(0, 0, bufWidth / 2, bufHeight / 2), buf->getStride(), 0, 0, 0);
215         fillBuffer(bufData, Rect(bufWidth / 2, 0, bufWidth, bufHeight / 2), buf->getStride(), 255,
216                    0, 0);
217         fillBuffer(bufData, Rect(bufWidth / 2, bufHeight / 2, bufWidth, bufHeight),
218                    buf->getStride(), 0, 255, 0);
219         fillBuffer(bufData, Rect(0, bufHeight / 2, bufWidth / 2, bufHeight), buf->getStride(), 0, 0,
220                    255);
221         buf->unlock();
222     }
223 
checkScreenCapture(uint8_t r,uint8_t g,uint8_t b,Rect region,int32_t border=0,bool outsideRegion=false)224     void checkScreenCapture(uint8_t r, uint8_t g, uint8_t b, Rect region, int32_t border = 0,
225                             bool outsideRegion = false) {
226         sp<GraphicBuffer>& captureBuf = mCaptureResults.buffer;
227         const auto epsilon = 3;
228         const auto width = captureBuf->getWidth();
229         const auto height = captureBuf->getHeight();
230         const auto stride = captureBuf->getStride();
231 
232         uint32_t* bufData;
233         captureBuf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_READ_OFTEN),
234                          reinterpret_cast<void**>(&bufData));
235 
236         for (uint32_t row = 0; row < height; row++) {
237             for (uint32_t col = 0; col < width; col++) {
238                 uint8_t* pixel = (uint8_t*)(bufData + (row * stride) + col);
239                 ASSERT_NE(nullptr, pixel);
240                 bool inRegion;
241                 if (!outsideRegion) {
242                     inRegion = row >= region.top + border && row < region.bottom - border &&
243                             col >= region.left + border && col < region.right - border;
244                 } else {
245                     inRegion = row >= region.top - border && row < region.bottom + border &&
246                             col >= region.left - border && col < region.right + border;
247                 }
248                 if (!outsideRegion && inRegion) {
249                     ASSERT_GE(epsilon, abs(r - *(pixel)));
250                     ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
251                     ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
252                 } else if (outsideRegion && !inRegion) {
253                     ASSERT_GE(epsilon, abs(r - *(pixel)));
254                     ASSERT_GE(epsilon, abs(g - *(pixel + 1)));
255                     ASSERT_GE(epsilon, abs(b - *(pixel + 2)));
256                 }
257                 ASSERT_EQ(false, ::testing::Test::HasFailure());
258             }
259         }
260         captureBuf->unlock();
261     }
262 
captureDisplay(DisplayCaptureArgs & captureArgs,ScreenCaptureResults & captureResults)263     static status_t captureDisplay(DisplayCaptureArgs& captureArgs,
264                                    ScreenCaptureResults& captureResults) {
265         const auto sf = ComposerService::getComposerService();
266         SurfaceComposerClient::Transaction().apply(true);
267 
268         const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
269         status_t status = sf->captureDisplay(captureArgs, captureListener);
270         if (status != NO_ERROR) {
271             return status;
272         }
273         captureResults = captureListener->waitForResults();
274         return captureResults.result;
275     }
276 
queueBuffer(sp<IGraphicBufferProducer> igbp,uint8_t r,uint8_t g,uint8_t b,nsecs_t presentTimeDelay)277     void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
278                      nsecs_t presentTimeDelay) {
279         int slot;
280         sp<Fence> fence;
281         sp<GraphicBuffer> buf;
282         auto ret = igbp->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
283                                        PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
284                                        nullptr, nullptr);
285         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
286         ASSERT_EQ(OK, igbp->requestBuffer(slot, &buf));
287 
288         uint32_t* bufData;
289         buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
290                   reinterpret_cast<void**>(&bufData));
291         fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
292         buf->unlock();
293 
294         IGraphicBufferProducer::QueueBufferOutput qbOutput;
295         nsecs_t timestampNanos = systemTime() + presentTimeDelay;
296         IGraphicBufferProducer::QueueBufferInput input(timestampNanos, false, HAL_DATASPACE_UNKNOWN,
297                                                        Rect(mDisplayWidth, mDisplayHeight / 2),
298                                                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
299                                                        Fence::NO_FENCE);
300         igbp->queueBuffer(slot, input, &qbOutput);
301     }
302 
303     sp<SurfaceComposerClient> mClient;
304     sp<ISurfaceComposer> mComposer;
305 
306     sp<IBinder> mDisplayToken;
307 
308     sp<SurfaceControl> mSurfaceControl;
309 
310     uint32_t mDisplayWidth;
311     uint32_t mDisplayHeight;
312 
313     DisplayCaptureArgs mCaptureArgs;
314     ScreenCaptureResults mCaptureResults;
315     sp<CountProducerListener> mProducerListener;
316 };
317 
TEST_F(BLASTBufferQueueTest,CreateBLASTBufferQueue)318 TEST_F(BLASTBufferQueueTest, CreateBLASTBufferQueue) {
319     // create BLASTBufferQueue adapter associated with this surface
320     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
321     ASSERT_EQ(mSurfaceControl, adapter.getSurfaceControl());
322     ASSERT_EQ(mDisplayWidth, adapter.getWidth());
323     ASSERT_EQ(mDisplayHeight, adapter.getHeight());
324     ASSERT_EQ(nullptr, adapter.getNextTransaction());
325 }
326 
TEST_F(BLASTBufferQueueTest,Update)327 TEST_F(BLASTBufferQueueTest, Update) {
328     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
329     sp<SurfaceControl> updateSurface =
330             mClient->createSurface(String8("UpdateTest"), mDisplayWidth / 2, mDisplayHeight / 2,
331                                    PIXEL_FORMAT_RGBA_8888);
332     adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
333     ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
334     sp<IGraphicBufferProducer> igbProducer;
335     setUpProducer(adapter, igbProducer);
336 
337     int32_t width;
338     igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
339     ASSERT_EQ(mDisplayWidth / 2, width);
340     int32_t height;
341     igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
342     ASSERT_EQ(mDisplayHeight / 2, height);
343 }
344 
TEST_F(BLASTBufferQueueTest,SetNextTransaction)345 TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
346     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
347     Transaction next;
348     adapter.setNextTransaction(&next);
349     ASSERT_EQ(&next, adapter.getNextTransaction());
350 }
351 
TEST_F(BLASTBufferQueueTest,DISABLED_onFrameAvailable_ApplyDesiredPresentTime)352 TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
353     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
354     sp<IGraphicBufferProducer> igbProducer;
355     setUpProducer(adapter, igbProducer);
356 
357     int slot;
358     sp<Fence> fence;
359     sp<GraphicBuffer> buf;
360     auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
361                                           PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
362                                           nullptr, nullptr);
363     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
364     ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
365 
366     nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8);
367     IGraphicBufferProducer::QueueBufferOutput qbOutput;
368     IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */,
369                                                    HAL_DATASPACE_UNKNOWN,
370                                                    Rect(mDisplayWidth, mDisplayHeight),
371                                                    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
372                                                    Fence::NO_FENCE);
373     igbProducer->queueBuffer(slot, input, &qbOutput);
374     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
375 
376     adapter.waitForCallbacks();
377     ASSERT_GE(systemTime(), desiredPresentTime);
378 }
379 
TEST_F(BLASTBufferQueueTest,onFrameAvailable_Apply)380 TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) {
381     uint8_t r = 255;
382     uint8_t g = 0;
383     uint8_t b = 0;
384 
385     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
386     sp<IGraphicBufferProducer> igbProducer;
387     setUpProducer(adapter, igbProducer);
388 
389     int slot;
390     sp<Fence> fence;
391     sp<GraphicBuffer> buf;
392     auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
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(), r, g, b);
402     buf->unlock();
403 
404     IGraphicBufferProducer::QueueBufferOutput qbOutput;
405     IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
406                                                    HAL_DATASPACE_UNKNOWN,
407                                                    Rect(mDisplayWidth, mDisplayHeight),
408                                                    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
409                                                    Fence::NO_FENCE);
410     igbProducer->queueBuffer(slot, input, &qbOutput);
411     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
412 
413     adapter.waitForCallbacks();
414 
415     // capture screen and verify that it is red
416     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
417     ASSERT_NO_FATAL_FAILURE(
418             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
419 }
420 
TEST_F(BLASTBufferQueueTest,TripleBuffering)421 TEST_F(BLASTBufferQueueTest, TripleBuffering) {
422     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
423     sp<IGraphicBufferProducer> igbProducer;
424     setUpProducer(adapter, igbProducer);
425 
426     std::vector<std::pair<int, sp<Fence>>> allocated;
427     int minUndequeuedBuffers = 0;
428     ASSERT_EQ(OK, igbProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers));
429     const auto bufferCount = minUndequeuedBuffers + 2;
430 
431     for (int i = 0; i < bufferCount; i++) {
432         int slot;
433         sp<Fence> fence;
434         sp<GraphicBuffer> buf;
435         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
436                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
437                                               nullptr, nullptr);
438         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
439         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
440         allocated.push_back({slot, fence});
441     }
442     for (int i = 0; i < allocated.size(); i++) {
443         igbProducer->cancelBuffer(allocated[i].first, allocated[i].second);
444     }
445 
446     for (int i = 0; i < 100; i++) {
447         int slot;
448         sp<Fence> fence;
449         sp<GraphicBuffer> buf;
450         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
451                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
452                                               nullptr, nullptr);
453         ASSERT_EQ(NO_ERROR, ret);
454         IGraphicBufferProducer::QueueBufferOutput qbOutput;
455         IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
456                                                        HAL_DATASPACE_UNKNOWN,
457                                                        Rect(mDisplayWidth, mDisplayHeight),
458                                                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
459                                                        Fence::NO_FENCE);
460         igbProducer->queueBuffer(slot, input, &qbOutput);
461     }
462     adapter.waitForCallbacks();
463 }
464 
TEST_F(BLASTBufferQueueTest,SetCrop_Item)465 TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
466     uint8_t r = 255;
467     uint8_t g = 0;
468     uint8_t b = 0;
469 
470     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
471     sp<IGraphicBufferProducer> igbProducer;
472     setUpProducer(adapter, igbProducer);
473     int slot;
474     sp<Fence> fence;
475     sp<GraphicBuffer> buf;
476     auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
477                                           PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
478                                           nullptr, nullptr);
479     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
480     ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
481 
482     uint32_t* bufData;
483     buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
484               reinterpret_cast<void**>(&bufData));
485     fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight() / 2), buf->getStride(), r, g, b);
486     buf->unlock();
487 
488     IGraphicBufferProducer::QueueBufferOutput qbOutput;
489     IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
490                                                    HAL_DATASPACE_UNKNOWN,
491                                                    Rect(mDisplayWidth, mDisplayHeight / 2),
492                                                    NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
493                                                    Fence::NO_FENCE);
494     igbProducer->queueBuffer(slot, input, &qbOutput);
495     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
496 
497     adapter.waitForCallbacks();
498     // capture screen and verify that it is red
499     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
500 
501     ASSERT_NO_FATAL_FAILURE(
502             checkScreenCapture(r, g, b,
503                                {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
504 }
505 
TEST_F(BLASTBufferQueueTest,SetCrop_ScalingModeScaleCrop)506 TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) {
507     uint8_t r = 255;
508     uint8_t g = 0;
509     uint8_t b = 0;
510 
511     int32_t bufferSideLength =
512             (mDisplayWidth < mDisplayHeight) ? mDisplayWidth / 2 : mDisplayHeight / 2;
513     int32_t finalCropSideLength = bufferSideLength / 2;
514 
515     auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
516                                      ISurfaceComposerClient::eFXSurfaceEffect);
517     ASSERT_NE(nullptr, bg.get());
518     Transaction t;
519     t.setLayerStack(bg, 0)
520             .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
521             .setColor(bg, half3{0, 0, 0})
522             .setLayer(bg, 0)
523             .apply();
524 
525     BLASTBufferQueueHelper adapter(mSurfaceControl, bufferSideLength, bufferSideLength);
526     sp<IGraphicBufferProducer> igbProducer;
527     setUpProducer(adapter, igbProducer);
528     int slot;
529     sp<Fence> fence;
530     sp<GraphicBuffer> buf;
531     auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSideLength, bufferSideLength,
532                                           PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
533                                           nullptr, nullptr);
534     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
535     ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
536 
537     uint32_t* bufData;
538     buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
539               reinterpret_cast<void**>(&bufData));
540     fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), 0, 0, 0);
541     fillBuffer(bufData,
542                Rect(finalCropSideLength / 2, 0, buf->getWidth() - finalCropSideLength / 2,
543                     buf->getHeight()),
544                buf->getStride(), r, g, b);
545     buf->unlock();
546 
547     IGraphicBufferProducer::QueueBufferOutput qbOutput;
548     IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
549                                                    HAL_DATASPACE_UNKNOWN,
550                                                    Rect(bufferSideLength, finalCropSideLength),
551                                                    NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0,
552                                                    Fence::NO_FENCE);
553     igbProducer->queueBuffer(slot, input, &qbOutput);
554     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
555 
556     adapter.waitForCallbacks();
557     // capture screen and verify that it is red
558     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
559     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b,
560                                                {10, 10, (int32_t)bufferSideLength - 10,
561                                                 (int32_t)bufferSideLength - 10}));
562     ASSERT_NO_FATAL_FAILURE(
563             checkScreenCapture(0, 0, 0,
564                                {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength},
565                                /*border*/ 0, /*outsideRegion*/ true));
566 }
567 
TEST_F(BLASTBufferQueueTest,ScaleCroppedBufferToBufferSize)568 TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToBufferSize) {
569     // add black background
570     auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
571                                      ISurfaceComposerClient::eFXSurfaceEffect);
572     ASSERT_NE(nullptr, bg.get());
573     Transaction t;
574     t.setLayerStack(bg, 0)
575             .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
576             .setColor(bg, half3{0, 0, 0})
577             .setLayer(bg, 0)
578             .apply();
579 
580     Rect windowSize(1000, 1000);
581     Rect bufferSize(windowSize);
582     Rect bufferCrop(200, 200, 700, 700);
583 
584     BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
585     sp<IGraphicBufferProducer> igbProducer;
586     setUpProducer(adapter, igbProducer);
587     int slot;
588     sp<Fence> fence;
589     sp<GraphicBuffer> buf;
590     auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
591                                           bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
592                                           GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
593     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
594     ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
595 
596     uint32_t* bufData;
597     buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
598               reinterpret_cast<void**>(&bufData));
599     // fill buffer with grey
600     fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
601 
602     // fill crop area with different colors so we can verify the cropped region has been scaled
603     // correctly.
604     fillBuffer(bufData, Rect(200, 200, 450, 450), buf->getStride(), /* rgb */ 255, 0, 0);
605     fillBuffer(bufData, Rect(200, 451, 450, 700), buf->getStride(), /* rgb */ 0, 255, 0);
606     fillBuffer(bufData, Rect(451, 200, 700, 450), buf->getStride(), /* rgb */ 0, 0, 255);
607     fillBuffer(bufData, Rect(451, 451, 700, 700), buf->getStride(), /* rgb */ 255, 0, 0);
608     buf->unlock();
609 
610     IGraphicBufferProducer::QueueBufferOutput qbOutput;
611     IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
612                                                    HAL_DATASPACE_UNKNOWN,
613                                                    bufferCrop /* Rect::INVALID_RECT */,
614                                                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
615                                                    Fence::NO_FENCE);
616     igbProducer->queueBuffer(slot, input, &qbOutput);
617     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
618 
619     adapter.waitForCallbacks();
620 
621     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
622 
623     // Verify cropped region is scaled correctly.
624     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
625     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
626     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
627     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
628     // Verify outside region is black.
629     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
630                                                {0, 0, (int32_t)windowSize.getWidth(),
631                                                 (int32_t)windowSize.getHeight()},
632                                                /*border*/ 0, /*outsideRegion*/ true));
633 }
634 
TEST_F(BLASTBufferQueueTest,ScaleCroppedBufferToWindowSize)635 TEST_F(BLASTBufferQueueTest, ScaleCroppedBufferToWindowSize) {
636     // add black background
637     auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
638                                      ISurfaceComposerClient::eFXSurfaceEffect);
639     ASSERT_NE(nullptr, bg.get());
640     Transaction t;
641     t.setLayerStack(bg, 0)
642             .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight))
643             .setColor(bg, half3{0, 0, 0})
644             .setLayer(bg, 0)
645             .apply();
646 
647     Rect windowSize(1000, 1000);
648     Rect bufferSize(500, 500);
649     Rect bufferCrop(100, 100, 350, 350);
650 
651     BLASTBufferQueueHelper adapter(mSurfaceControl, windowSize.getWidth(), windowSize.getHeight());
652     sp<IGraphicBufferProducer> igbProducer;
653     setUpProducer(adapter, igbProducer);
654     int slot;
655     sp<Fence> fence;
656     sp<GraphicBuffer> buf;
657     auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufferSize.getWidth(),
658                                           bufferSize.getHeight(), PIXEL_FORMAT_RGBA_8888,
659                                           GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr);
660     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
661     ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
662 
663     uint32_t* bufData;
664     buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
665               reinterpret_cast<void**>(&bufData));
666     // fill buffer with grey
667     fillBuffer(bufData, bufferSize, buf->getStride(), 127, 127, 127);
668 
669     // fill crop area with different colors so we can verify the cropped region has been scaled
670     // correctly.
671     fillBuffer(bufData, Rect(100, 100, 225, 225), buf->getStride(), /* rgb */ 255, 0, 0);
672     fillBuffer(bufData, Rect(100, 226, 225, 350), buf->getStride(), /* rgb */ 0, 255, 0);
673     fillBuffer(bufData, Rect(226, 100, 350, 225), buf->getStride(), /* rgb */ 0, 0, 255);
674     fillBuffer(bufData, Rect(226, 226, 350, 350), buf->getStride(), /* rgb */ 255, 0, 0);
675     buf->unlock();
676 
677     IGraphicBufferProducer::QueueBufferOutput qbOutput;
678     IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
679                                                    HAL_DATASPACE_UNKNOWN,
680                                                    bufferCrop /* Rect::INVALID_RECT */,
681                                                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0,
682                                                    Fence::NO_FENCE);
683     igbProducer->queueBuffer(slot, input, &qbOutput);
684     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
685 
686     adapter.waitForCallbacks();
687 
688     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
689     // Verify cropped region is scaled correctly.
690     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {10, 10, 490, 490}));
691     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0, {10, 510, 490, 990}));
692     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255, {510, 10, 990, 490}));
693     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0, {510, 510, 990, 990}));
694     // Verify outside region is black.
695     ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
696                                                {0, 0, (int32_t)windowSize.getWidth(),
697                                                 (int32_t)windowSize.getHeight()},
698                                                /*border*/ 0, /*outsideRegion*/ true));
699 }
700 
701 // b/196339769 verify we can can update the requested size while the in FREEZE scaling mode and
702 // scale the buffer properly when the mode changes to SCALE_TO_WINDOW
TEST_F(BLASTBufferQueueTest,ScalingModeChanges)703 TEST_F(BLASTBufferQueueTest, ScalingModeChanges) {
704     uint8_t r = 255;
705     uint8_t g = 0;
706     uint8_t b = 0;
707 
708     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight / 4);
709     sp<IGraphicBufferProducer> igbProducer;
710     setUpProducer(adapter, igbProducer);
711     {
712         int slot;
713         sp<Fence> fence;
714         sp<GraphicBuffer> buf;
715         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 4,
716                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
717                                               nullptr, nullptr);
718         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
719         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
720 
721         uint32_t* bufData;
722         buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
723                   reinterpret_cast<void**>(&bufData));
724         fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
725         buf->unlock();
726 
727         IGraphicBufferProducer::QueueBufferOutput qbOutput;
728         IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
729                                                        HAL_DATASPACE_UNKNOWN, {},
730                                                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
731                                                        Fence::NO_FENCE);
732         igbProducer->queueBuffer(slot, input, &qbOutput);
733         adapter.waitForCallbacks();
734     }
735     // capture screen and verify that it is red
736     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
737 
738     ASSERT_NO_FATAL_FAILURE(
739             checkScreenCapture(r, g, b,
740                                {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 4}));
741 
742     // update the size to half the display and dequeue a buffer quarter of the display.
743     adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight / 2);
744 
745     {
746         int slot;
747         sp<Fence> fence;
748         sp<GraphicBuffer> buf;
749         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight / 8,
750                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
751                                               nullptr, nullptr);
752         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
753         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
754 
755         uint32_t* bufData;
756         buf->lock(static_cast<uint32_t>(GraphicBuffer::USAGE_SW_WRITE_OFTEN),
757                   reinterpret_cast<void**>(&bufData));
758         g = 255;
759         fillBuffer(bufData, Rect(buf->getWidth(), buf->getHeight()), buf->getStride(), r, g, b);
760         buf->unlock();
761 
762         IGraphicBufferProducer::QueueBufferOutput qbOutput;
763         IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
764                                                        HAL_DATASPACE_UNKNOWN, {},
765                                                        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
766                                                        0, Fence::NO_FENCE);
767         igbProducer->queueBuffer(slot, input, &qbOutput);
768         adapter.waitForCallbacks();
769     }
770     // capture screen and verify that it is red
771     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
772     // verify we still scale the buffer to the new size (half the screen height)
773     ASSERT_NO_FATAL_FAILURE(
774             checkScreenCapture(r, g, b,
775                                {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
776 }
777 
TEST_F(BLASTBufferQueueTest,SyncThenNoSync)778 TEST_F(BLASTBufferQueueTest, SyncThenNoSync) {
779     uint8_t r = 255;
780     uint8_t g = 0;
781     uint8_t b = 0;
782 
783     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
784 
785     sp<IGraphicBufferProducer> igbProducer;
786     setUpProducer(adapter, igbProducer);
787 
788     Transaction next;
789     adapter.setNextTransaction(&next);
790     queueBuffer(igbProducer, 0, 255, 0, 0);
791 
792     // queue non sync buffer, so this one should get blocked
793     // Add a present delay to allow the first screenshot to get taken.
794     nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
795     queueBuffer(igbProducer, r, g, b, presentTimeDelay);
796 
797     CallbackHelper transactionCallback;
798     next.addTransactionCompletedCallback(transactionCallback.function,
799                                          transactionCallback.getContext())
800             .apply();
801 
802     CallbackData callbackData;
803     transactionCallback.getCallbackData(&callbackData);
804 
805     // capture screen and verify that it is red
806     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
807     ASSERT_NO_FATAL_FAILURE(
808             checkScreenCapture(0, 255, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
809 
810     mProducerListener->waitOnNumberReleased(1);
811     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
812     ASSERT_NO_FATAL_FAILURE(
813             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
814 }
815 
TEST_F(BLASTBufferQueueTest,MultipleSyncTransactions)816 TEST_F(BLASTBufferQueueTest, MultipleSyncTransactions) {
817     uint8_t r = 255;
818     uint8_t g = 0;
819     uint8_t b = 0;
820 
821     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
822 
823     sp<IGraphicBufferProducer> igbProducer;
824     setUpProducer(adapter, igbProducer);
825 
826     Transaction mainTransaction;
827 
828     Transaction next;
829     adapter.setNextTransaction(&next);
830     queueBuffer(igbProducer, 0, 255, 0, 0);
831 
832     mainTransaction.merge(std::move(next));
833 
834     adapter.setNextTransaction(&next);
835     queueBuffer(igbProducer, r, g, b, 0);
836 
837     mainTransaction.merge(std::move(next));
838     // Expect 1 buffer to be released even before sending to SurfaceFlinger
839     mProducerListener->waitOnNumberReleased(1);
840 
841     CallbackHelper transactionCallback;
842     mainTransaction
843             .addTransactionCompletedCallback(transactionCallback.function,
844                                              transactionCallback.getContext())
845             .apply();
846 
847     CallbackData callbackData;
848     transactionCallback.getCallbackData(&callbackData);
849 
850     // capture screen and verify that it is red
851     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
852     ASSERT_NO_FATAL_FAILURE(
853             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
854 }
855 
TEST_F(BLASTBufferQueueTest,MultipleSyncTransactionWithNonSync)856 TEST_F(BLASTBufferQueueTest, MultipleSyncTransactionWithNonSync) {
857     uint8_t r = 255;
858     uint8_t g = 0;
859     uint8_t b = 0;
860 
861     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
862 
863     sp<IGraphicBufferProducer> igbProducer;
864     setUpProducer(adapter, igbProducer);
865 
866     Transaction mainTransaction;
867 
868     Transaction next;
869     // queue a sync transaction
870     adapter.setNextTransaction(&next);
871     queueBuffer(igbProducer, 0, 255, 0, 0);
872 
873     mainTransaction.merge(std::move(next));
874 
875     // queue another buffer without setting next transaction
876     queueBuffer(igbProducer, 0, 0, 255, 0);
877 
878     // queue another sync transaction
879     adapter.setNextTransaction(&next);
880     queueBuffer(igbProducer, r, g, b, 0);
881     // Expect 1 buffer to be released because the non sync transaction should merge
882     // with the sync
883     mProducerListener->waitOnNumberReleased(1);
884 
885     mainTransaction.merge(std::move(next));
886     // Expect 2 buffers to be released due to merging the two syncs.
887     mProducerListener->waitOnNumberReleased(2);
888 
889     CallbackHelper transactionCallback;
890     mainTransaction
891             .addTransactionCompletedCallback(transactionCallback.function,
892                                              transactionCallback.getContext())
893             .apply();
894 
895     CallbackData callbackData;
896     transactionCallback.getCallbackData(&callbackData);
897 
898     // capture screen and verify that it is red
899     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
900     ASSERT_NO_FATAL_FAILURE(
901             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
902 }
903 
TEST_F(BLASTBufferQueueTest,MultipleSyncRunOutOfBuffers)904 TEST_F(BLASTBufferQueueTest, MultipleSyncRunOutOfBuffers) {
905     uint8_t r = 255;
906     uint8_t g = 0;
907     uint8_t b = 0;
908 
909     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
910 
911     sp<IGraphicBufferProducer> igbProducer;
912     setUpProducer(adapter, igbProducer, 3);
913 
914     Transaction mainTransaction;
915 
916     Transaction next;
917     // queue a sync transaction
918     adapter.setNextTransaction(&next);
919     queueBuffer(igbProducer, 0, 255, 0, 0);
920 
921     mainTransaction.merge(std::move(next));
922 
923     // queue a few buffers without setting next transaction
924     queueBuffer(igbProducer, 0, 0, 255, 0);
925     queueBuffer(igbProducer, 0, 0, 255, 0);
926     queueBuffer(igbProducer, 0, 0, 255, 0);
927 
928     // queue another sync transaction
929     adapter.setNextTransaction(&next);
930     queueBuffer(igbProducer, r, g, b, 0);
931     // Expect 3 buffers to be released because the non sync transactions should merge
932     // with the sync
933     mProducerListener->waitOnNumberReleased(3);
934 
935     mainTransaction.merge(std::move(next));
936     // Expect 4 buffers to be released due to merging the two syncs.
937     mProducerListener->waitOnNumberReleased(4);
938 
939     CallbackHelper transactionCallback;
940     mainTransaction
941             .addTransactionCompletedCallback(transactionCallback.function,
942                                              transactionCallback.getContext())
943             .apply();
944 
945     CallbackData callbackData;
946     transactionCallback.getCallbackData(&callbackData);
947 
948     // capture screen and verify that it is red
949     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
950     ASSERT_NO_FATAL_FAILURE(
951             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
952 }
953 
954 // Tests BBQ with a sync transaction when the buffers acquired reaches max and the only way to
955 // continue processing is for a release callback from SurfaceFlinger.
956 // This is done by sending a buffer to SF so it can release the previous one and allow BBQ to
957 // continue acquiring buffers.
TEST_F(BLASTBufferQueueTest,RunOutOfBuffersWaitingOnSF)958 TEST_F(BLASTBufferQueueTest, RunOutOfBuffersWaitingOnSF) {
959     uint8_t r = 255;
960     uint8_t g = 0;
961     uint8_t b = 0;
962 
963     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
964 
965     sp<IGraphicBufferProducer> igbProducer;
966     setUpProducer(adapter, igbProducer, 4);
967 
968     Transaction mainTransaction;
969 
970     // Send a buffer to SF
971     queueBuffer(igbProducer, 0, 255, 0, 0);
972 
973     Transaction next;
974     // queue a sync transaction
975     adapter.setNextTransaction(&next);
976     queueBuffer(igbProducer, 0, 255, 0, 0);
977 
978     mainTransaction.merge(std::move(next));
979 
980     // queue a few buffers without setting next transaction
981     queueBuffer(igbProducer, 0, 0, 255, 0);
982     queueBuffer(igbProducer, 0, 0, 255, 0);
983     queueBuffer(igbProducer, 0, 0, 255, 0);
984 
985     // apply the first synced buffer to ensure we have to wait on SF
986     mainTransaction.apply();
987 
988     // queue another sync transaction
989     adapter.setNextTransaction(&next);
990     queueBuffer(igbProducer, r, g, b, 0);
991     // Expect 2 buffers to be released because the non sync transactions should merge
992     // with the sync
993     mProducerListener->waitOnNumberReleased(3);
994 
995     mainTransaction.merge(std::move(next));
996 
997     CallbackHelper transactionCallback;
998     mainTransaction
999             .addTransactionCompletedCallback(transactionCallback.function,
1000                                              transactionCallback.getContext())
1001             .apply();
1002 
1003     CallbackData callbackData;
1004     transactionCallback.getCallbackData(&callbackData);
1005 
1006     // capture screen and verify that it is red
1007     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1008     ASSERT_NO_FATAL_FAILURE(
1009             checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
1010 }
1011 
1012 class TestProducerListener : public BnProducerListener {
1013 public:
1014     sp<IGraphicBufferProducer> mIgbp;
TestProducerListener(const sp<IGraphicBufferProducer> & igbp)1015     TestProducerListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
onBufferReleased()1016     void onBufferReleased() override {
1017         sp<GraphicBuffer> buffer;
1018         sp<Fence> fence;
1019         mIgbp->detachNextBuffer(&buffer, &fence);
1020     }
1021 };
1022 
TEST_F(BLASTBufferQueueTest,CustomProducerListener)1023 TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
1024     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1025     sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1026     ASSERT_NE(nullptr, igbProducer.get());
1027     ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1028     IGraphicBufferProducer::QueueBufferOutput qbOutput;
1029     ASSERT_EQ(NO_ERROR,
1030               igbProducer->connect(new TestProducerListener(igbProducer), NATIVE_WINDOW_API_CPU,
1031                                    false, &qbOutput));
1032     ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1033     for (int i = 0; i < 3; i++) {
1034         int slot;
1035         sp<Fence> fence;
1036         sp<GraphicBuffer> buf;
1037         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1038                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1039                                               nullptr, nullptr);
1040         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1041         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1042         IGraphicBufferProducer::QueueBufferOutput qbOutput;
1043         IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1044                                                        HAL_DATASPACE_UNKNOWN,
1045                                                        Rect(mDisplayWidth, mDisplayHeight),
1046                                                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1047                                                        Fence::NO_FENCE);
1048         igbProducer->queueBuffer(slot, input, &qbOutput);
1049     }
1050     adapter.waitForCallbacks();
1051 }
1052 
TEST_F(BLASTBufferQueueTest,QueryNativeWindowQueuesToWindowComposer)1053 TEST_F(BLASTBufferQueueTest, QueryNativeWindowQueuesToWindowComposer) {
1054     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1055 
1056     sp<android::Surface> surface = new Surface(adapter.getIGraphicBufferProducer());
1057     ANativeWindow* nativeWindow = (ANativeWindow*)(surface.get());
1058     int queuesToNativeWindow = 0;
1059     int err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
1060                                   &queuesToNativeWindow);
1061     ASSERT_EQ(NO_ERROR, err);
1062     ASSERT_EQ(queuesToNativeWindow, 1);
1063 }
1064 
1065 // Test a slow producer doesn't hold up a faster producer from the same client. Essentially tests
1066 // BBQ uses separate transaction queues.
TEST_F(BLASTBufferQueueTest,OutOfOrderTransactionTest)1067 TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) {
1068     sp<SurfaceControl> bgSurface =
1069             mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1070                                    ISurfaceComposerClient::eFXSurfaceBufferState);
1071     ASSERT_NE(nullptr, bgSurface.get());
1072     Transaction t;
1073     t.setLayerStack(bgSurface, 0)
1074             .show(bgSurface)
1075             .setDataspace(bgSurface, ui::Dataspace::V0_SRGB)
1076             .setLayer(bgSurface, std::numeric_limits<int32_t>::max() - 1)
1077             .apply();
1078 
1079     BLASTBufferQueueHelper slowAdapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1080     sp<IGraphicBufferProducer> slowIgbProducer;
1081     setUpProducer(slowAdapter, slowIgbProducer);
1082     nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count();
1083     queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay);
1084 
1085     BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight);
1086     sp<IGraphicBufferProducer> fastIgbProducer;
1087     setUpProducer(fastAdapter, fastIgbProducer);
1088     uint8_t r = 255;
1089     uint8_t g = 0;
1090     uint8_t b = 0;
1091     queueBuffer(fastIgbProducer, r, g, b, 0 /* presentTimeDelay */);
1092     fastAdapter.waitForCallbacks();
1093 
1094     // capture screen and verify that it is red
1095     ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1096 
1097     ASSERT_NO_FATAL_FAILURE(
1098             checkScreenCapture(r, g, b,
1099                                {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2}));
1100 }
1101 
TEST_F(BLASTBufferQueueTest,TransformHint)1102 TEST_F(BLASTBufferQueueTest, TransformHint) {
1103     // Transform hint is provided to BBQ via the surface control passed by WM
1104     mSurfaceControl->setTransformHint(ui::Transform::ROT_90);
1105 
1106     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1107     sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
1108     ASSERT_NE(nullptr, igbProducer.get());
1109     ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2));
1110     sp<Surface> surface = adapter.getSurface();
1111 
1112     // Before connecting to the surface, we do not get a valid transform hint
1113     int transformHint;
1114     surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1115     ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1116 
1117     ASSERT_EQ(NO_ERROR,
1118               surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
1119 
1120     // After connecting to the surface, we should get the correct hint.
1121     surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1122     ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1123 
1124     ANativeWindow_Buffer buffer;
1125     surface->lock(&buffer, nullptr /* inOutDirtyBounds */);
1126 
1127     // Transform hint is updated via callbacks or surface control updates
1128     mSurfaceControl->setTransformHint(ui::Transform::ROT_0);
1129     adapter.update(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1130 
1131     // The hint does not change and matches the value used when dequeueing the buffer.
1132     surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1133     ASSERT_EQ(ui::Transform::ROT_90, transformHint);
1134 
1135     surface->unlockAndPost();
1136 
1137     // After queuing the buffer, we get the updated transform hint
1138     surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
1139     ASSERT_EQ(ui::Transform::ROT_0, transformHint);
1140 
1141     adapter.waitForCallbacks();
1142 }
1143 
1144 class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest {
1145 public:
test(uint32_t tr)1146     void test(uint32_t tr) {
1147         BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1148         sp<IGraphicBufferProducer> igbProducer;
1149         setUpProducer(adapter, igbProducer);
1150 
1151         auto bufWidth = mDisplayWidth;
1152         auto bufHeight = mDisplayHeight;
1153         int slot;
1154         sp<Fence> fence;
1155         sp<GraphicBuffer> buf;
1156 
1157         auto ret = igbProducer->dequeueBuffer(&slot, &fence, bufWidth, bufHeight,
1158                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1159                                               nullptr, nullptr);
1160         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret);
1161         ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1162 
1163         fillQuadrants(buf);
1164 
1165         IGraphicBufferProducer::QueueBufferOutput qbOutput;
1166         IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */,
1167                                                        HAL_DATASPACE_UNKNOWN,
1168                                                        Rect(bufWidth, bufHeight),
1169                                                        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
1170                                                        tr, Fence::NO_FENCE);
1171         igbProducer->queueBuffer(slot, input, &qbOutput);
1172         ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint);
1173 
1174         adapter.waitForCallbacks();
1175         ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
1176 
1177         switch (tr) {
1178             case ui::Transform::ROT_0:
1179                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 0,
1180                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1181                                                             (int32_t)mDisplayHeight / 2},
1182                                                            1));
1183                 ASSERT_NO_FATAL_FAILURE(
1184                         checkScreenCapture(255, 0, 0,
1185                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1186                                             (int32_t)mDisplayHeight / 2},
1187                                            1));
1188                 ASSERT_NO_FATAL_FAILURE(
1189                         checkScreenCapture(0, 255, 0,
1190                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1191                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1192                                            1));
1193                 ASSERT_NO_FATAL_FAILURE(
1194                         checkScreenCapture(0, 0, 255,
1195                                            {0, (int32_t)mDisplayHeight / 2,
1196                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1197                                            1));
1198                 break;
1199             case ui::Transform::FLIP_H:
1200                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1201                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1202                                                             (int32_t)mDisplayHeight / 2},
1203                                                            1));
1204                 ASSERT_NO_FATAL_FAILURE(
1205                         checkScreenCapture(0, 0, 0,
1206                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1207                                             (int32_t)mDisplayHeight / 2},
1208                                            1));
1209                 ASSERT_NO_FATAL_FAILURE(
1210                         checkScreenCapture(0, 0, 255,
1211                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1212                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1213                                            1));
1214                 ASSERT_NO_FATAL_FAILURE(
1215                         checkScreenCapture(0, 255, 0,
1216                                            {0, (int32_t)mDisplayHeight / 2,
1217                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1218                                            1));
1219                 break;
1220             case ui::Transform::FLIP_V:
1221                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1222                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1223                                                             (int32_t)mDisplayHeight / 2},
1224                                                            1));
1225                 ASSERT_NO_FATAL_FAILURE(
1226                         checkScreenCapture(0, 255, 0,
1227                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1228                                             (int32_t)mDisplayHeight / 2},
1229                                            1));
1230                 ASSERT_NO_FATAL_FAILURE(
1231                         checkScreenCapture(255, 0, 0,
1232                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1233                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1234                                            1));
1235                 ASSERT_NO_FATAL_FAILURE(
1236                         checkScreenCapture(0, 0, 0,
1237                                            {0, (int32_t)mDisplayHeight / 2,
1238                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1239                                            1));
1240                 break;
1241             case ui::Transform::ROT_90:
1242                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 0, 255,
1243                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1244                                                             (int32_t)mDisplayHeight / 2},
1245                                                            1));
1246                 ASSERT_NO_FATAL_FAILURE(
1247                         checkScreenCapture(0, 0, 0,
1248                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1249                                             (int32_t)mDisplayHeight / 2},
1250                                            1));
1251                 ASSERT_NO_FATAL_FAILURE(
1252                         checkScreenCapture(255, 0, 0,
1253                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1254                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1255                                            1));
1256                 ASSERT_NO_FATAL_FAILURE(
1257                         checkScreenCapture(0, 255, 0,
1258                                            {0, (int32_t)mDisplayHeight / 2,
1259                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1260                                            1));
1261                 break;
1262             case ui::Transform::ROT_180:
1263                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(0, 255, 0,
1264                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1265                                                             (int32_t)mDisplayHeight / 2},
1266                                                            1));
1267                 ASSERT_NO_FATAL_FAILURE(
1268                         checkScreenCapture(0, 0, 255,
1269                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1270                                             (int32_t)mDisplayHeight / 2},
1271                                            1));
1272                 ASSERT_NO_FATAL_FAILURE(
1273                         checkScreenCapture(0, 0, 0,
1274                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1275                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1276                                            1));
1277                 ASSERT_NO_FATAL_FAILURE(
1278                         checkScreenCapture(255, 0, 0,
1279                                            {0, (int32_t)mDisplayHeight / 2,
1280                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1281                                            1));
1282                 break;
1283             case ui::Transform::ROT_270:
1284                 ASSERT_NO_FATAL_FAILURE(checkScreenCapture(255, 0, 0,
1285                                                            {0, 0, (int32_t)mDisplayWidth / 2,
1286                                                             (int32_t)mDisplayHeight / 2},
1287                                                            1));
1288                 ASSERT_NO_FATAL_FAILURE(
1289                         checkScreenCapture(0, 255, 0,
1290                                            {(int32_t)mDisplayWidth / 2, 0, (int32_t)mDisplayWidth,
1291                                             (int32_t)mDisplayHeight / 2},
1292                                            1));
1293                 ASSERT_NO_FATAL_FAILURE(
1294                         checkScreenCapture(0, 0, 255,
1295                                            {(int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight / 2,
1296                                             (int32_t)mDisplayWidth, (int32_t)mDisplayHeight},
1297                                            1));
1298                 ASSERT_NO_FATAL_FAILURE(
1299                         checkScreenCapture(0, 0, 0,
1300                                            {0, (int32_t)mDisplayHeight / 2,
1301                                             (int32_t)mDisplayWidth / 2, (int32_t)mDisplayHeight},
1302                                            1));
1303         }
1304     }
1305 };
1306 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_0)1307 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_0) {
1308     test(ui::Transform::ROT_0);
1309 }
1310 
TEST_F(BLASTBufferQueueTransformTest,setTransform_FLIP_H)1311 TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_H) {
1312     test(ui::Transform::FLIP_H);
1313 }
1314 
TEST_F(BLASTBufferQueueTransformTest,setTransform_FLIP_V)1315 TEST_F(BLASTBufferQueueTransformTest, setTransform_FLIP_V) {
1316     test(ui::Transform::FLIP_V);
1317 }
1318 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_90)1319 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_90) {
1320     test(ui::Transform::ROT_90);
1321 }
1322 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_180)1323 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_180) {
1324     test(ui::Transform::ROT_180);
1325 }
1326 
TEST_F(BLASTBufferQueueTransformTest,setTransform_ROT_270)1327 TEST_F(BLASTBufferQueueTransformTest, setTransform_ROT_270) {
1328     test(ui::Transform::ROT_270);
1329 }
1330 
1331 class BLASTFrameEventHistoryTest : public BLASTBufferQueueTest {
1332 public:
setUpAndQueueBuffer(const sp<IGraphicBufferProducer> & igbProducer,nsecs_t * outRequestedPresentTime,nsecs_t * postedTime,IGraphicBufferProducer::QueueBufferOutput * qbOutput,bool getFrameTimestamps,nsecs_t requestedPresentTime=systemTime ())1333     void setUpAndQueueBuffer(const sp<IGraphicBufferProducer>& igbProducer,
1334                              nsecs_t* outRequestedPresentTime, nsecs_t* postedTime,
1335                              IGraphicBufferProducer::QueueBufferOutput* qbOutput,
1336                              bool getFrameTimestamps, nsecs_t requestedPresentTime = systemTime()) {
1337         int slot;
1338         sp<Fence> fence;
1339         sp<GraphicBuffer> buf;
1340         auto ret = igbProducer->dequeueBuffer(&slot, &fence, mDisplayWidth, mDisplayHeight,
1341                                               PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN,
1342                                               nullptr, nullptr);
1343         if (IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION == ret) {
1344             ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf));
1345         }
1346 
1347         *outRequestedPresentTime = requestedPresentTime;
1348         IGraphicBufferProducer::QueueBufferInput input(requestedPresentTime, false,
1349                                                        HAL_DATASPACE_UNKNOWN,
1350                                                        Rect(mDisplayWidth, mDisplayHeight),
1351                                                        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1352                                                        Fence::NO_FENCE, /*sticky*/ 0,
1353                                                        getFrameTimestamps);
1354         if (postedTime) *postedTime = systemTime();
1355         igbProducer->queueBuffer(slot, input, qbOutput);
1356     }
1357     sp<SurfaceControl> mBufferQueueSurfaceControl;
1358 };
1359 
TEST_F(BLASTFrameEventHistoryTest,FrameEventHistory_Basic)1360 TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) {
1361     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1362     sp<IGraphicBufferProducer> igbProducer;
1363     ProducerFrameEventHistory history;
1364     setUpProducer(adapter, igbProducer);
1365 
1366     IGraphicBufferProducer::QueueBufferOutput qbOutput;
1367     nsecs_t requestedPresentTimeA = 0;
1368     nsecs_t postedTimeA = 0;
1369     adapter.setTransactionCompleteCallback(1);
1370     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1371     history.applyDelta(qbOutput.frameTimestamps);
1372 
1373     FrameEvents* events = nullptr;
1374     events = history.getFrame(1);
1375     ASSERT_NE(nullptr, events);
1376     ASSERT_EQ(1, events->frameNumber);
1377     ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1378     ASSERT_GE(events->postedTime, postedTimeA);
1379 
1380     adapter.waitForCallback(1);
1381 
1382     // queue another buffer so we query for frame event deltas
1383     nsecs_t requestedPresentTimeB = 0;
1384     nsecs_t postedTimeB = 0;
1385     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1386     history.applyDelta(qbOutput.frameTimestamps);
1387     events = history.getFrame(1);
1388     ASSERT_NE(nullptr, events);
1389 
1390     // frame number, requestedPresentTime, and postTime should not have changed
1391     ASSERT_EQ(1, events->frameNumber);
1392     ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1393     ASSERT_GE(events->postedTime, postedTimeA);
1394 
1395     ASSERT_GE(events->latchTime, postedTimeA);
1396     ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1397     ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1398     ASSERT_NE(nullptr, events->displayPresentFence);
1399     ASSERT_NE(nullptr, events->releaseFence);
1400 
1401     // we should also have gotten the initial values for the next frame
1402     events = history.getFrame(2);
1403     ASSERT_NE(nullptr, events);
1404     ASSERT_EQ(2, events->frameNumber);
1405     ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1406     ASSERT_GE(events->postedTime, postedTimeB);
1407 
1408     // wait for any callbacks that have not been received
1409     adapter.waitForCallbacks();
1410 }
1411 
TEST_F(BLASTFrameEventHistoryTest,FrameEventHistory_DroppedFrame)1412 TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) {
1413     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1414     sp<IGraphicBufferProducer> igbProducer;
1415     setUpProducer(adapter, igbProducer);
1416 
1417     ProducerFrameEventHistory history;
1418     IGraphicBufferProducer::QueueBufferOutput qbOutput;
1419     nsecs_t requestedPresentTimeA = 0;
1420     nsecs_t postedTimeA = 0;
1421     // Present the frame sometime in the future so we can add two frames to the queue so the older
1422     // one will be dropped.
1423     nsecs_t presentTime = systemTime() + std::chrono::nanoseconds(500ms).count();
1424     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true,
1425                         presentTime);
1426     history.applyDelta(qbOutput.frameTimestamps);
1427 
1428     FrameEvents* events = nullptr;
1429     events = history.getFrame(1);
1430     ASSERT_NE(nullptr, events);
1431     ASSERT_EQ(1, events->frameNumber);
1432     ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1433     ASSERT_GE(events->postedTime, postedTimeA);
1434 
1435     // queue another buffer so the first can be dropped
1436     nsecs_t requestedPresentTimeB = 0;
1437     nsecs_t postedTimeB = 0;
1438     adapter.setTransactionCompleteCallback(2);
1439     presentTime = systemTime() + std::chrono::nanoseconds(1ms).count();
1440     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true,
1441                         presentTime);
1442     history.applyDelta(qbOutput.frameTimestamps);
1443     events = history.getFrame(1);
1444     ASSERT_NE(nullptr, events);
1445 
1446     // frame number, requestedPresentTime, and postTime should not have changed
1447     ASSERT_EQ(1, events->frameNumber);
1448     ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1449     ASSERT_GE(events->postedTime, postedTimeA);
1450 
1451     // a valid latchtime and pre and post composition info should not be set for the dropped frame
1452     ASSERT_FALSE(events->hasLatchInfo());
1453     ASSERT_FALSE(events->hasDequeueReadyInfo());
1454     ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1455     ASSERT_FALSE(events->hasDisplayPresentInfo());
1456     ASSERT_FALSE(events->hasReleaseInfo());
1457 
1458     // wait for the last transaction to be completed.
1459     adapter.waitForCallback(2);
1460 
1461     // queue another buffer so we query for frame event deltas
1462     nsecs_t requestedPresentTimeC = 0;
1463     nsecs_t postedTimeC = 0;
1464     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeC, &postedTimeC, &qbOutput, true);
1465     history.applyDelta(qbOutput.frameTimestamps);
1466 
1467     // frame number, requestedPresentTime, and postTime should not have changed
1468     ASSERT_EQ(1, events->frameNumber);
1469     ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime);
1470     ASSERT_GE(events->postedTime, postedTimeA);
1471 
1472     // a valid latchtime and pre and post composition info should not be set for the dropped frame
1473     ASSERT_FALSE(events->hasLatchInfo());
1474     ASSERT_FALSE(events->hasDequeueReadyInfo());
1475     ASSERT_FALSE(events->hasGpuCompositionDoneInfo());
1476     ASSERT_FALSE(events->hasDisplayPresentInfo());
1477     ASSERT_FALSE(events->hasReleaseInfo());
1478 
1479     // we should also have gotten values for the presented frame
1480     events = history.getFrame(2);
1481     ASSERT_NE(nullptr, events);
1482     ASSERT_EQ(2, events->frameNumber);
1483     ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
1484     ASSERT_GE(events->postedTime, postedTimeB);
1485     ASSERT_GE(events->latchTime, postedTimeB);
1486     ASSERT_GE(events->dequeueReadyTime, events->latchTime);
1487     ASSERT_NE(nullptr, events->gpuCompositionDoneFence);
1488     ASSERT_NE(nullptr, events->displayPresentFence);
1489     ASSERT_NE(nullptr, events->releaseFence);
1490 
1491     // wait for any callbacks that have not been received
1492     adapter.waitForCallbacks();
1493 }
1494 
TEST_F(BLASTFrameEventHistoryTest,FrameEventHistory_CompositorTimings)1495 TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) {
1496     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
1497     sp<IGraphicBufferProducer> igbProducer;
1498     ProducerFrameEventHistory history;
1499     setUpProducer(adapter, igbProducer);
1500 
1501     IGraphicBufferProducer::QueueBufferOutput qbOutput;
1502     nsecs_t requestedPresentTimeA = 0;
1503     nsecs_t postedTimeA = 0;
1504     adapter.setTransactionCompleteCallback(1);
1505     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true);
1506     history.applyDelta(qbOutput.frameTimestamps);
1507     adapter.waitForCallback(1);
1508 
1509     // queue another buffer so we query for frame event deltas
1510     nsecs_t requestedPresentTimeB = 0;
1511     nsecs_t postedTimeB = 0;
1512     setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true);
1513     history.applyDelta(qbOutput.frameTimestamps);
1514 
1515     // check for a valid compositor deadline
1516     ASSERT_NE(0, history.getReportedCompositeDeadline());
1517 
1518     // wait for any callbacks that have not been received
1519     adapter.waitForCallbacks();
1520 }
1521 
1522 } // namespace android
1523