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