Loading include/gui/BufferQueue.h +8 −271 Original line number Diff line number Diff line Loading @@ -17,22 +17,15 @@ #ifndef ANDROID_GUI_BUFFERQUEUE_H #define ANDROID_GUI_BUFFERQUEUE_H #include <EGL/egl.h> #include <EGL/eglext.h> #include <binder/IBinder.h> #include <gui/BufferQueueProducer.h> #include <gui/BufferQueueConsumer.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IGraphicBufferConsumer.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> // These are only required to keep other parts of the framework with incomplete // dependencies building successfully #include <gui/IGraphicBufferAlloc.h> #include <utils/String8.h> #include <utils/Vector.h> #include <utils/threads.h> #include <binder/IBinder.h> namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -317,264 +310,8 @@ public: virtual void dump(String8& result, const char* prefix) const; private: // The default API number used to indicate no producer client is connected. enum { NO_CONNECTED_API = 0 }; // Aliases for using enums from <IGraphicBufferConsumer.h> enum { STALE_BUFFER_SLOT = IGraphicBufferConsumer::STALE_BUFFER_SLOT }; // freeBufferLocked frees the GraphicBuffer and sync resources for the // given slot. void freeBufferLocked(int index); // freeAllBuffersLocked frees the GraphicBuffer and sync resources for // all slots. void freeAllBuffersLocked(); // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots // that will be used if the producer does not override the buffer slot // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. // The initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); // getMinUndequeuedBufferCount returns the minimum number of buffers // that must remain in a state other than DEQUEUED. // The async parameter tells whether we're in asynchronous mode. int getMinUndequeuedBufferCount(bool async) const; // getMinBufferCountLocked returns the minimum number of buffers allowed // given the current BufferQueue state. // The async parameter tells whether we're in asynchronous mode. int getMinMaxBufferCountLocked(bool async) const; // getMaxBufferCountLocked returns the maximum number of buffers that can // be allocated at once. This value depends upon the following member // variables: // // mDequeueBufferCannotBlock // mMaxAcquiredBufferCount // mDefaultMaxBufferCount // mOverrideMaxBufferCount // async parameter // // Any time one of these member variables is changed while a producer is // connected, mDequeueCondition must be broadcast. int getMaxBufferCountLocked(bool async) const; // stillTracking returns true iff the buffer item is still being tracked // in one of the slots. bool stillTracking(const BufferItem *item) const; struct BufferSlot { BufferSlot() : mEglDisplay(EGL_NO_DISPLAY), mBufferState(BufferSlot::FREE), mRequestBufferCalled(false), mFrameNumber(0), mEglFence(EGL_NO_SYNC_KHR), mAcquireCalled(false), mNeedsCleanupOnRelease(false) { } // mGraphicBuffer points to the buffer allocated for this slot or is NULL // if no buffer has been allocated. sp<GraphicBuffer> mGraphicBuffer; // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects. EGLDisplay mEglDisplay; // BufferState represents the different states in which a buffer slot // can be. All slots are initially FREE. enum BufferState { // FREE indicates that the buffer is available to be dequeued // by the producer. The buffer may be in use by the consumer for // a finite time, so the buffer must not be modified until the // associated fence is signaled. // // The slot is "owned" by BufferQueue. It transitions to DEQUEUED // when dequeueBuffer is called. FREE = 0, // DEQUEUED indicates that the buffer has been dequeued by the // producer, but has not yet been queued or canceled. The // producer may modify the buffer's contents as soon as the // associated ready fence is signaled. // // The slot is "owned" by the producer. It can transition to // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer). DEQUEUED = 1, // QUEUED indicates that the buffer has been filled by the // producer and queued for use by the consumer. The buffer // contents may continue to be modified for a finite time, so // the contents must not be accessed until the associated fence // is signaled. // // The slot is "owned" by BufferQueue. It can transition to // ACQUIRED (via acquireBuffer) or to FREE (if another buffer is // queued in asynchronous mode). QUEUED = 2, // ACQUIRED indicates that the buffer has been acquired by the // consumer. As with QUEUED, the contents must not be accessed // by the consumer until the fence is signaled. // // The slot is "owned" by the consumer. It transitions to FREE // when releaseBuffer is called. ACQUIRED = 3 }; // mBufferState is the current state of this buffer slot. BufferState mBufferState; // mRequestBufferCalled is used for validating that the producer did // call requestBuffer() when told to do so. Technically this is not // needed but useful for debugging and catching producer bugs. bool mRequestBufferCalled; // mFrameNumber is the number of the queued frame for this slot. This // is used to dequeue buffers in LRU order (useful because buffers // may be released before their release fence is signaled). uint64_t mFrameNumber; // mEglFence is the EGL sync object that must signal before the buffer // associated with this buffer slot may be dequeued. It is initialized // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a // new sync object in releaseBuffer. (This is deprecated in favor of // mFence, below.) EGLSyncKHR mEglFence; // mFence is a fence which will signal when work initiated by the // previous owner of the buffer is finished. When the buffer is FREE, // the fence indicates when the consumer has finished reading // from the buffer, or when the producer has finished writing if it // called cancelBuffer after queueing some writes. When the buffer is // QUEUED, it indicates when the producer has finished filling the // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been // passed to the consumer or producer along with ownership of the // buffer, and mFence is set to NO_FENCE. sp<Fence> mFence; // Indicates whether this buffer has been seen by a consumer yet bool mAcquireCalled; // Indicates whether this buffer needs to be cleaned up by the // consumer. This is set when a buffer in ACQUIRED state is freed. // It causes releaseBuffer to return STALE_BUFFER_SLOT. bool mNeedsCleanupOnRelease; }; // mSlots is the array of buffer slots that must be mirrored on the // producer side. This allows buffer ownership to be transferred between // the producer and consumer without sending a GraphicBuffer over binder. // The entire array is initialized to NULL at construction time, and // buffers are allocated for a slot when requestBuffer is called with // that slot's index. BufferSlot mSlots[NUM_BUFFER_SLOTS]; // mDefaultWidth holds the default width of allocated buffers. It is used // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultWidth; // mDefaultHeight holds the default height of allocated buffers. It is used // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultHeight; // mMaxAcquiredBufferCount is the number of buffers that the consumer may // acquire at one time. It defaults to 1 and can be changed by the // consumer via the setMaxAcquiredBufferCount method, but this may only be // done when no producer is connected to the BufferQueue. // // This value is used to derive the value returned for the // MIN_UNDEQUEUED_BUFFERS query by the producer. int mMaxAcquiredBufferCount; // mDefaultMaxBufferCount is the default limit on the number of buffers // that will be allocated at one time. This default limit is set by the // consumer. The limit (as opposed to the default limit) may be // overridden by the producer. int mDefaultMaxBufferCount; // mOverrideMaxBufferCount is the limit on the number of buffers that will // be allocated at one time. This value is set by the image producer by // calling setBufferCount. The default is zero, which means the producer // doesn't care about the number of buffers in the pool. In that case // mDefaultMaxBufferCount is used as the limit. int mOverrideMaxBufferCount; // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to // allocate new GraphicBuffer objects. sp<IGraphicBufferAlloc> mGraphicBufferAlloc; // mConsumerListener is used to notify the connected consumer of // asynchronous events that it may wish to react to. It is initially set // to NULL and is written by consumerConnect and consumerDisconnect. sp<IConsumerListener> mConsumerListener; // mConsumerControlledByApp whether the connected consumer is controlled by the // application. bool mConsumerControlledByApp; // mDequeueBufferCannotBlock whether dequeueBuffer() isn't allowed to block. // this flag is set during connect() when both consumer and producer are controlled // by the application. bool mDequeueBufferCannotBlock; // mUseAsyncBuffer whether an extra buffer is used in async mode to prevent // dequeueBuffer() from ever blocking. bool mUseAsyncBuffer; // mConnectedApi indicates the producer API that is currently connected // to this BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets // updated by the connect and disconnect methods. int mConnectedApi; // mDequeueCondition condition used for dequeueBuffer in synchronous mode mutable Condition mDequeueCondition; // mQueue is a FIFO of queued buffers used in synchronous mode typedef Vector<BufferItem> Fifo; Fifo mQueue; // mAbandoned indicates that the BufferQueue will no longer be used to // consume image buffers pushed to it using the IGraphicBufferProducer // interface. It is initialized to false, and set to true in the // consumerDisconnect method. A BufferQueue that has been abandoned will // return the NO_INIT error from all IGraphicBufferProducer methods // capable of returning an error. bool mAbandoned; // mConsumerName is a string used to identify the BufferQueue in log // messages. It is set by the setConsumerName method. String8 mConsumerName; // mMutex is the mutex used to prevent concurrent access to the member // variables of BufferQueue objects. It must be locked whenever the // member variables are accessed. mutable Mutex mMutex; // mFrameCounter is the free running counter, incremented on every // successful queueBuffer call, and buffer allocation. uint64_t mFrameCounter; // mBufferHasBeenQueued is true once a buffer has been queued. It is // reset when something causes all buffers to be freed (e.g. changing the // buffer count). bool mBufferHasBeenQueued; // mDefaultBufferFormat can be set so it will override // the buffer format when it isn't specified in dequeueBuffer uint32_t mDefaultBufferFormat; // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers uint32_t mConsumerUsageBits; // mTransformHint is used to optimize for screen rotations uint32_t mTransformHint; // mConnectedProducerToken is used to set a binder death notification on the producer sp<IBinder> mConnectedProducerToken; sp<BufferQueueProducer> mProducer; sp<BufferQueueConsumer> mConsumer; }; // ---------------------------------------------------------------------------- Loading include/gui/BufferQueueConsumer.h +27 −3 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <gui/BufferQueueCore.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferConsumer.h> namespace android { Loading Loading @@ -136,10 +136,34 @@ public: // dump our state in a String virtual void dump(String8& result, const char* prefix) const; // Functions required for backwards compatibility. // These will be modified/renamed in IGraphicBufferConsumer and will be // removed from this class at that time. See b/13306289. virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, releaseFence, display, fence); } virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { return connect(consumer, controlledByApp); } virtual status_t consumerDisconnect() { return disconnect(); } // End functions required for backwards compatibility private: sp<BufferQueueCore> mCore; BufferQueueCore::SlotsType& mSlots; String8 mConsumerName; // Cached from mCore. Updated on setConsumerName. // This references mCore->mSlots. Lock mCore->mMutex while accessing. BufferQueueDefs::SlotsType& mSlots; // This is a cached copy of the name stored in the BufferQueueCore. // It's updated during setConsumerName. String8 mConsumerName; }; // class BufferQueueConsumer Loading include/gui/BufferQueueCore.h +125 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef ANDROID_GUI_BUFFERQUEUECORE_H #define ANDROID_GUI_BUFFERQUEUECORE_H #include <gui/BufferQueueDefs.h> #include <gui/BufferSlot.h> #include <utils/Condition.h> Loading Loading @@ -54,22 +55,17 @@ class BufferQueueCore : public virtual RefBase { friend class BufferQueueConsumer; public: // BufferQueue will keep track of at most this value of buffers. Attempts // at runtime to increase the number of buffers past this will fail. enum { NUM_BUFFER_SLOTS = 32 }; // Used as a placeholder slot number when the value isn't pointing to an // existing buffer. enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem // We reserve two slots in order to guarantee that the producer and // consumer can run asynchronously. enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 }; // The default API number used to indicate that no producer is connected enum { NO_CONNECTED_API = 0 }; typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; typedef Vector<BufferItem> Fifo; // BufferQueueCore manages a pool of gralloc memory slots to be used by Loading @@ -79,38 +75,159 @@ public: virtual ~BufferQueueCore(); private: // Dump our state in a string void dump(String8& result, const char* prefix) const; // getMinUndequeuedBufferCountLocked returns the minimum number of buffers // that must remain in a state other than DEQUEUED. The async parameter // tells whether we're in asynchronous mode. int getMinUndequeuedBufferCountLocked(bool async) const; // getMinMaxBufferCountLocked returns the minimum number of buffers allowed // given the current BufferQueue state. The async parameter tells whether // we're in asynchonous mode. int getMinMaxBufferCountLocked(bool async) const; // getMaxBufferCountLocked returns the maximum number of buffers that can be // allocated at once. This value depends on the following member variables: // // mDequeueBufferCannotBlock // mMaxAcquiredBufferCount // mDefaultMaxBufferCount // mOverrideMaxBufferCount // async parameter // // Any time one of these member variables is changed while a producer is // connected, mDequeueCondition must be broadcast. int getMaxBufferCountLocked(bool async) const; // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots // that will be used if the producer does not override the buffer slot // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The // initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); // freeBufferLocked frees the GraphicBuffer and sync resources for the // given slot. void freeBufferLocked(int slot); // freeAllBuffersLocked frees the GraphicBuffer and sync resources for // all slots. void freeAllBuffersLocked(); // stillTracking returns true iff the buffer item is still being tracked // in one of the slots. bool stillTracking(const BufferItem* item) const; const sp<IGraphicBufferAlloc>& mAllocator; // mAllocator is the connection to SurfaceFlinger that is used to allocate // new GraphicBuffer objects. sp<IGraphicBufferAlloc> mAllocator; // mMutex is the mutex used to prevent concurrent access to the member // variables of BufferQueueCore objects. It must be locked whenever any // member variable is accessed. mutable Mutex mMutex; // mIsAbandoned indicates that the BufferQueue will no longer be used to // consume image buffers pushed to it using the IGraphicBufferProducer // interface. It is initialized to false, and set to true in the // consumerDisconnect method. A BufferQueue that is abandoned will return // the NO_INIT error from all IGraphicBufferProducer methods capable of // returning an error. bool mIsAbandoned; // mConsumerControlledByApp indicates whether the connected consumer is // controlled by the application. bool mConsumerControlledByApp; // mConsumerName is a string used to identify the BufferQueue in log // messages. It is set by the IGraphicBufferConsumer::setConsumerName // method. String8 mConsumerName; // mConsumerListener is used to notify the connected consumer of // asynchronous events that it may wish to react to. It is initially // set to NULL and is written by consumerConnect and consumerDisconnect. sp<IConsumerListener> mConsumerListener; // mConsumerUsageBits contains flags that the consumer wants for // GraphicBuffers. uint32_t mConsumerUsageBits; // mConnectedApi indicates the producer API that is currently connected // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated // by the connect and disconnect methods. int mConnectedApi; // mConnectedProducerToken is used to set a binder death notification on // the producer. sp<IBinder> mConnectedProducerToken; BufferSlot mSlots[NUM_BUFFER_SLOTS]; // mSlots is an array of buffer slots that must be mirrored on the producer // side. This allows buffer ownership to be transferred between the producer // and consumer without sending a GraphicBuffer over Binder. The entire // array is initialized to NULL at construction time, and buffers are // allocated for a slot when requestBuffer is called with that slot's index. BufferQueueDefs::SlotsType mSlots; // mQueue is a FIFO of queued buffers used in synchronous mode. Fifo mQueue; // mOverrideMaxBufferCount is the limit on the number of buffers that will // be allocated at one time. This value is set by the producer by calling // setBufferCount. The default is 0, which means that the producer doesn't // care about the number of buffers in the pool. In that case, // mDefaultMaxBufferCount is used as the limit. int mOverrideMaxBufferCount; // mDequeueCondition is a condition variable used for dequeueBuffer in // synchronous mode. mutable Condition mDequeueCondition; // mUseAsyncBuffer indicates whether an extra buffer is used in async mode // to prevent dequeueBuffer from blocking. bool mUseAsyncBuffer; // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to // block. This flag is set during connect when both the producer and // consumer are controlled by the application. bool mDequeueBufferCannotBlock; // mDefaultBufferFormat can be set so it will override the buffer format // when it isn't specified in dequeueBuffer. uint32_t mDefaultBufferFormat; // mDefaultWidth holds the default width of allocated buffers. It is used // in dequeueBuffer if a width and height of 0 are specified. int mDefaultWidth; // mDefaultHeight holds the default height of allocated buffers. It is used // in dequeueBuffer if a width and height of 0 are specified. int mDefaultHeight; // mDefaultMaxBufferCount is the default limit on the number of buffers that // will be allocated at one time. This default limit is set by the consumer. // The limit (as opposed to the default limit) may be overriden by the // producer. int mDefaultMaxBufferCount; // mMaxAcquiredBufferCount is the number of buffers that the consumer may // acquire at one time. It defaults to 1, and can be changed by the consumer // via setMaxAcquiredBufferCount, but this may only be done while no // producer is connected to the BufferQueue. This value is used to derive // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. int mMaxAcquiredBufferCount; // mBufferHasBeenQueued is true once a buffer has been queued. It is reset // when something causes all buffers to be freed (e.g., changing the buffer // count). bool mBufferHasBeenQueued; // mFrameCounter is the free running counter, incremented on every // successful queueBuffer call and buffer allocation. uint64_t mFrameCounter; // mTransformHint is used to optimize for screen rotations. uint32_t mTransformHint; }; // class BufferQueueCore Loading include/gui/BufferQueueDefs.h 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H #define ANDROID_GUI_BUFFERQUEUECOREDEFS_H #include <gui/BufferSlot.h> namespace android { class BufferQueueCore; namespace BufferQueueDefs { // BufferQueue will keep track of at most this value of buffers. // Attempts at runtime to increase the number of buffers past this // will fail. enum { NUM_BUFFER_SLOTS = 32 }; typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; } // namespace BufferQueueDefs } // namespace android #endif include/gui/BufferQueueProducer.h +6 −3 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ #ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H #define ANDROID_GUI_BUFFERQUEUEPRODUCER_H #include <gui/BufferQueueCore.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferProducer.h> namespace android { Loading @@ -26,8 +26,9 @@ class BufferSlot; class BufferQueueProducer : public BnGraphicBufferProducer, private IBinder::DeathRecipient { public: friend class BufferQueue; // Needed to access binderDied BufferQueueProducer(const sp<BufferQueueCore>& core); virtual ~BufferQueueProducer(); Loading Loading @@ -151,7 +152,9 @@ private: virtual void binderDied(const wp<IBinder>& who); sp<BufferQueueCore> mCore; BufferQueueCore::SlotsType& mSlots; // This references mCore->mSlots. Lock mCore->mMutex while accessing. BufferQueueDefs::SlotsType& mSlots; // This is a cached copy of the name stored in the BufferQueueCore. // It's updated during connect and dequeueBuffer (which should catch Loading Loading
include/gui/BufferQueue.h +8 −271 Original line number Diff line number Diff line Loading @@ -17,22 +17,15 @@ #ifndef ANDROID_GUI_BUFFERQUEUE_H #define ANDROID_GUI_BUFFERQUEUE_H #include <EGL/egl.h> #include <EGL/eglext.h> #include <binder/IBinder.h> #include <gui/BufferQueueProducer.h> #include <gui/BufferQueueConsumer.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IGraphicBufferConsumer.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> // These are only required to keep other parts of the framework with incomplete // dependencies building successfully #include <gui/IGraphicBufferAlloc.h> #include <utils/String8.h> #include <utils/Vector.h> #include <utils/threads.h> #include <binder/IBinder.h> namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -317,264 +310,8 @@ public: virtual void dump(String8& result, const char* prefix) const; private: // The default API number used to indicate no producer client is connected. enum { NO_CONNECTED_API = 0 }; // Aliases for using enums from <IGraphicBufferConsumer.h> enum { STALE_BUFFER_SLOT = IGraphicBufferConsumer::STALE_BUFFER_SLOT }; // freeBufferLocked frees the GraphicBuffer and sync resources for the // given slot. void freeBufferLocked(int index); // freeAllBuffersLocked frees the GraphicBuffer and sync resources for // all slots. void freeAllBuffersLocked(); // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots // that will be used if the producer does not override the buffer slot // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. // The initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); // getMinUndequeuedBufferCount returns the minimum number of buffers // that must remain in a state other than DEQUEUED. // The async parameter tells whether we're in asynchronous mode. int getMinUndequeuedBufferCount(bool async) const; // getMinBufferCountLocked returns the minimum number of buffers allowed // given the current BufferQueue state. // The async parameter tells whether we're in asynchronous mode. int getMinMaxBufferCountLocked(bool async) const; // getMaxBufferCountLocked returns the maximum number of buffers that can // be allocated at once. This value depends upon the following member // variables: // // mDequeueBufferCannotBlock // mMaxAcquiredBufferCount // mDefaultMaxBufferCount // mOverrideMaxBufferCount // async parameter // // Any time one of these member variables is changed while a producer is // connected, mDequeueCondition must be broadcast. int getMaxBufferCountLocked(bool async) const; // stillTracking returns true iff the buffer item is still being tracked // in one of the slots. bool stillTracking(const BufferItem *item) const; struct BufferSlot { BufferSlot() : mEglDisplay(EGL_NO_DISPLAY), mBufferState(BufferSlot::FREE), mRequestBufferCalled(false), mFrameNumber(0), mEglFence(EGL_NO_SYNC_KHR), mAcquireCalled(false), mNeedsCleanupOnRelease(false) { } // mGraphicBuffer points to the buffer allocated for this slot or is NULL // if no buffer has been allocated. sp<GraphicBuffer> mGraphicBuffer; // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects. EGLDisplay mEglDisplay; // BufferState represents the different states in which a buffer slot // can be. All slots are initially FREE. enum BufferState { // FREE indicates that the buffer is available to be dequeued // by the producer. The buffer may be in use by the consumer for // a finite time, so the buffer must not be modified until the // associated fence is signaled. // // The slot is "owned" by BufferQueue. It transitions to DEQUEUED // when dequeueBuffer is called. FREE = 0, // DEQUEUED indicates that the buffer has been dequeued by the // producer, but has not yet been queued or canceled. The // producer may modify the buffer's contents as soon as the // associated ready fence is signaled. // // The slot is "owned" by the producer. It can transition to // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer). DEQUEUED = 1, // QUEUED indicates that the buffer has been filled by the // producer and queued for use by the consumer. The buffer // contents may continue to be modified for a finite time, so // the contents must not be accessed until the associated fence // is signaled. // // The slot is "owned" by BufferQueue. It can transition to // ACQUIRED (via acquireBuffer) or to FREE (if another buffer is // queued in asynchronous mode). QUEUED = 2, // ACQUIRED indicates that the buffer has been acquired by the // consumer. As with QUEUED, the contents must not be accessed // by the consumer until the fence is signaled. // // The slot is "owned" by the consumer. It transitions to FREE // when releaseBuffer is called. ACQUIRED = 3 }; // mBufferState is the current state of this buffer slot. BufferState mBufferState; // mRequestBufferCalled is used for validating that the producer did // call requestBuffer() when told to do so. Technically this is not // needed but useful for debugging and catching producer bugs. bool mRequestBufferCalled; // mFrameNumber is the number of the queued frame for this slot. This // is used to dequeue buffers in LRU order (useful because buffers // may be released before their release fence is signaled). uint64_t mFrameNumber; // mEglFence is the EGL sync object that must signal before the buffer // associated with this buffer slot may be dequeued. It is initialized // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a // new sync object in releaseBuffer. (This is deprecated in favor of // mFence, below.) EGLSyncKHR mEglFence; // mFence is a fence which will signal when work initiated by the // previous owner of the buffer is finished. When the buffer is FREE, // the fence indicates when the consumer has finished reading // from the buffer, or when the producer has finished writing if it // called cancelBuffer after queueing some writes. When the buffer is // QUEUED, it indicates when the producer has finished filling the // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been // passed to the consumer or producer along with ownership of the // buffer, and mFence is set to NO_FENCE. sp<Fence> mFence; // Indicates whether this buffer has been seen by a consumer yet bool mAcquireCalled; // Indicates whether this buffer needs to be cleaned up by the // consumer. This is set when a buffer in ACQUIRED state is freed. // It causes releaseBuffer to return STALE_BUFFER_SLOT. bool mNeedsCleanupOnRelease; }; // mSlots is the array of buffer slots that must be mirrored on the // producer side. This allows buffer ownership to be transferred between // the producer and consumer without sending a GraphicBuffer over binder. // The entire array is initialized to NULL at construction time, and // buffers are allocated for a slot when requestBuffer is called with // that slot's index. BufferSlot mSlots[NUM_BUFFER_SLOTS]; // mDefaultWidth holds the default width of allocated buffers. It is used // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultWidth; // mDefaultHeight holds the default height of allocated buffers. It is used // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultHeight; // mMaxAcquiredBufferCount is the number of buffers that the consumer may // acquire at one time. It defaults to 1 and can be changed by the // consumer via the setMaxAcquiredBufferCount method, but this may only be // done when no producer is connected to the BufferQueue. // // This value is used to derive the value returned for the // MIN_UNDEQUEUED_BUFFERS query by the producer. int mMaxAcquiredBufferCount; // mDefaultMaxBufferCount is the default limit on the number of buffers // that will be allocated at one time. This default limit is set by the // consumer. The limit (as opposed to the default limit) may be // overridden by the producer. int mDefaultMaxBufferCount; // mOverrideMaxBufferCount is the limit on the number of buffers that will // be allocated at one time. This value is set by the image producer by // calling setBufferCount. The default is zero, which means the producer // doesn't care about the number of buffers in the pool. In that case // mDefaultMaxBufferCount is used as the limit. int mOverrideMaxBufferCount; // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to // allocate new GraphicBuffer objects. sp<IGraphicBufferAlloc> mGraphicBufferAlloc; // mConsumerListener is used to notify the connected consumer of // asynchronous events that it may wish to react to. It is initially set // to NULL and is written by consumerConnect and consumerDisconnect. sp<IConsumerListener> mConsumerListener; // mConsumerControlledByApp whether the connected consumer is controlled by the // application. bool mConsumerControlledByApp; // mDequeueBufferCannotBlock whether dequeueBuffer() isn't allowed to block. // this flag is set during connect() when both consumer and producer are controlled // by the application. bool mDequeueBufferCannotBlock; // mUseAsyncBuffer whether an extra buffer is used in async mode to prevent // dequeueBuffer() from ever blocking. bool mUseAsyncBuffer; // mConnectedApi indicates the producer API that is currently connected // to this BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets // updated by the connect and disconnect methods. int mConnectedApi; // mDequeueCondition condition used for dequeueBuffer in synchronous mode mutable Condition mDequeueCondition; // mQueue is a FIFO of queued buffers used in synchronous mode typedef Vector<BufferItem> Fifo; Fifo mQueue; // mAbandoned indicates that the BufferQueue will no longer be used to // consume image buffers pushed to it using the IGraphicBufferProducer // interface. It is initialized to false, and set to true in the // consumerDisconnect method. A BufferQueue that has been abandoned will // return the NO_INIT error from all IGraphicBufferProducer methods // capable of returning an error. bool mAbandoned; // mConsumerName is a string used to identify the BufferQueue in log // messages. It is set by the setConsumerName method. String8 mConsumerName; // mMutex is the mutex used to prevent concurrent access to the member // variables of BufferQueue objects. It must be locked whenever the // member variables are accessed. mutable Mutex mMutex; // mFrameCounter is the free running counter, incremented on every // successful queueBuffer call, and buffer allocation. uint64_t mFrameCounter; // mBufferHasBeenQueued is true once a buffer has been queued. It is // reset when something causes all buffers to be freed (e.g. changing the // buffer count). bool mBufferHasBeenQueued; // mDefaultBufferFormat can be set so it will override // the buffer format when it isn't specified in dequeueBuffer uint32_t mDefaultBufferFormat; // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers uint32_t mConsumerUsageBits; // mTransformHint is used to optimize for screen rotations uint32_t mTransformHint; // mConnectedProducerToken is used to set a binder death notification on the producer sp<IBinder> mConnectedProducerToken; sp<BufferQueueProducer> mProducer; sp<BufferQueueConsumer> mConsumer; }; // ---------------------------------------------------------------------------- Loading
include/gui/BufferQueueConsumer.h +27 −3 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <gui/BufferQueueCore.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferConsumer.h> namespace android { Loading Loading @@ -136,10 +136,34 @@ public: // dump our state in a String virtual void dump(String8& result, const char* prefix) const; // Functions required for backwards compatibility. // These will be modified/renamed in IGraphicBufferConsumer and will be // removed from this class at that time. See b/13306289. virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, const sp<Fence>& releaseFence) { return releaseBuffer(buf, frameNumber, releaseFence, display, fence); } virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { return connect(consumer, controlledByApp); } virtual status_t consumerDisconnect() { return disconnect(); } // End functions required for backwards compatibility private: sp<BufferQueueCore> mCore; BufferQueueCore::SlotsType& mSlots; String8 mConsumerName; // Cached from mCore. Updated on setConsumerName. // This references mCore->mSlots. Lock mCore->mMutex while accessing. BufferQueueDefs::SlotsType& mSlots; // This is a cached copy of the name stored in the BufferQueueCore. // It's updated during setConsumerName. String8 mConsumerName; }; // class BufferQueueConsumer Loading
include/gui/BufferQueueCore.h +125 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef ANDROID_GUI_BUFFERQUEUECORE_H #define ANDROID_GUI_BUFFERQUEUECORE_H #include <gui/BufferQueueDefs.h> #include <gui/BufferSlot.h> #include <utils/Condition.h> Loading Loading @@ -54,22 +55,17 @@ class BufferQueueCore : public virtual RefBase { friend class BufferQueueConsumer; public: // BufferQueue will keep track of at most this value of buffers. Attempts // at runtime to increase the number of buffers past this will fail. enum { NUM_BUFFER_SLOTS = 32 }; // Used as a placeholder slot number when the value isn't pointing to an // existing buffer. enum { INVALID_BUFFER_SLOT = -1 }; // TODO: Extract from IGBC::BufferItem // We reserve two slots in order to guarantee that the producer and // consumer can run asynchronously. enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 }; // The default API number used to indicate that no producer is connected enum { NO_CONNECTED_API = 0 }; typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; typedef Vector<BufferItem> Fifo; // BufferQueueCore manages a pool of gralloc memory slots to be used by Loading @@ -79,38 +75,159 @@ public: virtual ~BufferQueueCore(); private: // Dump our state in a string void dump(String8& result, const char* prefix) const; // getMinUndequeuedBufferCountLocked returns the minimum number of buffers // that must remain in a state other than DEQUEUED. The async parameter // tells whether we're in asynchronous mode. int getMinUndequeuedBufferCountLocked(bool async) const; // getMinMaxBufferCountLocked returns the minimum number of buffers allowed // given the current BufferQueue state. The async parameter tells whether // we're in asynchonous mode. int getMinMaxBufferCountLocked(bool async) const; // getMaxBufferCountLocked returns the maximum number of buffers that can be // allocated at once. This value depends on the following member variables: // // mDequeueBufferCannotBlock // mMaxAcquiredBufferCount // mDefaultMaxBufferCount // mOverrideMaxBufferCount // async parameter // // Any time one of these member variables is changed while a producer is // connected, mDequeueCondition must be broadcast. int getMaxBufferCountLocked(bool async) const; // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots // that will be used if the producer does not override the buffer slot // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The // initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); // freeBufferLocked frees the GraphicBuffer and sync resources for the // given slot. void freeBufferLocked(int slot); // freeAllBuffersLocked frees the GraphicBuffer and sync resources for // all slots. void freeAllBuffersLocked(); // stillTracking returns true iff the buffer item is still being tracked // in one of the slots. bool stillTracking(const BufferItem* item) const; const sp<IGraphicBufferAlloc>& mAllocator; // mAllocator is the connection to SurfaceFlinger that is used to allocate // new GraphicBuffer objects. sp<IGraphicBufferAlloc> mAllocator; // mMutex is the mutex used to prevent concurrent access to the member // variables of BufferQueueCore objects. It must be locked whenever any // member variable is accessed. mutable Mutex mMutex; // mIsAbandoned indicates that the BufferQueue will no longer be used to // consume image buffers pushed to it using the IGraphicBufferProducer // interface. It is initialized to false, and set to true in the // consumerDisconnect method. A BufferQueue that is abandoned will return // the NO_INIT error from all IGraphicBufferProducer methods capable of // returning an error. bool mIsAbandoned; // mConsumerControlledByApp indicates whether the connected consumer is // controlled by the application. bool mConsumerControlledByApp; // mConsumerName is a string used to identify the BufferQueue in log // messages. It is set by the IGraphicBufferConsumer::setConsumerName // method. String8 mConsumerName; // mConsumerListener is used to notify the connected consumer of // asynchronous events that it may wish to react to. It is initially // set to NULL and is written by consumerConnect and consumerDisconnect. sp<IConsumerListener> mConsumerListener; // mConsumerUsageBits contains flags that the consumer wants for // GraphicBuffers. uint32_t mConsumerUsageBits; // mConnectedApi indicates the producer API that is currently connected // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated // by the connect and disconnect methods. int mConnectedApi; // mConnectedProducerToken is used to set a binder death notification on // the producer. sp<IBinder> mConnectedProducerToken; BufferSlot mSlots[NUM_BUFFER_SLOTS]; // mSlots is an array of buffer slots that must be mirrored on the producer // side. This allows buffer ownership to be transferred between the producer // and consumer without sending a GraphicBuffer over Binder. The entire // array is initialized to NULL at construction time, and buffers are // allocated for a slot when requestBuffer is called with that slot's index. BufferQueueDefs::SlotsType mSlots; // mQueue is a FIFO of queued buffers used in synchronous mode. Fifo mQueue; // mOverrideMaxBufferCount is the limit on the number of buffers that will // be allocated at one time. This value is set by the producer by calling // setBufferCount. The default is 0, which means that the producer doesn't // care about the number of buffers in the pool. In that case, // mDefaultMaxBufferCount is used as the limit. int mOverrideMaxBufferCount; // mDequeueCondition is a condition variable used for dequeueBuffer in // synchronous mode. mutable Condition mDequeueCondition; // mUseAsyncBuffer indicates whether an extra buffer is used in async mode // to prevent dequeueBuffer from blocking. bool mUseAsyncBuffer; // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to // block. This flag is set during connect when both the producer and // consumer are controlled by the application. bool mDequeueBufferCannotBlock; // mDefaultBufferFormat can be set so it will override the buffer format // when it isn't specified in dequeueBuffer. uint32_t mDefaultBufferFormat; // mDefaultWidth holds the default width of allocated buffers. It is used // in dequeueBuffer if a width and height of 0 are specified. int mDefaultWidth; // mDefaultHeight holds the default height of allocated buffers. It is used // in dequeueBuffer if a width and height of 0 are specified. int mDefaultHeight; // mDefaultMaxBufferCount is the default limit on the number of buffers that // will be allocated at one time. This default limit is set by the consumer. // The limit (as opposed to the default limit) may be overriden by the // producer. int mDefaultMaxBufferCount; // mMaxAcquiredBufferCount is the number of buffers that the consumer may // acquire at one time. It defaults to 1, and can be changed by the consumer // via setMaxAcquiredBufferCount, but this may only be done while no // producer is connected to the BufferQueue. This value is used to derive // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. int mMaxAcquiredBufferCount; // mBufferHasBeenQueued is true once a buffer has been queued. It is reset // when something causes all buffers to be freed (e.g., changing the buffer // count). bool mBufferHasBeenQueued; // mFrameCounter is the free running counter, incremented on every // successful queueBuffer call and buffer allocation. uint64_t mFrameCounter; // mTransformHint is used to optimize for screen rotations. uint32_t mTransformHint; }; // class BufferQueueCore Loading
include/gui/BufferQueueDefs.h 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H #define ANDROID_GUI_BUFFERQUEUECOREDEFS_H #include <gui/BufferSlot.h> namespace android { class BufferQueueCore; namespace BufferQueueDefs { // BufferQueue will keep track of at most this value of buffers. // Attempts at runtime to increase the number of buffers past this // will fail. enum { NUM_BUFFER_SLOTS = 32 }; typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; } // namespace BufferQueueDefs } // namespace android #endif
include/gui/BufferQueueProducer.h +6 −3 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ #ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H #define ANDROID_GUI_BUFFERQUEUEPRODUCER_H #include <gui/BufferQueueCore.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferProducer.h> namespace android { Loading @@ -26,8 +26,9 @@ class BufferSlot; class BufferQueueProducer : public BnGraphicBufferProducer, private IBinder::DeathRecipient { public: friend class BufferQueue; // Needed to access binderDied BufferQueueProducer(const sp<BufferQueueCore>& core); virtual ~BufferQueueProducer(); Loading Loading @@ -151,7 +152,9 @@ private: virtual void binderDied(const wp<IBinder>& who); sp<BufferQueueCore> mCore; BufferQueueCore::SlotsType& mSlots; // This references mCore->mSlots. Lock mCore->mMutex while accessing. BufferQueueDefs::SlotsType& mSlots; // This is a cached copy of the name stored in the BufferQueueCore. // It's updated during connect and dequeueBuffer (which should catch Loading