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