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