| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2012 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_BUFFERQUEUE_H | 
|  | 18 | #define ANDROID_GUI_BUFFERQUEUE_H | 
|  | 19 |  | 
|  | 20 | #include <EGL/egl.h> | 
| Daniel Lam | f71c4ae | 2012-03-23 18:12:04 -0700 | [diff] [blame] | 21 | #include <EGL/eglext.h> | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 22 |  | 
| Mathias Agopian | 90ac799 | 2012-02-25 18:48:35 -0800 | [diff] [blame] | 23 | #include <gui/IGraphicBufferAlloc.h> | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 24 | #include <gui/ISurfaceTexture.h> | 
|  | 25 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 26 | #include <ui/GraphicBuffer.h> | 
|  | 27 |  | 
|  | 28 | #include <utils/String8.h> | 
|  | 29 | #include <utils/Vector.h> | 
|  | 30 | #include <utils/threads.h> | 
|  | 31 |  | 
|  | 32 | namespace android { | 
|  | 33 | // ---------------------------------------------------------------------------- | 
|  | 34 |  | 
|  | 35 | class BufferQueue : public BnSurfaceTexture { | 
|  | 36 | public: | 
|  | 37 | enum { MIN_UNDEQUEUED_BUFFERS = 2 }; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 38 | enum { NUM_BUFFER_SLOTS = 32 }; | 
|  | 39 | enum { NO_CONNECTED_API = 0 }; | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 40 | enum { INVALID_BUFFER_SLOT = -1 }; | 
| Daniel Lam | fbcda93 | 2012-04-09 22:51:52 -0700 | [diff] [blame] | 41 | enum { STALE_BUFFER_SLOT = 1, NO_BUFFER_AVAILABLE }; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 42 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 43 | // ConsumerListener is the interface through which the BufferQueue notifies | 
|  | 44 | // the consumer of events that the consumer may wish to react to.  Because | 
|  | 45 | // the consumer will generally have a mutex that is locked during calls from | 
|  | 46 | // teh consumer to the BufferQueue, these calls from the BufferQueue to the | 
|  | 47 | // consumer *MUST* be called only when the BufferQueue mutex is NOT locked. | 
|  | 48 | struct ConsumerListener : public virtual RefBase { | 
|  | 49 | // onFrameAvailable is called from queueBuffer each time an additional | 
|  | 50 | // frame becomes available for consumption. This means that frames that | 
|  | 51 | // are queued while in asynchronous mode only trigger the callback if no | 
|  | 52 | // previous frames are pending. Frames queued while in synchronous mode | 
|  | 53 | // always trigger the callback. | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 54 | // | 
|  | 55 | // This is called without any lock held and can be called concurrently | 
|  | 56 | // by multiple threads. | 
|  | 57 | virtual void onFrameAvailable() = 0; | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 58 |  | 
|  | 59 | // onBuffersReleased is called to notify the buffer consumer that the | 
|  | 60 | // BufferQueue has released its references to one or more GraphicBuffers | 
|  | 61 | // contained in its slots.  The buffer consumer should then call | 
|  | 62 | // BufferQueue::getReleasedBuffers to retrieve the list of buffers | 
|  | 63 | // | 
|  | 64 | // This is called without any lock held and can be called concurrently | 
|  | 65 | // by multiple threads. | 
|  | 66 | virtual void onBuffersReleased() = 0; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 67 | }; | 
|  | 68 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 69 | // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak | 
|  | 70 | // reference to the actual consumer object.  It forwards all calls to that | 
|  | 71 | // consumer object so long as it exists. | 
|  | 72 | // | 
|  | 73 | // This class exists to avoid having a circular reference between the | 
|  | 74 | // BufferQueue object and the consumer object.  The reason this can't be a weak | 
|  | 75 | // reference in the BufferQueue class is because we're planning to expose the | 
|  | 76 | // consumer side of a BufferQueue as a binder interface, which doesn't support | 
|  | 77 | // weak references. | 
|  | 78 | class ProxyConsumerListener : public BufferQueue::ConsumerListener { | 
|  | 79 | public: | 
|  | 80 |  | 
|  | 81 | ProxyConsumerListener(const wp<BufferQueue::ConsumerListener>& consumerListener); | 
|  | 82 | virtual ~ProxyConsumerListener(); | 
|  | 83 | virtual void onFrameAvailable(); | 
|  | 84 | virtual void onBuffersReleased(); | 
|  | 85 |  | 
|  | 86 | private: | 
|  | 87 |  | 
|  | 88 | // mConsumerListener is a weak reference to the ConsumerListener.  This is | 
|  | 89 | // the raison d'etre of ProxyConsumerListener. | 
|  | 90 | wp<BufferQueue::ConsumerListener> mConsumerListener; | 
|  | 91 | }; | 
|  | 92 |  | 
|  | 93 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 94 | // BufferQueue manages a pool of gralloc memory slots to be used | 
|  | 95 | // by producers and consumers. | 
|  | 96 | // allowSynchronousMode specifies whether or not synchronous mode can be | 
|  | 97 | // enabled. | 
| Daniel Lam | abe61bf | 2012-03-26 20:37:15 -0700 | [diff] [blame] | 98 | // bufferCount sets the minimum number of undequeued buffers for this queue | 
|  | 99 | BufferQueue(  bool allowSynchronousMode = true, int bufferCount = MIN_UNDEQUEUED_BUFFERS); | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 100 | virtual ~BufferQueue(); | 
|  | 101 |  | 
| Daniel Lam | b856052 | 2012-01-30 15:51:27 -0800 | [diff] [blame] | 102 | virtual int query(int what, int* value); | 
|  | 103 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 104 | // setBufferCount updates the number of available buffer slots.  After | 
|  | 105 | // calling this all buffer slots are both unallocated and owned by the | 
|  | 106 | // BufferQueue object (i.e. they are not owned by the client). | 
|  | 107 | virtual status_t setBufferCount(int bufferCount); | 
|  | 108 |  | 
|  | 109 | virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); | 
|  | 110 |  | 
|  | 111 | // dequeueBuffer gets the next buffer slot index for the client to use. If a | 
|  | 112 | // buffer slot is available then that slot index is written to the location | 
|  | 113 | // pointed to by the buf argument and a status of OK is returned.  If no | 
|  | 114 | // slot is available then a status of -EBUSY is returned and buf is | 
|  | 115 | // unmodified. | 
|  | 116 | // The width and height parameters must be no greater than the minimum of | 
|  | 117 | // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). | 
|  | 118 | // An error due to invalid dimensions might not be reported until | 
|  | 119 | // updateTexImage() is called. | 
|  | 120 | virtual status_t dequeueBuffer(int *buf, uint32_t width, uint32_t height, | 
|  | 121 | uint32_t format, uint32_t usage); | 
|  | 122 |  | 
|  | 123 | // queueBuffer returns a filled buffer to the BufferQueue. In addition, a | 
|  | 124 | // timestamp must be provided for the buffer. The timestamp is in | 
|  | 125 | // nanoseconds, and must be monotonically increasing. Its other semantics | 
|  | 126 | // (zero point, etc) are client-dependent and should be documented by the | 
|  | 127 | // client. | 
| Mathias Agopian | f0bc2f1 | 2012-04-09 16:14:01 -0700 | [diff] [blame] | 128 | virtual status_t queueBuffer(int buf, | 
|  | 129 | const QueueBufferInput& input, QueueBufferOutput* output); | 
|  | 130 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 131 | virtual void cancelBuffer(int buf); | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 132 |  | 
|  | 133 | // setSynchronousMode set whether dequeueBuffer is synchronous or | 
|  | 134 | // asynchronous. In synchronous mode, dequeueBuffer blocks until | 
|  | 135 | // a buffer is available, the currently bound buffer can be dequeued and | 
|  | 136 | // queued buffers will be retired in order. | 
|  | 137 | // The default mode is asynchronous. | 
|  | 138 | virtual status_t setSynchronousMode(bool enabled); | 
|  | 139 |  | 
|  | 140 | // connect attempts to connect a producer client API to the BufferQueue. | 
|  | 141 | // This must be called before any other ISurfaceTexture methods are called | 
|  | 142 | // except for getAllocator. | 
|  | 143 | // | 
|  | 144 | // This method will fail if the connect was previously called on the | 
|  | 145 | // BufferQueue and no corresponding disconnect call was made. | 
| Mathias Agopian | 24202f5 | 2012-04-23 14:28:58 -0700 | [diff] [blame] | 146 | virtual status_t connect(int api, QueueBufferOutput* output); | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 147 |  | 
|  | 148 | // disconnect attempts to disconnect a producer client API from the | 
|  | 149 | // BufferQueue. Calling this method will cause any subsequent calls to other | 
|  | 150 | // ISurfaceTexture methods to fail except for getAllocator and connect. | 
|  | 151 | // Successfully calling connect after this will allow the other methods to | 
|  | 152 | // succeed again. | 
|  | 153 | // | 
|  | 154 | // This method will fail if the the BufferQueue is not currently | 
|  | 155 | // connected to the specified client API. | 
|  | 156 | virtual status_t disconnect(int api); | 
|  | 157 |  | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 158 | // dump our state in a String | 
|  | 159 | virtual void dump(String8& result) const; | 
|  | 160 | virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 161 |  | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 162 | // public facing structure for BufferSlot | 
|  | 163 | struct BufferItem { | 
|  | 164 |  | 
|  | 165 | BufferItem() | 
|  | 166 | : | 
|  | 167 | mTransform(0), | 
|  | 168 | mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), | 
|  | 169 | mTimestamp(0), | 
|  | 170 | mFrameNumber(0), | 
|  | 171 | mBuf(INVALID_BUFFER_SLOT) { | 
|  | 172 | mCrop.makeInvalid(); | 
|  | 173 | } | 
|  | 174 | // mGraphicBuffer points to the buffer allocated for this slot or is NULL | 
|  | 175 | // if no buffer has been allocated. | 
|  | 176 | sp<GraphicBuffer> mGraphicBuffer; | 
|  | 177 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 178 | // mCrop is the current crop rectangle for this buffer slot. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 179 | Rect mCrop; | 
|  | 180 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 181 | // mTransform is the current transform flags for this buffer slot. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 182 | uint32_t mTransform; | 
|  | 183 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 184 | // mScalingMode is the current scaling mode for this buffer slot. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 185 | uint32_t mScalingMode; | 
|  | 186 |  | 
|  | 187 | // mTimestamp is the current timestamp for this buffer slot. This gets | 
|  | 188 | // to set by queueBuffer each time this slot is queued. | 
|  | 189 | int64_t mTimestamp; | 
|  | 190 |  | 
|  | 191 | // mFrameNumber is the number of the queued frame for this slot. | 
|  | 192 | uint64_t mFrameNumber; | 
|  | 193 |  | 
| Jamie Gennis | efc7ab6 | 2012-04-17 19:36:18 -0700 | [diff] [blame] | 194 | // mBuf is the slot index of this buffer | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 195 | int mBuf; | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 196 | }; | 
|  | 197 |  | 
|  | 198 | // The following public functions is the consumer facing interface | 
|  | 199 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 200 | // acquireBuffer attempts to acquire ownership of the next pending buffer in | 
|  | 201 | // the BufferQueue.  If no buffer is pending then it returns -EINVAL.  If a | 
|  | 202 | // buffer is successfully acquired, the information about the buffer is | 
|  | 203 | // returned in BufferItem.  If the buffer returned had previously been | 
|  | 204 | // acquired then the BufferItem::mGraphicBuffer field of buffer is set to | 
|  | 205 | // NULL and it is assumed that the consumer still holds a reference to the | 
|  | 206 | // buffer. | 
|  | 207 | status_t acquireBuffer(BufferItem *buffer); | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 208 |  | 
|  | 209 | // releaseBuffer releases a buffer slot from the consumer back to the | 
|  | 210 | // BufferQueue pending a fence sync. | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 211 | // | 
|  | 212 | // Note that the dependencies on EGL will be removed once we switch to using | 
|  | 213 | // the Android HW Sync HAL. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 214 | status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence); | 
|  | 215 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 216 | // consumerConnect connects a consumer to the BufferQueue.  Only one | 
|  | 217 | // consumer may be connected, and when that consumer disconnects the | 
|  | 218 | // BufferQueue is placed into the "abandoned" state, causing most | 
|  | 219 | // interactions with the BufferQueue by the producer to fail. | 
|  | 220 | status_t consumerConnect(const sp<ConsumerListener>& consumer); | 
|  | 221 |  | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 222 | // consumerDisconnect disconnects a consumer from the BufferQueue. All | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 223 | // buffers will be freed and the BufferQueue is placed in the "abandoned" | 
|  | 224 | // state, causing most interactions with the BufferQueue by the producer to | 
|  | 225 | // fail. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 226 | status_t consumerDisconnect(); | 
|  | 227 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 228 | // getReleasedBuffers sets the value pointed to by slotMask to a bit mask | 
|  | 229 | // indicating which buffer slots the have been released by the BufferQueue | 
|  | 230 | // but have not yet been released by the consumer. | 
|  | 231 | status_t getReleasedBuffers(uint32_t* slotMask); | 
|  | 232 |  | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 233 | // setDefaultBufferSize is used to set the size of buffers returned by | 
|  | 234 | // requestBuffers when a with and height of zero is requested. | 
|  | 235 | status_t setDefaultBufferSize(uint32_t w, uint32_t h); | 
|  | 236 |  | 
|  | 237 | // setBufferCountServer set the buffer count. If the client has requested | 
|  | 238 | // a buffer count using setBufferCount, the server-buffer count will | 
|  | 239 | // take effect once the client sets the count back to zero. | 
|  | 240 | status_t setBufferCountServer(int bufferCount); | 
|  | 241 |  | 
|  | 242 | // isSynchronousMode returns whether the SurfaceTexture is currently in | 
|  | 243 | // synchronous mode. | 
|  | 244 | bool isSynchronousMode() const; | 
|  | 245 |  | 
|  | 246 | // setConsumerName sets the name used in logging | 
|  | 247 | void setConsumerName(const String8& name); | 
|  | 248 |  | 
| Daniel Lam | b267579 | 2012-02-23 14:35:13 -0800 | [diff] [blame] | 249 | // setDefaultBufferFormat allows the BufferQueue to create | 
|  | 250 | // GraphicBuffers of a defaultFormat if no format is specified | 
|  | 251 | // in dequeueBuffer | 
|  | 252 | status_t setDefaultBufferFormat(uint32_t defaultFormat); | 
|  | 253 |  | 
|  | 254 | // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer | 
|  | 255 | status_t setConsumerUsageBits(uint32_t usage); | 
|  | 256 |  | 
|  | 257 | // setTransformHint bakes in rotation to buffers so overlays can be used | 
|  | 258 | status_t setTransformHint(uint32_t hint); | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 259 |  | 
|  | 260 | private: | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 261 | // freeBufferLocked frees the resources (both GraphicBuffer and EGLImage) | 
|  | 262 | // for the given slot. | 
|  | 263 | void freeBufferLocked(int index); | 
|  | 264 |  | 
|  | 265 | // freeAllBuffersLocked frees the resources (both GraphicBuffer and | 
|  | 266 | // EGLImage) for all slots. | 
|  | 267 | void freeAllBuffersLocked(); | 
|  | 268 |  | 
|  | 269 | // freeAllBuffersExceptHeadLocked frees the resources (both GraphicBuffer | 
|  | 270 | // and EGLImage) for all slots except the head of mQueue | 
|  | 271 | void freeAllBuffersExceptHeadLocked(); | 
|  | 272 |  | 
|  | 273 | // drainQueueLocked drains the buffer queue if we're in synchronous mode | 
|  | 274 | // returns immediately otherwise. It returns NO_INIT if the BufferQueue | 
|  | 275 | // became abandoned or disconnected during this call. | 
|  | 276 | status_t drainQueueLocked(); | 
|  | 277 |  | 
|  | 278 | // drainQueueAndFreeBuffersLocked drains the buffer queue if we're in | 
|  | 279 | // synchronous mode and free all buffers. In asynchronous mode, all buffers | 
|  | 280 | // are freed except the current buffer. | 
|  | 281 | status_t drainQueueAndFreeBuffersLocked(); | 
|  | 282 |  | 
|  | 283 | status_t setBufferCountServerLocked(int bufferCount); | 
|  | 284 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 285 | struct BufferSlot { | 
|  | 286 |  | 
|  | 287 | BufferSlot() | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 288 | : mEglDisplay(EGL_NO_DISPLAY), | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 289 | mBufferState(BufferSlot::FREE), | 
|  | 290 | mRequestBufferCalled(false), | 
|  | 291 | mTransform(0), | 
|  | 292 | mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), | 
|  | 293 | mTimestamp(0), | 
|  | 294 | mFrameNumber(0), | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 295 | mFence(EGL_NO_SYNC_KHR), | 
| Daniel Lam | 9abe1eb | 2012-03-26 20:37:15 -0700 | [diff] [blame] | 296 | mAcquireCalled(false), | 
|  | 297 | mNeedsCleanupOnRelease(false) { | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 298 | mCrop.makeInvalid(); | 
|  | 299 | } | 
|  | 300 |  | 
|  | 301 | // mGraphicBuffer points to the buffer allocated for this slot or is NULL | 
|  | 302 | // if no buffer has been allocated. | 
|  | 303 | sp<GraphicBuffer> mGraphicBuffer; | 
|  | 304 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 305 | // mEglDisplay is the EGLDisplay used to create mEglImage. | 
|  | 306 | EGLDisplay mEglDisplay; | 
|  | 307 |  | 
|  | 308 | // BufferState represents the different states in which a buffer slot | 
|  | 309 | // can be. | 
|  | 310 | enum BufferState { | 
|  | 311 | // FREE indicates that the buffer is not currently being used and | 
|  | 312 | // will not be used in the future until it gets dequeued and | 
|  | 313 | // subsequently queued by the client. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 314 | // aka "owned by BufferQueue, ready to be dequeued" | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 315 | FREE = 0, | 
|  | 316 |  | 
|  | 317 | // DEQUEUED indicates that the buffer has been dequeued by the | 
|  | 318 | // client, but has not yet been queued or canceled. The buffer is | 
|  | 319 | // considered 'owned' by the client, and the server should not use | 
|  | 320 | // it for anything. | 
|  | 321 | // | 
|  | 322 | // Note that when in synchronous-mode (mSynchronousMode == true), | 
|  | 323 | // the buffer that's currently attached to the texture may be | 
|  | 324 | // dequeued by the client.  That means that the current buffer can | 
|  | 325 | // be in either the DEQUEUED or QUEUED state.  In asynchronous mode, | 
|  | 326 | // however, the current buffer is always in the QUEUED state. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 327 | // aka "owned by producer, ready to be queued" | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 328 | DEQUEUED = 1, | 
|  | 329 |  | 
|  | 330 | // QUEUED indicates that the buffer has been queued by the client, | 
|  | 331 | // and has not since been made available for the client to dequeue. | 
|  | 332 | // Attaching the buffer to the texture does NOT transition the | 
|  | 333 | // buffer away from the QUEUED state. However, in Synchronous mode | 
|  | 334 | // the current buffer may be dequeued by the client under some | 
|  | 335 | // circumstances. See the note about the current buffer in the | 
|  | 336 | // documentation for DEQUEUED. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 337 | // aka "owned by BufferQueue, ready to be acquired" | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 338 | QUEUED = 2, | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 339 |  | 
|  | 340 | // aka "owned by consumer, ready to be released" | 
|  | 341 | ACQUIRED = 3 | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 342 | }; | 
|  | 343 |  | 
|  | 344 | // mBufferState is the current state of this buffer slot. | 
|  | 345 | BufferState mBufferState; | 
|  | 346 |  | 
|  | 347 | // mRequestBufferCalled is used for validating that the client did | 
|  | 348 | // call requestBuffer() when told to do so. Technically this is not | 
|  | 349 | // needed but useful for debugging and catching client bugs. | 
|  | 350 | bool mRequestBufferCalled; | 
|  | 351 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 352 | // mCrop is the current crop rectangle for this buffer slot. | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 353 | Rect mCrop; | 
|  | 354 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 355 | // mTransform is the current transform flags for this buffer slot. | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 356 | uint32_t mTransform; | 
|  | 357 |  | 
| Mathias Agopian | 851ef8f | 2012-03-29 17:10:08 -0700 | [diff] [blame] | 358 | // mScalingMode is the current scaling mode for this buffer slot. | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 359 | uint32_t mScalingMode; | 
|  | 360 |  | 
|  | 361 | // mTimestamp is the current timestamp for this buffer slot. This gets | 
|  | 362 | // to set by queueBuffer each time this slot is queued. | 
|  | 363 | int64_t mTimestamp; | 
|  | 364 |  | 
|  | 365 | // mFrameNumber is the number of the queued frame for this slot. | 
|  | 366 | uint64_t mFrameNumber; | 
|  | 367 |  | 
|  | 368 | // mFence is the EGL sync object that must signal before the buffer | 
|  | 369 | // associated with this buffer slot may be dequeued. It is initialized | 
|  | 370 | // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based | 
|  | 371 | // on a compile-time option) set to a new sync object in updateTexImage. | 
|  | 372 | EGLSyncKHR mFence; | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 373 |  | 
|  | 374 | // Indicates whether this buffer has been seen by a consumer yet | 
|  | 375 | bool mAcquireCalled; | 
| Daniel Lam | 9abe1eb | 2012-03-26 20:37:15 -0700 | [diff] [blame] | 376 |  | 
|  | 377 | // Indicates whether this buffer needs to be cleaned up by consumer | 
|  | 378 | bool mNeedsCleanupOnRelease; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 379 | }; | 
|  | 380 |  | 
|  | 381 | // mSlots is the array of buffer slots that must be mirrored on the client | 
|  | 382 | // side. This allows buffer ownership to be transferred between the client | 
|  | 383 | // and server without sending a GraphicBuffer over binder. The entire array | 
|  | 384 | // is initialized to NULL at construction time, and buffers are allocated | 
|  | 385 | // for a slot when requestBuffer is called with that slot's index. | 
|  | 386 | BufferSlot mSlots[NUM_BUFFER_SLOTS]; | 
|  | 387 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 388 | // mDefaultWidth holds the default width of allocated buffers. It is used | 
|  | 389 | // in requestBuffers() if a width and height of zero is specified. | 
|  | 390 | uint32_t mDefaultWidth; | 
|  | 391 |  | 
|  | 392 | // mDefaultHeight holds the default height of allocated buffers. It is used | 
|  | 393 | // in requestBuffers() if a width and height of zero is specified. | 
|  | 394 | uint32_t mDefaultHeight; | 
|  | 395 |  | 
|  | 396 | // mPixelFormat holds the pixel format of allocated buffers. It is used | 
|  | 397 | // in requestBuffers() if a format of zero is specified. | 
|  | 398 | uint32_t mPixelFormat; | 
|  | 399 |  | 
| Daniel Lam | abe61bf | 2012-03-26 20:37:15 -0700 | [diff] [blame] | 400 | // mMinUndequeuedBuffers is a constraint on the number of buffers | 
|  | 401 | // not dequeued at any time | 
|  | 402 | int mMinUndequeuedBuffers; | 
|  | 403 |  | 
|  | 404 | // mMinAsyncBufferSlots is a constraint on the minimum mBufferCount | 
|  | 405 | // when this BufferQueue is in asynchronous mode | 
|  | 406 | int mMinAsyncBufferSlots; | 
|  | 407 |  | 
|  | 408 | // mMinSyncBufferSlots is a constraint on the minimum mBufferCount | 
|  | 409 | // when this BufferQueue is in synchronous mode | 
|  | 410 | int mMinSyncBufferSlots; | 
|  | 411 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 412 | // mBufferCount is the number of buffer slots that the client and server | 
|  | 413 | // must maintain. It defaults to MIN_ASYNC_BUFFER_SLOTS and can be changed | 
|  | 414 | // by calling setBufferCount or setBufferCountServer | 
|  | 415 | int mBufferCount; | 
|  | 416 |  | 
|  | 417 | // mClientBufferCount is the number of buffer slots requested by the client. | 
|  | 418 | // The default is zero, which means the client doesn't care how many buffers | 
|  | 419 | // there is. | 
|  | 420 | int mClientBufferCount; | 
|  | 421 |  | 
|  | 422 | // mServerBufferCount buffer count requested by the server-side | 
|  | 423 | int mServerBufferCount; | 
|  | 424 |  | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 425 | // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to | 
|  | 426 | // allocate new GraphicBuffer objects. | 
|  | 427 | sp<IGraphicBufferAlloc> mGraphicBufferAlloc; | 
|  | 428 |  | 
| Jamie Gennis | fa5b40e | 2012-03-15 14:01:24 -0700 | [diff] [blame] | 429 | // mConsumerListener is used to notify the connected consumer of | 
|  | 430 | // asynchronous events that it may wish to react to.  It is initially set | 
|  | 431 | // to NULL and is written by consumerConnect and consumerDisconnect. | 
|  | 432 | sp<ConsumerListener> mConsumerListener; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 433 |  | 
|  | 434 | // mSynchronousMode whether we're in synchronous mode or not | 
|  | 435 | bool mSynchronousMode; | 
|  | 436 |  | 
|  | 437 | // mAllowSynchronousMode whether we allow synchronous mode or not | 
|  | 438 | const bool mAllowSynchronousMode; | 
|  | 439 |  | 
|  | 440 | // mConnectedApi indicates the API that is currently connected to this | 
|  | 441 | // BufferQueue.  It defaults to NO_CONNECTED_API (= 0), and gets updated | 
|  | 442 | // by the connect and disconnect methods. | 
|  | 443 | int mConnectedApi; | 
|  | 444 |  | 
|  | 445 | // mDequeueCondition condition used for dequeueBuffer in synchronous mode | 
|  | 446 | mutable Condition mDequeueCondition; | 
|  | 447 |  | 
|  | 448 | // mQueue is a FIFO of queued buffers used in synchronous mode | 
|  | 449 | typedef Vector<int> Fifo; | 
|  | 450 | Fifo mQueue; | 
|  | 451 |  | 
|  | 452 | // mAbandoned indicates that the BufferQueue will no longer be used to | 
|  | 453 | // consume images buffers pushed to it using the ISurfaceTexture interface. | 
|  | 454 | // It is initialized to false, and set to true in the abandon method.  A | 
|  | 455 | // BufferQueue that has been abandoned will return the NO_INIT error from | 
|  | 456 | // all ISurfaceTexture methods capable of returning an error. | 
|  | 457 | bool mAbandoned; | 
|  | 458 |  | 
|  | 459 | // mName is a string used to identify the BufferQueue in log messages. | 
|  | 460 | // It is set by the setName method. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 461 | String8 mConsumerName; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 462 |  | 
|  | 463 | // mMutex is the mutex used to prevent concurrent access to the member | 
|  | 464 | // variables of BufferQueue objects. It must be locked whenever the | 
|  | 465 | // member variables are accessed. | 
|  | 466 | mutable Mutex mMutex; | 
|  | 467 |  | 
|  | 468 | // mFrameCounter is the free running counter, incremented for every buffer queued | 
|  | 469 | // with the surface Texture. | 
|  | 470 | uint64_t mFrameCounter; | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 471 |  | 
| Daniel Lam | b267579 | 2012-02-23 14:35:13 -0800 | [diff] [blame] | 472 | // mBufferHasBeenQueued is true once a buffer has been queued.  It is reset | 
|  | 473 | // by changing the buffer count. | 
| Daniel Lam | eae59d2 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 474 | bool mBufferHasBeenQueued; | 
| Daniel Lam | b267579 | 2012-02-23 14:35:13 -0800 | [diff] [blame] | 475 |  | 
|  | 476 | // mDefaultBufferFormat can be set so it will override | 
|  | 477 | // the buffer format when it isn't specified in dequeueBuffer | 
|  | 478 | uint32_t mDefaultBufferFormat; | 
|  | 479 |  | 
|  | 480 | // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers | 
|  | 481 | uint32_t mConsumerUsageBits; | 
|  | 482 |  | 
|  | 483 | // mTransformHint is used to optimize for screen rotations | 
|  | 484 | uint32_t mTransformHint; | 
| Daniel Lam | 6b091c5 | 2012-01-22 15:26:27 -0800 | [diff] [blame] | 485 | }; | 
|  | 486 |  | 
|  | 487 | // ---------------------------------------------------------------------------- | 
|  | 488 | }; // namespace android | 
|  | 489 |  | 
|  | 490 | #endif // ANDROID_GUI_BUFFERQUEUE_H |