Change BufferQueue into producer/consumer wrapper
Now that BufferQueue has been split into core + producer + consumer, rewrite BufferQueue to be a thin layer over a producer and consumer interface. Eventually, this layer will be deprecated in favor of only using either the producer or consumer interface, as applicable. Change-Id: I340ae5f5b633b244fb594615ff52ba50b9e2f7e4
This commit is contained in:
parent
289ade165e
commit
3e96f1982f
@ -17,23 +17,16 @@
|
||||
#ifndef ANDROID_GUI_BUFFERQUEUE_H
|
||||
#define ANDROID_GUI_BUFFERQUEUE_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <gui/BufferQueueProducer.h>
|
||||
#include <gui/BufferQueueConsumer.h>
|
||||
#include <gui/IConsumerListener.h>
|
||||
|
||||
// These are only required to keep other parts of the framework with incomplete
|
||||
// dependencies building successfully
|
||||
#include <gui/IGraphicBufferAlloc.h>
|
||||
|
||||
#include <binder/IBinder.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>
|
||||
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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 {
|
||||
@ -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
|
||||
|
||||
|
@ -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>
|
||||
@ -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
|
||||
@ -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
|
||||
|
35
include/gui/BufferQueueDefs.h
Normal file
35
include/gui/BufferQueueDefs.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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
|
@ -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 {
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
@ -38,6 +38,9 @@ BufferItem::BufferItem() :
|
||||
|
||||
BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
|
||||
IGraphicBufferConsumer::BufferItem bufferItem;
|
||||
bufferItem.mGraphicBuffer = mGraphicBuffer;
|
||||
bufferItem.mFence = mFence;
|
||||
bufferItem.mCrop = mCrop;
|
||||
bufferItem.mTransform = mTransform;
|
||||
bufferItem.mScalingMode = mScalingMode;
|
||||
bufferItem.mTimestamp = mTimestamp;
|
||||
@ -47,7 +50,6 @@ BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
|
||||
bufferItem.mIsDroppable = mIsDroppable;
|
||||
bufferItem.mAcquireCalled = mAcquireCalled;
|
||||
bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
|
||||
bufferItem.mCrop = mCrop;
|
||||
return bufferItem;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "BufferQueueConsumer"
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <gui/BufferItem.h>
|
||||
#include <gui/BufferQueueConsumer.h>
|
||||
#include <gui/BufferQueueCore.h>
|
||||
@ -38,7 +42,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
|
||||
// buffer so that the consumer can successfully set up the newly acquired
|
||||
// buffer before releasing the old one.
|
||||
int numAcquiredBuffers = 0;
|
||||
for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
|
||||
++numAcquiredBuffers;
|
||||
}
|
||||
@ -275,7 +279,7 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint32_t *outSlotMask) {
|
||||
}
|
||||
|
||||
uint32_t mask = 0;
|
||||
for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
if (!mSlots[s].mAcquireCalled) {
|
||||
mask |= (1u << s);
|
||||
}
|
||||
|
@ -14,11 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "BufferQueueCore"
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
|
||||
#include <gui/BufferItem.h>
|
||||
#include <gui/BufferQueueCore.h>
|
||||
#include <gui/IConsumerListener.h>
|
||||
#include <gui/IGraphicBufferAlloc.h>
|
||||
#include <gui/ISurfaceComposer.h>
|
||||
#include <private/gui/ComposerService.h>
|
||||
|
||||
template <typename T>
|
||||
static inline T max(T a, T b) { return a > b ? a : b; }
|
||||
@ -54,7 +61,16 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
|
||||
mMaxAcquiredBufferCount(1),
|
||||
mBufferHasBeenQueued(false),
|
||||
mFrameCounter(0),
|
||||
mTransformHint(0) {}
|
||||
mTransformHint(0)
|
||||
{
|
||||
if (allocator == NULL) {
|
||||
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
|
||||
mAllocator = composer->createGraphicBufferAlloc();
|
||||
if (mAllocator == NULL) {
|
||||
BQ_LOGE("createGraphicBufferAlloc failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferQueueCore::~BufferQueueCore() {}
|
||||
|
||||
@ -82,7 +98,7 @@ void BufferQueueCore::dump(String8& result, const char* prefix) const {
|
||||
|
||||
// Trim the free buffers so as to not spam the dump
|
||||
int maxBufferCount = 0;
|
||||
for (int s = NUM_BUFFER_SLOTS - 1; s >= 0; --s) {
|
||||
for (int s = BufferQueueDefs::NUM_BUFFER_SLOTS - 1; s >= 0; --s) {
|
||||
const BufferSlot& slot(mSlots[s]);
|
||||
if (slot.mBufferState != BufferSlot::FREE ||
|
||||
slot.mGraphicBuffer != NULL) {
|
||||
@ -140,7 +156,7 @@ int BufferQueueCore::getMaxBufferCountLocked(bool async) const {
|
||||
// waiting to be consumed need to have their slots preserved. Such buffers
|
||||
// will temporarily keep the max buffer count up until the slots no longer
|
||||
// need to be preserved.
|
||||
for (int s = maxBufferCount; s < NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
BufferSlot::BufferState state = mSlots[s].mBufferState;
|
||||
if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
|
||||
maxBufferCount = s + 1;
|
||||
@ -152,9 +168,9 @@ int BufferQueueCore::getMaxBufferCountLocked(bool async) const {
|
||||
|
||||
status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
|
||||
const int minBufferCount = mUseAsyncBuffer ? 2 : 1;
|
||||
if (count < minBufferCount || count > NUM_BUFFER_SLOTS) {
|
||||
if (count < minBufferCount || count > BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
||||
BQ_LOGV("setDefaultMaxBufferCount: invalid count %d, should be in "
|
||||
"[%d, %d]", minBufferCount, NUM_BUFFER_SLOTS);
|
||||
"[%d, %d]", minBufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
@ -185,7 +201,7 @@ void BufferQueueCore::freeBufferLocked(int slot) {
|
||||
|
||||
void BufferQueueCore::freeAllBuffersLocked() {
|
||||
mBufferHasBeenQueued = false;
|
||||
for (int s = 0; s < NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
freeBufferLocked(s);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "BufferQueueProducer"
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
|
||||
#include <gui/BufferItem.h>
|
||||
@ -44,9 +48,9 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
if (slot < 0 || slot >= BufferQueueCore::NUM_BUFFER_SLOTS) {
|
||||
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
||||
BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
|
||||
slot, BufferQueueCore::NUM_BUFFER_SLOTS);
|
||||
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
|
||||
return BAD_VALUE;
|
||||
} else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
|
||||
BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
|
||||
@ -72,14 +76,14 @@ status_t BufferQueueProducer::setBufferCount(int bufferCount) {
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
if (bufferCount > BufferQueueCore::NUM_BUFFER_SLOTS) {
|
||||
if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
||||
BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)",
|
||||
bufferCount, BufferQueueCore::NUM_BUFFER_SLOTS);
|
||||
bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
// There must be no dequeued buffers when changing the buffer count.
|
||||
for (int s = 0; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) {
|
||||
BQ_LOGE("setBufferCount: buffer owned by producer");
|
||||
return -EINVAL;
|
||||
@ -169,7 +173,7 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
|
||||
}
|
||||
|
||||
// Free up any buffers that are in slots beyond the max buffer count
|
||||
for (int s = maxBufferCount; s < BufferQueueCore::NUM_BUFFER_SLOTS; ++s) {
|
||||
for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||
assert(mSlots[s].mBufferState == BufferSlot::FREE);
|
||||
if (mSlots[s].mGraphicBuffer != NULL) {
|
||||
mCore->freeBufferLocked(s);
|
||||
@ -494,9 +498,9 @@ void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot < 0 || slot >= BufferQueueCore::NUM_BUFFER_SLOTS) {
|
||||
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
|
||||
BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
|
||||
slot, BufferQueueCore::NUM_BUFFER_SLOTS);
|
||||
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
|
||||
return;
|
||||
} else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
|
||||
BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
|
||||
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gui/BufferSlot.h>
|
||||
|
||||
namespace android {
|
||||
|
Loading…
Reference in New Issue
Block a user