1d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin/*
2d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Copyright (C) 2013 The Android Open Source Project
3d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
4d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * you may not use this file except in compliance with the License.
6d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * You may obtain a copy of the License at
7d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
8d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
10d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Unless required by applicable law or agreed to in writing, software
11d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * See the License for the specific language governing permissions and
14d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * limitations under the License.
15d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin */
16d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
17d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#ifndef ANDROID_GUI_RINGBUFFERCONSUMER_H
18d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define ANDROID_GUI_RINGBUFFERCONSUMER_H
19d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
20d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <gui/ConsumerBase.h>
21d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
22d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <ui/GraphicBuffer.h>
23d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
24d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <utils/String8.h>
25d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <utils/Vector.h>
26d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <utils/threads.h>
27d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#include <utils/List.h>
28d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
29d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#define ANDROID_GRAPHICS_RINGBUFFERCONSUMER_JNI_ID "mRingBufferConsumer"
30d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
31d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinnamespace android {
32d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
33d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin/**
34d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * The RingBufferConsumer maintains a ring buffer of BufferItem objects,
35d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * (which are 'acquired' as long as they are part of the ring buffer, and
36d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *  'released' when they leave the ring buffer).
37d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
38d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * When new buffers are produced, the oldest non-pinned buffer item is immediately
39d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * dropped from the ring buffer, and overridden with the newest buffer.
40d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
41d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Users can only access a buffer item after pinning it (which also guarantees
42d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * that during its duration it will not be released back into the BufferQueue).
43d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
44d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Note that the 'oldest' buffer is the one with the smallest timestamp.
45d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *
46d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin * Edge cases:
47d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *  - If ringbuffer is not full, no drops occur when a buffer is produced.
48d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *  - If all the buffers get filled or pinned then there will be no empty
49d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin *    buffers left, so the producer will block on dequeue.
50d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin */
51d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkinclass RingBufferConsumer : public ConsumerBase,
52d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                           public ConsumerBase::FrameAvailableListener
53d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin{
54d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin  public:
55d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
56d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
57d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    typedef BufferQueue::BufferItem BufferItem;
58d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
59d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
60d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
61d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
62d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Create a new ring buffer consumer. The consumerUsage parameter determines
63d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // the consumer usage flags passed to the graphics allocator. The
64d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // bufferCount parameter specifies how many buffers can be pinned for user
65d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // access at the same time.
66d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    RingBufferConsumer(uint32_t consumerUsage,
67d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            int bufferCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS);
68d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
69d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    virtual ~RingBufferConsumer();
70d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
71d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // set the name of the RingBufferConsumer that will be used to identify it in
72d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // log messages.
73d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    void setName(const String8& name);
74d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
75d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    sp<IGraphicBufferProducer> getProducerInterface() const { return getBufferQueue(); }
76d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
77d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // setDefaultBufferSize is used to set the size of buffers returned by
78d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // requestBuffers when a with and height of zero is requested.
79d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t setDefaultBufferSize(uint32_t w, uint32_t h);
80d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
81d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // setDefaultBufferFormat allows the BufferQueue to create
82d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // GraphicBuffers of a defaultFormat if no format is specified
83d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // by the producer endpoint.
84d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t setDefaultBufferFormat(uint32_t defaultFormat);
85d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
86d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // setConsumerUsage allows the BufferQueue consumer usage to be
87d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // set at a later time after construction.
88d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t setConsumerUsage(uint32_t usage);
89d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
90d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Buffer info, minus the graphics buffer/slot itself.
91d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    struct BufferInfo {
92d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mCrop is the current crop rectangle for this buffer slot.
93d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        Rect mCrop;
94d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
95d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mTransform is the current transform flags for this buffer slot.
96d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        uint32_t mTransform;
97d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
98d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mScalingMode is the current scaling mode for this buffer slot.
99d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        uint32_t mScalingMode;
100d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
101d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mTimestamp is the current timestamp for this buffer slot. This gets
102d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // to set by queueBuffer each time this slot is queued.
103d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        int64_t mTimestamp;
104d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
105d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mFrameNumber is the number of the queued frame for this slot.
106d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        uint64_t mFrameNumber;
107d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
108d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // mPinned is whether or not the buffer has been pinned already.
109d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        bool mPinned;
110d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    };
111d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
112d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    struct RingBufferComparator {
113d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // Return < 0 to select i1, > 0 to select i2, 0 for neither
114d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // i1 or i2 can be NULL.
115d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        //
116d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // The comparator has to implement a total ordering. Otherwise
117d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        // a linear scan won't find the most preferred buffer.
118d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        virtual int compare(const BufferInfo* i1,
119d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                            const BufferInfo* i2) const = 0;
120d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
121d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        virtual ~RingBufferComparator() {}
122d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    };
123d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
124d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    struct PinnedBufferItem : public LightRefBase<PinnedBufferItem> {
125d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        PinnedBufferItem(wp<RingBufferConsumer> consumer,
126d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                         const BufferItem& item) :
127d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                mConsumer(consumer),
128d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                mBufferItem(item) {
129d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
130d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
131d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        ~PinnedBufferItem() {
132d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            sp<RingBufferConsumer> consumer = mConsumer.promote();
133d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            if (consumer != NULL) {
134d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                consumer->unpinBuffer(mBufferItem);
135d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            }
136d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
137d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
138d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        bool isEmpty() {
139d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin            return mBufferItem.mBuf == BufferQueue::INVALID_BUFFER_SLOT;
140d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        }
141d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
142d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BufferItem& getBufferItem() { return mBufferItem; }
143d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        const BufferItem& getBufferItem() const { return mBufferItem; }
144d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
145d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin      private:
146d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        wp<RingBufferConsumer> mConsumer;
147d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        BufferItem             mBufferItem;
148d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    };
149d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
150d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Find a buffer using the filter, then pin it before returning it.
151d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    //
152d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // The filter will be invoked on each buffer item in the ring buffer,
153d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // passing the item that was selected from each previous iteration,
154d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // as well as the current iteration's item.
155d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    //
156d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Pinning will ensure that the buffer will not be dropped when a new
157d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // frame is available.
158d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    sp<PinnedBufferItem> pinSelectedBuffer(const RingBufferComparator& filter,
159d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin                                           bool waitForFence = true);
160d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
161d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Release all the non-pinned buffers in the ring buffer
162d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t clear();
163d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
164d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin  private:
165d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
166d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Override ConsumerBase::onFrameAvailable
167d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    virtual void onFrameAvailable();
168d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
169d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    void pinBufferLocked(const BufferItem& item);
170d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    void unpinBuffer(const BufferItem& item);
171d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
172d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Releases oldest buffer. Returns NO_BUFFER_AVAILABLE
173d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // if all the buffers were pinned.
174d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // Returns NOT_ENOUGH_DATA if list was empty.
175d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    status_t releaseOldestBufferLocked(size_t* pinnedFrames);
176d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
177d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    struct RingBufferItem : public BufferItem {
178d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        RingBufferItem() : BufferItem(), mPinCount(0) {}
179d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin        int mPinCount;
180d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    };
181d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
182d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    // List of acquired buffers in our ring buffer
183d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    List<RingBufferItem>       mBufferItemList;
184d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin    const int                  mBufferCount;
185d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin};
186d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
187d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin} // namespace android
188d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin
189d4d5227521a53dec6f77bed33846b4ccd4a760e4Igor Murashkin#endif // ANDROID_GUI_CPUCONSUMER_H
190