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