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