19e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis/*
29e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * Copyright (C) 2012 The Android Open Source Project
39e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis *
49e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
59e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * you may not use this file except in compliance with the License.
69e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * You may obtain a copy of the License at
79e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis *
89e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
99e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis *
109e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * Unless required by applicable law or agreed to in writing, software
119e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
129e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * See the License for the specific language governing permissions and
149e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis * limitations under the License.
159e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis */
169e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
179e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis#define LOG_TAG "BufferQueue_test"
189e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis//#define LOG_NDEBUG 0
199e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
20c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza#include "DummyConsumer.h"
21c6f30bdee1f634eb90d68cb76efe935b6535a1e8Dan Stoza
22cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza#include <gui/BufferItem.h>
23f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <gui/BufferQueue.h>
24f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <gui/IProducerListener.h>
259e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
269e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis#include <ui/GraphicBuffer.h>
279e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
281a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza#include <binder/IPCThreadState.h>
299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza#include <binder/IServiceManager.h>
301a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza#include <binder/ProcessState.h>
31f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza
32f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <utils/String8.h>
33f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <utils/threads.h>
34f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza
356a3c05bcfab588fd99dd8d619a53d15374e99507Mathias Agopian#include <system/window.h>
366a3c05bcfab588fd99dd8d619a53d15374e99507Mathias Agopian
37f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza#include <gtest/gtest.h>
389e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
39e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza#include <thread>
40e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
41e77c7669bee30b7c0099172cf0c38cef92412040Dan Stozausing namespace std::chrono_literals;
42e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
439e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennisnamespace android {
449e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
459e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennisclass BufferQueueTest : public ::testing::Test {
469e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozapublic:
489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stozaprotected:
499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    BufferQueueTest() {
509e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis        const ::testing::TestInfo* const testInfo =
519e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
529e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
539e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis                testInfo->name());
549e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    }
559e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ~BufferQueueTest() {
579e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis        const ::testing::TestInfo* const testInfo =
589e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis            ::testing::UnitTest::GetInstance()->current_test_info();
599e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
609e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis                testInfo->name());
619e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    }
629e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
637ea777f097784492f880623067becac1b276f884Igor Murashkin    void GetMinUndequeuedBufferCount(int* bufferCount) {
649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_TRUE(bufferCount != NULL);
659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza                    bufferCount));
679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_GE(*bufferCount, 0);
687ea777f097784492f880623067becac1b276f884Igor Murashkin    }
697ea777f097784492f880623067becac1b276f884Igor Murashkin
701a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    void createBufferQueue() {
711a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
721a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    }
739e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
74ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
75ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            const BufferItem& item) {
76ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        int64_t timestamp;
77ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        bool isAutoTimestamp;
78ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        android_dataspace dataSpace;
79ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        Rect crop;
80ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        int scalingMode;
81ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        uint32_t transform;
82ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        sp<Fence> fence;
83ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
84ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
85ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos                &scalingMode, &transform, &fence, NULL);
86ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(timestamp, item.mTimestamp);
87ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
88ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(dataSpace, item.mDataSpace);
89ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(crop, item.mCrop);
90ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
91ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(transform, item.mTransform);
92ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(fence, item.mFence);
93ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    }
94ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
951a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<IGraphicBufferProducer> mProducer;
961a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<IGraphicBufferConsumer> mConsumer;
971a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza};
989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
99f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stozastatic const uint32_t TEST_DATA = 0x12345678u;
100f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza
1011a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza// XXX: Tests that fork a process to hold the BufferQueue must run before tests
1021a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza// that use a local BufferQueue, or else Binder will get unhappy
10388752d7f1a13a425c59c429f0986f6f899b7826bKalle Raita//
10488752d7f1a13a425c59c429f0986f6f899b7826bKalle Raita// In one instance this was a crash in the createBufferQueue where the
10588752d7f1a13a425c59c429f0986f6f899b7826bKalle Raita// binder call to create a buffer allocator apparently got garbage back.
10688752d7f1a13a425c59c429f0986f6f899b7826bKalle Raita// See b/36592665.
10788752d7f1a13a425c59c429f0986f6f899b7826bKalle RaitaTEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
1081a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    const String16 PRODUCER_NAME = String16("BQTestProducer");
1091a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    const String16 CONSUMER_NAME = String16("BQTestConsumer");
1101a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1111a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    pid_t forkPid = fork();
1121a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_NE(forkPid, -1);
1131a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1141a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    if (forkPid == 0) {
1151a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        // Child process
116b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza        sp<IGraphicBufferProducer> producer;
117b3d0bdf0dbc19f0a0d7d924693025371e24828fdDan Stoza        sp<IGraphicBufferConsumer> consumer;
1181a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        BufferQueue::createBufferQueue(&producer, &consumer);
1191a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        sp<IServiceManager> serviceManager = defaultServiceManager();
120097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen        serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
121097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen        serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
1221a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        ProcessState::self()->startThreadPool();
1231a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        IPCThreadState::self()->joinThreadPool();
1241a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        LOG_ALWAYS_FATAL("Shouldn't be here");
1251a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    }
1261a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1271a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<IServiceManager> serviceManager = defaultServiceManager();
1281a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<IBinder> binderProducer =
1291a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        serviceManager->getService(PRODUCER_NAME);
1301a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
1311a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    EXPECT_TRUE(mProducer != NULL);
1321a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<IBinder> binderConsumer =
1331a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza        serviceManager->getService(CONSUMER_NAME);
1341a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
1351a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    EXPECT_TRUE(mConsumer != NULL);
1361a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1371a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
1381a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
1391a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
1401a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK,
1411a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
1421a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1431a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    int slot;
1441a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<Fence> fence;
1451a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    sp<GraphicBuffer> buffer;
1461a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
147a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
148a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
1491a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1501a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1511a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    uint32_t* dataIn;
1521a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
1531a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza            reinterpret_cast<void**>(&dataIn)));
154f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    *dataIn = TEST_DATA;
1551a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, buffer->unlock());
1561a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
15782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput input(0, false,
15882c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
159567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1601a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1611a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
162cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza    BufferItem item;
1631a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1641a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1651a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    uint32_t* dataOut;
1661a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
1671a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza            reinterpret_cast<void**>(&dataOut)));
168f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    ASSERT_EQ(*dataOut, TEST_DATA);
1691a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
1701a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza}
1711a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza
1729e75ddda93888755d0b14144b62e896cd9f78f3aJamie GennisTEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
1731a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
1749e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    sp<DummyConsumer> dc(new DummyConsumer);
1759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    mConsumer->consumerConnect(dc, false);
1762adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    IGraphicBufferProducer::QueueBufferOutput qbo;
177f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza    mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
178f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza            &qbo);
179fa455354557f6283ff3a7d76979e52fd251c155fPablo Ceballos    mProducer->setMaxDequeuedBufferCount(3);
1809e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
1819e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    int slot;
1829e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    sp<Fence> fence;
1839e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    sp<GraphicBuffer> buf;
18482c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput qbi(0, false,
18582c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
186567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
187cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza    BufferItem item;
1889e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
1899e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    for (int i = 0; i < 2; i++) {
1902adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
191a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                  mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
192a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                           nullptr, nullptr));
1939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
1949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
1959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1969e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    }
1979e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
1982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
199a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
200a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
2019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
2029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
2039e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
2049e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis    // Acquire the third buffer, which should fail.
2059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
2069e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis}
2079e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis
208c68f2ecfa02037144d1a3856f637a77f523cf416Jamie GennisTEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
2091a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
210c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis    sp<DummyConsumer> dc(new DummyConsumer);
2119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    mConsumer->consumerConnect(dc, false);
212c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis
21372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
21472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
21572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
21672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    IGraphicBufferProducer::QueueBufferOutput qbo;
21772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
21872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            &qbo);
21972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(3);
22072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
2217ea777f097784492f880623067becac1b276f884Igor Murashkin    int minBufferCount;
2227ea777f097784492f880623067becac1b276f884Igor Murashkin    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
2239f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
2249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza                minBufferCount - 1));
2257ea777f097784492f880623067becac1b276f884Igor Murashkin
2269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
2279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
2289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
229c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
2309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
23119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
23272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    int slot;
23372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    sp<Fence> fence;
23472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    sp<GraphicBuffer> buf;
23572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    IGraphicBufferProducer::QueueBufferInput qbi(0, false,
23672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
23772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
23872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    BufferItem item;
23972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
24072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    for (int i = 0; i < 3; i++) {
24172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
242a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                  mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
243a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                           nullptr, nullptr));
24472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
24572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
24672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
24772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    }
24872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
24972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
250c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis}
251c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis
252c68f2ecfa02037144d1a3856f637a77f523cf416Jamie GennisTEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
2531a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
254c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis    sp<DummyConsumer> dc(new DummyConsumer);
2559f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    mConsumer->consumerConnect(dc, false);
256c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis
25772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    IGraphicBufferProducer::QueueBufferOutput qbo;
25872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
25972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            &qbo);
26072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    mProducer->setMaxDequeuedBufferCount(2);
26172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
2627ea777f097784492f880623067becac1b276f884Igor Murashkin    int minBufferCount;
2637ea777f097784492f880623067becac1b276f884Igor Murashkin    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
2647ea777f097784492f880623067becac1b276f884Igor Murashkin
2659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
2669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
2679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
26872daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
26972daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    int slot;
27072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    sp<Fence> fence;
27172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    sp<GraphicBuffer> buf;
27272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    IGraphicBufferProducer::QueueBufferInput qbi(0, false,
27372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
27472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
27572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    BufferItem item;
27672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
27772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
278a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
279a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
28072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
28172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
28272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
28372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
28472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
28572daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
28672daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    for (int i = 0; i < 2; i++) {
28772daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
288a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                  mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
289a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                           nullptr, nullptr));
29072daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
29172daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
29272daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
29372daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos    }
29472daab652e3481566c01ce45c6afdb9fcec6f140Pablo Ceballos
2959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
296c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
297c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis}
298c68f2ecfa02037144d1a3856f637a77f523cf416Jamie Gennis
29919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo CeballosTEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
30019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    createBufferQueue();
30119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    sp<DummyConsumer> dc(new DummyConsumer);
30219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mConsumer->consumerConnect(dc, false);
30319e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
3043559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    // Test shared buffer mode
30519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
30619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos}
30719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
30819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo CeballosTEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
30919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    createBufferQueue();
31019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    sp<DummyConsumer> dc(new DummyConsumer);
31119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    mConsumer->consumerConnect(dc, false);
31219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
31319e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
31419e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
31519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos            BufferQueue::NUM_BUFFER_SLOTS + 1));
31619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
31719e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
31819e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
31919e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos}
32019e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos
3219f3053de78630815d60cf48a2cf2348cc5867c45Dan StozaTEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
3221a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
3239f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
3249f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
3259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
326f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
327f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza            NATIVE_WINDOW_API_CPU, false, &output));
3289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
3309f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
3319f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza                BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
3329f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
3339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3349f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int slot;
3359f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<Fence> fence;
3369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<GraphicBuffer> buffer;
3379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
338a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
339a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
3409f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
3419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
3429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->detachBuffer(slot));
3439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
3449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<GraphicBuffer> safeToClobberBuffer;
3469f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    // Can no longer request buffer from this slot
3479f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
3489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataIn;
3509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
3519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataIn)));
352f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    *dataIn = TEST_DATA;
3539f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, buffer->unlock());
3549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3559f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int newSlot;
3569f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
3579f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
3589f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
36082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput input(0, false,
36182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
362567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
3639f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
3649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
365cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza    BufferItem item;
3669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
3679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataOut;
3699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
3709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataOut)));
371f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    ASSERT_EQ(*dataOut, TEST_DATA);
3721a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
3739f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza}
3749f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3759f3053de78630815d60cf48a2cf2348cc5867c45Dan StozaTEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
3761a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
3779f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
3789f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
3799f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
380f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
381f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza            NATIVE_WINDOW_API_CPU, false, &output));
3829f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3839f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int slot;
3849f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<Fence> fence;
3859f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<GraphicBuffer> buffer;
3869f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
387a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
388a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
3899f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
39082c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput input(0, false,
39182c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
392567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
3939f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
3949f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
3959f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
3969f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
3979f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
3989f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
3999f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
400cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza    BufferItem item;
4019f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
4029f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
40347650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
40447650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
4059f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4069f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataIn;
4079f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->lock(
4089f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            GraphicBuffer::USAGE_SW_WRITE_OFTEN,
4099f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataIn)));
410f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    *dataIn = TEST_DATA;
4119f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
4129f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4139f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int newSlot;
4149f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<GraphicBuffer> safeToClobberBuffer;
4159f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
4169f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
4179f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
4189f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
41999b18b447dec188bcec37b415603b9dd400fc7e1Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
4209f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            EGL_NO_SYNC_KHR, Fence::NO_FENCE));
4219f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4229f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
423a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
424a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
4259f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
4269f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4279f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataOut;
4289f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
4299f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataOut)));
430f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    ASSERT_EQ(*dataOut, TEST_DATA);
4311a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, buffer->unlock());
4329f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza}
4339f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4349f3053de78630815d60cf48a2cf2348cc5867c45Dan StozaTEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
4351a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    createBufferQueue();
4369f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
4379f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
4389f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
439f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
440f0eaf25e9247edf4d124bedaeb863f7abdf35a3eDan Stoza            NATIVE_WINDOW_API_CPU, false, &output));
4419f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4429f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int slot;
4439f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<Fence> fence;
4449f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    sp<GraphicBuffer> buffer;
4459f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
446a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
447a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
4489f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
4499f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4509f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataIn;
4519f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
4529f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataIn)));
453f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    *dataIn = TEST_DATA;
4549f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, buffer->unlock());
4559f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
45682c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput input(0, false,
45782c6bcc9705eabcaf5b9e45bc81867b0e2d61a02Eino-Ville Talvala            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
458567dbbb6dd42be5013fcde0dadb3316d85f2fa0dPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
4599f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
4609f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
461cf3834db104e0b052056e3a06d46e3f222f0d372Dan Stoza    BufferItem item;
4629f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
46347650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
4649f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4659f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    int newSlot;
4669f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
4679f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
4689f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
4699f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4709f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    uint32_t* dataOut;
4719f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
4729f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza            reinterpret_cast<void**>(&dataOut)));
473f8cebe54576c8100769e2515d4f67bdd013a6927Dan Stoza    ASSERT_EQ(*dataOut, TEST_DATA);
4741a0b8617909c94f6c7301b651cb7b07463529c8cDan Stoza    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
4759f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza}
4769f3053de78630815d60cf48a2cf2348cc5867c45Dan Stoza
4779de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan StozaTEST_F(BufferQueueTest, TestDisallowingAllocation) {
4789de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    createBufferQueue();
4799de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
4809de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
4819de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
4829de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
4839de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza            NATIVE_WINDOW_API_CPU, true, &output));
4849de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
4859de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    static const uint32_t WIDTH = 320;
4869de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    static const uint32_t HEIGHT = 240;
4879de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
4889de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
4899de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
4909de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    int slot;
4919de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    sp<Fence> fence;
4929de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    sp<GraphicBuffer> buffer;
4939de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    // This should return an error since it would require an allocation
4949de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mProducer->allowAllocation(false));
495a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(WOULD_BLOCK,
496a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
497a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
4989de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
4999de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    // This should succeed, now that we've lifted the prohibition
5009de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mProducer->allowAllocation(true));
5019de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
502a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
503a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       nullptr, nullptr));
5049de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
5059de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    // Release the previous buffer back to the BufferQueue
5069de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    mProducer->cancelBuffer(slot, fence);
5079de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
5089de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    // This should fail since we're requesting a different size
5099de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza    ASSERT_EQ(OK, mProducer->allowAllocation(false));
510a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(WOULD_BLOCK,
511a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0,
512a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                                       GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr));
5139de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza}
5149de7293b0a1b01ebe6fb1ab4a498f144adc8029fDan Stoza
515812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan StozaTEST_F(BufferQueueTest, TestGenerationNumbers) {
516812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    createBufferQueue();
517812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
518812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
519812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
520812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
521812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza            NATIVE_WINDOW_API_CPU, true, &output));
522812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
523812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
524812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
525812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    // Get one buffer to play with
526812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    int slot;
527812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    sp<Fence> fence;
528812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
529a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
530812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
531812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    sp<GraphicBuffer> buffer;
532812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
533812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
534812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    // Ensure that the generation number we set propagates to allocated buffers
535812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(1U, buffer->getGenerationNumber());
536812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
537812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->detachBuffer(slot));
538812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
539812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
540812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
541812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    // These should fail, since we've changed the generation number on the queue
542812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    int outSlot;
543812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
544812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
545812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
546812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    buffer->setGenerationNumber(2);
547812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
548812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    // This should succeed now that we've changed the buffer's generation number
549812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
550812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
551812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
552812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
553812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    // This should also succeed with the new generation number
554812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza    ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
555812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza}
556812ed0644f8f8f71ca403f4e5793f0dbc1fcf9b2Dan Stoza
5573559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo CeballosTEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
558ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    createBufferQueue();
559ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    sp<DummyConsumer> dc(new DummyConsumer);
560ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
561ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    IGraphicBufferProducer::QueueBufferOutput output;
562ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
563ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            NATIVE_WINDOW_API_CPU, true, &output));
564ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
5653559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
566ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
567ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // Get a buffer
5683559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    int sharedSlot;
569ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    sp<Fence> fence;
570ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    sp<GraphicBuffer> buffer;
571ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
572a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
5733559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
574ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
575ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // Queue the buffer
576ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    IGraphicBufferProducer::QueueBufferInput input(0, false,
577ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
578ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
5793559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
580ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
581ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // Repeatedly queue and dequeue a buffer from the producer side, it should
582ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // always return the same one. And we won't run out of buffers because it's
583ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // always the same one and because async mode gets enabled.
584ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    int slot;
585ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    for (int i = 0; i < 5; i++) {
586a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
5873559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(sharedSlot, slot);
5883559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
589ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    }
590ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
591ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // acquire the buffer
592ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    BufferItem item;
593ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
5943559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(sharedSlot, item.mSlot);
595ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    testBufferItem(input, item);
596ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(true, item.mQueuedBuffer);
597ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(false, item.mAutoRefresh);
598ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
599ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
600ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
601ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
602ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    // attempt to acquire a second time should return no buffer available
603ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
604ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos            mConsumer->acquireBuffer(&item, 0));
605ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos}
606ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos
6073559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo CeballosTEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
608ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    createBufferQueue();
609ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    sp<DummyConsumer> dc(new DummyConsumer);
610ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
611ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    IGraphicBufferProducer::QueueBufferOutput output;
612ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
613ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos            NATIVE_WINDOW_API_CPU, true, &output));
614ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
6153559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
616ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos    ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
617ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
618ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // Get a buffer
6193559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    int sharedSlot;
620ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    sp<Fence> fence;
621ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    sp<GraphicBuffer> buffer;
622ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
623a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
6243559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
625ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
626ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // Queue the buffer
627ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    IGraphicBufferProducer::QueueBufferInput input(0, false,
628ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
629ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
6303559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
631ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
632ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // Repeatedly acquire and release a buffer from the consumer side, it should
633ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // always return the same one.
634ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    BufferItem item;
635ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    for (int i = 0; i < 5; i++) {
636ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
6373559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(sharedSlot, item.mSlot);
638ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        testBufferItem(input, item);
639ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(i == 0, item.mQueuedBuffer);
640ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(true, item.mAutoRefresh);
641ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
642ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
643ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
644ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    }
645ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
646ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // Repeatedly queue and dequeue a buffer from the producer side, it should
647ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // always return the same one.
648ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    int slot;
649ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    for (int i = 0; i < 5; i++) {
650a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
6513559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(sharedSlot, slot);
6523559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
653ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    }
654ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
655ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // Repeatedly acquire and release a buffer from the consumer side, it should
656ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    // always return the same one. First grabbing them from the queue and then
6573559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    // when the queue is empty, returning the shared buffer.
658ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    for (int i = 0; i < 10; i++) {
659ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
6603559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(sharedSlot, item.mSlot);
661ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(0, item.mTimestamp);
662ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(false, item.mIsAutoTimestamp);
663ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
664ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
665ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
6665ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza        ASSERT_EQ(0u, item.mTransform);
667ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(Fence::NO_FENCE, item.mFence);
668ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(i == 0, item.mQueuedBuffer);
669ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos        ASSERT_EQ(true, item.mAutoRefresh);
670ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
671ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
672ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
673ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos    }
674ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos}
675ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos
6763559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo CeballosTEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
677295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    createBufferQueue();
678295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    sp<DummyConsumer> dc(new DummyConsumer);
679295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
680295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    IGraphicBufferProducer::QueueBufferOutput output;
681295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
682295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos            NATIVE_WINDOW_API_CPU, true, &output));
683295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
684295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // Dequeue a buffer
6853559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    int sharedSlot;
686295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    sp<Fence> fence;
687295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    sp<GraphicBuffer> buffer;
688295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
689a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
6903559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
691295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
6923559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    // Enable shared buffer mode
6933559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
694295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
695295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // Queue the buffer
696295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    IGraphicBufferProducer::QueueBufferInput input(0, false,
697295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
698295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
6993559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
700295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
701295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // Repeatedly queue and dequeue a buffer from the producer side, it should
702295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // always return the same one. And we won't run out of buffers because it's
703295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // always the same one and because async mode gets enabled.
704295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    int slot;
705295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    for (int i = 0; i < 5; i++) {
706a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
7073559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(sharedSlot, slot);
7083559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos        ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
709295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    }
710295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
711295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // acquire the buffer
712295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    BufferItem item;
713295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
7143559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos    ASSERT_EQ(sharedSlot, item.mSlot);
715295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    testBufferItem(input, item);
716295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(true, item.mQueuedBuffer);
717295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(false, item.mAutoRefresh);
718295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
719295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
720295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
721295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
722295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    // attempt to acquire a second time should return no buffer available
723295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos    ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
724295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos            mConsumer->acquireBuffer(&item, 0));
725295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos}
726295a9fc8aa87daa2cded5c1a279b8cd24e9a9a9fPablo Ceballos
727127fc63e8a15366b4395f1363e8e18eb058d1709Dan StozaTEST_F(BufferQueueTest, TestTimeouts) {
728127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    createBufferQueue();
729127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
730127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
731127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
732127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
733127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza            NATIVE_WINDOW_API_CPU, true, &output));
734127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
735127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // Fill up the queue. Since the controlledByApp flags are set to true, this
736127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // queue should be in non-blocking mode, and we should be recycling the same
737127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // two buffers
738127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    for (int i = 0; i < 5; ++i) {
739127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        int slot = BufferQueue::INVALID_BUFFER_SLOT;
740127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        sp<Fence> fence = Fence::NO_FENCE;
741a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
742127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        if (i < 2) {
743127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza            ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
744127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza                    result);
745127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        } else {
746127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza            ASSERT_EQ(OK, result);
747127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        }
748127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        sp<GraphicBuffer> buffer;
749127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
750127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        IGraphicBufferProducer::QueueBufferInput input(0ull, true,
751127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza                HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
752127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza                NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
753127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        IGraphicBufferProducer::QueueBufferOutput output{};
754127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
755127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    }
756127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
757127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    const auto TIMEOUT = ms2ns(250);
758127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    mProducer->setDequeueTimeout(TIMEOUT);
759127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
760127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // Setting a timeout will change the BufferQueue into blocking mode (with
761127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // one droppable buffer in the queue and one free from the previous
762127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // dequeue/queues), so dequeue and queue two more buffers: one to replace
763127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // the current droppable buffer, and a second to max out the buffer count
764127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    sp<GraphicBuffer> buffer; // Save a buffer to attach later
765127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    for (int i = 0; i < 2; ++i) {
766127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        int slot = BufferQueue::INVALID_BUFFER_SLOT;
767127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        sp<Fence> fence = Fence::NO_FENCE;
768a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
769127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
770127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        IGraphicBufferProducer::QueueBufferInput input(0ull, true,
771127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza                HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
772127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza                NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
773127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
774127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    }
775127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
776127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    int slot = BufferQueue::INVALID_BUFFER_SLOT;
777127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    sp<Fence> fence = Fence::NO_FENCE;
778127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    auto startTime = systemTime();
779a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
780127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    ASSERT_GE(systemTime() - startTime, TIMEOUT);
781127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
782127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // We're technically attaching the same buffer multiple times (since we
783127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    // queued it previously), but that doesn't matter for this test
784127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    startTime = systemTime();
785127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
786127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza    ASSERT_GE(systemTime() - startTime, TIMEOUT);
787127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza}
788127fc63e8a15366b4395f1363e8e18eb058d1709Dan Stoza
7895ecfb68ffd63d352df0392dca6e95ef67a66c679Dan StozaTEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
7905ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    createBufferQueue();
7915ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
7925ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
7935ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
7945ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
7955ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza            NATIVE_WINDOW_API_CPU, true, &output));
7965ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza
7975ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    int slot = BufferQueue::INVALID_BUFFER_SLOT;
7985ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    sp<Fence> sourceFence;
7995ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
800a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr, nullptr));
8015ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    sp<GraphicBuffer> buffer;
8025ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
8035ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mProducer->detachBuffer(slot));
8045ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza
8055ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mProducer->allowAllocation(false));
8065ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza
8075ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    slot = BufferQueue::INVALID_BUFFER_SLOT;
8085ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza    ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
8095ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza}
8105ecfb68ffd63d352df0392dca6e95ef67a66c679Dan Stoza
81150101d02a8eae555887282a5f761fdec57bdaf30Dan StozaTEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
81250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    createBufferQueue();
81350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
81450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
81550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
81650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
81750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza            NATIVE_WINDOW_API_CPU, false, &output));
81850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
81950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Dequeue and queue the first buffer, storing the handle
82050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    int slot = BufferQueue::INVALID_BUFFER_SLOT;
82150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<Fence> fence;
82250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
823a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
82450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<GraphicBuffer> firstBuffer;
82550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
82650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
82750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
82850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza        HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
82950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
83050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
83150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
83250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Dequeue a second buffer
83350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    slot = BufferQueue::INVALID_BUFFER_SLOT;
83450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
835a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott              mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
83650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<GraphicBuffer> secondBuffer;
83750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
83850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
83950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Ensure it's a new buffer
84050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
84150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza            secondBuffer->getNativeBuffer()->handle);
84250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
84350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Queue the second buffer
84450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
84550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
84650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Acquire and release both buffers
84750101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    for (size_t i = 0; i < 2; ++i) {
84850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza        BufferItem item;
84950101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
85050101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
85150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
85250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    }
85350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
85450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    // Make sure we got the second buffer back
85550101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<GraphicBuffer> returnedBuffer;
85650101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    sp<Fence> returnedFence;
8571a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck    float transform[16];
85850101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(OK,
8591a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck            mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
8601a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck            transform));
86150101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza    ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
86250101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza            returnedBuffer->getNativeBuffer()->handle);
86350101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza}
86450101d02a8eae555887282a5f761fdec57bdaf30Dan Stoza
865e77c7669bee30b7c0099172cf0c38cef92412040Dan StozaTEST_F(BufferQueueTest, TestOccupancyHistory) {
866e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    createBufferQueue();
867e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
868e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
869e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
870e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
871e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            NATIVE_WINDOW_API_CPU, false, &output));
872e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
873e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    int slot = BufferQueue::INVALID_BUFFER_SLOT;
874e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    sp<Fence> fence = Fence::NO_FENCE;
875e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    sp<GraphicBuffer> buffer = nullptr;
876e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
877e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
878e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
879e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    BufferItem item{};
880e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
881e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
882e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // BUFFER_NEEDS_REALLOCATION below
883e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    int slots[3] = {};
884e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    mProducer->setMaxDequeuedBufferCount(3);
885e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (size_t i = 0; i < 3; ++i) {
886a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        status_t result =
887a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
888e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
889e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
890e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
891e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (size_t i = 0; i < 3; ++i) {
892e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
893e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
894e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
895e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Create 3 segments
896e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
897e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // The first segment is a two-buffer segment, so we only put one buffer into
898e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // the queue at a time
899e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (size_t i = 0; i < 5; ++i) {
900a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
901e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
902e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
903e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
904e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
905e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::this_thread::sleep_for(16ms);
906e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
907e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
908e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Sleep between segments
909e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::this_thread::sleep_for(500ms);
910e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
911e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // The second segment is a double-buffer segment. It starts the same as the
912e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // two-buffer segment, but then at the end, we put two buffers in the queue
913e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // at the same time before draining it.
914e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (size_t i = 0; i < 5; ++i) {
915a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
916e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
917e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
918e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
919e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
920e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::this_thread::sleep_for(16ms);
921e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
922a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
923e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
924a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
925e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
926e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
927e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
928e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
929e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::this_thread::sleep_for(16ms);
930e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
931e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
932e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
933e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
934e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Sleep between segments
935e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::this_thread::sleep_for(500ms);
936e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
937e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // The third segment is a triple-buffer segment, so the queue is switching
938e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // between one buffer and two buffers deep.
939a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
940e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
941e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    for (size_t i = 0; i < 5; ++i) {
942a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
943e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
944e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
945e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
946e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
947e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza        std::this_thread::sleep_for(16ms);
948e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    }
949e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
950e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
951e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
952e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
953e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Now we read the segments
954e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    std::vector<OccupancyTracker::Segment> history;
955e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
956e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
957e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Since we didn't force a flush, we should only get the first two segments
958e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // (since the third segment hasn't been closed out by the appearance of a
959e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // new segment yet)
960e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(2u, history.size());
961e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
962e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // The first segment (which will be history[1], since the newest segment
963e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // should be at the front of the vector) should be a two-buffer segment,
964e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // which implies that the occupancy average should be between 0 and 1, and
965e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // usedThirdBuffer should be false
966e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    const auto& firstSegment = history[1];
967e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(5u, firstSegment.numFrames);
968e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_LT(0, firstSegment.occupancyAverage);
969e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_GT(1, firstSegment.occupancyAverage);
970e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(false, firstSegment.usedThirdBuffer);
971e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
972e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // The second segment should be a double-buffered segment, which implies that
973e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // the occupancy average should be between 0 and 1, but usedThirdBuffer
974e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // should be true
975e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    const auto& secondSegment = history[0];
976e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(7u, secondSegment.numFrames);
977e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_LT(0, secondSegment.occupancyAverage);
978e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_GT(1, secondSegment.occupancyAverage);
979e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(true, secondSegment.usedThirdBuffer);
980e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
981e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // If we read the segments again without flushing, we shouldn't get any new
982e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // segments
983e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
984e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(0u, history.size());
985e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
986e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // Read the segments again, this time forcing a flush so we get the third
987e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // segment
988e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
989e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(1u, history.size());
990e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
991e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // This segment should be a triple-buffered segment, which implies that the
992e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // occupancy average should be between 1 and 2, and usedThirdBuffer should
993e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    // be true
994e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    const auto& thirdSegment = history[0];
995e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(6u, thirdSegment.numFrames);
996e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_LT(1, thirdSegment.occupancyAverage);
997e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_GT(2, thirdSegment.occupancyAverage);
998e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza    ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
999e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza}
1000e77c7669bee30b7c0099172cf0c38cef92412040Dan Stoza
1001bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville TalvalaTEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
1002bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    createBufferQueue();
1003bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    sp<DummyConsumer> dc(new DummyConsumer);
1004bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
1005bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferOutput output;
1006bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
1007bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala            NATIVE_WINDOW_API_CPU, false, &output));
1008bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1009bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    int slot = BufferQueue::INVALID_BUFFER_SLOT;
1010bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    sp<Fence> fence = Fence::NO_FENCE;
1011bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    sp<GraphicBuffer> buffer = nullptr;
1012bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1013bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1014bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1015bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    BufferItem item{};
1016bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1017bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
1018bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // BUFFER_NEEDS_REALLOCATION below
1019bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    int slots[4] = {};
1020bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    mProducer->setMaxDequeuedBufferCount(4);
1021bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    for (size_t i = 0; i < 4; ++i) {
1022a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        status_t result =
1023a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
1024bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1025bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1026bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    }
1027bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    for (size_t i = 0; i < 4; ++i) {
1028bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1029bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    }
1030bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1031bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Get buffers in all states: dequeued, filled, acquired, free
1032bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1033bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Fill 3 buffers
1034a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1035bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1036a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1037bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1038a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1039bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1040bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Dequeue 1 buffer
1041a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1042bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1043bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Acquire and free 1 buffer
1044bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1045bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1046bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1047bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Acquire 1 buffer, leaving 1 filled buffer in queue
1048bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1049bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1050bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Now discard the free buffers
1051bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
1052bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1053bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Check no free buffers in dump
1054bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    String8 dumpString;
10550c9a1ed91f8e19887ac43eff5af16e59878c8226Dan Stoza    mConsumer->dumpState(String8{}, &dumpString);
1056bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
1057bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Parse the dump to ensure that all buffer slots that are FREE also
1058bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // have a null GraphicBuffer
1059bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // Fragile - assumes the following format for the dump for a buffer entry:
1060bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
1061bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    ssize_t idx = dumpString.find("state=FREE");
1062bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    while (idx != -1) {
1063bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ssize_t bufferPtrIdx = idx - 1;
1064bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        while (bufferPtrIdx > 0) {
1065bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala            if (dumpString[bufferPtrIdx] == ':') {
1066bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala                bufferPtrIdx++;
1067bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala                break;
1068bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala            }
1069bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala            bufferPtrIdx--;
1070bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        }
1071bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
1072bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
1073bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
1074bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala        idx = dumpString.find("FREE", idx + 1);
1075bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala    }
1076bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala}
1077bc2df65a3f3f4b8abaaaa2a4e576a3a42c2d30f3Eino-Ville Talvala
107822f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen WangTEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
107922f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    createBufferQueue();
108022f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    sp<DummyConsumer> dc(new DummyConsumer);
108122f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
108222f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    IGraphicBufferProducer::QueueBufferOutput output;
108322f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
108422f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang            NATIVE_WINDOW_API_CPU, true, &output));
108522f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
108622f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang
108722f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    int slot = BufferQueue::INVALID_BUFFER_SLOT;
108822f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    sp<Fence> fence = Fence::NO_FENCE;
108922f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    sp<GraphicBuffer> buffer = nullptr;
109022f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
109122f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang        HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
109222f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang        NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
109322f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    BufferItem item{};
109422f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang
109522f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
109622f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    // BUFFER_NEEDS_REALLOCATION below
109722f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    int slots[2] = {};
109822f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
109922f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    for (size_t i = 0; i < 2; ++i) {
1100a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott        status_t result =
1101a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott                mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
110222f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
110322f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang        ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
110422f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    }
110522f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    for (size_t i = 0; i < 2; ++i) {
110622f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang        ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
110722f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    }
110822f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang
110922f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    // Fill 2 buffers without consumer consuming them. Verify that all
111022f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    // queued buffer returns proper bufferReplaced flag
1111a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
111222f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
111322f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(false, output.bufferReplaced);
1114a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
111522f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
111622f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang    ASSERT_EQ(true, output.bufferReplaced);
111722f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang}
111822f842ba04c32cef2faf855dc304eb0ab131b9ecShuzhen Wang
1119d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan StozaTEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
1120d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    createBufferQueue();
1121d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    sp<DummyConsumer> dc(new DummyConsumer);
1122d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1123d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    IGraphicBufferProducer::QueueBufferOutput output;
1124d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    sp<IProducerListener> dummyListener(new DummyProducerListener);
1125d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->connect(dummyListener, NATIVE_WINDOW_API_CPU,
1126d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza            true, &output));
1127d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1128d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    int slot = BufferQueue::INVALID_BUFFER_SLOT;
1129d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    sp<Fence> fence = Fence::NO_FENCE;
1130d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    sp<GraphicBuffer> buffer = nullptr;
1131d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1132d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza            HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1133d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1134d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1135d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Dequeue, request, and queue one buffer
1136a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
1137d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1138d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1139d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1140d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1141d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Acquire and release the buffer. Upon acquiring, the buffer handle should
1142d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // be non-null since this is the first time we've acquired this slot.
1143d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    BufferItem item;
1144d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1145d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(slot, item.mSlot);
1146d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1147d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1148d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1149d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1150d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Dequeue and queue the buffer again
1151a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1152d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1153d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1154d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Acquire and release the buffer again. Upon acquiring, the buffer handle
1155d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // should be null since this is not the first time we've acquired this slot.
1156d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1157d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(slot, item.mSlot);
1158d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
1159d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1160d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza            EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1161d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1162d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Dequeue and queue the buffer again
1163a2eb34cfbe089deb9a519e9702e17d9dfe26f9e8Ian Elliott    ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1164d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1165d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1166d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Disconnect the producer end. This should clear all of the slots and mark
1167d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // the buffer in the queue as stale.
1168d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1169d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
1170d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // Acquire the buffer again. Upon acquiring, the buffer handle should not be
1171d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // null since the queued buffer should have been marked as stale, which
1172d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    // should trigger the BufferQueue to resend the buffer handle.
1173d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1174d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_EQ(slot, item.mSlot);
1175d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza    ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1176d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza}
1177d4c6f9912fa4f9d6a5a2e51672adf27c7a1c8624Dan Stoza
11783e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik KimTEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
11793e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    createBufferQueue();
11803e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    sp<DummyConsumer> dc(new DummyConsumer);
11813e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
11823e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    IGraphicBufferProducer::QueueBufferOutput output;
11833e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    sp<IProducerListener> dummyListener(new DummyProducerListener);
11843e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
11853e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(OK, mProducer->connect(
11863e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim            dummyListener, NATIVE_WINDOW_API_CPU, true, &output));
11873e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(BAD_VALUE, mProducer->connect(
11883e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim            dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output));
11893e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim
11903e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
11913e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
11923e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim    ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
11933e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim}
11943e198b2b331c09e8d078b5cd4cb770bcf049c0d1Wonsik Kim
11959e75ddda93888755d0b14144b62e896cd9f78f3aJamie Gennis} // namespace android
1196