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