RingBufferConsumer.h revision 549e735c2ca22d16eea32fda418ba80da32a8558
140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin/*
240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * you may not use this file except in compliance with the License.
640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * You may obtain a copy of the License at
740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
1040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Unless required by applicable law or agreed to in writing, software
1140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
1240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * See the License for the specific language governing permissions and
1440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * limitations under the License.
1540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin */
1640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
1740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#ifndef ANDROID_GUI_RINGBUFFERCONSUMER_H
1840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#define ANDROID_GUI_RINGBUFFERCONSUMER_H
1940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
20549e735c2ca22d16eea32fda418ba80da32a8558Dan Stoza#include <gui/BufferItem.h>
2140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <gui/ConsumerBase.h>
2240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
2340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <ui/GraphicBuffer.h>
2440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
2540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <utils/String8.h>
2640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <utils/Vector.h>
2740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <utils/threads.h>
2840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#include <utils/List.h>
2940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
3040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#define ANDROID_GRAPHICS_RINGBUFFERCONSUMER_JNI_ID "mRingBufferConsumer"
3140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
3240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkinnamespace android {
3340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
3440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin/**
3540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * The RingBufferConsumer maintains a ring buffer of BufferItem objects,
3640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * (which are 'acquired' as long as they are part of the ring buffer, and
3740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *  'released' when they leave the ring buffer).
3840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
3940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * When new buffers are produced, the oldest non-pinned buffer item is immediately
4040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * dropped from the ring buffer, and overridden with the newest buffer.
4140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
4240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Users can only access a buffer item after pinning it (which also guarantees
4340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * that during its duration it will not be released back into the BufferQueue).
4440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
4540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Note that the 'oldest' buffer is the one with the smallest timestamp.
4640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *
4740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin * Edge cases:
4840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *  - If ringbuffer is not full, no drops occur when a buffer is produced.
4940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *  - If all the buffers get filled or pinned then there will be no empty
5040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin *    buffers left, so the producer will block on dequeue.
5140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin */
5240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkinclass RingBufferConsumer : public ConsumerBase,
5340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                           public ConsumerBase::FrameAvailableListener
5440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin{
5540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin  public:
5640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
5740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
5840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
5940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
6040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
6140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Create a new ring buffer consumer. The consumerUsage parameter determines
6240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // the consumer usage flags passed to the graphics allocator. The
6340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // bufferCount parameter specifies how many buffers can be pinned for user
6440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // access at the same time.
65deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    RingBufferConsumer(const sp<IGraphicBufferConsumer>& consumer, uint32_t consumerUsage,
66054aab3479a094b0a04d48db9cb8f325ea5be162Igor Murashkin            int bufferCount);
6740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
6840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    virtual ~RingBufferConsumer();
6940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
7040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // set the name of the RingBufferConsumer that will be used to identify it in
7140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // log messages.
7240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    void setName(const String8& name);
7340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
7440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // setDefaultBufferSize is used to set the size of buffers returned by
7540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // requestBuffers when a with and height of zero is requested.
7640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    status_t setDefaultBufferSize(uint32_t w, uint32_t h);
7740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
7840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // setDefaultBufferFormat allows the BufferQueue to create
7940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // GraphicBuffers of a defaultFormat if no format is specified
8040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // by the producer endpoint.
8140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    status_t setDefaultBufferFormat(uint32_t defaultFormat);
8240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
8340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // setConsumerUsage allows the BufferQueue consumer usage to be
8440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // set at a later time after construction.
8540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    status_t setConsumerUsage(uint32_t usage);
8640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
8740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Buffer info, minus the graphics buffer/slot itself.
8840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    struct BufferInfo {
8940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mCrop is the current crop rectangle for this buffer slot.
9040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        Rect mCrop;
9140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
9240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mTransform is the current transform flags for this buffer slot.
9340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        uint32_t mTransform;
9440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
9540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mScalingMode is the current scaling mode for this buffer slot.
9640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        uint32_t mScalingMode;
9740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
9840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mTimestamp is the current timestamp for this buffer slot. This gets
9940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // to set by queueBuffer each time this slot is queued.
10040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        int64_t mTimestamp;
10140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
10240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mFrameNumber is the number of the queued frame for this slot.
10340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        uint64_t mFrameNumber;
10440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
10540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // mPinned is whether or not the buffer has been pinned already.
10640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        bool mPinned;
10740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    };
10840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
10940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    struct RingBufferComparator {
11040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // Return < 0 to select i1, > 0 to select i2, 0 for neither
11140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // i1 or i2 can be NULL.
11240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        //
11340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // The comparator has to implement a total ordering. Otherwise
11440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        // a linear scan won't find the most preferred buffer.
11540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        virtual int compare(const BufferInfo* i1,
11640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                            const BufferInfo* i2) const = 0;
11740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
11840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        virtual ~RingBufferComparator() {}
11940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    };
12040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
12140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    struct PinnedBufferItem : public LightRefBase<PinnedBufferItem> {
12240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        PinnedBufferItem(wp<RingBufferConsumer> consumer,
12340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                         const BufferItem& item) :
12440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                mConsumer(consumer),
12540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                mBufferItem(item) {
12640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        }
12740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
12840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        ~PinnedBufferItem() {
12940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin            sp<RingBufferConsumer> consumer = mConsumer.promote();
13040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin            if (consumer != NULL) {
13140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                consumer->unpinBuffer(mBufferItem);
13240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin            }
13340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        }
13440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
13540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        bool isEmpty() {
13640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin            return mBufferItem.mBuf == BufferQueue::INVALID_BUFFER_SLOT;
13740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        }
13840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
13940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        BufferItem& getBufferItem() { return mBufferItem; }
14040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        const BufferItem& getBufferItem() const { return mBufferItem; }
14140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
14240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin      private:
14340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        wp<RingBufferConsumer> mConsumer;
14440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        BufferItem             mBufferItem;
14540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    };
14640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
14740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Find a buffer using the filter, then pin it before returning it.
14840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    //
14940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // The filter will be invoked on each buffer item in the ring buffer,
15040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // passing the item that was selected from each previous iteration,
15140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // as well as the current iteration's item.
15240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    //
15340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Pinning will ensure that the buffer will not be dropped when a new
15440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // frame is available.
15540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    sp<PinnedBufferItem> pinSelectedBuffer(const RingBufferComparator& filter,
15640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin                                           bool waitForFence = true);
15740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
15840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Release all the non-pinned buffers in the ring buffer
15940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    status_t clear();
16040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
1616b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    // Return 0 if RingBuffer is empty, otherwise return timestamp of latest buffer.
1626b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    nsecs_t getLatestTimestamp();
1636b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh
16440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin  private:
16540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
16640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Override ConsumerBase::onFrameAvailable
167549e735c2ca22d16eea32fda418ba80da32a8558Dan Stoza    virtual void onFrameAvailable(const BufferItem& item);
16840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
16940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    void pinBufferLocked(const BufferItem& item);
17040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    void unpinBuffer(const BufferItem& item);
17140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
17240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Releases oldest buffer. Returns NO_BUFFER_AVAILABLE
17340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // if all the buffers were pinned.
17440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // Returns NOT_ENOUGH_DATA if list was empty.
17540602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    status_t releaseOldestBufferLocked(size_t* pinnedFrames);
17640602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
17740602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    struct RingBufferItem : public BufferItem {
17840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        RingBufferItem() : BufferItem(), mPinCount(0) {}
17940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin        int mPinCount;
18040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    };
18140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
18240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    // List of acquired buffers in our ring buffer
18340602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    List<RingBufferItem>       mBufferItemList;
18440602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin    const int                  mBufferCount;
1856b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh
1866b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    // Timestamp of latest buffer
1876b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    nsecs_t mLatestTimestamp;
18840602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin};
18940602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
19040602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin} // namespace android
19140602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin
19240602741ae87e6bf368c17dd28db4d2db344bdedIgor Murashkin#endif // ANDROID_GUI_CPUCONSUMER_H
193