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