• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "BufferQueueCore"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20 
21 #define EGL_EGLEXT_PROTOTYPES
22 
23 #if DEBUG_ONLY_CODE
24 #define VALIDATE_CONSISTENCY() do { validateConsistencyLocked(); } while (0)
25 #else
26 #define VALIDATE_CONSISTENCY()
27 #endif
28 
29 #include <inttypes.h>
30 
31 #include <cutils/atomic.h>
32 
33 #include <gui/BufferItem.h>
34 #include <gui/BufferQueueCore.h>
35 #include <gui/IConsumerListener.h>
36 #include <gui/IProducerListener.h>
37 #include <private/gui/ComposerService.h>
38 
39 #include <system/window.h>
40 
41 #include <ui/BufferQueueDefs.h>
42 
43 namespace android {
44 
45 // Macros for include BufferQueueCore information in log messages
46 #define BQ_LOGV(x, ...)                                                                          \
47     ALOGV("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
48           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
49 #define BQ_LOGD(x, ...)                                                                          \
50     ALOGD("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
51           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
52 #define BQ_LOGI(x, ...)                                                                          \
53     ALOGI("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
54           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
55 #define BQ_LOGW(x, ...)                                                                          \
56     ALOGW("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
57           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
58 #define BQ_LOGE(x, ...)                                                                          \
59     ALOGE("[%s](id:%" PRIx64 ",api:%d,p:%d,c:%" PRIu64 ") " x, mConsumerName.c_str(), mUniqueId, \
60           mConnectedApi, mConnectedPid, mUniqueId >> 32, ##__VA_ARGS__)
61 
getUniqueName()62 static String8 getUniqueName() {
63     static volatile int32_t counter = 0;
64     return String8::format("unnamed-%d-%d", getpid(),
65             android_atomic_inc(&counter));
66 }
67 
getUniqueId()68 static uint64_t getUniqueId() {
69     static std::atomic<uint32_t> counter{0};
70     static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
71     return id | counter++;
72 }
73 
getProcessName(int pid,String8 & name)74 static status_t getProcessName(int pid, String8& name) {
75     FILE* fp = fopen(String8::format("/proc/%d/cmdline", pid), "r");
76     if (NULL != fp) {
77         const size_t size = 64;
78         char proc_name[size];
79         char* result = fgets(proc_name, size, fp);
80         fclose(fp);
81         if (result != nullptr) {
82             name = proc_name;
83             return NO_ERROR;
84         }
85     }
86     return INVALID_OPERATION;
87 }
88 
BufferQueueCore()89 BufferQueueCore::BufferQueueCore()
90       : mMutex(),
91         mIsAbandoned(false),
92         mConsumerControlledByApp(false),
93         mConsumerName(getUniqueName()),
94         mConsumerListener(),
95         mConsumerUsageBits(0),
96         mConsumerIsProtected(false),
97         mConnectedApi(NO_CONNECTED_API),
98         mLinkedToDeath(),
99         mConnectedProducerListener(),
100         mBufferReleasedCbEnabled(false),
101         mBufferAttachedCbEnabled(false),
102 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
103         mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS),
104 #else
105         mSlots(),
106 #endif
107         mQueue(),
108         mFreeSlots(),
109         mFreeBuffers(),
110         mUnusedSlots(),
111         mActiveBuffers(),
112         mDequeueCondition(),
113         mDequeueBufferCannotBlock(false),
114         mQueueBufferCanDrop(false),
115         mLegacyBufferDrop(true),
116         mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
117         mDefaultWidth(1),
118         mDefaultHeight(1),
119         mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
120 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
121         mAllowExtendedSlotCount(false),
122 #endif
123         mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
124         mMaxAcquiredBufferCount(1),
125         mMaxDequeuedBufferCount(1),
126         mBufferHasBeenQueued(false),
127         mFrameCounter(0),
128         mTransformHint(0),
129         mIsAllocating(false),
130         mIsAllocatingCondition(),
131         mAllowAllocation(true),
132         mBufferAge(0),
133         mGenerationNumber(0),
134         mAsyncMode(false),
135         mSharedBufferMode(false),
136         mAutoRefresh(false),
137         mSharedBufferSlot(INVALID_BUFFER_SLOT),
138         mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,
139                            HAL_DATASPACE_UNKNOWN),
140         mLastQueuedSlot(INVALID_BUFFER_SLOT),
141         mUniqueId(getUniqueId()),
142         mAutoPrerotation(false),
143         mTransformHintInUse(0) {
144     int numStartingBuffers = getMaxBufferCountLocked();
145     for (int s = 0; s < numStartingBuffers; s++) {
146         mFreeSlots.insert(s);
147     }
148     for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
149             s++) {
150         mUnusedSlots.push_front(s);
151     }
152 }
153 
~BufferQueueCore()154 BufferQueueCore::~BufferQueueCore() {}
155 
dumpState(const String8 & prefix,String8 * outResult) const156 void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
157     std::lock_guard<std::mutex> lock(mMutex);
158 
159     outResult->appendFormat("%s- BufferQueue ", prefix.c_str());
160     outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
161                             mMaxAcquiredBufferCount, mMaxDequeuedBufferCount);
162     outResult->appendFormat("%s  mDequeueBufferCannotBlock=%d mAsyncMode=%d\n", prefix.c_str(),
163                             mDequeueBufferCannotBlock, mAsyncMode);
164     outResult->appendFormat("%s  mQueueBufferCanDrop=%d mLegacyBufferDrop=%d\n", prefix.c_str(),
165                             mQueueBufferCanDrop, mLegacyBufferDrop);
166     outResult->appendFormat("%s  default-size=[%dx%d] default-format=%d ", prefix.c_str(),
167                             mDefaultWidth, mDefaultHeight, mDefaultBufferFormat);
168     outResult->appendFormat("%s  transform-hint=%02x frame-counter=%" PRIu64 "\n", prefix.c_str(),
169                             mTransformHint, mFrameCounter);
170     outResult->appendFormat("%s  mTransformHintInUse=%02x mAutoPrerotation=%d\n", prefix.c_str(),
171                             mTransformHintInUse, mAutoPrerotation);
172 
173     outResult->appendFormat("%sFIFO(%zu):\n", prefix.c_str(), mQueue.size());
174 
175     outResult->appendFormat("%s(mConsumerName=%s, ", prefix.c_str(), mConsumerName.c_str());
176 
177     outResult->appendFormat("mConnectedApi=%d, mConsumerUsageBits=%" PRIu64 ", ", mConnectedApi,
178                             mConsumerUsageBits);
179 
180     String8 producerProcName = String8("\?\?\?");
181     String8 consumerProcName = String8("\?\?\?");
182     int32_t pid = getpid();
183     getProcessName(mConnectedPid, producerProcName);
184     getProcessName(pid, consumerProcName);
185     outResult->appendFormat("mId=%" PRIx64 ", producer=[%d:%s], consumer=[%d:%s])\n", mUniqueId,
186                             mConnectedPid, producerProcName.c_str(), pid, consumerProcName.c_str());
187     Fifo::const_iterator current(mQueue.begin());
188     while (current != mQueue.end()) {
189         double timestamp = current->mTimestamp / 1e9;
190         outResult->appendFormat("%s  %02d:%p ", prefix.c_str(), current->mSlot,
191                                 current->mGraphicBuffer.get());
192         outResult->appendFormat("crop=[%d,%d,%d,%d] ", current->mCrop.left, current->mCrop.top,
193                                 current->mCrop.right, current->mCrop.bottom);
194         outResult->appendFormat("xform=0x%02x time=%.4f scale=%s\n", current->mTransform, timestamp,
195                                 BufferItem::scalingModeName(current->mScalingMode));
196         ++current;
197     }
198 
199     outResult->appendFormat("%sSlots:\n", prefix.c_str());
200     for (int s : mActiveBuffers) {
201         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
202         // A dequeued buffer might be null if it's still being allocated
203         if (buffer.get()) {
204             outResult->appendFormat("%s %s[%02d:%p] ", prefix.c_str(),
205                                     (mSlots[s].mBufferState.isAcquired()) ? ">" : " ", s,
206                                     buffer.get());
207             outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
208                                     buffer->handle, mSlots[s].mFrameNumber);
209             outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
210                                     buffer->stride, buffer->format);
211         } else {
212             outResult->appendFormat("%s  [%02d:%p] ", prefix.c_str(), s, buffer.get());
213             outResult->appendFormat("state=%-8s frame=%" PRIu64 "\n",
214                                     mSlots[s].mBufferState.string(), mSlots[s].mFrameNumber);
215         }
216     }
217     for (int s : mFreeBuffers) {
218         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
219         outResult->appendFormat("%s  [%02d:%p] ", prefix.c_str(), s, buffer.get());
220         outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
221                                 buffer->handle, mSlots[s].mFrameNumber);
222         outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
223                                 buffer->stride, buffer->format);
224     }
225 
226     for (int s : mFreeSlots) {
227         const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
228         outResult->appendFormat("%s  [%02d:%p] state=%-8s\n", prefix.c_str(), s, buffer.get(),
229                                 mSlots[s].mBufferState.string());
230     }
231 }
232 
getTotalSlotCountLocked() const233 int BufferQueueCore::getTotalSlotCountLocked() const {
234 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
235     return mAllowExtendedSlotCount ? mMaxBufferCount : BufferQueueDefs::NUM_BUFFER_SLOTS;
236 #else
237     return BufferQueueDefs::NUM_BUFFER_SLOTS;
238 #endif
239 }
240 
getMinUndequeuedBufferCountLocked() const241 int BufferQueueCore::getMinUndequeuedBufferCountLocked() const {
242     // If dequeueBuffer is allowed to error out, we don't have to add an
243     // extra buffer.
244     if (mAsyncMode || mDequeueBufferCannotBlock) {
245         return mMaxAcquiredBufferCount + 1;
246     }
247 
248     return mMaxAcquiredBufferCount;
249 }
250 
getMinMaxBufferCountLocked() const251 int BufferQueueCore::getMinMaxBufferCountLocked() const {
252     return getMinUndequeuedBufferCountLocked() + 1;
253 }
254 
getMaxBufferCountLocked(bool asyncMode,bool dequeueBufferCannotBlock,int maxBufferCount) const255 int BufferQueueCore::getMaxBufferCountLocked(bool asyncMode,
256         bool dequeueBufferCannotBlock, int maxBufferCount) const {
257     int maxCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
258             ((asyncMode || dequeueBufferCannotBlock) ? 1 : 0);
259     maxCount = std::min(maxBufferCount, maxCount);
260     return maxCount;
261 }
262 
getMaxBufferCountLocked() const263 int BufferQueueCore::getMaxBufferCountLocked() const {
264     int maxBufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
265             ((mAsyncMode || mDequeueBufferCannotBlock) ? 1 : 0);
266 
267     // limit maxBufferCount by mMaxBufferCount always
268     maxBufferCount = std::min(mMaxBufferCount, maxBufferCount);
269 
270     return maxBufferCount;
271 }
272 
273 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
extendSlotCountLocked(int size)274 status_t BufferQueueCore::extendSlotCountLocked(int size) {
275     int previousSize = (int)mSlots.size();
276     if (previousSize > size) {
277         return BAD_VALUE;
278     }
279     if (previousSize == size) {
280         return NO_ERROR;
281     }
282 
283     mSlots.resize(size);
284     for (int i = previousSize; i < size; i++) {
285         mUnusedSlots.push_back(i);
286     }
287 
288     mMaxBufferCount = size;
289     return NO_ERROR;
290 }
291 #endif
292 
clearBufferSlotLocked(int slot)293 void BufferQueueCore::clearBufferSlotLocked(int slot) {
294     BQ_LOGV("clearBufferSlotLocked: slot %d", slot);
295 
296     mSlots[slot].mGraphicBuffer.clear();
297     mSlots[slot].mBufferState.reset();
298     mSlots[slot].mRequestBufferCalled = false;
299     mSlots[slot].mFrameNumber = 0;
300     mSlots[slot].mAcquireCalled = false;
301     mSlots[slot].mNeedsReallocation = true;
302     mSlots[slot].mFence = Fence::NO_FENCE;
303 
304 #if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
305     // Destroy fence as BufferQueue now takes ownership
306     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
307         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
308         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
309     }
310     mSlots[slot].mEglDisplay = EGL_NO_DISPLAY;
311 #endif
312 
313     if (mLastQueuedSlot == slot) {
314         mLastQueuedSlot = INVALID_BUFFER_SLOT;
315     }
316 }
317 
freeAllBuffersLocked()318 void BufferQueueCore::freeAllBuffersLocked() {
319     for (int s : mFreeSlots) {
320         clearBufferSlotLocked(s);
321     }
322 
323     for (int s : mFreeBuffers) {
324         mFreeSlots.insert(s);
325         clearBufferSlotLocked(s);
326     }
327     mFreeBuffers.clear();
328 
329     for (int s : mActiveBuffers) {
330         mFreeSlots.insert(s);
331         clearBufferSlotLocked(s);
332     }
333     mActiveBuffers.clear();
334 
335     for (auto& b : mQueue) {
336         b.mIsStale = true;
337 
338         // We set this to false to force the BufferQueue to resend the buffer
339         // handle upon acquire, since if we're here due to a producer
340         // disconnect, the consumer will have been told to purge its cache of
341         // slot-to-buffer-handle mappings and will not be able to otherwise
342         // obtain a valid buffer handle.
343         b.mAcquireCalled = false;
344     }
345 
346     VALIDATE_CONSISTENCY();
347 }
348 
discardFreeBuffersLocked()349 void BufferQueueCore::discardFreeBuffersLocked() {
350     // Notify producer about the discarded buffers.
351     if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) {
352         std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end());
353         mConnectedProducerListener->onBuffersDiscarded(freeBuffers);
354     }
355 
356     for (int s : mFreeBuffers) {
357         mFreeSlots.insert(s);
358         clearBufferSlotLocked(s);
359     }
360     mFreeBuffers.clear();
361 
362     VALIDATE_CONSISTENCY();
363 }
364 
adjustAvailableSlotsLocked(int delta)365 bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) {
366     if (delta >= 0) {
367         // If we're going to fail, do so before modifying anything
368         if (delta > static_cast<int>(mUnusedSlots.size())) {
369             return false;
370         }
371         while (delta > 0) {
372             if (mUnusedSlots.empty()) {
373                 return false;
374             }
375             int slot = mUnusedSlots.back();
376             mUnusedSlots.pop_back();
377             mFreeSlots.insert(slot);
378             delta--;
379         }
380     } else {
381         // If we're going to fail, do so before modifying anything
382         if (-delta > static_cast<int>(mFreeSlots.size() +
383                 mFreeBuffers.size())) {
384             return false;
385         }
386         while (delta < 0) {
387             if (!mFreeSlots.empty()) {
388                 auto slot = mFreeSlots.begin();
389                 clearBufferSlotLocked(*slot);
390                 mUnusedSlots.push_back(*slot);
391                 mFreeSlots.erase(slot);
392             } else if (!mFreeBuffers.empty()) {
393                 int slot = mFreeBuffers.back();
394                 clearBufferSlotLocked(slot);
395                 mUnusedSlots.push_back(slot);
396                 mFreeBuffers.pop_back();
397             } else {
398                 return false;
399             }
400             delta++;
401         }
402     }
403     return true;
404 }
405 
waitWhileAllocatingLocked(std::unique_lock<std::mutex> & lock) const406 void BufferQueueCore::waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const {
407     ATRACE_CALL();
408     while (mIsAllocating) {
409         mIsAllocatingCondition.wait(lock);
410     }
411 }
412 
413 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
notifyBufferReleased() const414 void BufferQueueCore::notifyBufferReleased() const {
415     mDequeueCondition.notify_all();
416 }
417 #endif
418 
419 #if DEBUG_ONLY_CODE
validateConsistencyLocked() const420 void BufferQueueCore::validateConsistencyLocked() const {
421     static const useconds_t PAUSE_TIME = 0;
422     int allocatedSlots = 0;
423     for (int slot = 0; slot < getTotalSlotCountLocked(); ++slot) {
424         bool isInFreeSlots = mFreeSlots.count(slot) != 0;
425         bool isInFreeBuffers =
426                 std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=
427                 mFreeBuffers.cend();
428         bool isInActiveBuffers = mActiveBuffers.count(slot) != 0;
429         bool isInUnusedSlots =
430                 std::find(mUnusedSlots.cbegin(), mUnusedSlots.cend(), slot) !=
431                 mUnusedSlots.cend();
432 
433         if (isInFreeSlots || isInFreeBuffers || isInActiveBuffers) {
434             allocatedSlots++;
435         }
436 
437         if (isInUnusedSlots) {
438             if (isInFreeSlots) {
439                 BQ_LOGE("Slot %d is in mUnusedSlots and in mFreeSlots", slot);
440                 usleep(PAUSE_TIME);
441             }
442             if (isInFreeBuffers) {
443                 BQ_LOGE("Slot %d is in mUnusedSlots and in mFreeBuffers", slot);
444                 usleep(PAUSE_TIME);
445             }
446             if (isInActiveBuffers) {
447                 BQ_LOGE("Slot %d is in mUnusedSlots and in mActiveBuffers",
448                         slot);
449                 usleep(PAUSE_TIME);
450             }
451             if (!mSlots[slot].mBufferState.isFree()) {
452                 BQ_LOGE("Slot %d is in mUnusedSlots but is not FREE", slot);
453                 usleep(PAUSE_TIME);
454             }
455             if (mSlots[slot].mGraphicBuffer != nullptr) {
456                 BQ_LOGE("Slot %d is in mUnusedSluts but has an active buffer",
457                         slot);
458                 usleep(PAUSE_TIME);
459             }
460         } else if (isInFreeSlots) {
461             if (isInUnusedSlots) {
462                 BQ_LOGE("Slot %d is in mFreeSlots and in mUnusedSlots", slot);
463                 usleep(PAUSE_TIME);
464             }
465             if (isInFreeBuffers) {
466                 BQ_LOGE("Slot %d is in mFreeSlots and in mFreeBuffers", slot);
467                 usleep(PAUSE_TIME);
468             }
469             if (isInActiveBuffers) {
470                 BQ_LOGE("Slot %d is in mFreeSlots and in mActiveBuffers", slot);
471                 usleep(PAUSE_TIME);
472             }
473             if (!mSlots[slot].mBufferState.isFree()) {
474                 BQ_LOGE("Slot %d is in mFreeSlots but is not FREE", slot);
475                 usleep(PAUSE_TIME);
476             }
477             if (mSlots[slot].mGraphicBuffer != nullptr) {
478                 BQ_LOGE("Slot %d is in mFreeSlots but has a buffer",
479                         slot);
480                 usleep(PAUSE_TIME);
481             }
482         } else if (isInFreeBuffers) {
483             if (isInUnusedSlots) {
484                 BQ_LOGE("Slot %d is in mFreeBuffers and in mUnusedSlots", slot);
485                 usleep(PAUSE_TIME);
486             }
487             if (isInFreeSlots) {
488                 BQ_LOGE("Slot %d is in mFreeBuffers and in mFreeSlots", slot);
489                 usleep(PAUSE_TIME);
490             }
491             if (isInActiveBuffers) {
492                 BQ_LOGE("Slot %d is in mFreeBuffers and in mActiveBuffers",
493                         slot);
494                 usleep(PAUSE_TIME);
495             }
496             if (!mSlots[slot].mBufferState.isFree()) {
497                 BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE", slot);
498                 usleep(PAUSE_TIME);
499             }
500             if (mSlots[slot].mGraphicBuffer == nullptr) {
501                 BQ_LOGE("Slot %d is in mFreeBuffers but has no buffer", slot);
502                 usleep(PAUSE_TIME);
503             }
504         } else if (isInActiveBuffers) {
505             if (isInUnusedSlots) {
506                 BQ_LOGE("Slot %d is in mActiveBuffers and in mUnusedSlots",
507                         slot);
508                 usleep(PAUSE_TIME);
509             }
510             if (isInFreeSlots) {
511                 BQ_LOGE("Slot %d is in mActiveBuffers and in mFreeSlots", slot);
512                 usleep(PAUSE_TIME);
513             }
514             if (isInFreeBuffers) {
515                 BQ_LOGE("Slot %d is in mActiveBuffers and in mFreeBuffers",
516                         slot);
517                 usleep(PAUSE_TIME);
518             }
519             if (mSlots[slot].mBufferState.isFree() &&
520                     !mSlots[slot].mBufferState.isShared()) {
521                 BQ_LOGE("Slot %d is in mActiveBuffers but is FREE", slot);
522                 usleep(PAUSE_TIME);
523             }
524             if (mSlots[slot].mGraphicBuffer == nullptr && !mIsAllocating) {
525                 BQ_LOGE("Slot %d is in mActiveBuffers but has no buffer", slot);
526                 usleep(PAUSE_TIME);
527             }
528         } else {
529             BQ_LOGE("Slot %d isn't in any of mUnusedSlots, mFreeSlots, "
530                     "mFreeBuffers, or mActiveBuffers", slot);
531             usleep(PAUSE_TIME);
532         }
533     }
534 
535     if (allocatedSlots != getMaxBufferCountLocked()) {
536         BQ_LOGE("Number of allocated slots is incorrect. Allocated = %d, "
537                 "Should be %d (%zu free slots, %zu free buffers, "
538                 "%zu activeBuffers, %zu unusedSlots)", allocatedSlots,
539                 getMaxBufferCountLocked(), mFreeSlots.size(),
540                 mFreeBuffers.size(), mActiveBuffers.size(),
541                 mUnusedSlots.size());
542     }
543 }
544 #endif
545 
546 } // namespace android
547