• 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 <gui/SurfaceTexture.h>
33 #include <utils/Trace.h>
34 
35 // Macros for including the BufferQueue name in log messages
36 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
37 #define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
38 #define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
39 #define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
40 #define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
41 
42 #define ATRACE_BUFFER_INDEX(index)                                            \
43     if (ATRACE_ENABLED()) {                                                   \
44         char ___traceBuf[1024];                                               \
45         snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
46                 (index));                                                     \
47         android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
48     }
49 
50 namespace android {
51 
52 // Get an ID that's unique within this process.
createProcessUniqueId()53 static int32_t createProcessUniqueId() {
54     static volatile int32_t globalCounter = 0;
55     return android_atomic_inc(&globalCounter);
56 }
57 
scalingModeName(int scalingMode)58 static const char* scalingModeName(int scalingMode) {
59     switch (scalingMode) {
60         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
61         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
62         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
63         default: return "Unknown";
64     }
65 }
66 
BufferQueue(bool allowSynchronousMode,const sp<IGraphicBufferAlloc> & allocator)67 BufferQueue::BufferQueue(bool allowSynchronousMode,
68         const sp<IGraphicBufferAlloc>& allocator) :
69     mDefaultWidth(1),
70     mDefaultHeight(1),
71     mMaxAcquiredBufferCount(1),
72     mDefaultMaxBufferCount(2),
73     mOverrideMaxBufferCount(0),
74     mSynchronousMode(false),
75     mAllowSynchronousMode(allowSynchronousMode),
76     mConnectedApi(NO_CONNECTED_API),
77     mAbandoned(false),
78     mFrameCounter(0),
79     mBufferHasBeenQueued(false),
80     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
81     mConsumerUsageBits(0),
82     mTransformHint(0)
83 {
84     // Choose a name using the PID and a process-unique ID.
85     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
86 
87     ST_LOGV("BufferQueue");
88     if (allocator == NULL) {
89         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
90         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
91         if (mGraphicBufferAlloc == 0) {
92             ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
93         }
94     } else {
95         mGraphicBufferAlloc = allocator;
96     }
97 }
98 
~BufferQueue()99 BufferQueue::~BufferQueue() {
100     ST_LOGV("~BufferQueue");
101 }
102 
setDefaultMaxBufferCountLocked(int count)103 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
104     if (count < 2 || count > NUM_BUFFER_SLOTS)
105         return BAD_VALUE;
106 
107     mDefaultMaxBufferCount = count;
108     mDequeueCondition.broadcast();
109 
110     return OK;
111 }
112 
isSynchronousMode() const113 bool BufferQueue::isSynchronousMode() const {
114     Mutex::Autolock lock(mMutex);
115     return mSynchronousMode;
116 }
117 
setConsumerName(const String8 & name)118 void BufferQueue::setConsumerName(const String8& name) {
119     Mutex::Autolock lock(mMutex);
120     mConsumerName = name;
121 }
122 
setDefaultBufferFormat(uint32_t defaultFormat)123 status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
124     Mutex::Autolock lock(mMutex);
125     mDefaultBufferFormat = defaultFormat;
126     return OK;
127 }
128 
setConsumerUsageBits(uint32_t usage)129 status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
130     Mutex::Autolock lock(mMutex);
131     mConsumerUsageBits = usage;
132     return OK;
133 }
134 
setTransformHint(uint32_t hint)135 status_t BufferQueue::setTransformHint(uint32_t hint) {
136     ST_LOGV("setTransformHint: %02x", hint);
137     Mutex::Autolock lock(mMutex);
138     mTransformHint = hint;
139     return OK;
140 }
141 
setBufferCount(int bufferCount)142 status_t BufferQueue::setBufferCount(int bufferCount) {
143     ST_LOGV("setBufferCount: count=%d", bufferCount);
144 
145     sp<ConsumerListener> listener;
146     {
147         Mutex::Autolock lock(mMutex);
148 
149         if (mAbandoned) {
150             ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
151             return NO_INIT;
152         }
153         if (bufferCount > NUM_BUFFER_SLOTS) {
154             ST_LOGE("setBufferCount: bufferCount larger than slots available");
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 OK;
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 OK;
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: SurfaceTexture 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: SurfaceTexture 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: SurfaceTexture 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 |= ISurfaceTexture::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         // buffer is now in DEQUEUED (but can also be current at the same time,
377         // if we're in synchronous mode)
378         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
379 
380         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
381         if ((buffer == NULL) ||
382             (uint32_t(buffer->width)  != w) ||
383             (uint32_t(buffer->height) != h) ||
384             (uint32_t(buffer->format) != format) ||
385             ((uint32_t(buffer->usage) & usage) != usage))
386         {
387             mSlots[buf].mAcquireCalled = false;
388             mSlots[buf].mGraphicBuffer = NULL;
389             mSlots[buf].mRequestBufferCalled = false;
390             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
391             mSlots[buf].mFence.clear();
392             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
393 
394             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
395         }
396 
397         dpy = mSlots[buf].mEglDisplay;
398         eglFence = mSlots[buf].mEglFence;
399         outFence = mSlots[buf].mFence;
400         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
401         mSlots[buf].mFence.clear();
402     }  // end lock scope
403 
404     if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) {
405         status_t error;
406         sp<GraphicBuffer> graphicBuffer(
407                 mGraphicBufferAlloc->createGraphicBuffer(
408                         w, h, format, usage, &error));
409         if (graphicBuffer == 0) {
410             ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
411                     "failed");
412             return error;
413         }
414 
415         { // Scope for the lock
416             Mutex::Autolock lock(mMutex);
417 
418             if (mAbandoned) {
419                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
420                 return NO_INIT;
421             }
422 
423             mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
424         }
425     }
426 
427 
428     if (eglFence != EGL_NO_SYNC_KHR) {
429         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
430         // If something goes wrong, log the error, but return the buffer without
431         // synchronizing access to it.  It's too late at this point to abort the
432         // dequeue operation.
433         if (result == EGL_FALSE) {
434             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
435         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
436             ST_LOGE("dequeueBuffer: timeout waiting for fence");
437         }
438         eglDestroySyncKHR(dpy, eglFence);
439     }
440 
441     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
442             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
443 
444     return returnFlags;
445 }
446 
setSynchronousMode(bool enabled)447 status_t BufferQueue::setSynchronousMode(bool enabled) {
448     ATRACE_CALL();
449     ST_LOGV("setSynchronousMode: enabled=%d", enabled);
450     Mutex::Autolock lock(mMutex);
451 
452     if (mAbandoned) {
453         ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
454         return NO_INIT;
455     }
456 
457     status_t err = OK;
458     if (!mAllowSynchronousMode && enabled)
459         return err;
460 
461     if (!enabled) {
462         // going to asynchronous mode, drain the queue
463         err = drainQueueLocked();
464         if (err != NO_ERROR)
465             return err;
466     }
467 
468     if (mSynchronousMode != enabled) {
469         // - if we're going to asynchronous mode, the queue is guaranteed to be
470         // empty here
471         // - if the client set the number of buffers, we're guaranteed that
472         // we have at least 3 (because we don't allow less)
473         mSynchronousMode = enabled;
474         mDequeueCondition.broadcast();
475     }
476     return err;
477 }
478 
queueBuffer(int buf,const QueueBufferInput & input,QueueBufferOutput * output)479 status_t BufferQueue::queueBuffer(int buf,
480         const QueueBufferInput& input, QueueBufferOutput* output) {
481     ATRACE_CALL();
482     ATRACE_BUFFER_INDEX(buf);
483 
484     Rect crop;
485     uint32_t transform;
486     int scalingMode;
487     int64_t timestamp;
488     sp<Fence> fence;
489 
490     input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
491 
492     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
493             "scale=%s",
494             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
495             transform, scalingModeName(scalingMode));
496 
497     sp<ConsumerListener> listener;
498 
499     { // scope for the lock
500         Mutex::Autolock lock(mMutex);
501         if (mAbandoned) {
502             ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
503             return NO_INIT;
504         }
505         int maxBufferCount = getMaxBufferCountLocked();
506         if (buf < 0 || buf >= maxBufferCount) {
507             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
508                     maxBufferCount, buf);
509             return -EINVAL;
510         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
511             ST_LOGE("queueBuffer: slot %d is not owned by the client "
512                     "(state=%d)", buf, mSlots[buf].mBufferState);
513             return -EINVAL;
514         } else if (!mSlots[buf].mRequestBufferCalled) {
515             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
516                     "buffer", buf);
517             return -EINVAL;
518         }
519 
520         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
521         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
522         Rect croppedCrop;
523         crop.intersect(bufferRect, &croppedCrop);
524         if (croppedCrop != crop) {
525             ST_LOGE("queueBuffer: crop rect is not contained within the "
526                     "buffer in slot %d", buf);
527             return -EINVAL;
528         }
529 
530         if (mSynchronousMode) {
531             // In synchronous mode we queue all buffers in a FIFO.
532             mQueue.push_back(buf);
533 
534             // Synchronous mode always signals that an additional frame should
535             // be consumed.
536             listener = mConsumerListener;
537         } else {
538             // In asynchronous mode we only keep the most recent buffer.
539             if (mQueue.empty()) {
540                 mQueue.push_back(buf);
541 
542                 // Asynchronous mode only signals that a frame should be
543                 // consumed if no previous frame was pending. If a frame were
544                 // pending then the consumer would have already been notified.
545                 listener = mConsumerListener;
546             } else {
547                 Fifo::iterator front(mQueue.begin());
548                 // buffer currently queued is freed
549                 mSlots[*front].mBufferState = BufferSlot::FREE;
550                 // and we record the new buffer index in the queued list
551                 *front = buf;
552             }
553         }
554 
555         mSlots[buf].mTimestamp = timestamp;
556         mSlots[buf].mCrop = crop;
557         mSlots[buf].mTransform = transform;
558         mSlots[buf].mFence = fence;
559 
560         switch (scalingMode) {
561             case NATIVE_WINDOW_SCALING_MODE_FREEZE:
562             case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
563             case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
564                 break;
565             default:
566                 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
567                 scalingMode = mSlots[buf].mScalingMode;
568                 break;
569         }
570 
571         mSlots[buf].mBufferState = BufferSlot::QUEUED;
572         mSlots[buf].mScalingMode = scalingMode;
573         mFrameCounter++;
574         mSlots[buf].mFrameNumber = mFrameCounter;
575 
576         mBufferHasBeenQueued = true;
577         mDequeueCondition.broadcast();
578 
579         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
580                 mQueue.size());
581 
582         ATRACE_INT(mConsumerName.string(), mQueue.size());
583     } // scope for the lock
584 
585     // call back without lock held
586     if (listener != 0) {
587         listener->onFrameAvailable();
588     }
589     return OK;
590 }
591 
cancelBuffer(int buf,sp<Fence> fence)592 void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) {
593     ATRACE_CALL();
594     ST_LOGV("cancelBuffer: slot=%d", buf);
595     Mutex::Autolock lock(mMutex);
596 
597     if (mAbandoned) {
598         ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
599         return;
600     }
601 
602     int maxBufferCount = getMaxBufferCountLocked();
603     if (buf < 0 || buf >= maxBufferCount) {
604         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
605                 maxBufferCount, buf);
606         return;
607     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
608         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
609                 buf, mSlots[buf].mBufferState);
610         return;
611     }
612     mSlots[buf].mBufferState = BufferSlot::FREE;
613     mSlots[buf].mFrameNumber = 0;
614     mSlots[buf].mFence = fence;
615     mDequeueCondition.broadcast();
616 }
617 
connect(int api,QueueBufferOutput * output)618 status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
619     ATRACE_CALL();
620     ST_LOGV("connect: api=%d", api);
621     Mutex::Autolock lock(mMutex);
622 
623     if (mAbandoned) {
624         ST_LOGE("connect: BufferQueue has been abandoned!");
625         return NO_INIT;
626     }
627 
628     if (mConsumerListener == NULL) {
629         ST_LOGE("connect: BufferQueue has no consumer!");
630         return NO_INIT;
631     }
632 
633     int err = NO_ERROR;
634     switch (api) {
635         case NATIVE_WINDOW_API_EGL:
636         case NATIVE_WINDOW_API_CPU:
637         case NATIVE_WINDOW_API_MEDIA:
638         case NATIVE_WINDOW_API_CAMERA:
639             if (mConnectedApi != NO_CONNECTED_API) {
640                 ST_LOGE("connect: already connected (cur=%d, req=%d)",
641                         mConnectedApi, api);
642                 err = -EINVAL;
643             } else {
644                 mConnectedApi = api;
645                 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
646                         mQueue.size());
647             }
648             break;
649         default:
650             err = -EINVAL;
651             break;
652     }
653 
654     mBufferHasBeenQueued = false;
655 
656     return err;
657 }
658 
disconnect(int api)659 status_t BufferQueue::disconnect(int api) {
660     ATRACE_CALL();
661     ST_LOGV("disconnect: api=%d", api);
662 
663     int err = NO_ERROR;
664     sp<ConsumerListener> listener;
665 
666     { // Scope for the lock
667         Mutex::Autolock lock(mMutex);
668 
669         if (mAbandoned) {
670             // it is not really an error to disconnect after the surface
671             // has been abandoned, it should just be a no-op.
672             return NO_ERROR;
673         }
674 
675         switch (api) {
676             case NATIVE_WINDOW_API_EGL:
677             case NATIVE_WINDOW_API_CPU:
678             case NATIVE_WINDOW_API_MEDIA:
679             case NATIVE_WINDOW_API_CAMERA:
680                 if (mConnectedApi == api) {
681                     drainQueueAndFreeBuffersLocked();
682                     mConnectedApi = NO_CONNECTED_API;
683                     mDequeueCondition.broadcast();
684                     listener = mConsumerListener;
685                 } else {
686                     ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
687                             mConnectedApi, api);
688                     err = -EINVAL;
689                 }
690                 break;
691             default:
692                 ST_LOGE("disconnect: unknown API %d", api);
693                 err = -EINVAL;
694                 break;
695         }
696     }
697 
698     if (listener != NULL) {
699         listener->onBuffersReleased();
700     }
701 
702     return err;
703 }
704 
dump(String8 & result) const705 void BufferQueue::dump(String8& result) const
706 {
707     char buffer[1024];
708     BufferQueue::dump(result, "", buffer, 1024);
709 }
710 
dump(String8 & result,const char * prefix,char * buffer,size_t SIZE) const711 void BufferQueue::dump(String8& result, const char* prefix,
712         char* buffer, size_t SIZE) const
713 {
714     Mutex::Autolock _l(mMutex);
715 
716     String8 fifo;
717     int fifoSize = 0;
718     Fifo::const_iterator i(mQueue.begin());
719     while (i != mQueue.end()) {
720        snprintf(buffer, SIZE, "%02d ", *i++);
721        fifoSize++;
722        fifo.append(buffer);
723     }
724 
725     int maxBufferCount = getMaxBufferCountLocked();
726 
727     snprintf(buffer, SIZE,
728             "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
729             "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
730             prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
731             mDefaultHeight, mDefaultBufferFormat, mTransformHint,
732             fifoSize, fifo.string());
733     result.append(buffer);
734 
735 
736     struct {
737         const char * operator()(int state) const {
738             switch (state) {
739                 case BufferSlot::DEQUEUED: return "DEQUEUED";
740                 case BufferSlot::QUEUED: return "QUEUED";
741                 case BufferSlot::FREE: return "FREE";
742                 case BufferSlot::ACQUIRED: return "ACQUIRED";
743                 default: return "Unknown";
744             }
745         }
746     } stateName;
747 
748     for (int i=0 ; i<maxBufferCount ; i++) {
749         const BufferSlot& slot(mSlots[i]);
750         snprintf(buffer, SIZE,
751                 "%s%s[%02d] "
752                 "state=%-8s, crop=[%d,%d,%d,%d], "
753                 "xform=0x%02x, time=%#llx, scale=%s",
754                 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
755                 stateName(slot.mBufferState),
756                 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
757                 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp,
758                 scalingModeName(slot.mScalingMode)
759         );
760         result.append(buffer);
761 
762         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
763         if (buf != NULL) {
764             snprintf(buffer, SIZE,
765                     ", %p [%4ux%4u:%4u,%3X]",
766                     buf->handle, buf->width, buf->height, buf->stride,
767                     buf->format);
768             result.append(buffer);
769         }
770         result.append("\n");
771     }
772 }
773 
freeBufferLocked(int slot)774 void BufferQueue::freeBufferLocked(int slot) {
775     ST_LOGV("freeBufferLocked: slot=%d", slot);
776     mSlots[slot].mGraphicBuffer = 0;
777     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
778         mSlots[slot].mNeedsCleanupOnRelease = true;
779     }
780     mSlots[slot].mBufferState = BufferSlot::FREE;
781     mSlots[slot].mFrameNumber = 0;
782     mSlots[slot].mAcquireCalled = false;
783 
784     // destroy fence as BufferQueue now takes ownership
785     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
786         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
787         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
788     }
789     mSlots[slot].mFence.clear();
790 }
791 
freeAllBuffersLocked()792 void BufferQueue::freeAllBuffersLocked() {
793     ALOGW_IF(!mQueue.isEmpty(),
794             "freeAllBuffersLocked called but mQueue is not empty");
795     mQueue.clear();
796     mBufferHasBeenQueued = false;
797     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
798         freeBufferLocked(i);
799     }
800 }
801 
acquireBuffer(BufferItem * buffer)802 status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
803     ATRACE_CALL();
804     Mutex::Autolock _l(mMutex);
805 
806     // Check that the consumer doesn't currently have the maximum number of
807     // buffers acquired.  We allow the max buffer count to be exceeded by one
808     // buffer, so that the consumer can successfully set up the newly acquired
809     // buffer before releasing the old one.
810     int numAcquiredBuffers = 0;
811     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
812         if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
813             numAcquiredBuffers++;
814         }
815     }
816     if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
817         ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
818                 numAcquiredBuffers, mMaxAcquiredBufferCount);
819         return INVALID_OPERATION;
820     }
821 
822     // check if queue is empty
823     // In asynchronous mode the list is guaranteed to be one buffer
824     // deep, while in synchronous mode we use the oldest buffer.
825     if (!mQueue.empty()) {
826         Fifo::iterator front(mQueue.begin());
827         int buf = *front;
828 
829         ATRACE_BUFFER_INDEX(buf);
830 
831         if (mSlots[buf].mAcquireCalled) {
832             buffer->mGraphicBuffer = NULL;
833         } else {
834             buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
835         }
836         buffer->mCrop = mSlots[buf].mCrop;
837         buffer->mTransform = mSlots[buf].mTransform;
838         buffer->mScalingMode = mSlots[buf].mScalingMode;
839         buffer->mFrameNumber = mSlots[buf].mFrameNumber;
840         buffer->mTimestamp = mSlots[buf].mTimestamp;
841         buffer->mBuf = buf;
842         buffer->mFence = mSlots[buf].mFence;
843 
844         mSlots[buf].mAcquireCalled = true;
845         mSlots[buf].mNeedsCleanupOnRelease = false;
846         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
847         mSlots[buf].mFence.clear();
848 
849         mQueue.erase(front);
850         mDequeueCondition.broadcast();
851 
852         ATRACE_INT(mConsumerName.string(), mQueue.size());
853     } else {
854         return NO_BUFFER_AVAILABLE;
855     }
856 
857     return OK;
858 }
859 
releaseBuffer(int buf,EGLDisplay display,EGLSyncKHR eglFence,const sp<Fence> & fence)860 status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
861         EGLSyncKHR eglFence, const sp<Fence>& fence) {
862     ATRACE_CALL();
863     ATRACE_BUFFER_INDEX(buf);
864 
865     Mutex::Autolock _l(mMutex);
866 
867     if (buf == INVALID_BUFFER_SLOT) {
868         return -EINVAL;
869     }
870 
871     mSlots[buf].mEglDisplay = display;
872     mSlots[buf].mEglFence = eglFence;
873     mSlots[buf].mFence = fence;
874 
875     // The buffer can now only be released if its in the acquired state
876     if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
877         mSlots[buf].mBufferState = BufferSlot::FREE;
878     } else if (mSlots[buf].mNeedsCleanupOnRelease) {
879         ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
880         mSlots[buf].mNeedsCleanupOnRelease = false;
881         return STALE_BUFFER_SLOT;
882     } else {
883         ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
884         return -EINVAL;
885     }
886 
887     mDequeueCondition.broadcast();
888     return OK;
889 }
890 
consumerConnect(const sp<ConsumerListener> & consumerListener)891 status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
892     ST_LOGV("consumerConnect");
893     Mutex::Autolock lock(mMutex);
894 
895     if (mAbandoned) {
896         ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
897         return NO_INIT;
898     }
899 
900     mConsumerListener = consumerListener;
901 
902     return OK;
903 }
904 
consumerDisconnect()905 status_t BufferQueue::consumerDisconnect() {
906     ST_LOGV("consumerDisconnect");
907     Mutex::Autolock lock(mMutex);
908 
909     if (mConsumerListener == NULL) {
910         ST_LOGE("consumerDisconnect: No consumer is connected!");
911         return -EINVAL;
912     }
913 
914     mAbandoned = true;
915     mConsumerListener = NULL;
916     mQueue.clear();
917     freeAllBuffersLocked();
918     mDequeueCondition.broadcast();
919     return OK;
920 }
921 
getReleasedBuffers(uint32_t * slotMask)922 status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
923     ST_LOGV("getReleasedBuffers");
924     Mutex::Autolock lock(mMutex);
925 
926     if (mAbandoned) {
927         ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
928         return NO_INIT;
929     }
930 
931     uint32_t mask = 0;
932     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
933         if (!mSlots[i].mAcquireCalled) {
934             mask |= 1 << i;
935         }
936     }
937     *slotMask = mask;
938 
939     ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
940     return NO_ERROR;
941 }
942 
setDefaultBufferSize(uint32_t w,uint32_t h)943 status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
944 {
945     ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
946     if (!w || !h) {
947         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
948                 w, h);
949         return BAD_VALUE;
950     }
951 
952     Mutex::Autolock lock(mMutex);
953     mDefaultWidth = w;
954     mDefaultHeight = h;
955     return OK;
956 }
957 
setDefaultMaxBufferCount(int bufferCount)958 status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
959     ATRACE_CALL();
960     Mutex::Autolock lock(mMutex);
961     return setDefaultMaxBufferCountLocked(bufferCount);
962 }
963 
setMaxAcquiredBufferCount(int maxAcquiredBuffers)964 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
965     ATRACE_CALL();
966     Mutex::Autolock lock(mMutex);
967     if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) {
968         ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d",
969                 maxAcquiredBuffers);
970         return BAD_VALUE;
971     }
972     if (mConnectedApi != NO_CONNECTED_API) {
973         return INVALID_OPERATION;
974     }
975     mMaxAcquiredBufferCount = maxAcquiredBuffers;
976     return OK;
977 }
978 
freeAllBuffersExceptHeadLocked()979 void BufferQueue::freeAllBuffersExceptHeadLocked() {
980     int head = -1;
981     if (!mQueue.empty()) {
982         Fifo::iterator front(mQueue.begin());
983         head = *front;
984     }
985     mBufferHasBeenQueued = false;
986     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
987         if (i != head) {
988             freeBufferLocked(i);
989         }
990     }
991 }
992 
drainQueueLocked()993 status_t BufferQueue::drainQueueLocked() {
994     while (mSynchronousMode && !mQueue.isEmpty()) {
995         mDequeueCondition.wait(mMutex);
996         if (mAbandoned) {
997             ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
998             return NO_INIT;
999         }
1000         if (mConnectedApi == NO_CONNECTED_API) {
1001             ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
1002             return NO_INIT;
1003         }
1004     }
1005     return NO_ERROR;
1006 }
1007 
drainQueueAndFreeBuffersLocked()1008 status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
1009     status_t err = drainQueueLocked();
1010     if (err == NO_ERROR) {
1011         if (mSynchronousMode) {
1012             freeAllBuffersLocked();
1013         } else {
1014             freeAllBuffersExceptHeadLocked();
1015         }
1016     }
1017     return err;
1018 }
1019 
getMinMaxBufferCountLocked() const1020 int BufferQueue::getMinMaxBufferCountLocked() const {
1021     return getMinUndequeuedBufferCountLocked() + 1;
1022 }
1023 
getMinUndequeuedBufferCountLocked() const1024 int BufferQueue::getMinUndequeuedBufferCountLocked() const {
1025     return mSynchronousMode ? mMaxAcquiredBufferCount :
1026             mMaxAcquiredBufferCount + 1;
1027 }
1028 
getMaxBufferCountLocked() const1029 int BufferQueue::getMaxBufferCountLocked() const {
1030     int minMaxBufferCount = getMinMaxBufferCountLocked();
1031 
1032     int maxBufferCount = mDefaultMaxBufferCount;
1033     if (maxBufferCount < minMaxBufferCount) {
1034         maxBufferCount = minMaxBufferCount;
1035     }
1036     if (mOverrideMaxBufferCount != 0) {
1037         assert(mOverrideMaxBufferCount >= minMaxBufferCount);
1038         maxBufferCount = mOverrideMaxBufferCount;
1039     }
1040 
1041     // Any buffers that are dequeued by the producer or sitting in the queue
1042     // waiting to be consumed need to have their slots preserved.  Such
1043     // buffers will temporarily keep the max buffer count up until the slots
1044     // no longer need to be preserved.
1045     for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
1046         BufferSlot::BufferState state = mSlots[i].mBufferState;
1047         if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
1048             maxBufferCount = i + 1;
1049         }
1050     }
1051 
1052     return maxBufferCount;
1053 }
1054 
ProxyConsumerListener(const wp<BufferQueue::ConsumerListener> & consumerListener)1055 BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
1056         const wp<BufferQueue::ConsumerListener>& consumerListener):
1057         mConsumerListener(consumerListener) {}
1058 
~ProxyConsumerListener()1059 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
1060 
onFrameAvailable()1061 void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
1062     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1063     if (listener != NULL) {
1064         listener->onFrameAvailable();
1065     }
1066 }
1067 
onBuffersReleased()1068 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
1069     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
1070     if (listener != NULL) {
1071         listener->onBuffersReleased();
1072     }
1073 }
1074 
1075 }; // namespace android
1076