Пример #1
0
GuiExtPoolItem::GuiExtPoolItem(const sp<IBinder>& token,
                bool isHwcNeeded,
                uint32_t poolId,
                uint32_t /*w*/,
                uint32_t /*h*/,
                DefaultKeyedVector< uint32_t, sp<DispInfo> >& dispList,
                sp<IBinder::DeathRecipient> observer)
                : mConsumerDeathListener(NULL)
                //, mGPUUsedBq(NULL)
                , mGPUUsedProducer(NULL)
                , mGPUUsedConsumer(NULL)
#if !SUPPORT_MULTIBQ_FOR_HWC
                , mHwcUsedBq(NULL)
#endif
                , mId(poolId)
                , mIsHwcNeeded(isHwcNeeded)
                , mGpuUsedBufNum(MAX_GLES_DEQUEUED_NUM)
                , mProducerPid(-1)
                , mProducerToken(token)
                , mProducerDeathObserver(observer)

{
    GUIEXT_LOGV("GuiExtPoolItem ctor, poolId=%d, isHwcNeeded=%d, token=%p", poolId, isHwcNeeded, token.get());

    //String8 name(szUsageName[0]);
    //name.appendFormat("_%d", poolId);
    //mGPUUsedBq = createBufferQueue(w, h, mGpuUsedBufNum, name);
    //createBufferQueue(w, h, mGpuUsedBufNum, name, &mGPUUsedProducer, &mGPUUsedConsumer);

#ifdef CONFIG_FOR_SOURCE_PQ
    setOverlaySessionMode(true);
#endif
    if (mIsHwcNeeded) {
        String8 name(szUsageName[1]);
        name.appendFormat("_%d", poolId);
#if SUPPORT_MULTIBQ_FOR_HWC
        uint32_t disp_size = dispList.size();
        for (uint32_t i = 0; i < disp_size; i++) {
            uint32_t type = dispList[i]->type;
            String8 extname(name);
            extname.appendFormat("_%d", type);
            sp<HwcBqSlot> slot = new HwcBqSlot();
            //slot->bq = createBufferQueue(dispList[i]->w, dispList[i]->h, dispList[i]->bufNum, extname);
            createBufferQueue(dispList[i]->w, dispList[i]->h, dispList[i]->bufNum, extname, &slot->mProducer, &slot->mConsumer);
            slot->type = type;
            slot->bufNum = dispList[i]->bufNum;
            mHwcUsedBqList.add(type, slot);
        }
#else
        mHwcUsedBq = createBufferQueue(dispList[0]->w, dispList[0]->h, dispList[i]->bufNum, name);
#endif
    }

    mProducerPid = (NULL != token->localBinder())
                 ? getpid()
                 : IPCThreadState::self()->getCallingPid();

    for (uint32_t i = 0; i < GUI_EXT_USAGE_MAX; i++)
        mIsDisconnected[i] = true;
}
TEST_F(BufferQueueTest, TestDisallowingAllocation) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    IGraphicBufferProducer::QueueBufferOutput output;
    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
            NATIVE_WINDOW_API_CPU, true, &output));

    static const uint32_t WIDTH = 320;
    static const uint32_t HEIGHT = 240;

    ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));

    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;
    // This should return an error since it would require an allocation
    ASSERT_EQ(OK, mProducer->allowAllocation(false));
    ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0,
            0, GRALLOC_USAGE_SW_WRITE_OFTEN));

    // This should succeed, now that we've lifted the prohibition
    ASSERT_EQ(OK, mProducer->allowAllocation(true));
    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
            GRALLOC_USAGE_SW_WRITE_OFTEN));

    // Release the previous buffer back to the BufferQueue
    mProducer->cancelBuffer(slot, fence);

    // This should fail since we're requesting a different size
    ASSERT_EQ(OK, mProducer->allowAllocation(false));
    ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false,
            WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
}
TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);
    IGraphicBufferProducer::QueueBufferOutput qbo;
    mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
            &qbo);
    mProducer->setBufferCount(4);

    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buf;
    IGraphicBufferProducer::QueueBufferInput qbi(0, false,
            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
    BufferItem item;

    for (int i = 0; i < 2; i++) {
        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
                mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
                    GRALLOC_USAGE_SW_READ_OFTEN));
        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    }

    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
                GRALLOC_USAGE_SW_READ_OFTEN));
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
    ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));

    // Acquire the third buffer, which should fail.
    ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
}
TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
            NATIVE_WINDOW_API_CPU, false, &output));

    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;
    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
                    GRALLOC_USAGE_SW_WRITE_OFTEN));
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    IGraphicBufferProducer::QueueBufferInput input(0, false,
            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));

    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
            BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired

    BufferItem item;
    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));

    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired

    uint32_t* dataIn;
    ASSERT_EQ(OK, item.mGraphicBuffer->lock(
            GraphicBuffer::USAGE_SW_WRITE_OFTEN,
            reinterpret_cast<void**>(&dataIn)));
    *dataIn = TEST_DATA;
    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());

    int newSlot;
    sp<GraphicBuffer> safeToClobberBuffer;
    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
    ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));

    ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
            EGL_NO_SYNC_KHR, Fence::NO_FENCE));

    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
                    GRALLOC_USAGE_SW_WRITE_OFTEN));
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));

    uint32_t* dataOut;
    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, TEST_DATA);
    ASSERT_EQ(OK, buffer->unlock());
}
TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);

    int minBufferCount;
    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));

    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
}
TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    mConsumer->consumerConnect(dc, false);

    int minBufferCount;
    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
                minBufferCount - 1));

    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
}
TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    IGraphicBufferProducer::QueueBufferOutput output;
    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
            NATIVE_WINDOW_API_CPU, false, &output));

    int slot;
    sp<Fence> fence;
    sp<GraphicBuffer> buffer;
    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
                    GRALLOC_USAGE_SW_WRITE_OFTEN));
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));

    uint32_t* dataIn;
    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
            reinterpret_cast<void**>(&dataIn)));
    *dataIn = TEST_DATA;
    ASSERT_EQ(OK, buffer->unlock());

    IGraphicBufferProducer::QueueBufferInput input(0, false,
            HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));

    BufferItem item;
    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));

    int newSlot;
    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));

    uint32_t* dataOut;
    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
            reinterpret_cast<void**>(&dataOut)));
    ASSERT_EQ(*dataOut, TEST_DATA);
    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
TEST_F(BufferQueueTest, TestGenerationNumbers) {
    createBufferQueue();
    sp<DummyConsumer> dc(new DummyConsumer);
    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    IGraphicBufferProducer::QueueBufferOutput output;
    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
            NATIVE_WINDOW_API_CPU, true, &output));

    ASSERT_EQ(OK, mProducer->setGenerationNumber(1));

    // Get one buffer to play with
    int slot;
    sp<Fence> fence;
    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0, 0));

    sp<GraphicBuffer> buffer;
    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));

    // Ensure that the generation number we set propagates to allocated buffers
    ASSERT_EQ(1U, buffer->getGenerationNumber());

    ASSERT_EQ(OK, mProducer->detachBuffer(slot));

    ASSERT_EQ(OK, mProducer->setGenerationNumber(2));

    // These should fail, since we've changed the generation number on the queue
    int outSlot;
    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));

    buffer->setGenerationNumber(2);

    // This should succeed now that we've changed the buffer's generation number
    ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));

    ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));

    // This should also succeed with the new generation number
    ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
}