• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ISurfaceComposer.h>
29 #include <private/gui/ComposerService.h>
30 
31 #include <utils/Log.h>
32 #include <utils/Trace.h>
33 
34 // Macros for including the BufferQueue name in log messages
35 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
36 #define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
37 #define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
38 #define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
39 #define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
40 
41 #define ATRACE_BUFFER_INDEX(index)                                            \
42     if (ATRACE_ENABLED()) {                                                   \
43         char ___traceBuf[1024];                                               \
44         snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
45                 (index));                                                     \
46         android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
47     }
48 
49 namespace android {
50 
51 // Get an ID that's unique within this process.
createProcessUniqueId()52 static int32_t createProcessUniqueId() {
53     static volatile int32_t globalCounter = 0;
54     return android_atomic_inc(&globalCounter);
55 }
56 
scalingModeName(int scalingMode)57 static const char* scalingModeName(int scalingMode) {
58     switch (scalingMode) {
59         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
60         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
61         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
62         default: return "Unknown";
63     }
64 }
65 
BufferQueue(bool allowSynchronousMode,const sp<IGraphicBufferAlloc> & allocator)66 BufferQueue::BufferQueue(bool allowSynchronousMode,
67         const sp<IGraphicBufferAlloc>& allocator) :
68     mDefaultWidth(1),
69     mDefaultHeight(1),
70     mMaxAcquiredBufferCount(1),
71     mDefaultMaxBufferCount(2),
72     mOverrideMaxBufferCount(0),
73     mSynchronousMode(false),
74     mAllowSynchronousMode(allowSynchronousMode),
75     mConnectedApi(NO_CONNECTED_API),
76     mAbandoned(false),
77     mFrameCounter(0),
78     mBufferHasBeenQueued(false),
79     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
80     mConsumerUsageBits(0),
81     mTransformHint(0)
82 {
83     // Choose a name using the PID and a process-unique ID.
84     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
85 
86     ST_LOGV("BufferQueue");
87     if (allocator == NULL) {
88         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
89         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
90         if (mGraphicBufferAlloc == 0) {
91             ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
92         }
93     } else {
94         mGraphicBufferAlloc = allocator;
95     }
96 }
97 
~BufferQueue()98 BufferQueue::~BufferQueue() {
99     ST_LOGV("~BufferQueue");
100 }
101 
setDefaultMaxBufferCountLocked(int count)102 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
103     if (count < 2 || count > NUM_BUFFER_SLOTS)
104         return BAD_VALUE;
105 
106     mDefaultMaxBufferCount = count;
107     mDequeueCondition.broadcast();
108 
109     return NO_ERROR;
110 }
111 
isSynchronousMode() const112 bool BufferQueue::isSynchronousMode() const {
113     Mutex::Autolock lock(mMutex);
114     return mSynchronousMode;
115 }
116 
setConsumerName(const String8 & name)117 void BufferQueue::setConsumerName(const String8& name) {
118     Mutex::Autolock lock(mMutex);
119     mConsumerName = name;
120 }
121 
setDefaultBufferFormat(uint32_t defaultFormat)122 status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
123     Mutex::Autolock lock(mMutex);
124     mDefaultBufferFormat = defaultFormat;
125     return NO_ERROR;
126 }
127 
setConsumerUsageBits(uint32_t usage)128 status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
129     Mutex::Autolock lock(mMutex);
130     mConsumerUsageBits = usage;
131     return NO_ERROR;
132 }
133 
setTransformHint(uint32_t hint)134 status_t BufferQueue::setTransformHint(uint32_t hint) {
135     ST_LOGV("setTransformHint: %02x", hint);
136     Mutex::Autolock lock(mMutex);
137     mTransformHint = hint;
138     return NO_ERROR;
139 }
140 
setBufferCount(int bufferCount)141 status_t BufferQueue::setBufferCount(int bufferCount) {
142     ST_LOGV("setBufferCount: count=%d", bufferCount);
143 
144     sp<ConsumerListener> listener;
145     {
146         Mutex::Autolock lock(mMutex);
147 
148         if (mAbandoned) {
149             ST_LOGE("setBufferCount: BufferQueue has been abandoned!");
150             return NO_INIT;
151         }
152         if (bufferCount > NUM_BUFFER_SLOTS) {
153             ST_LOGE("setBufferCount: bufferCount too large (max %d)",
154                     NUM_BUFFER_SLOTS);
155             return BAD_VALUE;
156         }
157 
158         // Error out if the user has dequeued buffers
159         int maxBufferCount = getMaxBufferCountLocked();
160         for (int i=0 ; i<maxBufferCount; i++) {
161             if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
162                 ST_LOGE("setBufferCount: client owns some buffers");
163                 return -EINVAL;
164             }
165         }
166 
167         const int minBufferSlots = getMinMaxBufferCountLocked();
168         if (bufferCount == 0) {
169             mOverrideMaxBufferCount = 0;
170             mDequeueCondition.broadcast();
171             return NO_ERROR;
172         }
173 
174         if (bufferCount < minBufferSlots) {
175             ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
176                     "minimum (%d)", bufferCount, minBufferSlots);
177             return BAD_VALUE;
178         }
179 
180         // here we're guaranteed that the client doesn't have dequeued buffers
181         // and will release all of its buffer references.
182         //
183         // XXX: Should this use drainQueueAndFreeBuffersLocked instead?
184         freeAllBuffersLocked();
185         mOverrideMaxBufferCount = bufferCount;
186         mBufferHasBeenQueued = false;
187         mDequeueCondition.broadcast();
188         listener = mConsumerListener;
189     } // scope for lock
190 
191     if (listener != NULL) {
192         listener->onBuffersReleased();
193     }
194 
195     return NO_ERROR;
196 }
197 
query(int what,int * outValue)198 int BufferQueue::query(int what, int* outValue)
199 {
200     ATRACE_CALL();
201     Mutex::Autolock lock(mMutex);
202 
203     if (mAbandoned) {
204         ST_LOGE("query: BufferQueue has been abandoned!");
205         return NO_INIT;
206     }
207 
208     int value;
209     switch (what) {
210     case NATIVE_WINDOW_WIDTH:
211         value = mDefaultWidth;
212         break;
213     case NATIVE_WINDOW_HEIGHT:
214         value = mDefaultHeight;
215         break;
216     case NATIVE_WINDOW_FORMAT:
217         value = mDefaultBufferFormat;
218         break;
219     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
220         value = getMinUndequeuedBufferCountLocked();
221         break;
222     case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
223         value = (mQueue.size() >= 2);
224         break;
225     default:
226         return BAD_VALUE;
227     }
228     outValue[0] = value;
229     return NO_ERROR;
230 }
231 
requestBuffer(int slot,sp<GraphicBuffer> * buf)232 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
233     ATRACE_CALL();
234     ST_LOGV("requestBuffer: slot=%d", slot);
235     Mutex::Autolock lock(mMutex);
236     if (mAbandoned) {
237         ST_LOGE("requestBuffer: BufferQueue has been abandoned!");
238         return NO_INIT;
239     }
240     int maxBufferCount = getMaxBufferCountLocked();
241     if (slot < 0 || maxBufferCount <= slot) {
242         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
243                 maxBufferCount, slot);
244         return BAD_VALUE;
245     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
246         // XXX: I vaguely recall there was some reason this can be valid, but
247         // for the life of me I can't recall under what circumstances that's
248         // the case.
249         ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)",
250                 slot, mSlots[slot].mBufferState);
251         return BAD_VALUE;
252     }
253     mSlots[slot].mRequestBufferCalled = true;
254     *buf = mSlots[slot].mGraphicBuffer;
255     return NO_ERROR;
256 }
257 
dequeueBuffer(int * outBuf,sp<Fence> * outFence,uint32_t w,uint32_t h,uint32_t format,uint32_t usage)258 status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
259         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
260     ATRACE_CALL();
261     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
262 
263     if ((w && !h) || (!w && h)) {
264         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
265         return BAD_VALUE;
266     }
267 
268     status_t returnFlags(OK);
269     EGLDisplay dpy = EGL_NO_DISPLAY;
270     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
271 
272     { // Scope for the lock
273         Mutex::Autolock lock(mMutex);
274 
275         if (format == 0) {
276             format = mDefaultBufferFormat;
277         }
278         // turn on usage bits the consumer requested
279         usage |= mConsumerUsageBits;
280 
281         int found = -1;
282         int dequeuedCount = 0;
283         bool tryAgain = true;
284         while (tryAgain) {
285             if (mAbandoned) {
286                 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!");
287                 return NO_INIT;
288             }
289 
290             const int maxBufferCount = getMaxBufferCountLocked();
291 
292             // Free up any buffers that are in slots beyond the max buffer
293             // count.
294             for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
295                 assert(mSlots[i].mBufferState == BufferSlot::FREE);
296                 if (mSlots[i].mGraphicBuffer != NULL) {
297                     freeBufferLocked(i);
298                     returnFlags |= IGraphicBufferProducer::RELEASE_ALL_BUFFERS;
299                 }
300             }
301 
302             // look for a free buffer to give to the client
303             found = INVALID_BUFFER_SLOT;
304             dequeuedCount = 0;
305             for (int i = 0; i < maxBufferCount; i++) {
306                 const int state = mSlots[i].mBufferState;
307                 if (state == BufferSlot::DEQUEUED) {
308                     dequeuedCount++;
309                 }
310 
311                 if (state == BufferSlot::FREE) {
312                     /* We return the oldest of the free buffers to avoid
313                      * stalling the producer if possible.  This is because
314                      * the consumer may still have pending reads of the
315                      * buffers in flight.
316                      */
317                     if ((found < 0) ||
318                             mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
319                         found = i;
320                     }
321                 }
322             }
323 
324             // clients are not allowed to dequeue more than one buffer
325             // if they didn't set a buffer count.
326             if (!mOverrideMaxBufferCount && dequeuedCount) {
327                 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
328                         "setting the buffer count");
329                 return -EINVAL;
330             }
331 
332             // See whether a buffer has been queued since the last
333             // setBufferCount so we know whether to perform the min undequeued
334             // buffers check below.
335             if (mBufferHasBeenQueued) {
336                 // make sure the client is not trying to dequeue more buffers
337                 // than allowed.
338                 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
339                 const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
340                 if (newUndequeuedCount < minUndequeuedCount) {
341                     ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
342                             "exceeded (dequeued=%d undequeudCount=%d)",
343                             minUndequeuedCount, dequeuedCount,
344                             newUndequeuedCount);
345                     return -EBUSY;
346                 }
347             }
348 
349             // If no buffer is found, wait for a buffer to be released or for
350             // the max buffer count to change.
351             tryAgain = found == INVALID_BUFFER_SLOT;
352             if (tryAgain) {
353                 mDequeueCondition.wait(mMutex);
354             }
355         }
356 
357 
358         if (found == INVALID_BUFFER_SLOT) {
359             // This should not happen.
360             ST_LOGE("dequeueBuffer: no available buffer slots");
361             return -EBUSY;
362         }
363 
364         const int buf = found;
365         *outBuf = found;
366 
367         ATRACE_BUFFER_INDEX(buf);
368 
369         const bool useDefaultSize = !w && !h;
370         if (useDefaultSize) {
371             // use the default size
372             w = mDefaultWidth;
373             h = mDefaultHeight;
374         }
375 
376         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
377 
378         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
379         if ((buffer == NULL) ||
380             (uint32_t(buffer->width)  != w) ||
381             (uint32_t(buffer->height) != h) ||
382             (uint32_t(buffer->format) != format) ||
383             ((uint32_t(buffer->usage) & usage) != usage))
384         {
385             mSlots[buf].mAcquireCalled = false;
386             mSlots[buf].mGraphicBuffer = NULL;
387             mSlots[buf].mRequestBufferCalled = false;
388             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
389             mSlots[buf].mFence = Fence::NO_FENCE;
390             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
391 
392             returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
393         }
394 
395         dpy = mSlots[buf].mEglDisplay;
396         eglFence = mSlots[buf].mEglFence;
397         *outFence = mSlots[buf].mFence;
398         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
399         mSlots[buf].mFence = Fence::NO_FENCE;
400     }  // end lock scope
401 
402     if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
403         status_t error;
404         sp<GraphicBuffer> graphicBuffer(
405                 mGraphicBufferAlloc->createGraphicBuffer(
406                         w, h, format, usage, &error));
407         if (graphicBuffer == 0) {
408             ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
409                     "failed");
410             return error;
411         }
412 
413         { // Scope for the lock
414             Mutex::Autolock lock(mMutex);
415 
416             if (mAbandoned) {
417                 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!");
418                 return NO_INIT;
419             }
420 
421             mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
422         }
423     }
424 
425     if (eglFence != EGL_NO_SYNC_KHR) {
426         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
427         // If something goes wrong, log the error, but return the buffer without
428         // synchronizing access to it.  It's too late at this point to abort the
429         // dequeue operation.
430         if (result == EGL_FALSE) {
431             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
432         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
433             ST_LOGE("dequeueBuffer: timeout waiting for fence");
434         }
435         eglDestroySyncKHR(dpy, eglFence);
436     }
437 
438     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
439             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
440 
441     return returnFlags;
442 }
443 
setSynchronousMode(bool enabled)444 status_t BufferQueue::setSynchronousMode(bool enabled) {
445     ATRACE_CALL();
446     ST_LOGV("setSynchronousMode: enabled=%d", enabled);
447     Mutex::Autolock lock(mMutex);
448 
449     if (mAbandoned) {
450         ST_LOGE("setSynchronousMode: BufferQueue has been abandoned!");
451         return NO_INIT;
452     }
453 
454     status_t err = OK;
455     if (!mAllowSynchronousMode && enabled)
456         return err;
457 
458     if (!enabled) {
459         // going to asynchronous mode, drain the queue
460         err = drainQueueLocked();
461         if (err != NO_ERROR)
462             return err;
463     }
464 
465     if (mSynchronousMode != enabled) {
466         // - if we're going to asynchronous mode, the queue is guaranteed to be
467         // empty here
468         // - if the client set the number of buffers, we're guaranteed that
469         // we have at least 3 (because we don't allow less)
470         mSynchronousMode = enabled;
471         mDequeueCondition.broadcast();
472     }
473     return err;
474 }
475 
queueBuffer(int buf,const QueueBufferInput & input,QueueBufferOutput * output)476 status_t BufferQueue::queueBuffer(int buf,
477         const QueueBufferInput& input, QueueBufferOutput* output) {
478     ATRACE_CALL();
479     ATRACE_BUFFER_INDEX(buf);
480 
481     Rect crop;
482     uint32_t transform;
483     int scalingMode;
484     int64_t timestamp;
485     sp<Fence> fence;
486 
487     input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
488 
489     if (fence == NULL) {
490         ST_LOGE("queueBuffer: fence is NULL");
491         return BAD_VALUE;
492     }
493 
494     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
495             "scale=%s",
496             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
497             transform, scalingModeName(scalingMode));
498 
499     sp<ConsumerListener> listener;
500 
501     { // scope for the lock
502         Mutex::Autolock lock(mMutex);
503         if (mAbandoned) {
504             ST_LOGE("queueBuffer: BufferQueue has been abandoned!");
505             return NO_INIT;
506         }
507         int maxBufferCount = getMaxBufferCountLocked();
508         if (buf < 0 || buf >= maxBufferCount) {
509             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
510                     maxBufferCount, buf);
511             return -EINVAL;
512         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
513             ST_LOGE("queueBuffer: slot %d is not owned by the client "
514                     "(state=%d)", buf, mSlots[buf].mBufferState);
515             return -EINVAL;
516         } else if (!mSlots[buf].mRequestBufferCalled) {
517             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
518                     "buffer", buf);
519             return -EINVAL;
520         }
521 
522         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
523         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
524         Rect croppedCrop;
525         crop.intersect(bufferRect, &croppedCrop);
526         if (croppedCrop != crop) {
527             ST_LOGE("queueBuffer: crop rect is not contained within the "
528                     "buffer in slot %d", buf);
529             return -EINVAL;
530         }
531 
532         if (mSynchronousMode) {
533             // In synchronous mode we queue all buffers in a FIFO.
534             mQueue.push_back(buf);
535 
536             // Synchronous mode always signals that an additional frame should
537             // be consumed.
538             listener = mConsumerListener;
539         } else {
540             // In asynchronous mode we only keep the most recent buffer.
541             if (mQueue.empty()) {
542                 mQueue.push_back(buf);
543 
544                 // Asynchronous mode only signals that a frame should be
545                 // consumed if no previous frame was pending. If a frame were
546                 // pending then the consumer would have already been notified.
547                 listener = mConsumerListener;
548             } else {
549                 Fifo::iterator front(mQueue.begin());
550                 // buffer currently queued is freed
551                 mSlots[*front].mBufferState = BufferSlot::FREE;
552                 // and we record the new buffer index in the queued list
553                 *front = buf;
554             }
555         }
556 
557         mSlots[buf].mTimestamp = timestamp;
558         mSlots[buf].mCrop = crop;
559         mSlots[buf].mTransform = transform;
560         mSlots[buf].mFence = fence;
561 
562         switch (scalingMode) {
563             case NATIVE_WINDOW_SCALING_MODE_FREEZE:
564             case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
565             case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
566                 break;
567             default:
568                 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
569                 scalingMode = mSlots[buf].mScalingMode;
570                 break;
571         }
572 
573         mSlots[buf].mBufferState = BufferSlot::QUEUED;
574         mSlots[buf].mScalingMode = scalingMode;
575         mFrameCounter++;
576         mSlots[buf].mFrameNumber = mFrameCounter;
577 
578         mBufferHasBeenQueued = true;
579         mDequeueCondition.broadcast();
580 
581         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
582                 mQueue.size());
583 
584         ATRACE_INT(mConsumerName.string(), mQueue.size());
585     } // scope for the lock
586 
587     // call back without lock held
588     if (listener != 0) {
589         listener->onFrameAvailable();
590     }
591     return NO_ERROR;
592 }
593 
cancelBuffer(int buf,const sp<Fence> & fence)594 void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) {
595     ATRACE_CALL();
596     ST_LOGV("cancelBuffer: slot=%d", buf);
597     Mutex::Autolock lock(mMutex);
598 
599     if (mAbandoned) {
600         ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
601         return;
602     }
603 
604     int maxBufferCount = getMaxBufferCountLocked();
605     if (buf < 0 || buf >= maxBufferCount) {
606         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
607                 maxBufferCount, buf);
608         return;
609     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
610         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
611                 buf, mSlots[buf].mBufferState);
612         return;
613     } else if (fence == NULL) {
614         ST_LOGE("cancelBuffer: fence is NULL");
615         return;
616     }
617     mSlots[buf].mBufferState = BufferSlot::FREE;
618     mSlots[buf].mFrameNumber = 0;
619     mSlots[buf].mFence = fence;
620     mDequeueCondition.broadcast();
621 }
622 
connect(int api,QueueBufferOutput * output)623 status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
624     ATRACE_CALL();
625     ST_LOGV("connect: api=%d", api);
626     Mutex::Autolock lock(mMutex);
627 
628     if (mAbandoned) {
629         ST_LOGE("connect: BufferQueue has been abandoned!");
630         return NO_INIT;
631     }
632 
633     if (mConsumerListener == NULL) {
634         ST_LOGE("connect: BufferQueue has no consumer!");
635         return NO_INIT;
636     }
637 
638     int err = NO_ERROR;
639     switch (api) {
640         case NATIVE_WINDOW_API_EGL:
641         case NATIVE_WINDOW_API_CPU:
642         case NATIVE_WINDOW_API_MEDIA:
643         case NATIVE_WINDOW_API_CAMERA:
644             if (mConnectedApi != NO_CONNECTED_API) {
645                 ST_LOGE("connect: already connected (cur=%d, req=%d)",
646                         mConnectedApi, api);
647                 err = -EINVAL;
648             } else {
649                 mConnectedApi = api;
650                 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
651                         mQueue.size());
652             }
653             break;
654         default:
655             err = -EINVAL;
656             break;
657     }
658 
659     mBufferHasBeenQueued = false;
660 
661     return err;
662 }
663 
disconnect(int api)664 status_t BufferQueue::disconnect(int api) {
665     ATRACE_CALL();
666     ST_LOGV("disconnect: api=%d", api);
667 
668     int err = NO_ERROR;
669     sp<ConsumerListener> listener;
670 
671     { // Scope for the lock
672         Mutex::Autolock lock(mMutex);
673 
674         if (mAbandoned) {
675             // it is not really an error to disconnect after the surface
676             // has been abandoned, it should just be a no-op.
677             return NO_ERROR;
678         }
679 
680         switch (api) {
681             case NATIVE_WINDOW_API_EGL:
682             case NATIVE_WINDOW_API_CPU:
683             case NATIVE_WINDOW_API_MEDIA:
684             case NATIVE_WINDOW_API_CAMERA:
685                 if (mConnectedApi == api) {
686                     drainQueueAndFreeBuffersLocked();
687                     mConnectedApi = NO_CONNECTED_API;
688                     mDequeueCondition.broadcast();
689                     listener = mConsumerListener;
690                 } else {
691                     ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
692                             mConnectedApi, api);
693                     err = -EINVAL;
694                 }
695                 break;
696             default:
697                 ST_LOGE("disconnect: unknown API %d", api);
698                 err = -EINVAL;
699                 break;
700         }
701     }
702 
703     if (listener != NULL) {
704         listener->onBuffersReleased();
705     }
706 
707     return err;
708 }
709 
dump(String8 & result) const710 void BufferQueue::dump(String8& result) const
711 {
712     char buffer[1024];
713     BufferQueue::dump(result, "", buffer, 1024);
714 }
715 
dump(String8 & result,const char * prefix,char * buffer,size_t SIZE) const716 void BufferQueue::dump(String8& result, const char* prefix,
717         char* buffer, size_t SIZE) const
718 {
719     Mutex::Autolock _l(mMutex);
720 
721     String8 fifo;
722     int fifoSize = 0;
723     Fifo::const_iterator i(mQueue.begin());
724     while (i != mQueue.end()) {
725        snprintf(buffer, SIZE, "%02d ", *i++);
726        fifoSize++;
727        fifo.append(buffer);
728     }
729 
730     int maxBufferCount = getMaxBufferCountLocked();
731 
732     snprintf(buffer, SIZE,
733             "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
734             "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
735             prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
736             mDefaultHeight, mDefaultBufferFormat, mTransformHint,
737             fifoSize, fifo.string());
738     result.append(buffer);
739 
740 
741     struct {
742         const char * operator()(int state) const {
743             switch (state) {
744                 case BufferSlot::DEQUEUED: return "DEQUEUED";
745                 case BufferSlot::QUEUED: return "QUEUED";
746                 case BufferSlot::FREE: return "FREE";
747                 case BufferSlot::ACQUIRED: return "ACQUIRED";
748                 default: return "Unknown";
749             }
750         }
751     } stateName;
752 
753     for (int i=0 ; i<maxBufferCount ; i++) {
754         const BufferSlot& slot(mSlots[i]);
755         snprintf(buffer, SIZE,
756                 "%s%s[%02d] "
757                 "state=%-8s, crop=[%d,%d,%d,%d], "
758                 "xform=0x%02x, time=%#llx, scale=%s",
759                 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
760                 stateName(slot.mBufferState),
761                 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
762                 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp,
763                 scalingModeName(slot.mScalingMode)
764         );
765         result.append(buffer);
766 
767         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
768         if (buf != NULL) {
769             snprintf(buffer, SIZE,
770                     ", %p [%4ux%4u:%4u,%3X]",
771                     buf->handle, buf->width, buf->height, buf->stride,
772                     buf->format);
773             result.append(buffer);
774         }
775         result.append("\n");
776     }
777 }
778 
freeBufferLocked(int slot)779 void BufferQueue::freeBufferLocked(int slot) {
780     ST_LOGV("freeBufferLocked: slot=%d", slot);
781     mSlots[slot].mGraphicBuffer = 0;
782     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
783         mSlots[slot].mNeedsCleanupOnRelease = true;
784     }
785     mSlots[slot].mBufferState = BufferSlot::FREE;
786     mSlots[slot].mFrameNumber = 0;
787     mSlots[slot].mAcquireCalled = false;
788 
789     // destroy fence as BufferQueue now takes ownership
790     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
791         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
792         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
793     }
794     mSlots[slot].mFence = Fence::NO_FENCE;
795 }
796 
freeAllBuffersLocked()797 void BufferQueue::freeAllBuffersLocked() {
798     ALOGW_IF(!mQueue.isEmpty(),
799             "freeAllBuffersLocked called but mQueue is not empty");
800     mQueue.clear();
801     mBufferHasBeenQueued = false;
802     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
803         freeBufferLocked(i);
804     }
805 }
806 
acquireBuffer(BufferItem * buffer)807 status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
808     ATRACE_CALL();
809     Mutex::Autolock _l(mMutex);
810 
811     // Check that the consumer doesn't currently have the maximum number of
812     // buffers acquired.  We allow the max buffer count to be exceeded by one
813     // buffer, so that the consumer can successfully set up the newly acquired
814     // buffer before releasing the old one.
815     int numAcquiredBuffers = 0;
816     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
817         if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
818             numAcquiredBuffers++;
819         }
820     }
821     if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
822         ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
823                 numAcquiredBuffers, mMaxAcquiredBufferCount);
824         return INVALID_OPERATION;
825     }
826 
827     // check if queue is empty
828     // In asynchronous mode the list is guaranteed to be one buffer
829     // deep, while in synchronous mode we use the oldest buffer.
830     if (!mQueue.empty()) {
831         Fifo::iterator front(mQueue.begin());
832         int buf = *front;
833 
834         ATRACE_BUFFER_INDEX(buf);
835 
836         if (mSlots[buf].mAcquireCalled) {
837             buffer->mGraphicBuffer = NULL;
838         } else {
839             buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
840         }
841         buffer->mCrop = mSlots[buf].mCrop;
842         buffer->mTransform = mSlots[buf].mTransform;
843         buffer->mScalingMode = mSlots[buf].mScalingMode;
844         buffer->mFrameNumber = mSlots[buf].mFrameNumber;
845         buffer->mTimestamp = mSlots[buf].mTimestamp;
846         buffer->mBuf = buf;
847         buffer->mFence = mSlots[buf].mFence;
848 
849         mSlots[buf].mAcquireCalled = true;
850         mSlots[buf].mNeedsCleanupOnRelease = false;
851         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
852         mSlots[buf].mFence = Fence::NO_FENCE;
853 
854         mQueue.erase(front);
855         mDequeueCondition.broadcast();
856 
857         ATRACE_INT(mConsumerName.string(), mQueue.size());
858     } else {
859         return NO_BUFFER_AVAILABLE;
860     }
861 
862     return NO_ERROR;
863 }
864 
releaseBuffer(int buf,EGLDisplay display,EGLSyncKHR eglFence,const sp<Fence> & fence)865 status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
866         EGLSyncKHR eglFence, const sp<Fence>& fence) {
867     ATRACE_CALL();
868     ATRACE_BUFFER_INDEX(buf);
869 
870     Mutex::Autolock _l(mMutex);
871 
872     if (buf == INVALID_BUFFER_SLOT || fence == NULL) {
873         return BAD_VALUE;
874     }
875 
876     mSlots[buf].mEglDisplay = display;
877     mSlots[buf].mEglFence = eglFence;
878     mSlots[buf].mFence = fence;
879 
880     // The buffer can now only be released if its in the acquired state
881     if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
882         mSlots[buf].mBufferState = BufferSlot::FREE;
883     } else if (mSlots[buf].mNeedsCleanupOnRelease) {
884         ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
885         mSlots[buf].mNeedsCleanupOnRelease = false;
886         return STALE_BUFFER_SLOT;
887     } else {
888         ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
889         return -EINVAL;
890     }
891 
892     mDequeueCondition.broadcast();
893     return NO_ERROR;
894 }
895 
consumerConnect(const sp<ConsumerListener> & consumerListener)896 status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
897     ST_LOGV("consumerConnect");
898     Mutex::Autolock lock(mMutex);
899 
900     if (mAbandoned) {
901         ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
902         return NO_INIT;
903     }
904     if (consumerListener == NULL) {
905         ST_LOGE("consumerConnect: consumerListener may not be NULL");
906         return BAD_VALUE;
907     }
908 
909     mConsumerListener = consumerListener;
910 
911     return NO_ERROR;
912 }
913 
consumerDisconnect()914 status_t BufferQueue::consumerDisconnect() {
915     ST_LOGV("consumerDisconnect");
916     Mutex::Autolock lock(mMutex);
917 
918     if (mConsumerListener == NULL) {
919         ST_LOGE("consumerDisconnect: No consumer is connected!");
920         return -EINVAL;
921     }
922 
923     mAbandoned = true;
924     mConsumerListener = NULL;
925     mQueue.clear();
926     freeAllBuffersLocked();
927     mDequeueCondition.broadcast();
928     return NO_ERROR;
929 }
930 
getReleasedBuffers(uint32_t * slotMask)931 status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
932     ST_LOGV("getReleasedBuffers");
933     Mutex::Autolock lock(mMutex);
934 
935     if (mAbandoned) {
936         ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
937         return NO_INIT;
938     }
939 
940     uint32_t mask = 0;
941     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
942         if (!mSlots[i].mAcquireCalled) {
943             mask |= 1 << i;
944         }
945     }
946     *slotMask = mask;
947 
948     ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
949     return NO_ERROR;
950 }
951 
setDefaultBufferSize(uint32_t w,uint32_t h)952 status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
953 {
954     ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
955     if (!w || !h) {
956         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
957                 w, h);
958         return BAD_VALUE;
959     }
960 
961     Mutex::Autolock lock(mMutex);
962     mDefaultWidth = w;
963     mDefaultHeight = h;
964     return NO_ERROR;
965 }
966 
setDefaultMaxBufferCount(int bufferCount)967 status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
968     ATRACE_CALL();
969     Mutex::Autolock lock(mMutex);
970     return setDefaultMaxBufferCountLocked(bufferCount);
971 }
972 
setMaxAcquiredBufferCount(int maxAcquiredBuffers)973 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
974     ATRACE_CALL();
975     Mutex::Autolock lock(mMutex);
976     if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) {
977         ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d",
978                 maxAcquiredBuffers);
979         return BAD_VALUE;
980     }
981     if (mConnectedApi != NO_CONNECTED_API) {
982         return INVALID_OPERATION;
983     }
984     mMaxAcquiredBufferCount = maxAcquiredBuffers;
985     return NO_ERROR;
986 }
987 
freeAllBuffersExceptHeadLocked()988 void BufferQueue::freeAllBuffersExceptHeadLocked() {
989     int head = -1;
990     if (!mQueue.empty()) {
991         Fifo::iterator front(mQueue.begin());
992         head = *front;
993     }
994     mBufferHasBeenQueued = false;
995     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
996         if (i != head) {
997             freeBufferLocked(i);
998         }
999     }
1000 }
1001 
drainQueueLocked()1002 status_t BufferQueue::drainQueueLocked() {
1003     while (mSynchronousMode && mQueue.size() > 1) {
1004         mDequeueCondition.wait(mMutex);
1005         if (mAbandoned) {
1006             ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
1007             return NO_INIT;
1008         }
1009         if (mConnectedApi == NO_CONNECTED_API) {
1010             ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
1011             return NO_INIT;
1012         }
1013     }
1014     return NO_ERROR;
1015 }
1016 
drainQueueAndFreeBuffersLocked()1017 status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
1018     status_t err = drainQueueLocked();
1019     if (err == NO_ERROR) {
1020         if (mQueue.empty()) {
1021             freeAllBuffersLocked();
1022         } else {
1023             freeAllBuffersExceptHeadLocked();
1024         }
1025     }
1026     return err;
1027 }
1028 
getMinMaxBufferCountLocked() const1029 int BufferQueue::getMinMaxBufferCountLocked() const {
1030     return getMinUndequeuedBufferCountLocked() + 1;
1031 }
1032 
getMinUndequeuedBufferCountLocked() const1033 int BufferQueue::getMinUndequeuedBufferCountLocked() const {
1034     return mSynchronousMode ? mMaxAcquiredBufferCount :
1035             mMaxAcquiredBufferCount + 1;
1036 }
1037 
getMaxBufferCountLocked() const1038 int BufferQueue::getMaxBufferCountLocked() const {
1039     int minMaxBufferCount = getMinMaxBufferCountLocked();
1040 
1041     int maxBufferCount = mDefaultMaxBufferCount;
1042     if (maxBufferCount < minMaxBufferCount) {
1043         maxBufferCount = minMaxBufferCount;
1044     }
1045     if (mOverrideMaxBufferCount != 0) {
1046         assert(mOverrideMaxBufferCount >= minMaxBufferCount);
1047         maxBufferCount = mOverrideMaxBufferCount;
1048     }
1049 
1050     // Any buffers that are dequeued by the producer or sitting in the queue
1051     // waiting to be consumed need to have their slots preserved.  Such
1052     // buffers will temporarily keep the max buffer count up until the slots
1053     // no longer need to be preserved.
1054     for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
1055         BufferSlot::BufferState state = mSlots[i].mBufferState;
1056         if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
1057             maxBufferCount = i + 1;
1058         }
1059     }
1060 
1061     return maxBufferCount;
1062 }
1063 
ProxyConsumerListener(const wp<BufferQueue::ConsumerListener> & consumerListener)1064 BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
1065         const wp<BufferQueue::ConsumerListener>& consumerListener):
1066         mConsumerListener(consumerListener) {}
1067 
~ProxyConsumerListener()1068 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
1069 
onFrameAvailable()1070 void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
1071     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1072     if (listener != NULL) {
1073         listener->onFrameAvailable();
1074     }
1075 }
1076 
onBuffersReleased()1077 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
1078     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1079     if (listener != NULL) {
1080         listener->onBuffersReleased();
1081     }
1082 }
1083 
1084 }; // namespace android
1085