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