OSDN Git Service

SurfaceFlinger: Add NULL check for buffer handling
[android-x86/frameworks-native.git] / libs / gui / BufferQueue.cpp
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 #define LOG_TAG "BufferQueue"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20
21 #define GL_GLEXT_PROTOTYPES
22 #define EGL_EGLEXT_PROTOTYPES
23
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26
27 #include <gui/BufferQueue.h>
28 #include <gui/IConsumerListener.h>
29 #include <gui/ISurfaceComposer.h>
30 #include <private/gui/ComposerService.h>
31
32 #include <utils/Log.h>
33 #include <utils/Trace.h>
34 #include <utils/CallStack.h>
35
36 static const nsecs_t DEQUEUE_TIMEOUT_VALUE = seconds(5);
37
38
39 // Macros for including the BufferQueue name in log messages
40 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
41 #define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
42 #define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
43 #define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
44 #define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
45
46 #define ATRACE_BUFFER_INDEX(index)                                            \
47     if (ATRACE_ENABLED()) {                                                   \
48         char ___traceBuf[1024];                                               \
49         snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
50                 (index));                                                     \
51         android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
52     }
53
54 namespace android {
55
56 // Get an ID that's unique within this process.
57 static int32_t createProcessUniqueId() {
58     static volatile int32_t globalCounter = 0;
59     return android_atomic_inc(&globalCounter);
60 }
61
62 static const char* scalingModeName(int scalingMode) {
63     switch (scalingMode) {
64         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
65         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
66         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
67         default: return "Unknown";
68     }
69 }
70
71 BufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) :
72     mDefaultWidth(1),
73     mDefaultHeight(1),
74     mMaxAcquiredBufferCount(1),
75     mDefaultMaxBufferCount(2),
76     mOverrideMaxBufferCount(0),
77     mConsumerControlledByApp(false),
78     mDequeueBufferCannotBlock(false),
79     mUseAsyncBuffer(true),
80     mConnectedApi(NO_CONNECTED_API),
81     mAbandoned(false),
82     mFrameCounter(0),
83     mBufferHasBeenQueued(false),
84     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
85     mConsumerUsageBits(0),
86     mTransformHint(0)
87 {
88     // Choose a name using the PID and a process-unique ID.
89     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
90
91     ST_LOGV("BufferQueue");
92     if (allocator == NULL) {
93         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
94         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
95         if (mGraphicBufferAlloc == 0) {
96             ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
97         }
98     } else {
99         mGraphicBufferAlloc = allocator;
100     }
101 }
102
103 BufferQueue::~BufferQueue() {
104     ST_LOGV("~BufferQueue");
105 }
106
107 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
108     const int minBufferCount = mUseAsyncBuffer ? 2 : 1;
109     if (count < minBufferCount || count > NUM_BUFFER_SLOTS)
110         return BAD_VALUE;
111
112     mDefaultMaxBufferCount = count;
113     mDequeueCondition.broadcast();
114
115     return NO_ERROR;
116 }
117
118 void BufferQueue::setConsumerName(const String8& name) {
119     Mutex::Autolock lock(mMutex);
120     mConsumerName = name;
121 }
122
123 status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
124     Mutex::Autolock lock(mMutex);
125     mDefaultBufferFormat = defaultFormat;
126     return NO_ERROR;
127 }
128
129 status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
130     Mutex::Autolock lock(mMutex);
131     mConsumerUsageBits = usage;
132     return NO_ERROR;
133 }
134
135 status_t BufferQueue::setTransformHint(uint32_t hint) {
136     ST_LOGV("setTransformHint: %02x", hint);
137     Mutex::Autolock lock(mMutex);
138     mTransformHint = hint;
139     return NO_ERROR;
140 }
141
142 status_t BufferQueue::setBufferCount(int bufferCount) {
143     ST_LOGV("setBufferCount: count=%d", bufferCount);
144
145     sp<IConsumerListener> listener;
146     {
147         Mutex::Autolock lock(mMutex);
148
149         if (mAbandoned) {
150             ST_LOGE("setBufferCount: BufferQueue has been abandoned!");
151             return NO_INIT;
152         }
153         if (bufferCount > NUM_BUFFER_SLOTS) {
154             ST_LOGE("setBufferCount: bufferCount too large (max %d)",
155                     NUM_BUFFER_SLOTS);
156             return BAD_VALUE;
157         }
158
159         // Error out if the user has dequeued buffers
160         for (int i=0 ; i<NUM_BUFFER_SLOTS; i++) {
161             if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
162                 ST_LOGE("setBufferCount: client owns some buffers");
163                 return -EINVAL;
164             }
165         }
166
167         if (bufferCount == 0) {
168             mOverrideMaxBufferCount = 0;
169             mDequeueCondition.broadcast();
170             return NO_ERROR;
171         }
172
173         // fine to assume async to false before we're setting the buffer count
174         const int minBufferSlots = getMinMaxBufferCountLocked(false);
175         if (bufferCount < minBufferSlots) {
176             ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
177                     "minimum (%d)", bufferCount, minBufferSlots);
178             return BAD_VALUE;
179         }
180
181         // here we're guaranteed that the client doesn't have dequeued buffers
182         // and will release all of its buffer references.  We don't clear the
183         // queue, however, so currently queued buffers still get displayed.
184         freeAllBuffersLocked();
185         mOverrideMaxBufferCount = bufferCount;
186         mDequeueCondition.broadcast();
187         listener = mConsumerListener;
188     } // scope for lock
189
190     if (listener != NULL) {
191         listener->onBuffersReleased();
192     }
193
194     return NO_ERROR;
195 }
196
197 int BufferQueue::query(int what, int* outValue)
198 {
199     ATRACE_CALL();
200     Mutex::Autolock lock(mMutex);
201
202     if (mAbandoned) {
203         ST_LOGE("query: BufferQueue has been abandoned!");
204         return NO_INIT;
205     }
206
207     int value;
208     switch (what) {
209     case NATIVE_WINDOW_WIDTH:
210         value = mDefaultWidth;
211         break;
212     case NATIVE_WINDOW_HEIGHT:
213         value = mDefaultHeight;
214         break;
215     case NATIVE_WINDOW_FORMAT:
216         value = mDefaultBufferFormat;
217         break;
218     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
219         value = getMinUndequeuedBufferCount(false);
220         break;
221     case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
222         value = (mQueue.size() >= 2);
223         break;
224     case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
225         value = mConsumerUsageBits;
226         break;
227     default:
228         return BAD_VALUE;
229     }
230     outValue[0] = value;
231     return NO_ERROR;
232 }
233
234 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
235     ATRACE_CALL();
236     ST_LOGV("requestBuffer: slot=%d", slot);
237     Mutex::Autolock lock(mMutex);
238     if (mAbandoned) {
239         ST_LOGE("requestBuffer: BufferQueue has been abandoned!");
240         return NO_INIT;
241     }
242     if (slot < 0 || slot >= NUM_BUFFER_SLOTS) {
243         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
244                 NUM_BUFFER_SLOTS, slot);
245         return BAD_VALUE;
246     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
247         ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)",
248                 slot, mSlots[slot].mBufferState);
249         return BAD_VALUE;
250     }
251     mSlots[slot].mRequestBufferCalled = true;
252     *buf = mSlots[slot].mGraphicBuffer;
253     return NO_ERROR;
254 }
255
256 status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool async,
257         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
258     ATRACE_CALL();
259     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
260
261     if ((w && !h) || (!w && h)) {
262         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
263         return BAD_VALUE;
264     }
265
266     status_t returnFlags(OK);
267     EGLDisplay dpy = EGL_NO_DISPLAY;
268     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
269
270     { // Scope for the lock
271         Mutex::Autolock lock(mMutex);
272
273         if (format == 0) {
274             format = mDefaultBufferFormat;
275         }
276         // turn on usage bits the consumer requested
277         usage |= mConsumerUsageBits;
278
279         int found = -1;
280         bool tryAgain = true;
281         while (tryAgain) {
282             if (mAbandoned) {
283                 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!");
284                 return NO_INIT;
285             }
286
287             const int maxBufferCount = getMaxBufferCountLocked(async);
288             if (async && mOverrideMaxBufferCount) {
289                 // FIXME: some drivers are manually setting the buffer-count (which they
290                 // shouldn't), so we do this extra test here to handle that case.
291                 // This is TEMPORARY, until we get this fixed.
292                 if (mOverrideMaxBufferCount < maxBufferCount) {
293                     ST_LOGE("dequeueBuffer: async mode is invalid with buffercount override");
294                     return BAD_VALUE;
295                 }
296             }
297
298             // Free up any buffers that are in slots beyond the max buffer
299             // count.
300             for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
301                 assert(mSlots[i].mBufferState == BufferSlot::FREE);
302                 if (mSlots[i].mGraphicBuffer != NULL) {
303                     freeBufferLocked(i);
304                     returnFlags |= IGraphicBufferProducer::RELEASE_ALL_BUFFERS;
305                 }
306             }
307
308             // look for a free buffer to give to the client
309             found = INVALID_BUFFER_SLOT;
310             int dequeuedCount = 0;
311             int acquiredCount = 0;
312             for (int i = 0; i < maxBufferCount; i++) {
313                 const int state = mSlots[i].mBufferState;
314                 switch (state) {
315                     case BufferSlot::DEQUEUED:
316                         dequeuedCount++;
317                         break;
318                     case BufferSlot::ACQUIRED:
319                         acquiredCount++;
320                         break;
321                     case BufferSlot::FREE:
322                         /* We return the oldest of the free buffers to avoid
323                          * stalling the producer if possible.  This is because
324                          * the consumer may still have pending reads of the
325                          * buffers in flight.
326                          */
327                         if ((found < 0) ||
328                                 mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
329                             found = i;
330                         }
331                         break;
332                 }
333             }
334
335             // clients are not allowed to dequeue more than one buffer
336             // if they didn't set a buffer count.
337             if (!mOverrideMaxBufferCount && dequeuedCount) {
338                 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
339                         "setting the buffer count");
340                 return -EINVAL;
341             }
342
343             // See whether a buffer has been queued since the last
344             // setBufferCount so we know whether to perform the min undequeued
345             // buffers check below.
346             if (mBufferHasBeenQueued) {
347                 // make sure the client is not trying to dequeue more buffers
348                 // than allowed.
349                 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
350                 const int minUndequeuedCount = getMinUndequeuedBufferCount(async);
351                 if (newUndequeuedCount < minUndequeuedCount) {
352                     ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
353                             "exceeded (dequeued=%d undequeudCount=%d)",
354                             minUndequeuedCount, dequeuedCount,
355                             newUndequeuedCount);
356                     return -EBUSY;
357                 }
358             }
359
360             // If no buffer is found, wait for a buffer to be released or for
361             // the max buffer count to change.
362             tryAgain = found == INVALID_BUFFER_SLOT;
363             if (tryAgain) {
364                 // return an error if we're in "cannot block" mode (producer and consumer
365                 // are controlled by the application) -- however, the consumer is allowed
366                 // to acquire briefly an extra buffer (which could cause us to have to wait here)
367                 // and that's okay because we know the wait will be brief (it happens
368                 // if we dequeue a buffer while the consumer has acquired one but not released
369                 // the old one yet -- for e.g.: see GLConsumer::updateTexImage()).
370                 if (mDequeueBufferCannotBlock && (acquiredCount <= mMaxAcquiredBufferCount)) {
371                     ST_LOGE("dequeueBuffer: would block! returning an error instead.");
372                     return WOULD_BLOCK;
373                 }
374                 if (mDequeueCondition.waitRelative(mMutex, DEQUEUE_TIMEOUT_VALUE)) {
375                     ST_LOGE("dequeueBuffer: time out and will free all buffer!");
376                     freeAllBuffersLocked();
377                 }
378             }
379         }
380
381
382         if (found == INVALID_BUFFER_SLOT) {
383             // This should not happen.
384             ST_LOGE("dequeueBuffer: no available buffer slots");
385             return -EBUSY;
386         }
387
388         const int buf = found;
389         *outBuf = found;
390
391         ATRACE_BUFFER_INDEX(buf);
392
393         const bool useDefaultSize = !w && !h;
394         if (useDefaultSize) {
395             // use the default size
396             w = mDefaultWidth;
397             h = mDefaultHeight;
398         }
399
400         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
401
402         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
403         if ((buffer == NULL) ||
404             (uint32_t(buffer->width)  != w) ||
405             (uint32_t(buffer->height) != h) ||
406             (uint32_t(buffer->format) != format) ||
407             ((uint32_t(buffer->usage) & usage) != usage))
408         {
409             mSlots[buf].mAcquireCalled = false;
410             mSlots[buf].mGraphicBuffer = NULL;
411             mSlots[buf].mRequestBufferCalled = false;
412             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
413             mSlots[buf].mFence = Fence::NO_FENCE;
414             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
415
416             returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
417         }
418
419
420         if (CC_UNLIKELY(mSlots[buf].mFence == NULL)) {
421             ST_LOGE("dequeueBuffer: about to return a NULL fence from mSlot. "
422                     "buf=%d, w=%d, h=%d, format=%d",
423                     buf, buffer->width, buffer->height, buffer->format);
424         }
425
426         dpy = mSlots[buf].mEglDisplay;
427         eglFence = mSlots[buf].mEglFence;
428         *outFence = mSlots[buf].mFence;
429         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
430         mSlots[buf].mFence = Fence::NO_FENCE;
431     }  // end lock scope
432
433     if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
434         status_t error;
435         sp<GraphicBuffer> graphicBuffer(
436                 mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage, &error));
437         if (graphicBuffer == 0) {
438             ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
439             return error;
440         }
441
442         { // Scope for the lock
443             Mutex::Autolock lock(mMutex);
444
445             if (mAbandoned) {
446                 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!");
447                 return NO_INIT;
448             }
449
450             mSlots[*outBuf].mFrameNumber = ~0;
451             mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
452         }
453     }
454
455     if (eglFence != EGL_NO_SYNC_KHR) {
456         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
457         // If something goes wrong, log the error, but return the buffer without
458         // synchronizing access to it.  It's too late at this point to abort the
459         // dequeue operation.
460         if (result == EGL_FALSE) {
461             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
462         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
463             ST_LOGE("dequeueBuffer: timeout waiting for fence");
464         }
465         eglDestroySyncKHR(dpy, eglFence);
466     }
467
468     ST_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outBuf,
469             mSlots[*outBuf].mFrameNumber,
470             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
471
472     return returnFlags;
473 }
474
475 status_t BufferQueue::queueBuffer(int buf,
476         const QueueBufferInput& input, QueueBufferOutput* output) {
477     ATRACE_CALL();
478     ATRACE_BUFFER_INDEX(buf);
479
480     Rect crop;
481     uint32_t transform;
482     int scalingMode;
483     int64_t timestamp;
484     bool isAutoTimestamp;
485     bool async;
486     sp<Fence> fence;
487
488     input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
489             &async, &fence);
490
491     if (fence == NULL) {
492         ST_LOGE("queueBuffer: fence is NULL");
493         return BAD_VALUE;
494     }
495
496     switch (scalingMode) {
497         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
498         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
499         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
500         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
501             break;
502         default:
503             ST_LOGE("unknown scaling mode: %d", scalingMode);
504             return -EINVAL;
505     }
506
507     sp<IConsumerListener> listener;
508
509     { // scope for the lock
510         Mutex::Autolock lock(mMutex);
511
512         if (mAbandoned) {
513             ST_LOGE("queueBuffer: BufferQueue has been abandoned!");
514             return NO_INIT;
515         }
516
517         const int maxBufferCount = getMaxBufferCountLocked(async);
518         if (async && mOverrideMaxBufferCount) {
519             // FIXME: some drivers are manually setting the buffer-count (which they
520             // shouldn't), so we do this extra test here to handle that case.
521             // This is TEMPORARY, until we get this fixed.
522             if (mOverrideMaxBufferCount < maxBufferCount) {
523                 ST_LOGE("queueBuffer: async mode is invalid with buffercount override");
524                 return BAD_VALUE;
525             }
526         }
527         if (buf < 0 || buf >= maxBufferCount) {
528             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
529                     maxBufferCount, buf);
530             return -EINVAL;
531         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
532             ST_LOGE("queueBuffer: slot %d is not owned by the client "
533                     "(state=%d)", buf, mSlots[buf].mBufferState);
534             return -EINVAL;
535         } else if (!mSlots[buf].mRequestBufferCalled) {
536             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
537                     "buffer", buf);
538             return -EINVAL;
539         }
540
541         ST_LOGV("queueBuffer: slot=%d/%llu time=%#llx crop=[%d,%d,%d,%d] "
542                 "tr=%#x scale=%s",
543                 buf, mFrameCounter + 1, timestamp,
544                 crop.left, crop.top, crop.right, crop.bottom,
545                 transform, scalingModeName(scalingMode));
546
547         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
548         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
549         Rect croppedCrop;
550         crop.intersect(bufferRect, &croppedCrop);
551         if (croppedCrop != crop) {
552             ST_LOGE("queueBuffer: crop rect is not contained within the "
553                     "buffer in slot %d", buf);
554             return -EINVAL;
555         }
556
557         mSlots[buf].mFence = fence;
558         mSlots[buf].mBufferState = BufferSlot::QUEUED;
559         mFrameCounter++;
560         mSlots[buf].mFrameNumber = mFrameCounter;
561
562         BufferItem item;
563         item.mAcquireCalled = mSlots[buf].mAcquireCalled;
564         item.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
565         item.mCrop = crop;
566         item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
567         item.mTransformToDisplayInverse = bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
568         item.mScalingMode = scalingMode;
569         item.mTimestamp = timestamp;
570         item.mIsAutoTimestamp = isAutoTimestamp;
571         item.mFrameNumber = mFrameCounter;
572         item.mBuf = buf;
573         item.mFence = fence;
574         item.mIsDroppable = mDequeueBufferCannotBlock || async;
575
576         if (mQueue.empty()) {
577             // when the queue is empty, we can ignore "mDequeueBufferCannotBlock", and
578             // simply queue this buffer.
579             mQueue.push_back(item);
580             listener = mConsumerListener;
581         } else {
582             // when the queue is not empty, we need to look at the front buffer
583             // state and see if we need to replace it.
584             Fifo::iterator front(mQueue.begin());
585             if (front->mIsDroppable) {
586                 // buffer slot currently queued is marked free if still tracked
587                 if (stillTracking(front)) {
588                     mSlots[front->mBuf].mBufferState = BufferSlot::FREE;
589                     // reset the frame number of the freed buffer so that it is the first in
590                     // line to be dequeued again.
591                     mSlots[front->mBuf].mFrameNumber = 0;
592                 }
593                 // and we record the new buffer in the queued list
594                 *front = item;
595             } else {
596                 mQueue.push_back(item);
597                 listener = mConsumerListener;
598             }
599         }
600
601         mBufferHasBeenQueued = true;
602         mDequeueCondition.broadcast();
603
604         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
605                 mQueue.size());
606
607         ATRACE_INT(mConsumerName.string(), mQueue.size());
608     } // scope for the lock
609
610     // call back without lock held
611     if (listener != 0) {
612         listener->onFrameAvailable();
613     }
614     return NO_ERROR;
615 }
616
617 void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) {
618     ATRACE_CALL();
619     ST_LOGV("cancelBuffer: slot=%d", buf);
620     Mutex::Autolock lock(mMutex);
621
622     if (mAbandoned) {
623         ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
624         return;
625     }
626
627     if (buf < 0 || buf >= NUM_BUFFER_SLOTS) {
628         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
629                 NUM_BUFFER_SLOTS, buf);
630         return;
631     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
632         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
633                 buf, mSlots[buf].mBufferState);
634         return;
635     } else if (fence == NULL) {
636         ST_LOGE("cancelBuffer: fence is NULL");
637         return;
638     }
639     mSlots[buf].mBufferState = BufferSlot::FREE;
640     mSlots[buf].mFrameNumber = 0;
641     mSlots[buf].mFence = fence;
642     mDequeueCondition.broadcast();
643 }
644
645
646 status_t BufferQueue::connect(const sp<IBinder>& token,
647         int api, bool producerControlledByApp, QueueBufferOutput* output) {
648     ATRACE_CALL();
649     ST_LOGV("connect: api=%d producerControlledByApp=%s", api,
650             producerControlledByApp ? "true" : "false");
651     Mutex::Autolock lock(mMutex);
652
653 retry:
654     if (mAbandoned) {
655         ST_LOGE("connect: BufferQueue has been abandoned!");
656         return NO_INIT;
657     }
658
659     if (mConsumerListener == NULL) {
660         ST_LOGE("connect: BufferQueue has no consumer!");
661         return NO_INIT;
662     }
663
664     if (mConnectedApi != NO_CONNECTED_API) {
665         ST_LOGE("connect: already connected (cur=%d, req=%d)",
666                 mConnectedApi, api);
667         return -EINVAL;
668     }
669
670     // If we disconnect and reconnect quickly, we can be in a state where our slots are
671     // empty but we have many buffers in the queue.  This can cause us to run out of
672     // memory if we outrun the consumer.  Wait here if it looks like we have too many
673     // buffers queued up.
674     int maxBufferCount = getMaxBufferCountLocked(false);    // worst-case, i.e. largest value
675     if (mQueue.size() > (size_t) maxBufferCount) {
676         // TODO: make this bound tighter?
677         ST_LOGV("queue size is %d, waiting", mQueue.size());
678         mDequeueCondition.wait(mMutex);
679         goto retry;
680     }
681
682     int err = NO_ERROR;
683     switch (api) {
684         case NATIVE_WINDOW_API_EGL:
685         case NATIVE_WINDOW_API_CPU:
686         case NATIVE_WINDOW_API_MEDIA:
687         case NATIVE_WINDOW_API_CAMERA:
688             mConnectedApi = api;
689             output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size());
690
691             // set-up a death notification so that we can disconnect
692             // automatically when/if the remote producer dies.
693             if (token != NULL && token->remoteBinder() != NULL) {
694                 status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
695                 if (err == NO_ERROR) {
696                     mConnectedProducerToken = token;
697                 } else {
698                     ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err);
699                 }
700             }
701             break;
702         default:
703             err = -EINVAL;
704             break;
705     }
706
707     mBufferHasBeenQueued = false;
708     mDequeueBufferCannotBlock = mConsumerControlledByApp && producerControlledByApp;
709
710     return err;
711 }
712
713 void BufferQueue::binderDied(const wp<IBinder>& who) {
714     // If we're here, it means that a producer we were connected to died.
715     // We're GUARANTEED that we still are connected to it because it has no other way
716     // to get disconnected -- or -- we wouldn't be here because we're removing this
717     // callback upon disconnect. Therefore, it's okay to read mConnectedApi without
718     // synchronization here.
719     int api = mConnectedApi;
720     this->disconnect(api);
721 }
722
723 status_t BufferQueue::disconnect(int api) {
724     ATRACE_CALL();
725     ST_LOGV("disconnect: api=%d", api);
726
727     int err = NO_ERROR;
728     sp<IConsumerListener> listener;
729
730     { // Scope for the lock
731         Mutex::Autolock lock(mMutex);
732
733         if (mAbandoned) {
734             // it is not really an error to disconnect after the surface
735             // has been abandoned, it should just be a no-op.
736             return NO_ERROR;
737         }
738
739         switch (api) {
740             case NATIVE_WINDOW_API_EGL:
741             case NATIVE_WINDOW_API_CPU:
742             case NATIVE_WINDOW_API_MEDIA:
743             case NATIVE_WINDOW_API_CAMERA:
744                 if (mConnectedApi == api) {
745                     freeAllBuffersLocked();
746                     // remove our death notification callback if we have one
747                     sp<IBinder> token = mConnectedProducerToken;
748                     if (token != NULL) {
749                         // this can fail if we're here because of the death notification
750                         // either way, we just ignore.
751                         token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this));
752                     }
753                     mConnectedProducerToken = NULL;
754                     mConnectedApi = NO_CONNECTED_API;
755                     mDequeueCondition.broadcast();
756                     listener = mConsumerListener;
757                 } else {
758                     ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
759                             mConnectedApi, api);
760                     err = -EINVAL;
761                 }
762                 break;
763             default:
764                 ST_LOGE("disconnect: unknown API %d", api);
765                 err = -EINVAL;
766                 break;
767         }
768     }
769
770     if (listener != NULL) {
771         listener->onBuffersReleased();
772     }
773
774     return err;
775 }
776
777 void BufferQueue::dump(String8& result, const char* prefix) const {
778     Mutex::Autolock _l(mMutex);
779
780     String8 fifo;
781     int fifoSize = 0;
782     Fifo::const_iterator i(mQueue.begin());
783     while (i != mQueue.end()) {
784         fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], "
785                 "xform=0x%02x, time=%#llx, scale=%s\n",
786                 i->mBuf, i->mGraphicBuffer.get(),
787                 i->mCrop.left, i->mCrop.top, i->mCrop.right,
788                 i->mCrop.bottom, i->mTransform, i->mTimestamp,
789                 scalingModeName(i->mScalingMode)
790                 );
791         i++;
792         fifoSize++;
793     }
794
795
796     result.appendFormat(
797             "%s-BufferQueue mMaxAcquiredBufferCount=%d, mDequeueBufferCannotBlock=%d, default-size=[%dx%d], "
798             "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
799             prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock, mDefaultWidth,
800             mDefaultHeight, mDefaultBufferFormat, mTransformHint,
801             fifoSize, fifo.string());
802
803     struct {
804         const char * operator()(int state) const {
805             switch (state) {
806                 case BufferSlot::DEQUEUED: return "DEQUEUED";
807                 case BufferSlot::QUEUED: return "QUEUED";
808                 case BufferSlot::FREE: return "FREE";
809                 case BufferSlot::ACQUIRED: return "ACQUIRED";
810                 default: return "Unknown";
811             }
812         }
813     } stateName;
814
815     // just trim the free buffers to not spam the dump
816     int maxBufferCount = 0;
817     for (int i=NUM_BUFFER_SLOTS-1 ; i>=0 ; i--) {
818         const BufferSlot& slot(mSlots[i]);
819         if ((slot.mBufferState != BufferSlot::FREE) || (slot.mGraphicBuffer != NULL)) {
820             maxBufferCount = i+1;
821             break;
822         }
823     }
824
825     for (int i=0 ; i<maxBufferCount ; i++) {
826         const BufferSlot& slot(mSlots[i]);
827         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
828         result.appendFormat(
829             "%s%s[%02d:%p] state=%-8s",
830                 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, buf.get(),
831                 stateName(slot.mBufferState)
832         );
833
834         if (buf != NULL) {
835             result.appendFormat(
836                     ", %p [%4ux%4u:%4u,%3X]",
837                     buf->handle, buf->width, buf->height, buf->stride,
838                     buf->format);
839         }
840         result.append("\n");
841     }
842 }
843
844 void BufferQueue::freeBufferLocked(int slot) {
845     ST_LOGV("freeBufferLocked: slot=%d", slot);
846     mSlots[slot].mGraphicBuffer = 0;
847     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
848         mSlots[slot].mNeedsCleanupOnRelease = true;
849     }
850     mSlots[slot].mBufferState = BufferSlot::FREE;
851     mSlots[slot].mFrameNumber = 0;
852     mSlots[slot].mAcquireCalled = false;
853
854     // destroy fence as BufferQueue now takes ownership
855     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
856         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
857         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
858     }
859     mSlots[slot].mFence = Fence::NO_FENCE;
860 }
861
862 void BufferQueue::freeAllBuffersLocked() {
863     mBufferHasBeenQueued = false;
864     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
865         freeBufferLocked(i);
866     }
867 }
868
869 status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent) {
870     ATRACE_CALL();
871     Mutex::Autolock _l(mMutex);
872
873     // Check that the consumer doesn't currently have the maximum number of
874     // buffers acquired.  We allow the max buffer count to be exceeded by one
875     // buffer, so that the consumer can successfully set up the newly acquired
876     // buffer before releasing the old one.
877     int numAcquiredBuffers = 0;
878     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
879         if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
880             numAcquiredBuffers++;
881         }
882     }
883     if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
884         ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
885                 numAcquiredBuffers, mMaxAcquiredBufferCount);
886         return INVALID_OPERATION;
887     }
888
889     // check if queue is empty
890     // In asynchronous mode the list is guaranteed to be one buffer
891     // deep, while in synchronous mode we use the oldest buffer.
892     if (mQueue.empty()) {
893         return NO_BUFFER_AVAILABLE;
894     }
895
896     Fifo::iterator front(mQueue.begin());
897
898     // If expectedPresent is specified, we may not want to return a buffer yet.
899     // If it's specified and there's more than one buffer queued, we may
900     // want to drop a buffer.
901     if (expectedPresent != 0) {
902         const int MAX_REASONABLE_NSEC = 1000000000ULL;  // 1 second
903
904         // The "expectedPresent" argument indicates when the buffer is expected
905         // to be presented on-screen.  If the buffer's desired-present time
906         // is earlier (less) than expectedPresent, meaning it'll be displayed
907         // on time or possibly late if we show it ASAP, we acquire and return
908         // it.  If we don't want to display it until after the expectedPresent
909         // time, we return PRESENT_LATER without acquiring it.
910         //
911         // To be safe, we don't defer acquisition if expectedPresent is
912         // more than one second in the future beyond the desired present time
913         // (i.e. we'd be holding the buffer for a long time).
914         //
915         // NOTE: code assumes monotonic time values from the system clock are
916         // positive.
917
918         // Start by checking to see if we can drop frames.  We skip this check
919         // if the timestamps are being auto-generated by Surface -- if the
920         // app isn't generating timestamps explicitly, they probably don't
921         // want frames to be discarded based on them.
922         while (mQueue.size() > 1 && !mQueue[0].mIsAutoTimestamp) {
923             // If entry[1] is timely, drop entry[0] (and repeat).  We apply
924             // an additional criteria here: we only drop the earlier buffer if
925             // our desiredPresent falls within +/- 1 second of the expected
926             // present.  Otherwise, bogus desiredPresent times (e.g. 0 or
927             // a small relative timestamp), which normally mean "ignore the
928             // timestamp and acquire immediately", would cause us to drop
929             // frames.
930             //
931             // We may want to add an additional criteria: don't drop the
932             // earlier buffer if entry[1]'s fence hasn't signaled yet.
933             //
934             // (Vector front is [0], back is [size()-1])
935             const BufferItem& bi(mQueue[1]);
936             nsecs_t desiredPresent = bi.mTimestamp;
937             if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
938                     desiredPresent > expectedPresent) {
939                 // This buffer is set to display in the near future, or
940                 // desiredPresent is garbage.  Either way we don't want to
941                 // drop the previous buffer just to get this on screen sooner.
942                 ST_LOGV("pts nodrop: des=%lld expect=%lld (%lld) now=%lld",
943                         desiredPresent, expectedPresent, desiredPresent - expectedPresent,
944                         systemTime(CLOCK_MONOTONIC));
945                 break;
946             }
947             ST_LOGV("pts drop: queue1des=%lld expect=%lld size=%d",
948                     desiredPresent, expectedPresent, mQueue.size());
949             if (stillTracking(front)) {
950                 // front buffer is still in mSlots, so mark the slot as free
951                 mSlots[front->mBuf].mBufferState = BufferSlot::FREE;
952             }
953             mQueue.erase(front);
954             front = mQueue.begin();
955         }
956
957         // See if the front buffer is due.
958         nsecs_t desiredPresent = front->mTimestamp;
959         if (desiredPresent > expectedPresent &&
960                 desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
961             ST_LOGV("pts defer: des=%lld expect=%lld (%lld) now=%lld",
962                     desiredPresent, expectedPresent, desiredPresent - expectedPresent,
963                     systemTime(CLOCK_MONOTONIC));
964             return PRESENT_LATER;
965         }
966
967         ST_LOGV("pts accept: des=%lld expect=%lld (%lld) now=%lld",
968                 desiredPresent, expectedPresent, desiredPresent - expectedPresent,
969                 systemTime(CLOCK_MONOTONIC));
970     }
971
972     int buf = front->mBuf;
973     *buffer = *front;
974     ATRACE_BUFFER_INDEX(buf);
975
976     ST_LOGV("acquireBuffer: acquiring { slot=%d/%llu, buffer=%p }",
977             front->mBuf, front->mFrameNumber,
978             front->mGraphicBuffer->handle);
979     // if front buffer still being tracked update slot state
980     if (stillTracking(front)) {
981         mSlots[buf].mAcquireCalled = true;
982         mSlots[buf].mNeedsCleanupOnRelease = false;
983         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
984         mSlots[buf].mFence = Fence::NO_FENCE;
985     }
986
987     // If the buffer has previously been acquired by the consumer, set
988     // mGraphicBuffer to NULL to avoid unnecessarily remapping this
989     // buffer on the consumer side.
990     if (buffer->mAcquireCalled) {
991         buffer->mGraphicBuffer = NULL;
992     }
993
994     mQueue.erase(front);
995     mDequeueCondition.broadcast();
996
997     ATRACE_INT(mConsumerName.string(), mQueue.size());
998
999     return NO_ERROR;
1000 }
1001
1002 status_t BufferQueue::releaseBuffer(
1003         int buf, uint64_t frameNumber, EGLDisplay display,
1004         EGLSyncKHR eglFence, const sp<Fence>& fence) {
1005     ATRACE_CALL();
1006     ATRACE_BUFFER_INDEX(buf);
1007
1008     if (buf == INVALID_BUFFER_SLOT || fence == NULL) {
1009         return BAD_VALUE;
1010     }
1011
1012     Mutex::Autolock _l(mMutex);
1013
1014     // If the frame number has changed because buffer has been reallocated,
1015     // we can ignore this releaseBuffer for the old buffer.
1016     if (frameNumber != mSlots[buf].mFrameNumber) {
1017         return STALE_BUFFER_SLOT;
1018     }
1019
1020
1021     // Internal state consistency checks:
1022     // Make sure this buffers hasn't been queued while we were owning it (acquired)
1023     Fifo::iterator front(mQueue.begin());
1024     Fifo::const_iterator const end(mQueue.end());
1025     while (front != end) {
1026         if (front->mBuf == buf) {
1027             LOG_ALWAYS_FATAL("[%s] received new buffer(#%lld) on slot #%d that has not yet been "
1028                     "acquired", mConsumerName.string(), frameNumber, buf);
1029             break; // never reached
1030         }
1031         front++;
1032     }
1033
1034     // The buffer can now only be released if its in the acquired state
1035     if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
1036         mSlots[buf].mEglDisplay = display;
1037         mSlots[buf].mEglFence = eglFence;
1038         mSlots[buf].mFence = fence;
1039         mSlots[buf].mBufferState = BufferSlot::FREE;
1040     } else if (mSlots[buf].mNeedsCleanupOnRelease) {
1041         ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
1042         mSlots[buf].mNeedsCleanupOnRelease = false;
1043         return STALE_BUFFER_SLOT;
1044     } else {
1045         ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
1046         return -EINVAL;
1047     }
1048
1049     mDequeueCondition.broadcast();
1050     return NO_ERROR;
1051 }
1052
1053 status_t BufferQueue::consumerConnect(const sp<IConsumerListener>& consumerListener,
1054         bool controlledByApp) {
1055     ST_LOGV("consumerConnect controlledByApp=%s",
1056             controlledByApp ? "true" : "false");
1057     Mutex::Autolock lock(mMutex);
1058
1059     if (mAbandoned) {
1060         ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
1061         return NO_INIT;
1062     }
1063     if (consumerListener == NULL) {
1064         ST_LOGE("consumerConnect: consumerListener may not be NULL");
1065         return BAD_VALUE;
1066     }
1067
1068     mConsumerListener = consumerListener;
1069     mConsumerControlledByApp = controlledByApp;
1070
1071     return NO_ERROR;
1072 }
1073
1074 status_t BufferQueue::consumerDisconnect() {
1075     ST_LOGV("consumerDisconnect");
1076     Mutex::Autolock lock(mMutex);
1077
1078     if (mConsumerListener == NULL) {
1079         ST_LOGE("consumerDisconnect: No consumer is connected!");
1080         return -EINVAL;
1081     }
1082
1083     mAbandoned = true;
1084     mConsumerListener = NULL;
1085     mQueue.clear();
1086     freeAllBuffersLocked();
1087     mDequeueCondition.broadcast();
1088     return NO_ERROR;
1089 }
1090
1091 status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
1092     ST_LOGV("getReleasedBuffers");
1093     Mutex::Autolock lock(mMutex);
1094
1095     if (mAbandoned) {
1096         ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
1097         return NO_INIT;
1098     }
1099
1100     uint32_t mask = 0;
1101     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
1102         if (!mSlots[i].mAcquireCalled) {
1103             mask |= 1 << i;
1104         }
1105     }
1106
1107     // Remove buffers in flight (on the queue) from the mask where acquire has
1108     // been called, as the consumer will not receive the buffer address, so
1109     // it should not free these slots.
1110     Fifo::iterator front(mQueue.begin());
1111     while (front != mQueue.end()) {
1112         if (front->mAcquireCalled)
1113             mask &= ~(1 << front->mBuf);
1114         front++;
1115     }
1116
1117     *slotMask = mask;
1118
1119     ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
1120     return NO_ERROR;
1121 }
1122
1123 status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) {
1124     ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
1125     if (!w || !h) {
1126         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
1127                 w, h);
1128         return BAD_VALUE;
1129     }
1130
1131     Mutex::Autolock lock(mMutex);
1132     mDefaultWidth = w;
1133     mDefaultHeight = h;
1134     return NO_ERROR;
1135 }
1136
1137 status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
1138     ATRACE_CALL();
1139     Mutex::Autolock lock(mMutex);
1140     return setDefaultMaxBufferCountLocked(bufferCount);
1141 }
1142
1143 status_t BufferQueue::disableAsyncBuffer() {
1144     ATRACE_CALL();
1145     Mutex::Autolock lock(mMutex);
1146     if (mConsumerListener != NULL) {
1147         ST_LOGE("disableAsyncBuffer: consumer already connected!");
1148         return INVALID_OPERATION;
1149     }
1150     mUseAsyncBuffer = false;
1151     return NO_ERROR;
1152 }
1153
1154 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
1155     ATRACE_CALL();
1156     Mutex::Autolock lock(mMutex);
1157     if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) {
1158         ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d",
1159                 maxAcquiredBuffers);
1160         return BAD_VALUE;
1161     }
1162     if (mConnectedApi != NO_CONNECTED_API) {
1163         return INVALID_OPERATION;
1164     }
1165     mMaxAcquiredBufferCount = maxAcquiredBuffers;
1166     return NO_ERROR;
1167 }
1168
1169 int BufferQueue::getMinUndequeuedBufferCount(bool async) const {
1170     // if dequeueBuffer is allowed to error out, we don't have to
1171     // add an extra buffer.
1172     if (!mUseAsyncBuffer)
1173         return mMaxAcquiredBufferCount;
1174
1175     // we're in async mode, or we want to prevent the app to
1176     // deadlock itself, we throw-in an extra buffer to guarantee it.
1177     if (mDequeueBufferCannotBlock || async)
1178         return mMaxAcquiredBufferCount+1;
1179
1180     return mMaxAcquiredBufferCount;
1181 }
1182
1183 int BufferQueue::getMinMaxBufferCountLocked(bool async) const {
1184     return getMinUndequeuedBufferCount(async) + 1;
1185 }
1186
1187 int BufferQueue::getMaxBufferCountLocked(bool async) const {
1188     int minMaxBufferCount = getMinMaxBufferCountLocked(async);
1189
1190     int maxBufferCount = mDefaultMaxBufferCount;
1191     if (maxBufferCount < minMaxBufferCount) {
1192         maxBufferCount = minMaxBufferCount;
1193     }
1194     if (mOverrideMaxBufferCount != 0) {
1195         assert(mOverrideMaxBufferCount >= minMaxBufferCount);
1196         maxBufferCount = mOverrideMaxBufferCount;
1197     }
1198
1199     // Any buffers that are dequeued by the producer or sitting in the queue
1200     // waiting to be consumed need to have their slots preserved.  Such
1201     // buffers will temporarily keep the max buffer count up until the slots
1202     // no longer need to be preserved.
1203     for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
1204         BufferSlot::BufferState state = mSlots[i].mBufferState;
1205         if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
1206             maxBufferCount = i + 1;
1207         }
1208     }
1209
1210     return maxBufferCount;
1211 }
1212
1213 bool BufferQueue::stillTracking(const BufferItem *item) const {
1214     const BufferSlot &slot = mSlots[item->mBuf];
1215
1216     ST_LOGV("stillTracking?: item: { slot=%d/%llu, buffer=%p }, "
1217             "slot: { slot=%d/%llu, buffer=%p }",
1218             item->mBuf, item->mFrameNumber,
1219             (item->mGraphicBuffer.get() ? item->mGraphicBuffer->handle : 0),
1220             item->mBuf, slot.mFrameNumber,
1221             (slot.mGraphicBuffer.get() ? slot.mGraphicBuffer->handle : 0));
1222
1223     // Compare item with its original buffer slot.  We can check the slot
1224     // as the buffer would not be moved to a different slot by the producer.
1225     return (slot.mGraphicBuffer != NULL &&
1226             item->mGraphicBuffer->handle == slot.mGraphicBuffer->handle);
1227 }
1228
1229 BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
1230         const wp<ConsumerListener>& consumerListener):
1231         mConsumerListener(consumerListener) {}
1232
1233 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
1234
1235 void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
1236     sp<ConsumerListener> listener(mConsumerListener.promote());
1237     if (listener != NULL) {
1238         listener->onFrameAvailable();
1239     }
1240 }
1241
1242 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
1243     sp<ConsumerListener> listener(mConsumerListener.promote());
1244     if (listener != NULL) {
1245         listener->onBuffersReleased();
1246     }
1247 }
1248
1249 }; // namespace android