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