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 // notification. 193 sp<IProducerListener> mConnectedProducerListener; 194 195 // mSlots is an array of buffer slots that must be mirrored on the producer 196 // side. This allows buffer ownership to be transferred between the producer 197 // and consumer without sending a GraphicBuffer over Binder. The entire 198 // array is initialized to NULL at construction time, and buffers are 199 // allocated for a slot when requestBuffer is called with that slot's index. 200 BufferQueueDefs::SlotsType mSlots; 201 202 // mQueue is a FIFO of queued buffers used in synchronous mode. 203 Fifo mQueue; 204 205 // mFreeSlots contains all of the slots which are FREE and do not currently 206 // have a buffer attached. 207 std::set<int> mFreeSlots; 208 209 // mFreeBuffers contains all of the slots which are FREE and currently have 210 // a buffer attached. 211 std::list<int> mFreeBuffers; 212 213 // mUnusedSlots contains all slots that are currently unused. They should be 214 // free and not have a buffer attached. 215 std::list<int> mUnusedSlots; 216 217 // mActiveBuffers contains all slots which have a non-FREE buffer attached. 218 std::set<int> mActiveBuffers; 219 220 // mDequeueCondition is a condition variable used for dequeueBuffer in 221 // synchronous mode. 222 mutable std::condition_variable mDequeueCondition; 223 224 // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to 225 // block. This flag is set during connect when both the producer and 226 // consumer are controlled by the application. 227 bool mDequeueBufferCannotBlock; 228 229 // mQueueBufferCanDrop indicates whether queueBuffer is allowed to drop 230 // buffers in non-async mode. This flag is set during connect when both the 231 // producer and consumer are controlled by application. 232 bool mQueueBufferCanDrop; 233 234 // mLegacyBufferDrop indicates whether mQueueBufferCanDrop is in effect. 235 // If this flag is set mQueueBufferCanDrop is working as explained. If not 236 // queueBuffer will not drop buffers unless consumer is SurfaceFlinger and 237 // mQueueBufferCanDrop is set. 238 bool mLegacyBufferDrop; 239 240 // mDefaultBufferFormat can be set so it will override the buffer format 241 // when it isn't specified in dequeueBuffer. 242 PixelFormat mDefaultBufferFormat; 243 244 // mDefaultWidth holds the default width of allocated buffers. It is used 245 // in dequeueBuffer if a width and height of 0 are specified. 246 uint32_t mDefaultWidth; 247 248 // mDefaultHeight holds the default height of allocated buffers. It is used 249 // in dequeueBuffer if a width and height of 0 are specified. 250 uint32_t mDefaultHeight; 251 252 // mDefaultBufferDataSpace holds the default dataSpace of queued buffers. 253 // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN) 254 // is specified. 255 android_dataspace mDefaultBufferDataSpace; 256 257 // mMaxBufferCount is the limit on the number of buffers that will be 258 // allocated at one time. This limit can be set by the consumer. 259 int mMaxBufferCount; 260 261 // mMaxAcquiredBufferCount is the number of buffers that the consumer may 262 // acquire at one time. It defaults to 1, and can be changed by the consumer 263 // via setMaxAcquiredBufferCount, but this may only be done while no 264 // producer is connected to the BufferQueue. This value is used to derive 265 // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. 266 int mMaxAcquiredBufferCount; 267 268 // mMaxDequeuedBufferCount is the number of buffers that the producer may 269 // dequeue at one time. It defaults to 1, and can be changed by the producer 270 // via setMaxDequeuedBufferCount. 271 int mMaxDequeuedBufferCount; 272 273 // mBufferHasBeenQueued is true once a buffer has been queued. It is reset 274 // when something causes all buffers to be freed (e.g., changing the buffer 275 // count). 276 bool mBufferHasBeenQueued; 277 278 // mFrameCounter is the free running counter, incremented on every 279 // successful queueBuffer call and buffer allocation. 280 uint64_t mFrameCounter; 281 282 // mTransformHint is used to optimize for screen rotations. 283 uint32_t mTransformHint; 284 285 // mSidebandStream is a handle to the sideband buffer stream, if any 286 sp<NativeHandle> mSidebandStream; 287 288 // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which 289 // releases mMutex while doing the allocation proper). Producers should not modify any of the 290 // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to 291 // false. 292 bool mIsAllocating; 293 294 // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating 295 // becomes false. 296 mutable std::condition_variable mIsAllocatingCondition; 297 298 // mAllowAllocation determines whether dequeueBuffer is allowed to allocate 299 // new buffers 300 bool mAllowAllocation; 301 302 // mBufferAge tracks the age of the contents of the most recently dequeued 303 // buffer as the number of frames that have elapsed since it was last queued 304 uint64_t mBufferAge; 305 306 // mGenerationNumber stores the current generation number of the attached 307 // producer. Any attempt to attach a buffer with a different generation 308 // number will fail. 309 uint32_t mGenerationNumber; 310 311 // mAsyncMode indicates whether or not async mode is enabled. 312 // In async mode an extra buffer will be allocated to allow the producer to 313 // enqueue buffers without blocking. 314 bool mAsyncMode; 315 316 // mSharedBufferMode indicates whether or not shared buffer mode is enabled. 317 bool mSharedBufferMode; 318 319 // When shared buffer mode is enabled, this indicates whether the consumer 320 // should acquire buffers even if BufferQueue doesn't indicate that they are 321 // available. 322 bool mAutoRefresh; 323 324 // When shared buffer mode is enabled, this tracks which slot contains the 325 // shared buffer. 326 int mSharedBufferSlot; 327 328 // Cached data about the shared buffer in shared buffer mode 329 struct SharedBufferCache { SharedBufferCacheSharedBufferCache330 SharedBufferCache(Rect _crop, uint32_t _transform, 331 uint32_t _scalingMode, android_dataspace _dataspace) 332 : crop(_crop), 333 transform(_transform), 334 scalingMode(_scalingMode), 335 dataspace(_dataspace) { 336 } 337 338 Rect crop; 339 uint32_t transform; 340 uint32_t scalingMode; 341 android_dataspace dataspace; 342 } mSharedBufferCache; 343 344 // The slot of the last queued buffer 345 int mLastQueuedSlot; 346 347 OccupancyTracker mOccupancyTracker; 348 349 const uint64_t mUniqueId; 350 351 }; // class BufferQueueCore 352 353 } // namespace android 354 355 #endif 356