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). BufferStateBufferState36 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 isFreeBufferState87 inline bool isFree() const { 88 return !isAcquired() && !isDequeued() && !isQueued(); 89 } 90 isDequeuedBufferState91 inline bool isDequeued() const { 92 return mDequeueCount > 0; 93 } 94 isQueuedBufferState95 inline bool isQueued() const { 96 return mQueueCount > 0; 97 } 98 isAcquiredBufferState99 inline bool isAcquired() const { 100 return mAcquireCount > 0; 101 } 102 isSharedBufferState103 inline bool isShared() const { 104 return mShared; 105 } 106 resetBufferState107 inline void reset() { 108 *this = BufferState(); 109 } 110 111 const char* string() const; 112 dequeueBufferState113 inline void dequeue() { 114 mDequeueCount++; 115 } 116 detachProducerBufferState117 inline void detachProducer() { 118 if (mDequeueCount > 0) { 119 mDequeueCount--; 120 } 121 } 122 attachProducerBufferState123 inline void attachProducer() { 124 mDequeueCount++; 125 } 126 queueBufferState127 inline void queue() { 128 if (mDequeueCount > 0) { 129 mDequeueCount--; 130 } 131 mQueueCount++; 132 } 133 cancelBufferState134 inline void cancel() { 135 if (mDequeueCount > 0) { 136 mDequeueCount--; 137 } 138 } 139 freeQueuedBufferState140 inline void freeQueued() { 141 if (mQueueCount > 0) { 142 mQueueCount--; 143 } 144 } 145 acquireBufferState146 inline void acquire() { 147 if (mQueueCount > 0) { 148 mQueueCount--; 149 } 150 mAcquireCount++; 151 } 152 acquireNotInQueueBufferState153 inline void acquireNotInQueue() { 154 mAcquireCount++; 155 } 156 releaseBufferState157 inline void release() { 158 if (mAcquireCount > 0) { 159 mAcquireCount--; 160 } 161 } 162 detachConsumerBufferState163 inline void detachConsumer() { 164 if (mAcquireCount > 0) { 165 mAcquireCount--; 166 } 167 } 168 attachConsumerBufferState169 inline void attachConsumer() { 170 mAcquireCount++; 171 } 172 }; 173 174 struct BufferSlot { 175 BufferSlotBufferSlot176 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