xref: /aosp_15_r20/frameworks/native/include/gui/BufferSlot.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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