Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright 2014 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_BUFFERSLOT_H
     18 #define ANDROID_GUI_BUFFERSLOT_H
     19 
     20 #include <ui/Fence.h>
     21 #include <ui/GraphicBuffer.h>
     22 
     23 #include <EGL/egl.h>
     24 #include <EGL/eglext.h>
     25 
     26 #include <utils/StrongPointer.h>
     27 
     28 namespace android {
     29 
     30 class Fence;
     31 
     32 // BufferState tracks the states in which a buffer slot can be.
     33 struct BufferState {
     34 
     35     // All slots are initially FREE (not dequeued, queued, acquired, or shared).
     36     BufferState()
     37     : mDequeueCount(0),
     38       mQueueCount(0),
     39       mAcquireCount(0),
     40       mShared(false) {
     41     }
     42 
     43     uint32_t mDequeueCount;
     44     uint32_t mQueueCount;
     45     uint32_t mAcquireCount;
     46     bool mShared;
     47 
     48     // A buffer can be in one of five states, represented as below:
     49     //
     50     //         | mShared | mDequeueCount | mQueueCount | mAcquireCount |
     51     // --------|---------|---------------|-------------|---------------|
     52     // FREE    |  false  |       0       |      0      |       0       |
     53     // DEQUEUED|  false  |       1       |      0      |       0       |
     54     // QUEUED  |  false  |       0       |      1      |       0       |
     55     // ACQUIRED|  false  |       0       |      0      |       1       |
     56     // SHARED  |  true   |      any      |     any     |      any      |
     57     //
     58     // FREE indicates that the buffer is available to be dequeued by the
     59     // producer. The slot is "owned" by BufferQueue. It transitions to DEQUEUED
     60     // when dequeueBuffer is called.
     61     //
     62     // DEQUEUED indicates that the buffer has been dequeued by the producer, but
     63     // has not yet been queued or canceled. The producer may modify the
     64     // buffer's contents as soon as the associated release fence is signaled.
     65     // The slot is "owned" by the producer. It can transition to QUEUED (via
     66     // queueBuffer or attachBuffer) or back to FREE (via cancelBuffer or
     67     // detachBuffer).
     68     //
     69     // QUEUED indicates that the buffer has been filled by the producer and
     70     // queued for use by the consumer. The buffer contents may continue to be
     71     // modified for a finite time, so the contents must not be accessed until
     72     // the associated fence is signaled. The slot is "owned" by BufferQueue. It
     73     // can transition to ACQUIRED (via acquireBuffer) or to FREE (if another
     74     // buffer is queued in asynchronous mode).
     75     //
     76     // ACQUIRED indicates that the buffer has been acquired by the consumer. As
     77     // with QUEUED, the contents must not be accessed by the consumer until the
     78     // acquire fence is signaled. The slot is "owned" by the consumer. It
     79     // transitions to FREE when releaseBuffer (or detachBuffer) is called. A
     80     // detached buffer can also enter the ACQUIRED state via attachBuffer.
     81     //
     82     // SHARED indicates that this buffer is being used in shared buffer
     83     // mode. It can be in any combination of the other states at the same time,
     84     // except for FREE (since that excludes being in any other state). It can
     85     // also be dequeued, queued, or acquired multiple times.
     86 
     87     inline bool isFree() const {
     88         return !isAcquired() && !isDequeued() && !isQueued();
     89     }
     90 
     91     inline bool isDequeued() const {
     92         return mDequeueCount > 0;
     93     }
     94 
     95     inline bool isQueued() const {
     96         return mQueueCount > 0;
     97     }
     98 
     99     inline bool isAcquired() const {
    100         return mAcquireCount > 0;
    101     }
    102 
    103     inline bool isShared() const {
    104         return mShared;
    105     }
    106 
    107     inline void reset() {
    108         *this = BufferState();
    109     }
    110 
    111     const char* string() const;
    112 
    113     inline void dequeue() {
    114         mDequeueCount++;
    115     }
    116 
    117     inline void detachProducer() {
    118         if (mDequeueCount > 0) {
    119             mDequeueCount--;
    120         }
    121     }
    122 
    123     inline void attachProducer() {
    124         mDequeueCount++;
    125     }
    126 
    127     inline void queue() {
    128         if (mDequeueCount > 0) {
    129             mDequeueCount--;
    130         }
    131         mQueueCount++;
    132     }
    133 
    134     inline void cancel() {
    135         if (mDequeueCount > 0) {
    136             mDequeueCount--;
    137         }
    138     }
    139 
    140     inline void freeQueued() {
    141         if (mQueueCount > 0) {
    142             mQueueCount--;
    143         }
    144     }
    145 
    146     inline void acquire() {
    147         if (mQueueCount > 0) {
    148             mQueueCount--;
    149         }
    150         mAcquireCount++;
    151     }
    152 
    153     inline void acquireNotInQueue() {
    154         mAcquireCount++;
    155     }
    156 
    157     inline void release() {
    158         if (mAcquireCount > 0) {
    159             mAcquireCount--;
    160         }
    161     }
    162 
    163     inline void detachConsumer() {
    164         if (mAcquireCount > 0) {
    165             mAcquireCount--;
    166         }
    167     }
    168 
    169     inline void attachConsumer() {
    170         mAcquireCount++;
    171     }
    172 };
    173 
    174 struct BufferSlot {
    175 
    176     BufferSlot()
    177     : mGraphicBuffer(nullptr),
    178       mEglDisplay(EGL_NO_DISPLAY),
    179       mBufferState(),
    180       mRequestBufferCalled(false),
    181       mFrameNumber(0),
    182       mEglFence(EGL_NO_SYNC_KHR),
    183       mFence(Fence::NO_FENCE),
    184       mAcquireCalled(false),
    185       mNeedsReallocation(false) {
    186     }
    187 
    188     // mGraphicBuffer points to the buffer allocated for this slot or is NULL
    189     // if no buffer has been allocated.
    190     sp<GraphicBuffer> mGraphicBuffer;
    191 
    192     // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
    193     EGLDisplay mEglDisplay;
    194 
    195     // mBufferState is the current state of this buffer slot.
    196     BufferState mBufferState;
    197 
    198     // mRequestBufferCalled is used for validating that the producer did
    199     // call requestBuffer() when told to do so. Technically this is not
    200     // needed but useful for debugging and catching producer bugs.
    201     bool mRequestBufferCalled;
    202 
    203     // mFrameNumber is the number of the queued frame for this slot.  This
    204     // is used to dequeue buffers in LRU order (useful because buffers
    205     // may be released before their release fence is signaled).
    206     uint64_t mFrameNumber;
    207 
    208     // mEglFence is the EGL sync object that must signal before the buffer
    209     // associated with this buffer slot may be dequeued. It is initialized
    210     // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a
    211     // new sync object in releaseBuffer.  (This is deprecated in favor of
    212     // mFence, below.)
    213     EGLSyncKHR mEglFence;
    214 
    215     // mFence is a fence which will signal when work initiated by the
    216     // previous owner of the buffer is finished. When the buffer is FREE,
    217     // the fence indicates when the consumer has finished reading
    218     // from the buffer, or when the producer has finished writing if it
    219     // called cancelBuffer after queueing some writes. When the buffer is
    220     // QUEUED, it indicates when the producer has finished filling the
    221     // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been
    222     // passed to the consumer or producer along with ownership of the
    223     // buffer, and mFence is set to NO_FENCE.
    224     sp<Fence> mFence;
    225 
    226     // Indicates whether this buffer has been seen by a consumer yet
    227     bool mAcquireCalled;
    228 
    229     // Indicates whether the buffer was re-allocated without notifying the
    230     // producer. If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when
    231     // dequeued to prevent the producer from using a stale cached buffer.
    232     bool mNeedsReallocation;
    233 };
    234 
    235 } // namespace android
    236 
    237 #endif
    238