Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_GUI_BUFFERQUEUE_H
     18 #define ANDROID_GUI_BUFFERQUEUE_H
     19 
     20 #include <EGL/egl.h>
     21 #include <EGL/eglext.h>
     22 
     23 #include <gui/IGraphicBufferAlloc.h>
     24 #include <gui/ISurfaceTexture.h>
     25 
     26 #include <ui/Fence.h>
     27 #include <ui/GraphicBuffer.h>
     28 
     29 #include <utils/String8.h>
     30 #include <utils/Vector.h>
     31 #include <utils/threads.h>
     32 
     33 namespace android {
     34 // ----------------------------------------------------------------------------
     35 
     36 class BufferQueue : public BnSurfaceTexture {
     37 public:
     38     enum { MIN_UNDEQUEUED_BUFFERS = 2 };
     39     enum { NUM_BUFFER_SLOTS = 32 };
     40     enum { NO_CONNECTED_API = 0 };
     41     enum { INVALID_BUFFER_SLOT = -1 };
     42     enum { STALE_BUFFER_SLOT = 1, NO_BUFFER_AVAILABLE };
     43 
     44     // When in async mode we reserve two slots in order to guarantee that the
     45     // producer and consumer can run asynchronously.
     46     enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 };
     47 
     48     // ConsumerListener is the interface through which the BufferQueue notifies
     49     // the consumer of events that the consumer may wish to react to.  Because
     50     // the consumer will generally have a mutex that is locked during calls from
     51     // teh consumer to the BufferQueue, these calls from the BufferQueue to the
     52     // consumer *MUST* be called only when the BufferQueue mutex is NOT locked.
     53     struct ConsumerListener : public virtual RefBase {
     54         // onFrameAvailable is called from queueBuffer each time an additional
     55         // frame becomes available for consumption. This means that frames that
     56         // are queued while in asynchronous mode only trigger the callback if no
     57         // previous frames are pending. Frames queued while in synchronous mode
     58         // always trigger the callback.
     59         //
     60         // This is called without any lock held and can be called concurrently
     61         // by multiple threads.
     62         virtual void onFrameAvailable() = 0;
     63 
     64         // onBuffersReleased is called to notify the buffer consumer that the
     65         // BufferQueue has released its references to one or more GraphicBuffers
     66         // contained in its slots.  The buffer consumer should then call
     67         // BufferQueue::getReleasedBuffers to retrieve the list of buffers
     68         //
     69         // This is called without any lock held and can be called concurrently
     70         // by multiple threads.
     71         virtual void onBuffersReleased() = 0;
     72     };
     73 
     74     // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak
     75     // reference to the actual consumer object.  It forwards all calls to that
     76     // consumer object so long as it exists.
     77     //
     78     // This class exists to avoid having a circular reference between the
     79     // BufferQueue object and the consumer object.  The reason this can't be a weak
     80     // reference in the BufferQueue class is because we're planning to expose the
     81     // consumer side of a BufferQueue as a binder interface, which doesn't support
     82     // weak references.
     83     class ProxyConsumerListener : public BufferQueue::ConsumerListener {
     84     public:
     85 
     86         ProxyConsumerListener(const wp<BufferQueue::ConsumerListener>& consumerListener);
     87         virtual ~ProxyConsumerListener();
     88         virtual void onFrameAvailable();
     89         virtual void onBuffersReleased();
     90 
     91     private:
     92 
     93         // mConsumerListener is a weak reference to the ConsumerListener.  This is
     94         // the raison d'etre of ProxyConsumerListener.
     95         wp<BufferQueue::ConsumerListener> mConsumerListener;
     96     };
     97 
     98 
     99     // BufferQueue manages a pool of gralloc memory slots to be used by
    100     // producers and consumers. allowSynchronousMode specifies whether or not
    101     // synchronous mode can be enabled by the producer. allocator is used to
    102     // allocate all the needed gralloc buffers.
    103     BufferQueue(bool allowSynchronousMode = true,
    104             const sp<IGraphicBufferAlloc>& allocator = NULL);
    105     virtual ~BufferQueue();
    106 
    107     virtual int query(int what, int* value);
    108 
    109     // setBufferCount updates the number of available buffer slots.  After
    110     // calling this all buffer slots are both unallocated and owned by the
    111     // BufferQueue object (i.e. they are not owned by the client).
    112     virtual status_t setBufferCount(int bufferCount);
    113 
    114     virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
    115 
    116     // dequeueBuffer gets the next buffer slot index for the client to use. If a
    117     // buffer slot is available then that slot index is written to the location
    118     // pointed to by the buf argument and a status of OK is returned.  If no
    119     // slot is available then a status of -EBUSY is returned and buf is
    120     // unmodified.
    121     //
    122     // The fence parameter will be updated to hold the fence associated with
    123     // the buffer. The contents of the buffer must not be overwritten until the
    124     // fence signals. If the fence is NULL, the buffer may be written
    125     // immediately.
    126     //
    127     // The width and height parameters must be no greater than the minimum of
    128     // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
    129     // An error due to invalid dimensions might not be reported until
    130     // updateTexImage() is called.
    131     virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence,
    132             uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
    133 
    134     // queueBuffer returns a filled buffer to the BufferQueue. In addition, a
    135     // timestamp must be provided for the buffer. The timestamp is in
    136     // nanoseconds, and must be monotonically increasing. Its other semantics
    137     // (zero point, etc) are client-dependent and should be documented by the
    138     // client.
    139     virtual status_t queueBuffer(int buf,
    140             const QueueBufferInput& input, QueueBufferOutput* output);
    141 
    142     virtual void cancelBuffer(int buf, sp<Fence> fence);
    143 
    144     // setSynchronousMode set whether dequeueBuffer is synchronous or
    145     // asynchronous. In synchronous mode, dequeueBuffer blocks until
    146     // a buffer is available, the currently bound buffer can be dequeued and
    147     // queued buffers will be retired in order.
    148     // The default mode is asynchronous.
    149     virtual status_t setSynchronousMode(bool enabled);
    150 
    151     // connect attempts to connect a producer client API to the BufferQueue.
    152     // This must be called before any other ISurfaceTexture methods are called
    153     // except for getAllocator.
    154     //
    155     // This method will fail if the connect was previously called on the
    156     // BufferQueue and no corresponding disconnect call was made.
    157     virtual status_t connect(int api, QueueBufferOutput* output);
    158 
    159     // disconnect attempts to disconnect a producer client API from the
    160     // BufferQueue. Calling this method will cause any subsequent calls to other
    161     // ISurfaceTexture methods to fail except for getAllocator and connect.
    162     // Successfully calling connect after this will allow the other methods to
    163     // succeed again.
    164     //
    165     // This method will fail if the the BufferQueue is not currently
    166     // connected to the specified client API.
    167     virtual status_t disconnect(int api);
    168 
    169     // dump our state in a String
    170     virtual void dump(String8& result) const;
    171     virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
    172 
    173     // public facing structure for BufferSlot
    174     struct BufferItem {
    175 
    176         BufferItem()
    177          :
    178            mTransform(0),
    179            mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
    180            mTimestamp(0),
    181            mFrameNumber(0),
    182            mBuf(INVALID_BUFFER_SLOT) {
    183              mCrop.makeInvalid();
    184          }
    185         // mGraphicBuffer points to the buffer allocated for this slot or is NULL
    186         // if no buffer has been allocated.
    187         sp<GraphicBuffer> mGraphicBuffer;
    188 
    189         // mCrop is the current crop rectangle for this buffer slot.
    190         Rect mCrop;
    191 
    192         // mTransform is the current transform flags for this buffer slot.
    193         uint32_t mTransform;
    194 
    195         // mScalingMode is the current scaling mode for this buffer slot.
    196         uint32_t mScalingMode;
    197 
    198         // mTimestamp is the current timestamp for this buffer slot. This gets
    199         // to set by queueBuffer each time this slot is queued.
    200         int64_t mTimestamp;
    201 
    202         // mFrameNumber is the number of the queued frame for this slot.
    203         uint64_t mFrameNumber;
    204 
    205         // mBuf is the slot index of this buffer
    206         int mBuf;
    207 
    208         // mFence is a fence that will signal when the buffer is idle.
    209         sp<Fence> mFence;
    210     };
    211 
    212     // The following public functions is the consumer facing interface
    213 
    214     // acquireBuffer attempts to acquire ownership of the next pending buffer in
    215     // the BufferQueue.  If no buffer is pending then it returns -EINVAL.  If a
    216     // buffer is successfully acquired, the information about the buffer is
    217     // returned in BufferItem.  If the buffer returned had previously been
    218     // acquired then the BufferItem::mGraphicBuffer field of buffer is set to
    219     // NULL and it is assumed that the consumer still holds a reference to the
    220     // buffer.
    221     status_t acquireBuffer(BufferItem *buffer);
    222 
    223     // releaseBuffer releases a buffer slot from the consumer back to the
    224     // BufferQueue pending a fence sync.
    225     //
    226     // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free
    227     // any references to the just-released buffer that it might have, as if it
    228     // had received a onBuffersReleased() call with a mask set for the released
    229     // buffer.
    230     //
    231     // Note that the dependencies on EGL will be removed once we switch to using
    232     // the Android HW Sync HAL.
    233     status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence,
    234             const sp<Fence>& releaseFence);
    235 
    236     // consumerConnect connects a consumer to the BufferQueue.  Only one
    237     // consumer may be connected, and when that consumer disconnects the
    238     // BufferQueue is placed into the "abandoned" state, causing most
    239     // interactions with the BufferQueue by the producer to fail.
    240     status_t consumerConnect(const sp<ConsumerListener>& consumer);
    241 
    242     // consumerDisconnect disconnects a consumer from the BufferQueue. All
    243     // buffers will be freed and the BufferQueue is placed in the "abandoned"
    244     // state, causing most interactions with the BufferQueue by the producer to
    245     // fail.
    246     status_t consumerDisconnect();
    247 
    248     // getReleasedBuffers sets the value pointed to by slotMask to a bit mask
    249     // indicating which buffer slots the have been released by the BufferQueue
    250     // but have not yet been released by the consumer.
    251     status_t getReleasedBuffers(uint32_t* slotMask);
    252 
    253     // setDefaultBufferSize is used to set the size of buffers returned by
    254     // requestBuffers when a with and height of zero is requested.
    255     status_t setDefaultBufferSize(uint32_t w, uint32_t h);
    256 
    257     // setDefaultBufferCount set the buffer count. If the client has requested
    258     // a buffer count using setBufferCount, the server-buffer count will
    259     // take effect once the client sets the count back to zero.
    260     status_t setDefaultMaxBufferCount(int bufferCount);
    261 
    262     // setMaxAcquiredBufferCount sets the maximum number of buffers that can
    263     // be acquired by the consumer at one time.  This call will fail if a
    264     // producer is connected to the BufferQueue.
    265     status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
    266 
    267     // isSynchronousMode returns whether the SurfaceTexture is currently in
    268     // synchronous mode.
    269     bool isSynchronousMode() const;
    270 
    271     // setConsumerName sets the name used in logging
    272     void setConsumerName(const String8& name);
    273 
    274     // setDefaultBufferFormat allows the BufferQueue to create
    275     // GraphicBuffers of a defaultFormat if no format is specified
    276     // in dequeueBuffer
    277     status_t setDefaultBufferFormat(uint32_t defaultFormat);
    278 
    279     // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer
    280     status_t setConsumerUsageBits(uint32_t usage);
    281 
    282     // setTransformHint bakes in rotation to buffers so overlays can be used
    283     status_t setTransformHint(uint32_t hint);
    284 
    285 private:
    286     // freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
    287     // for the given slot.
    288     void freeBufferLocked(int index);
    289 
    290     // freeAllBuffersLocked frees the resources (both GraphicBuffer and
    291     // EGLImage) for all slots.
    292     void freeAllBuffersLocked();
    293 
    294     // freeAllBuffersExceptHeadLocked frees the resources (both GraphicBuffer
    295     // and EGLImage) for all slots except the head of mQueue
    296     void freeAllBuffersExceptHeadLocked();
    297 
    298     // drainQueueLocked drains the buffer queue if we're in synchronous mode
    299     // returns immediately otherwise. It returns NO_INIT if the BufferQueue
    300     // became abandoned or disconnected during this call.
    301     status_t drainQueueLocked();
    302 
    303     // drainQueueAndFreeBuffersLocked drains the buffer queue if we're in
    304     // synchronous mode and free all buffers. In asynchronous mode, all buffers
    305     // are freed except the current buffer.
    306     status_t drainQueueAndFreeBuffersLocked();
    307 
    308     // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots
    309     // that will be used if the producer does not override the buffer slot
    310     // count.
    311     status_t setDefaultMaxBufferCountLocked(int count);
    312 
    313     // getMinBufferCountLocked returns the minimum number of buffers allowed
    314     // given the current BufferQueue state.
    315     int getMinMaxBufferCountLocked() const;
    316 
    317     // getMinUndequeuedBufferCountLocked returns the minimum number of buffers
    318     // that must remain in a state other than DEQUEUED.
    319     int getMinUndequeuedBufferCountLocked() const;
    320 
    321     // getMaxBufferCountLocked returns the maximum number of buffers that can
    322     // be allocated at once.  This value depends upon the following member
    323     // variables:
    324     //
    325     //      mSynchronousMode
    326     //      mMaxAcquiredBufferCount
    327     //      mDefaultMaxBufferCount
    328     //      mOverrideMaxBufferCount
    329     //
    330     // Any time one of these member variables is changed while a producer is
    331     // connected, mDequeueCondition must be broadcast.
    332     int getMaxBufferCountLocked() const;
    333 
    334     struct BufferSlot {
    335 
    336         BufferSlot()
    337         : mEglDisplay(EGL_NO_DISPLAY),
    338           mBufferState(BufferSlot::FREE),
    339           mRequestBufferCalled(false),
    340           mTransform(0),
    341           mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
    342           mTimestamp(0),
    343           mFrameNumber(0),
    344           mEglFence(EGL_NO_SYNC_KHR),
    345           mAcquireCalled(false),
    346           mNeedsCleanupOnRelease(false) {
    347             mCrop.makeInvalid();
    348         }
    349 
    350         // mGraphicBuffer points to the buffer allocated for this slot or is NULL
    351         // if no buffer has been allocated.
    352         sp<GraphicBuffer> mGraphicBuffer;
    353 
    354         // mEglDisplay is the EGLDisplay used to create mEglImage.
    355         EGLDisplay mEglDisplay;
    356 
    357         // BufferState represents the different states in which a buffer slot
    358         // can be.
    359         enum BufferState {
    360             // FREE indicates that the buffer is not currently being used and
    361             // will not be used in the future until it gets dequeued and
    362             // subsequently queued by the client.
    363             // aka "owned by BufferQueue, ready to be dequeued"
    364             FREE = 0,
    365 
    366             // DEQUEUED indicates that the buffer has been dequeued by the
    367             // client, but has not yet been queued or canceled. The buffer is
    368             // considered 'owned' by the client, and the server should not use
    369             // it for anything.
    370             //
    371             // Note that when in synchronous-mode (mSynchronousMode == true),
    372             // the buffer that's currently attached to the texture may be
    373             // dequeued by the client.  That means that the current buffer can
    374             // be in either the DEQUEUED or QUEUED state.  In asynchronous mode,
    375             // however, the current buffer is always in the QUEUED state.
    376             // aka "owned by producer, ready to be queued"
    377             DEQUEUED = 1,
    378 
    379             // QUEUED indicates that the buffer has been queued by the client,
    380             // and has not since been made available for the client to dequeue.
    381             // Attaching the buffer to the texture does NOT transition the
    382             // buffer away from the QUEUED state. However, in Synchronous mode
    383             // the current buffer may be dequeued by the client under some
    384             // circumstances. See the note about the current buffer in the
    385             // documentation for DEQUEUED.
    386             // aka "owned by BufferQueue, ready to be acquired"
    387             QUEUED = 2,
    388 
    389             // aka "owned by consumer, ready to be released"
    390             ACQUIRED = 3
    391         };
    392 
    393         // mBufferState is the current state of this buffer slot.
    394         BufferState mBufferState;
    395 
    396         // mRequestBufferCalled is used for validating that the client did
    397         // call requestBuffer() when told to do so. Technically this is not
    398         // needed but useful for debugging and catching client bugs.
    399         bool mRequestBufferCalled;
    400 
    401         // mCrop is the current crop rectangle for this buffer slot.
    402         Rect mCrop;
    403 
    404         // mTransform is the current transform flags for this buffer slot.
    405         // (example: NATIVE_WINDOW_TRANSFORM_ROT_90)
    406         uint32_t mTransform;
    407 
    408         // mScalingMode is the current scaling mode for this buffer slot.
    409         // (example: NATIVE_WINDOW_SCALING_MODE_FREEZE)
    410         uint32_t mScalingMode;
    411 
    412         // mTimestamp is the current timestamp for this buffer slot. This gets
    413         // to set by queueBuffer each time this slot is queued.
    414         int64_t mTimestamp;
    415 
    416         // mFrameNumber is the number of the queued frame for this slot.
    417         uint64_t mFrameNumber;
    418 
    419         // mEglFence is the EGL sync object that must signal before the buffer
    420         // associated with this buffer slot may be dequeued. It is initialized
    421         // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
    422         // on a compile-time option) set to a new sync object in updateTexImage.
    423         EGLSyncKHR mEglFence;
    424 
    425         // mFence is a fence which will signal when work initiated by the
    426         // previous owner of the buffer is finished. When the buffer is FREE,
    427         // the fence indicates when the consumer has finished reading
    428         // from the buffer, or when the producer has finished writing if it
    429         // called cancelBuffer after queueing some writes. When the buffer is
    430         // QUEUED, it indicates when the producer has finished filling the
    431         // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been
    432         // passed to the consumer or producer along with ownership of the
    433         // buffer, and mFence is empty.
    434         sp<Fence> mFence;
    435 
    436         // Indicates whether this buffer has been seen by a consumer yet
    437         bool mAcquireCalled;
    438 
    439         // Indicates whether this buffer needs to be cleaned up by consumer
    440         bool mNeedsCleanupOnRelease;
    441     };
    442 
    443     // mSlots is the array of buffer slots that must be mirrored on the client
    444     // side. This allows buffer ownership to be transferred between the client
    445     // and server without sending a GraphicBuffer over binder. The entire array
    446     // is initialized to NULL at construction time, and buffers are allocated
    447     // for a slot when requestBuffer is called with that slot's index.
    448     BufferSlot mSlots[NUM_BUFFER_SLOTS];
    449 
    450     // mDefaultWidth holds the default width of allocated buffers. It is used
    451     // in requestBuffers() if a width and height of zero is specified.
    452     uint32_t mDefaultWidth;
    453 
    454     // mDefaultHeight holds the default height of allocated buffers. It is used
    455     // in requestBuffers() if a width and height of zero is specified.
    456     uint32_t mDefaultHeight;
    457 
    458     // mMaxAcquiredBufferCount is the number of buffers that the consumer may
    459     // acquire at one time.  It defaults to 1 and can be changed by the
    460     // consumer via the setMaxAcquiredBufferCount method, but this may only be
    461     // done when no producer is connected to the BufferQueue.
    462     //
    463     // This value is used to derive the value returned for the
    464     // MIN_UNDEQUEUED_BUFFERS query by the producer.
    465     int mMaxAcquiredBufferCount;
    466 
    467     // mDefaultMaxBufferCount is the default limit on the number of buffers
    468     // that will be allocated at one time.  This default limit is set by the
    469     // consumer.  The limit (as opposed to the default limit) may be
    470     // overridden by the producer.
    471     int mDefaultMaxBufferCount;
    472 
    473     // mOverrideMaxBufferCount is the limit on the number of buffers that will
    474     // be allocated at one time. This value is set by the image producer by
    475     // calling setBufferCount. The default is zero, which means the producer
    476     // doesn't care about the number of buffers in the pool. In that case
    477     // mDefaultMaxBufferCount is used as the limit.
    478     int mOverrideMaxBufferCount;
    479 
    480     // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
    481     // allocate new GraphicBuffer objects.
    482     sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
    483 
    484     // mConsumerListener is used to notify the connected consumer of
    485     // asynchronous events that it may wish to react to.  It is initially set
    486     // to NULL and is written by consumerConnect and consumerDisconnect.
    487     sp<ConsumerListener> mConsumerListener;
    488 
    489     // mSynchronousMode whether we're in synchronous mode or not
    490     bool mSynchronousMode;
    491 
    492     // mAllowSynchronousMode whether we allow synchronous mode or not
    493     const bool mAllowSynchronousMode;
    494 
    495     // mConnectedApi indicates the API that is currently connected to this
    496     // BufferQueue.  It defaults to NO_CONNECTED_API (= 0), and gets updated
    497     // by the connect and disconnect methods.
    498     int mConnectedApi;
    499 
    500     // mDequeueCondition condition used for dequeueBuffer in synchronous mode
    501     mutable Condition mDequeueCondition;
    502 
    503     // mQueue is a FIFO of queued buffers used in synchronous mode
    504     typedef Vector<int> Fifo;
    505     Fifo mQueue;
    506 
    507     // mAbandoned indicates that the BufferQueue will no longer be used to
    508     // consume images buffers pushed to it using the ISurfaceTexture interface.
    509     // It is initialized to false, and set to true in the abandon method.  A
    510     // BufferQueue that has been abandoned will return the NO_INIT error from
    511     // all ISurfaceTexture methods capable of returning an error.
    512     bool mAbandoned;
    513 
    514     // mName is a string used to identify the BufferQueue in log messages.
    515     // It is set by the setName method.
    516     String8 mConsumerName;
    517 
    518     // mMutex is the mutex used to prevent concurrent access to the member
    519     // variables of BufferQueue objects. It must be locked whenever the
    520     // member variables are accessed.
    521     mutable Mutex mMutex;
    522 
    523     // mFrameCounter is the free running counter, incremented for every buffer queued
    524     // with the surface Texture.
    525     uint64_t mFrameCounter;
    526 
    527     // mBufferHasBeenQueued is true once a buffer has been queued.  It is reset
    528     // by changing the buffer count.
    529     bool mBufferHasBeenQueued;
    530 
    531     // mDefaultBufferFormat can be set so it will override
    532     // the buffer format when it isn't specified in dequeueBuffer
    533     uint32_t mDefaultBufferFormat;
    534 
    535     // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers
    536     uint32_t mConsumerUsageBits;
    537 
    538     // mTransformHint is used to optimize for screen rotations
    539     uint32_t mTransformHint;
    540 };
    541 
    542 // ----------------------------------------------------------------------------
    543 }; // namespace android
    544 
    545 #endif // ANDROID_GUI_BUFFERQUEUE_H
    546