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