Example #1
0
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    ATRACE_CALL();
    ALOGV("Surface::queueBuffer");
    Mutex::Autolock lock(mMutex);
    int64_t timestamp;
    bool isAutoTimestamp = false;
    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
        isAutoTimestamp = true;
        ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
              timestamp / 1000000.f);
    } else {
        timestamp = mTimestamp;
    }
    int i = getSlotFromBufferLocked(buffer);
    if (i < 0) {
        return i;
    }


    // Make sure the crop rectangle is entirely inside the buffer.
    Rect crop;
    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);

#ifdef QCOM_BSP
    Rect dirtyRect = mDirtyRect;
    if(dirtyRect.isEmpty()) {
        int drWidth = mUserWidth ? mUserWidth : mDefaultWidth;
        int drHeight = mUserHeight ? mUserHeight : mDefaultHeight;
        dirtyRect = Rect(drWidth, drHeight);
    }
#endif

    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
    IGraphicBufferProducer::QueueBufferOutput output;
    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
            crop,
#ifdef QCOM_BSP
            dirtyRect,
#endif
            mScalingMode, mTransform, mSwapIntervalZero,fence);
    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    if (err != OK)  {
        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
    }
    uint32_t numPendingBuffers = 0;
    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
                   &numPendingBuffers);

    mConsumerRunningBehind = (numPendingBuffers >= 2);
#ifdef QCOM_BSP
    mDirtyRect.clear();
#endif
    return err;
}
// TODO: queue under more complicated situations not involving just a single buffer
TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) {
    ASSERT_NO_FATAL_FAILURE(ConnectProducer());

    int dequeuedSlot = -1;
    sp<Fence> dequeuedFence;


    ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
            (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence,
                                     DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
                                     TEST_PRODUCER_USAGE_BITS)));

    EXPECT_LE(0, dequeuedSlot);
    EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);

    // Request the buffer (pre-requisite for queueing)
    sp<GraphicBuffer> dequeuedBuffer;
    ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));

    // A generic "valid" input
    IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
    IGraphicBufferProducer::QueueBufferOutput output;

    // Queue the buffer back into the BQ
    ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));

    {
        uint32_t width;
        uint32_t height;
        uint32_t transformHint;
        uint32_t numPendingBuffers;

        output.deflate(&width, &height, &transformHint, &numPendingBuffers);

        EXPECT_EQ(DEFAULT_WIDTH, width);
        EXPECT_EQ(DEFAULT_HEIGHT, height);
        EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint);
        EXPECT_EQ(1u, numPendingBuffers); // since queueBuffer was called exactly once
    }

    // Buffer was not in the dequeued state
    EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
}