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_BUFFERQUEUECORE_H 18 #define ANDROID_GUI_BUFFERQUEUECORE_H 19 20 #include <gui/BufferItem.h> 21 #include <gui/BufferQueueDefs.h> 22 #include <gui/BufferSlot.h> 23 #include <gui/OccupancyTracker.h> 24 25 #include <utils/NativeHandle.h> 26 #include <utils/RefBase.h> 27 #include <utils/String8.h> 28 #include <utils/StrongPointer.h> 29 #include <utils/Trace.h> 30 #include <utils/Vector.h> 31 32 #include <list> 33 #include <set> 34 #include <mutex> 35 #include <condition_variable> 36 37 #define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) 38 #define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) 39 #define BQ_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) 40 #define BQ_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) 41 #define BQ_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) 42 43 #define ATRACE_BUFFER_INDEX(index) \ 44 do { \ 45 if (ATRACE_ENABLED()) { \ 46 char ___traceBuf[1024]; \ 47 snprintf(___traceBuf, 1024, "%s: %d", mCore->mConsumerName.string(), (index)); \ 48 android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 49 } \ 50 } while (false) 51 52 namespace android { 53 54 class IConsumerListener; 55 class IProducerListener; 56 57 class BufferQueueCore : public virtual RefBase { 58 59 friend class BufferQueueProducer; 60 friend class BufferQueueConsumer; 61 62 public: 63 // Used as a placeholder slot number when the value isn't pointing to an 64 // existing buffer. 65 enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT }; 66 67 // We reserve two slots in order to guarantee that the producer and 68 // consumer can run asynchronously. 69 enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 }; 70 71 enum { 72 // The API number used to indicate the currently connected producer 73 CURRENTLY_CONNECTED_API = -1, 74 75 // The API number used to indicate that no producer is connected 76 NO_CONNECTED_API = 0, 77 }; 78 79 typedef Vector<BufferItem> Fifo; 80 81 // BufferQueueCore manages a pool of gralloc memory slots to be used by 82 // producers and consumers. 83 BufferQueueCore(); 84 virtual ~BufferQueueCore(); 85 86 private: 87 // Dump our state in a string 88 void dumpState(const String8& prefix, String8* outResult) const; 89 90 // getMinUndequeuedBufferCountLocked returns the minimum number of buffers 91 // that must remain in a state other than DEQUEUED. The async parameter 92 // tells whether we're in asynchronous mode. 93 int getMinUndequeuedBufferCountLocked() const; 94 95 // getMinMaxBufferCountLocked returns the minimum number of buffers allowed 96 // given the current BufferQueue state. The async parameter tells whether 97 // we're in asynchonous mode. 98 int getMinMaxBufferCountLocked() const; 99 100 // getMaxBufferCountLocked returns the maximum number of buffers that can be 101 // allocated at once. This value depends on the following member variables: 102 // 103 // mMaxDequeuedBufferCount 104 // mMaxAcquiredBufferCount 105 // mMaxBufferCount 106 // mAsyncMode 107 // mDequeueBufferCannotBlock 108 // 109 // Any time one of these member variables is changed while a producer is 110 // connected, mDequeueCondition must be broadcast. 111 int getMaxBufferCountLocked() const; 112 113 // This performs the same computation but uses the given arguments instead 114 // of the member variables for mMaxBufferCount, mAsyncMode, and 115 // mDequeueBufferCannotBlock. 116 int getMaxBufferCountLocked(bool asyncMode, 117 bool dequeueBufferCannotBlock, int maxBufferCount) const; 118 119 // clearBufferSlotLocked frees the GraphicBuffer and sync resources for the 120 // given slot. 121 void clearBufferSlotLocked(int slot); 122 123 // freeAllBuffersLocked frees the GraphicBuffer and sync resources for 124 // all slots, even if they're currently dequeued, queued, or acquired. 125 void freeAllBuffersLocked(); 126 127 // discardFreeBuffersLocked releases all currently-free buffers held by the 128 // queue, in order to reduce the memory consumption of the queue to the 129 // minimum possible without discarding data. 130 void discardFreeBuffersLocked(); 131 132 // If delta is positive, makes more slots available. If negative, takes 133 // away slots. Returns false if the request can't be met. 134 bool adjustAvailableSlotsLocked(int delta); 135 136 // waitWhileAllocatingLocked blocks until mIsAllocating is false. 137 void waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const; 138 139 #if DEBUG_ONLY_CODE 140 // validateConsistencyLocked ensures that the free lists are in sync with 141 // the information stored in mSlots 142 void validateConsistencyLocked() const; 143 #endif 144 145 // mMutex is the mutex used to prevent concurrent access to the member 146 // variables of BufferQueueCore objects. It must be locked whenever any 147 // member variable is accessed. 148 mutable std::mutex mMutex; 149 150 // mIsAbandoned indicates that the BufferQueue will no longer be used to 151 // consume image buffers pushed to it using the IGraphicBufferProducer 152 // interface. It is initialized to false, and set to true in the 153 // consumerDisconnect method. A BufferQueue that is abandoned will return 154 // the NO_INIT error from all IGraphicBufferProducer methods capable of 155 // returning an error. 156 bool mIsAbandoned; 157 158 // mConsumerControlledByApp indicates whether the connected consumer is 159 // controlled by the application. 160 bool mConsumerControlledByApp; 161 162 // mConsumerName is a string used to identify the BufferQueue in log 163 // messages. It is set by the IGraphicBufferConsumer::setConsumerName 164 // method. 165 String8 mConsumerName; 166 167 // mConsumerListener is used to notify the connected consumer of 168 // asynchronous events that it may wish to react to. It is initially 169 // set to NULL and is written by consumerConnect and consumerDisconnect. 170 sp<IConsumerListener> mConsumerListener; 171 172 // mConsumerUsageBits contains flags that the consumer wants for 173 // GraphicBuffers. 174 uint64_t mConsumerUsageBits; 175 176 // mConsumerIsProtected indicates the consumer is ready to handle protected 177 // buffer. 178 bool mConsumerIsProtected; 179 180 // mConnectedApi indicates the producer API that is currently connected 181 // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated 182 // by the connect and disconnect methods. 183 int mConnectedApi; 184 // PID of the process which last successfully called connect(...) 185 pid_t mConnectedPid; 186 187 // mLinkedToDeath is used to set a binder death notification on 188 // the producer. 189 sp<IProducerListener> mLinkedToDeath; 190 191 // mConnectedProducerListener is used to handle the onBufferReleased 192 // and onBuffersDiscarded notification. 193 sp<IProducerListener> mConnectedProducerListener; 194 // mBufferReleasedCbEnabled is used to indicate whether onBufferReleased() 195 // callback is registered by the listener. When set to false, 196 // mConnectedProducerListener will not trigger onBufferReleased() callback. 197 bool mBufferReleasedCbEnabled; 198 199 // mSlots is an array of buffer slots that must be mirrored on the producer 200 // side. This allows buffer ownership to be transferred between the producer 201 // and consumer without sending a GraphicBuffer over Binder. The entire 202 // array is initialized to NULL at construction time, and buffers are 203 // allocated for a slot when requestBuffer is called with that slot's index. 204 BufferQueueDefs::SlotsType mSlots; 205 206 // mQueue is a FIFO of queued buffers used in synchronous mode. 207 Fifo mQueue; 208 209 // mFreeSlots contains all of the slots which are FREE and do not currently 210 // have a buffer attached. 211 std::set<int> mFreeSlots; 212 213 // mFreeBuffers contains all of the slots which are FREE and currently have 214 // a buffer attached. 215 std::list<int> mFreeBuffers; 216 217 // mUnusedSlots contains all slots that are currently unused. They should be 218 // free and not have a buffer attached. 219 std::list<int> mUnusedSlots; 220 221 // mActiveBuffers contains all slots which have a non-FREE buffer attached. 222 std::set<int> mActiveBuffers; 223 224 // mDequeueCondition is a condition variable used for dequeueBuffer in 225 // synchronous mode. 226 mutable std::condition_variable mDequeueCondition; 227 228 // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to 229 // block. This flag is set during connect when both the producer and 230 // consumer are controlled by the application. 231 bool mDequeueBufferCannotBlock; 232 233 // mQueueBufferCanDrop indicates whether queueBuffer is allowed to drop 234 // buffers in non-async mode. This flag is set during connect when both the 235 // producer and consumer are controlled by application. 236 bool mQueueBufferCanDrop; 237 238 // mLegacyBufferDrop indicates whether mQueueBufferCanDrop is in effect. 239 // If this flag is set mQueueBufferCanDrop is working as explained. If not 240 // queueBuffer will not drop buffers unless consumer is SurfaceFlinger and 241 // mQueueBufferCanDrop is set. 242 bool mLegacyBufferDrop; 243 244 // mDefaultBufferFormat can be set so it will override the buffer format 245 // when it isn't specified in dequeueBuffer. 246 PixelFormat mDefaultBufferFormat; 247 248 // mDefaultWidth holds the default width of allocated buffers. It is used 249 // in dequeueBuffer if a width and height of 0 are specified. 250 uint32_t mDefaultWidth; 251 252 // mDefaultHeight holds the default height of allocated buffers. It is used 253 // in dequeueBuffer if a width and height of 0 are specified. 254 uint32_t mDefaultHeight; 255 256 // mDefaultBufferDataSpace holds the default dataSpace of queued buffers. 257 // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN) 258 // is specified. 259 android_dataspace mDefaultBufferDataSpace; 260 261 // mMaxBufferCount is the limit on the number of buffers that will be 262 // allocated at one time. This limit can be set by the consumer. 263 int mMaxBufferCount; 264 265 // mMaxAcquiredBufferCount is the number of buffers that the consumer may 266 // acquire at one time. It defaults to 1, and can be changed by the consumer 267 // via setMaxAcquiredBufferCount, but this may only be done while no 268 // producer is connected to the BufferQueue. This value is used to derive 269 // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. 270 int mMaxAcquiredBufferCount; 271 272 // mMaxDequeuedBufferCount is the number of buffers that the producer may 273 // dequeue at one time. It defaults to 1, and can be changed by the producer 274 // via setMaxDequeuedBufferCount. 275 int mMaxDequeuedBufferCount; 276 277 // mBufferHasBeenQueued is true once a buffer has been queued. It is reset 278 // when something causes all buffers to be freed (e.g., changing the buffer 279 // count). 280 bool mBufferHasBeenQueued; 281 282 // mFrameCounter is the free running counter, incremented on every 283 // successful queueBuffer call and buffer allocation. 284 uint64_t mFrameCounter; 285 286 // mTransformHint is used to optimize for screen rotations. 287 uint32_t mTransformHint; 288 289 // mSidebandStream is a handle to the sideband buffer stream, if any 290 sp<NativeHandle> mSidebandStream; 291 292 // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which 293 // releases mMutex while doing the allocation proper). Producers should not modify any of the 294 // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to 295 // false. 296 bool mIsAllocating; 297 298 // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating 299 // becomes false. 300 mutable std::condition_variable mIsAllocatingCondition; 301 302 // mAllowAllocation determines whether dequeueBuffer is allowed to allocate 303 // new buffers 304 bool mAllowAllocation; 305 306 // mBufferAge tracks the age of the contents of the most recently dequeued 307 // buffer as the number of frames that have elapsed since it was last queued 308 uint64_t mBufferAge; 309 310 // mGenerationNumber stores the current generation number of the attached 311 // producer. Any attempt to attach a buffer with a different generation 312 // number will fail. 313 uint32_t mGenerationNumber; 314 315 // mAsyncMode indicates whether or not async mode is enabled. 316 // In async mode an extra buffer will be allocated to allow the producer to 317 // enqueue buffers without blocking. 318 bool mAsyncMode; 319 320 // mSharedBufferMode indicates whether or not shared buffer mode is enabled. 321 bool mSharedBufferMode; 322 323 // When shared buffer mode is enabled, this indicates whether the consumer 324 // should acquire buffers even if BufferQueue doesn't indicate that they are 325 // available. 326 bool mAutoRefresh; 327 328 // When shared buffer mode is enabled, this tracks which slot contains the 329 // shared buffer. 330 int mSharedBufferSlot; 331 332 // Cached data about the shared buffer in shared buffer mode 333 struct SharedBufferCache { SharedBufferCacheSharedBufferCache334 SharedBufferCache(Rect _crop, uint32_t _transform, 335 uint32_t _scalingMode, android_dataspace _dataspace) 336 : crop(_crop), 337 transform(_transform), 338 scalingMode(_scalingMode), 339 dataspace(_dataspace) { 340 } 341 342 Rect crop; 343 uint32_t transform; 344 uint32_t scalingMode; 345 android_dataspace dataspace; 346 } mSharedBufferCache; 347 348 // The slot of the last queued buffer 349 int mLastQueuedSlot; 350 351 OccupancyTracker mOccupancyTracker; 352 353 const uint64_t mUniqueId; 354 355 }; // class BufferQueueCore 356 357 } // namespace android 358 359 #endif 360