BufferQueueProducer.cpp revision 1852db9aa3e558c0a601d6b15c45214b0c6deff1
1/*
2 * Copyright 2014 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#include <inttypes.h>
18
19#define LOG_TAG "BufferQueueProducer"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21//#define LOG_NDEBUG 0
22
23#if DEBUG_ONLY_CODE
24#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0)
25#else
26#define VALIDATE_CONSISTENCY()
27#endif
28
29#define EGL_EGLEXT_PROTOTYPES
30
31#include <gui/BufferItem.h>
32#include <gui/BufferQueueCore.h>
33#include <gui/BufferQueueProducer.h>
34#include <gui/GLConsumer.h>
35#include <gui/IConsumerListener.h>
36#include <gui/IGraphicBufferAlloc.h>
37#include <gui/IProducerListener.h>
38
39#include <utils/Log.h>
40#include <utils/Trace.h>
41
42namespace android {
43
44BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
45    mCore(core),
46    mSlots(core->mSlots),
47    mConsumerName(),
48    mStickyTransform(0),
49    mLastQueueBufferFence(Fence::NO_FENCE),
50    mCallbackMutex(),
51    mNextCallbackTicket(0),
52    mCurrentCallbackTicket(0),
53    mCallbackCondition(),
54    mDequeueTimeout(-1) {}
55
56BufferQueueProducer::~BufferQueueProducer() {}
57
58status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
59    ATRACE_CALL();
60    BQ_LOGV("requestBuffer: slot %d", slot);
61    Mutex::Autolock lock(mCore->mMutex);
62
63    if (mCore->mIsAbandoned) {
64        BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
65        return NO_INIT;
66    }
67
68    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
69        BQ_LOGE("requestBuffer: BufferQueue has no connected producer");
70        return NO_INIT;
71    }
72
73    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
74        BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
75                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
76        return BAD_VALUE;
77    } else if (!mSlots[slot].mBufferState.isDequeued()) {
78        BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
79                "(state = %s)", slot, mSlots[slot].mBufferState.string());
80        return BAD_VALUE;
81    }
82
83    mSlots[slot].mRequestBufferCalled = true;
84    *buf = mSlots[slot].mGraphicBuffer;
85    return NO_ERROR;
86}
87
88status_t BufferQueueProducer::setMaxDequeuedBufferCount(
89        int maxDequeuedBuffers) {
90    ATRACE_CALL();
91    BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
92            maxDequeuedBuffers);
93
94    sp<IConsumerListener> listener;
95    { // Autolock scope
96        Mutex::Autolock lock(mCore->mMutex);
97        mCore->waitWhileAllocatingLocked();
98
99        if (mCore->mIsAbandoned) {
100            BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
101                    "abandoned");
102            return NO_INIT;
103        }
104
105        if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
106            return NO_ERROR;
107        }
108
109        // The new maxDequeuedBuffer count should not be violated by the number
110        // of currently dequeued buffers
111        int dequeuedCount = 0;
112        for (int s : mCore->mActiveBuffers) {
113            if (mSlots[s].mBufferState.isDequeued()) {
114                dequeuedCount++;
115            }
116        }
117        if (dequeuedCount > maxDequeuedBuffers) {
118            BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer"
119                    "count (%d) exceeds the current dequeued buffer count (%d)",
120                    maxDequeuedBuffers, dequeuedCount);
121            return BAD_VALUE;
122        }
123
124        int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
125        bufferCount += maxDequeuedBuffers;
126
127        if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
128            BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
129                    "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
130            return BAD_VALUE;
131        }
132
133        const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
134        if (bufferCount < minBufferSlots) {
135            BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is "
136                    "less than minimum %d", bufferCount, minBufferSlots);
137            return BAD_VALUE;
138        }
139
140        if (bufferCount > mCore->mMaxBufferCount) {
141            BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would "
142                    "exceed the maxBufferCount (%d) (maxAcquired %d async %d "
143                    "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers,
144                    mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
145                    mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock);
146            return BAD_VALUE;
147        }
148
149        int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
150        if (!mCore->adjustAvailableSlotsLocked(delta)) {
151            return BAD_VALUE;
152        }
153        mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
154        VALIDATE_CONSISTENCY();
155        if (delta < 0) {
156            listener = mCore->mConsumerListener;
157        }
158        mCore->mDequeueCondition.broadcast();
159    } // Autolock scope
160
161    // Call back without lock held
162    if (listener != NULL) {
163        listener->onBuffersReleased();
164    }
165
166    return NO_ERROR;
167}
168
169status_t BufferQueueProducer::setAsyncMode(bool async) {
170    ATRACE_CALL();
171    BQ_LOGV("setAsyncMode: async = %d", async);
172
173    sp<IConsumerListener> listener;
174    { // Autolock scope
175        Mutex::Autolock lock(mCore->mMutex);
176        mCore->waitWhileAllocatingLocked();
177
178        if (mCore->mIsAbandoned) {
179            BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
180            return NO_INIT;
181        }
182
183        if (async == mCore->mAsyncMode) {
184            return NO_ERROR;
185        }
186
187        if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount +
188                (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) >
189                mCore->mMaxBufferCount) {
190            BQ_LOGE("setAsyncMode(%d): this call would cause the "
191                    "maxBufferCount (%d) to be exceeded (maxAcquired %d "
192                    "maxDequeued %d mDequeueBufferCannotBlock %d)", async,
193                    mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
194                    mCore->mMaxDequeuedBufferCount,
195                    mCore->mDequeueBufferCannotBlock);
196            return BAD_VALUE;
197        }
198
199        int delta = mCore->getMaxBufferCountLocked(async,
200                mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount)
201                - mCore->getMaxBufferCountLocked();
202
203        if (!mCore->adjustAvailableSlotsLocked(delta)) {
204            BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of "
205                    "available slots. Delta = %d", delta);
206            return BAD_VALUE;
207        }
208        mCore->mAsyncMode = async;
209        VALIDATE_CONSISTENCY();
210        mCore->mDequeueCondition.broadcast();
211        if (delta < 0) {
212            listener = mCore->mConsumerListener;
213        }
214    } // Autolock scope
215
216    // Call back without lock held
217    if (listener != NULL) {
218        listener->onBuffersReleased();
219    }
220    return NO_ERROR;
221}
222
223int BufferQueueProducer::getFreeBufferLocked() const {
224    if (mCore->mFreeBuffers.empty()) {
225        return BufferQueueCore::INVALID_BUFFER_SLOT;
226    }
227    int slot = mCore->mFreeBuffers.front();
228    mCore->mFreeBuffers.pop_front();
229    return slot;
230}
231
232int BufferQueueProducer::getFreeSlotLocked() const {
233    if (mCore->mFreeSlots.empty()) {
234        return BufferQueueCore::INVALID_BUFFER_SLOT;
235    }
236    int slot = *(mCore->mFreeSlots.begin());
237    mCore->mFreeSlots.erase(slot);
238    return slot;
239}
240
241status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
242        int* found) const {
243    auto callerString = (caller == FreeSlotCaller::Dequeue) ?
244            "dequeueBuffer" : "attachBuffer";
245    bool tryAgain = true;
246    while (tryAgain) {
247        if (mCore->mIsAbandoned) {
248            BQ_LOGE("%s: BufferQueue has been abandoned", callerString);
249            return NO_INIT;
250        }
251
252        int dequeuedCount = 0;
253        int acquiredCount = 0;
254        for (int s : mCore->mActiveBuffers) {
255            if (mSlots[s].mBufferState.isDequeued()) {
256                ++dequeuedCount;
257            }
258            if (mSlots[s].mBufferState.isAcquired()) {
259                ++acquiredCount;
260            }
261        }
262
263        // Producers are not allowed to dequeue more than
264        // mMaxDequeuedBufferCount buffers.
265        // This check is only done if a buffer has already been queued
266        if (mCore->mBufferHasBeenQueued &&
267                dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
268            BQ_LOGE("%s: attempting to exceed the max dequeued buffer count "
269                    "(%d)", callerString, mCore->mMaxDequeuedBufferCount);
270            return INVALID_OPERATION;
271        }
272
273        *found = BufferQueueCore::INVALID_BUFFER_SLOT;
274
275        // If we disconnect and reconnect quickly, we can be in a state where
276        // our slots are empty but we have many buffers in the queue. This can
277        // cause us to run out of memory if we outrun the consumer. Wait here if
278        // it looks like we have too many buffers queued up.
279        const int maxBufferCount = mCore->getMaxBufferCountLocked();
280        bool tooManyBuffers = mCore->mQueue.size()
281                            > static_cast<size_t>(maxBufferCount);
282        if (tooManyBuffers) {
283            BQ_LOGV("%s: queue size is %zu, waiting", callerString,
284                    mCore->mQueue.size());
285        } else {
286            // If in shared buffer mode and a shared buffer exists, always
287            // return it.
288            if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot !=
289                    BufferQueueCore::INVALID_BUFFER_SLOT) {
290                *found = mCore->mSharedBufferSlot;
291            } else {
292                if (caller == FreeSlotCaller::Dequeue) {
293                    // If we're calling this from dequeue, prefer free buffers
294                    int slot = getFreeBufferLocked();
295                    if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
296                        *found = slot;
297                    } else if (mCore->mAllowAllocation) {
298                        *found = getFreeSlotLocked();
299                    }
300                } else {
301                    // If we're calling this from attach, prefer free slots
302                    int slot = getFreeSlotLocked();
303                    if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
304                        *found = slot;
305                    } else {
306                        *found = getFreeBufferLocked();
307                    }
308                }
309            }
310        }
311
312        // If no buffer is found, or if the queue has too many buffers
313        // outstanding, wait for a buffer to be acquired or released, or for the
314        // max buffer count to change.
315        tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
316                   tooManyBuffers;
317        if (tryAgain) {
318            // Return an error if we're in non-blocking mode (producer and
319            // consumer are controlled by the application).
320            // However, the consumer is allowed to briefly acquire an extra
321            // buffer (which could cause us to have to wait here), which is
322            // okay, since it is only used to implement an atomic acquire +
323            // release (e.g., in GLConsumer::updateTexImage())
324            if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) &&
325                    (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
326                return WOULD_BLOCK;
327            }
328            if (mDequeueTimeout >= 0) {
329                status_t result = mCore->mDequeueCondition.waitRelative(
330                        mCore->mMutex, mDequeueTimeout);
331                if (result == TIMED_OUT) {
332                    return result;
333                }
334            } else {
335                mCore->mDequeueCondition.wait(mCore->mMutex);
336            }
337        }
338    } // while (tryAgain)
339
340    return NO_ERROR;
341}
342
343status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
344        sp<android::Fence> *outFence, uint32_t width, uint32_t height,
345        PixelFormat format, uint32_t usage) {
346    ATRACE_CALL();
347    { // Autolock scope
348        Mutex::Autolock lock(mCore->mMutex);
349        mConsumerName = mCore->mConsumerName;
350
351        if (mCore->mIsAbandoned) {
352            BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
353            return NO_INIT;
354        }
355
356        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
357            BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
358            return NO_INIT;
359        }
360    } // Autolock scope
361
362    BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height,
363            format, usage);
364
365    if ((width && !height) || (!width && height)) {
366        BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
367        return BAD_VALUE;
368    }
369
370    status_t returnFlags = NO_ERROR;
371    EGLDisplay eglDisplay = EGL_NO_DISPLAY;
372    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
373    bool attachedByConsumer = false;
374
375    { // Autolock scope
376        Mutex::Autolock lock(mCore->mMutex);
377        mCore->waitWhileAllocatingLocked();
378
379        if (format == 0) {
380            format = mCore->mDefaultBufferFormat;
381        }
382
383        // Enable the usage bits the consumer requested
384        usage |= mCore->mConsumerUsageBits;
385
386        const bool useDefaultSize = !width && !height;
387        if (useDefaultSize) {
388            width = mCore->mDefaultWidth;
389            height = mCore->mDefaultHeight;
390        }
391
392        int found = BufferItem::INVALID_BUFFER_SLOT;
393        while (found == BufferItem::INVALID_BUFFER_SLOT) {
394            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
395                    &found);
396            if (status != NO_ERROR) {
397                return status;
398            }
399
400            // This should not happen
401            if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
402                BQ_LOGE("dequeueBuffer: no available buffer slots");
403                return -EBUSY;
404            }
405
406            const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
407
408            // If we are not allowed to allocate new buffers,
409            // waitForFreeSlotThenRelock must have returned a slot containing a
410            // buffer. If this buffer would require reallocation to meet the
411            // requested attributes, we free it and attempt to get another one.
412            if (!mCore->mAllowAllocation) {
413                if (buffer->needsReallocation(width, height, format, usage)) {
414                    if (mCore->mSharedBufferSlot == found) {
415                        BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
416                                "buffer");
417                        return BAD_VALUE;
418                    }
419                    mCore->mFreeSlots.insert(found);
420                    mCore->clearBufferSlotLocked(found);
421                    found = BufferItem::INVALID_BUFFER_SLOT;
422                    continue;
423                }
424            }
425        }
426
427        const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
428        if (mCore->mSharedBufferSlot == found &&
429                buffer->needsReallocation(width,  height, format, usage)) {
430            BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
431                    "buffer");
432
433            return BAD_VALUE;
434        }
435
436        if (mCore->mSharedBufferSlot != found) {
437            mCore->mActiveBuffers.insert(found);
438        }
439        *outSlot = found;
440        ATRACE_BUFFER_INDEX(found);
441
442        attachedByConsumer = mSlots[found].mNeedsReallocation;
443        mSlots[found].mNeedsReallocation = false;
444
445        mSlots[found].mBufferState.dequeue();
446
447        if ((buffer == NULL) ||
448                buffer->needsReallocation(width, height, format, usage))
449        {
450            mSlots[found].mAcquireCalled = false;
451            mSlots[found].mGraphicBuffer = NULL;
452            mSlots[found].mRequestBufferCalled = false;
453            mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
454            mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
455            mSlots[found].mFence = Fence::NO_FENCE;
456            mCore->mBufferAge = 0;
457            mCore->mIsAllocating = true;
458
459            returnFlags |= BUFFER_NEEDS_REALLOCATION;
460        } else {
461            // We add 1 because that will be the frame number when this buffer
462            // is queued
463            mCore->mBufferAge =
464                    mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
465        }
466
467        BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
468                mCore->mBufferAge);
469
470        if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
471            BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
472                    "slot=%d w=%d h=%d format=%u",
473                    found, buffer->width, buffer->height, buffer->format);
474        }
475
476        eglDisplay = mSlots[found].mEglDisplay;
477        eglFence = mSlots[found].mEglFence;
478        // Don't return a fence in shared buffer mode, except for the first
479        // frame.
480        *outFence = (mCore->mSharedBufferMode &&
481                mCore->mSharedBufferSlot == found) ?
482                Fence::NO_FENCE : mSlots[found].mFence;
483        mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
484        mSlots[found].mFence = Fence::NO_FENCE;
485
486        // If shared buffer mode has just been enabled, cache the slot of the
487        // first buffer that is dequeued and mark it as the shared buffer.
488        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
489                BufferQueueCore::INVALID_BUFFER_SLOT) {
490            mCore->mSharedBufferSlot = found;
491            mSlots[found].mBufferState.mShared = true;
492        }
493    } // Autolock scope
494
495    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
496        status_t error;
497        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
498        sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
499                width, height, format, usage,
500                {mConsumerName.string(), mConsumerName.size()}, &error));
501        { // Autolock scope
502            Mutex::Autolock lock(mCore->mMutex);
503
504            if (graphicBuffer != NULL && !mCore->mIsAbandoned) {
505                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
506                mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
507            }
508
509            mCore->mIsAllocating = false;
510            mCore->mIsAllocatingCondition.broadcast();
511
512            if (graphicBuffer == NULL) {
513                mCore->mFreeSlots.insert(*outSlot);
514                mCore->clearBufferSlotLocked(*outSlot);
515                BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
516                return error;
517            }
518
519            if (mCore->mIsAbandoned) {
520                mCore->mFreeSlots.insert(*outSlot);
521                mCore->clearBufferSlotLocked(*outSlot);
522                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
523                return NO_INIT;
524            }
525
526            VALIDATE_CONSISTENCY();
527        } // Autolock scope
528    }
529
530    if (attachedByConsumer) {
531        returnFlags |= BUFFER_NEEDS_REALLOCATION;
532    }
533
534    if (eglFence != EGL_NO_SYNC_KHR) {
535        EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
536                1000000000);
537        // If something goes wrong, log the error, but return the buffer without
538        // synchronizing access to it. It's too late at this point to abort the
539        // dequeue operation.
540        if (result == EGL_FALSE) {
541            BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
542                    eglGetError());
543        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
544            BQ_LOGE("dequeueBuffer: timeout waiting for fence");
545        }
546        eglDestroySyncKHR(eglDisplay, eglFence);
547    }
548
549    BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
550            *outSlot,
551            mSlots[*outSlot].mFrameNumber,
552            mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
553
554    return returnFlags;
555}
556
557status_t BufferQueueProducer::detachBuffer(int slot) {
558    ATRACE_CALL();
559    ATRACE_BUFFER_INDEX(slot);
560    BQ_LOGV("detachBuffer: slot %d", slot);
561
562    sp<IConsumerListener> listener;
563    {
564        Mutex::Autolock lock(mCore->mMutex);
565
566        if (mCore->mIsAbandoned) {
567            BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
568            return NO_INIT;
569        }
570
571        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
572            BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
573            return NO_INIT;
574        }
575
576        if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) {
577            BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode");
578            return BAD_VALUE;
579        }
580
581        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
582            BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
583                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
584            return BAD_VALUE;
585        } else if (!mSlots[slot].mBufferState.isDequeued()) {
586            BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
587                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
588            return BAD_VALUE;
589        } else if (!mSlots[slot].mRequestBufferCalled) {
590            BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
591                    slot);
592            return BAD_VALUE;
593        }
594
595        mSlots[slot].mBufferState.detachProducer();
596        mCore->mActiveBuffers.erase(slot);
597        mCore->mFreeSlots.insert(slot);
598        mCore->clearBufferSlotLocked(slot);
599        mCore->mDequeueCondition.broadcast();
600        VALIDATE_CONSISTENCY();
601        listener = mCore->mConsumerListener;
602    }
603
604    if (listener != NULL) {
605        listener->onBuffersReleased();
606    }
607
608    return NO_ERROR;
609}
610
611status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
612        sp<Fence>* outFence) {
613    ATRACE_CALL();
614
615    if (outBuffer == NULL) {
616        BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
617        return BAD_VALUE;
618    } else if (outFence == NULL) {
619        BQ_LOGE("detachNextBuffer: outFence must not be NULL");
620        return BAD_VALUE;
621    }
622
623    Mutex::Autolock lock(mCore->mMutex);
624
625    if (mCore->mIsAbandoned) {
626        BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
627        return NO_INIT;
628    }
629
630    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
631        BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
632        return NO_INIT;
633    }
634
635    if (mCore->mSharedBufferMode) {
636        BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
637            "mode");
638        return BAD_VALUE;
639    }
640
641    mCore->waitWhileAllocatingLocked();
642
643    if (mCore->mFreeBuffers.empty()) {
644        return NO_MEMORY;
645    }
646
647    int found = mCore->mFreeBuffers.front();
648    mCore->mFreeBuffers.remove(found);
649    mCore->mFreeSlots.insert(found);
650
651    BQ_LOGV("detachNextBuffer detached slot %d", found);
652
653    *outBuffer = mSlots[found].mGraphicBuffer;
654    *outFence = mSlots[found].mFence;
655    mCore->clearBufferSlotLocked(found);
656    VALIDATE_CONSISTENCY();
657
658    return NO_ERROR;
659}
660
661status_t BufferQueueProducer::attachBuffer(int* outSlot,
662        const sp<android::GraphicBuffer>& buffer) {
663    ATRACE_CALL();
664
665    if (outSlot == NULL) {
666        BQ_LOGE("attachBuffer: outSlot must not be NULL");
667        return BAD_VALUE;
668    } else if (buffer == NULL) {
669        BQ_LOGE("attachBuffer: cannot attach NULL buffer");
670        return BAD_VALUE;
671    }
672
673    Mutex::Autolock lock(mCore->mMutex);
674
675    if (mCore->mIsAbandoned) {
676        BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
677        return NO_INIT;
678    }
679
680    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
681        BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
682        return NO_INIT;
683    }
684
685    if (mCore->mSharedBufferMode) {
686        BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
687        return BAD_VALUE;
688    }
689
690    if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
691        BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
692                "[queue %u]", buffer->getGenerationNumber(),
693                mCore->mGenerationNumber);
694        return BAD_VALUE;
695    }
696
697    mCore->waitWhileAllocatingLocked();
698
699    status_t returnFlags = NO_ERROR;
700    int found;
701    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
702    if (status != NO_ERROR) {
703        return status;
704    }
705
706    // This should not happen
707    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
708        BQ_LOGE("attachBuffer: no available buffer slots");
709        return -EBUSY;
710    }
711
712    *outSlot = found;
713    ATRACE_BUFFER_INDEX(*outSlot);
714    BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
715            *outSlot, returnFlags);
716
717    mSlots[*outSlot].mGraphicBuffer = buffer;
718    mSlots[*outSlot].mBufferState.attachProducer();
719    mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
720    mSlots[*outSlot].mFence = Fence::NO_FENCE;
721    mSlots[*outSlot].mRequestBufferCalled = true;
722    mSlots[*outSlot].mAcquireCalled = false;
723    mCore->mActiveBuffers.insert(found);
724    VALIDATE_CONSISTENCY();
725
726    return returnFlags;
727}
728
729status_t BufferQueueProducer::queueBuffer(int slot,
730        const QueueBufferInput &input, QueueBufferOutput *output) {
731    ATRACE_CALL();
732    ATRACE_BUFFER_INDEX(slot);
733
734    int64_t timestamp;
735    bool isAutoTimestamp;
736    android_dataspace dataSpace;
737    Rect crop(Rect::EMPTY_RECT);
738    int scalingMode;
739    uint32_t transform;
740    uint32_t stickyTransform;
741    sp<Fence> fence;
742    input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
743            &transform, &fence, &stickyTransform);
744    Region surfaceDamage = input.getSurfaceDamage();
745
746    if (fence == NULL) {
747        BQ_LOGE("queueBuffer: fence is NULL");
748        return BAD_VALUE;
749    }
750
751    switch (scalingMode) {
752        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
753        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
754        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
755        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
756            break;
757        default:
758            BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
759            return BAD_VALUE;
760    }
761
762    sp<IConsumerListener> frameAvailableListener;
763    sp<IConsumerListener> frameReplacedListener;
764    int callbackTicket = 0;
765    BufferItem item;
766    { // Autolock scope
767        Mutex::Autolock lock(mCore->mMutex);
768
769        if (mCore->mIsAbandoned) {
770            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
771            return NO_INIT;
772        }
773
774        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
775            BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
776            return NO_INIT;
777        }
778
779        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
780            BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
781                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
782            return BAD_VALUE;
783        } else if (!mSlots[slot].mBufferState.isDequeued()) {
784            BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
785                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
786            return BAD_VALUE;
787        } else if (!mSlots[slot].mRequestBufferCalled) {
788            BQ_LOGE("queueBuffer: slot %d was queued without requesting "
789                    "a buffer", slot);
790            return BAD_VALUE;
791        }
792
793        // If shared buffer mode has just been enabled, cache the slot of the
794        // first buffer that is queued and mark it as the shared buffer.
795        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
796                BufferQueueCore::INVALID_BUFFER_SLOT) {
797            mCore->mSharedBufferSlot = slot;
798            mSlots[slot].mBufferState.mShared = true;
799        }
800
801        BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
802                " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
803                slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
804                crop.left, crop.top, crop.right, crop.bottom, transform,
805                BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
806
807        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
808        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
809        Rect croppedRect(Rect::EMPTY_RECT);
810        crop.intersect(bufferRect, &croppedRect);
811        if (croppedRect != crop) {
812            BQ_LOGE("queueBuffer: crop rect is not contained within the "
813                    "buffer in slot %d", slot);
814            return BAD_VALUE;
815        }
816
817        // Override UNKNOWN dataspace with consumer default
818        if (dataSpace == HAL_DATASPACE_UNKNOWN) {
819            dataSpace = mCore->mDefaultBufferDataSpace;
820        }
821
822        mSlots[slot].mFence = fence;
823        mSlots[slot].mBufferState.queue();
824
825        ++mCore->mFrameCounter;
826        mSlots[slot].mFrameNumber = mCore->mFrameCounter;
827
828        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
829        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
830        item.mCrop = crop;
831        item.mTransform = transform &
832                ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
833        item.mTransformToDisplayInverse =
834                (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
835        item.mScalingMode = static_cast<uint32_t>(scalingMode);
836        item.mTimestamp = timestamp;
837        item.mIsAutoTimestamp = isAutoTimestamp;
838        item.mDataSpace = dataSpace;
839        item.mFrameNumber = mCore->mFrameCounter;
840        item.mSlot = slot;
841        item.mFence = fence;
842        item.mIsDroppable = mCore->mAsyncMode ||
843                mCore->mDequeueBufferCannotBlock ||
844                (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
845        item.mSurfaceDamage = surfaceDamage;
846        item.mQueuedBuffer = true;
847        item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
848
849        mStickyTransform = stickyTransform;
850
851        // Cache the shared buffer data so that the BufferItem can be recreated.
852        if (mCore->mSharedBufferMode) {
853            mCore->mSharedBufferCache.crop = crop;
854            mCore->mSharedBufferCache.transform = transform;
855            mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
856                    scalingMode);
857            mCore->mSharedBufferCache.dataspace = dataSpace;
858        }
859
860        if (mCore->mQueue.empty()) {
861            // When the queue is empty, we can ignore mDequeueBufferCannotBlock
862            // and simply queue this buffer
863            mCore->mQueue.push_back(item);
864            frameAvailableListener = mCore->mConsumerListener;
865        } else {
866            // When the queue is not empty, we need to look at the last buffer
867            // in the queue to see if we need to replace it
868            const BufferItem& last = mCore->mQueue.itemAt(
869                    mCore->mQueue.size() - 1);
870            if (last.mIsDroppable) {
871
872                if (!last.mIsStale) {
873                    mSlots[last.mSlot].mBufferState.freeQueued();
874
875                    // After leaving shared buffer mode, the shared buffer will
876                    // still be around. Mark it as no longer shared if this
877                    // operation causes it to be free.
878                    if (!mCore->mSharedBufferMode &&
879                            mSlots[last.mSlot].mBufferState.isFree()) {
880                        mSlots[last.mSlot].mBufferState.mShared = false;
881                    }
882                    // Don't put the shared buffer on the free list.
883                    if (!mSlots[last.mSlot].mBufferState.isShared()) {
884                        mCore->mActiveBuffers.erase(last.mSlot);
885                        mCore->mFreeBuffers.push_back(last.mSlot);
886                    }
887                }
888
889                // Overwrite the droppable buffer with the incoming one
890                mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
891                frameReplacedListener = mCore->mConsumerListener;
892            } else {
893                mCore->mQueue.push_back(item);
894                frameAvailableListener = mCore->mConsumerListener;
895            }
896        }
897
898        mCore->mBufferHasBeenQueued = true;
899        mCore->mDequeueCondition.broadcast();
900        mCore->mLastQueuedSlot = slot;
901
902        output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
903                mCore->mTransformHint,
904                static_cast<uint32_t>(mCore->mQueue.size()),
905                mCore->mFrameCounter + 1);
906
907        ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
908        mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
909
910        // Take a ticket for the callback functions
911        callbackTicket = mNextCallbackTicket++;
912
913        VALIDATE_CONSISTENCY();
914    } // Autolock scope
915
916    // Don't send the GraphicBuffer through the callback, and don't send
917    // the slot number, since the consumer shouldn't need it
918    item.mGraphicBuffer.clear();
919    item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
920
921    // Call back without the main BufferQueue lock held, but with the callback
922    // lock held so we can ensure that callbacks occur in order
923    {
924        Mutex::Autolock lock(mCallbackMutex);
925        while (callbackTicket != mCurrentCallbackTicket) {
926            mCallbackCondition.wait(mCallbackMutex);
927        }
928
929        if (frameAvailableListener != NULL) {
930            frameAvailableListener->onFrameAvailable(item);
931        } else if (frameReplacedListener != NULL) {
932            frameReplacedListener->onFrameReplaced(item);
933        }
934
935        ++mCurrentCallbackTicket;
936        mCallbackCondition.broadcast();
937    }
938
939    // Wait without lock held
940    if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
941        // Waiting here allows for two full buffers to be queued but not a
942        // third. In the event that frames take varying time, this makes a
943        // small trade-off in favor of latency rather than throughput.
944        mLastQueueBufferFence->waitForever("Throttling EGL Production");
945    }
946    mLastQueueBufferFence = fence;
947    mLastQueuedCrop = item.mCrop;
948    mLastQueuedTransform = item.mTransform;
949
950    return NO_ERROR;
951}
952
953status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
954    ATRACE_CALL();
955    BQ_LOGV("cancelBuffer: slot %d", slot);
956    Mutex::Autolock lock(mCore->mMutex);
957
958    if (mCore->mIsAbandoned) {
959        BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
960        return NO_INIT;
961    }
962
963    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
964        BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
965        return NO_INIT;
966    }
967
968    if (mCore->mSharedBufferMode) {
969        BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
970        return BAD_VALUE;
971    }
972
973    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
974        BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
975                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
976        return BAD_VALUE;
977    } else if (!mSlots[slot].mBufferState.isDequeued()) {
978        BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
979                "(state = %s)", slot, mSlots[slot].mBufferState.string());
980        return BAD_VALUE;
981    } else if (fence == NULL) {
982        BQ_LOGE("cancelBuffer: fence is NULL");
983        return BAD_VALUE;
984    }
985
986    mSlots[slot].mBufferState.cancel();
987
988    // After leaving shared buffer mode, the shared buffer will still be around.
989    // Mark it as no longer shared if this operation causes it to be free.
990    if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
991        mSlots[slot].mBufferState.mShared = false;
992    }
993
994    // Don't put the shared buffer on the free list.
995    if (!mSlots[slot].mBufferState.isShared()) {
996        mCore->mActiveBuffers.erase(slot);
997        mCore->mFreeBuffers.push_back(slot);
998    }
999
1000    mSlots[slot].mFence = fence;
1001    mCore->mDequeueCondition.broadcast();
1002    VALIDATE_CONSISTENCY();
1003
1004    return NO_ERROR;
1005}
1006
1007int BufferQueueProducer::query(int what, int *outValue) {
1008    ATRACE_CALL();
1009    Mutex::Autolock lock(mCore->mMutex);
1010
1011    if (outValue == NULL) {
1012        BQ_LOGE("query: outValue was NULL");
1013        return BAD_VALUE;
1014    }
1015
1016    if (mCore->mIsAbandoned) {
1017        BQ_LOGE("query: BufferQueue has been abandoned");
1018        return NO_INIT;
1019    }
1020
1021    int value;
1022    switch (what) {
1023        case NATIVE_WINDOW_WIDTH:
1024            value = static_cast<int32_t>(mCore->mDefaultWidth);
1025            break;
1026        case NATIVE_WINDOW_HEIGHT:
1027            value = static_cast<int32_t>(mCore->mDefaultHeight);
1028            break;
1029        case NATIVE_WINDOW_FORMAT:
1030            value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1031            break;
1032        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1033            value = mCore->getMinUndequeuedBufferCountLocked();
1034            break;
1035        case NATIVE_WINDOW_STICKY_TRANSFORM:
1036            value = static_cast<int32_t>(mStickyTransform);
1037            break;
1038        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1039            value = (mCore->mQueue.size() > 1);
1040            break;
1041        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1042            value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1043            break;
1044        case NATIVE_WINDOW_DEFAULT_DATASPACE:
1045            value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1046            break;
1047        case NATIVE_WINDOW_BUFFER_AGE:
1048            if (mCore->mBufferAge > INT32_MAX) {
1049                value = 0;
1050            } else {
1051                value = static_cast<int32_t>(mCore->mBufferAge);
1052            }
1053            break;
1054        default:
1055            return BAD_VALUE;
1056    }
1057
1058    BQ_LOGV("query: %d? %d", what, value);
1059    *outValue = value;
1060    return NO_ERROR;
1061}
1062
1063status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1064        int api, bool producerControlledByApp, QueueBufferOutput *output) {
1065    ATRACE_CALL();
1066    Mutex::Autolock lock(mCore->mMutex);
1067    mConsumerName = mCore->mConsumerName;
1068    BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1069            producerControlledByApp ? "true" : "false");
1070
1071    if (mCore->mIsAbandoned) {
1072        BQ_LOGE("connect: BufferQueue has been abandoned");
1073        return NO_INIT;
1074    }
1075
1076    if (mCore->mConsumerListener == NULL) {
1077        BQ_LOGE("connect: BufferQueue has no consumer");
1078        return NO_INIT;
1079    }
1080
1081    if (output == NULL) {
1082        BQ_LOGE("connect: output was NULL");
1083        return BAD_VALUE;
1084    }
1085
1086    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1087        BQ_LOGE("connect: already connected (cur=%d req=%d)",
1088                mCore->mConnectedApi, api);
1089        return BAD_VALUE;
1090    }
1091
1092    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1093            mDequeueTimeout < 0 ?
1094            mCore->mConsumerControlledByApp && producerControlledByApp : false,
1095            mCore->mMaxBufferCount) -
1096            mCore->getMaxBufferCountLocked();
1097    if (!mCore->adjustAvailableSlotsLocked(delta)) {
1098        BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1099                "slots. Delta = %d", delta);
1100        return BAD_VALUE;
1101    }
1102
1103    int status = NO_ERROR;
1104    switch (api) {
1105        case NATIVE_WINDOW_API_EGL:
1106        case NATIVE_WINDOW_API_CPU:
1107        case NATIVE_WINDOW_API_MEDIA:
1108        case NATIVE_WINDOW_API_CAMERA:
1109            mCore->mConnectedApi = api;
1110            output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
1111                    mCore->mTransformHint,
1112                    static_cast<uint32_t>(mCore->mQueue.size()),
1113                    mCore->mFrameCounter + 1);
1114
1115            // Set up a death notification so that we can disconnect
1116            // automatically if the remote producer dies
1117            if (listener != NULL &&
1118                    IInterface::asBinder(listener)->remoteBinder() != NULL) {
1119                status = IInterface::asBinder(listener)->linkToDeath(
1120                        static_cast<IBinder::DeathRecipient*>(this));
1121                if (status != NO_ERROR) {
1122                    BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1123                            strerror(-status), status);
1124                }
1125            }
1126            mCore->mConnectedProducerListener = listener;
1127            break;
1128        default:
1129            BQ_LOGE("connect: unknown API %d", api);
1130            status = BAD_VALUE;
1131            break;
1132    }
1133
1134    mCore->mBufferHasBeenQueued = false;
1135    mCore->mDequeueBufferCannotBlock = false;
1136    if (mDequeueTimeout < 0) {
1137        mCore->mDequeueBufferCannotBlock =
1138                mCore->mConsumerControlledByApp && producerControlledByApp;
1139    }
1140
1141    mCore->mAllowAllocation = true;
1142    VALIDATE_CONSISTENCY();
1143    return status;
1144}
1145
1146status_t BufferQueueProducer::disconnect(int api) {
1147    ATRACE_CALL();
1148    BQ_LOGV("disconnect: api %d", api);
1149
1150    int status = NO_ERROR;
1151    sp<IConsumerListener> listener;
1152    { // Autolock scope
1153        Mutex::Autolock lock(mCore->mMutex);
1154        mCore->waitWhileAllocatingLocked();
1155
1156        if (mCore->mIsAbandoned) {
1157            // It's not really an error to disconnect after the surface has
1158            // been abandoned; it should just be a no-op.
1159            return NO_ERROR;
1160        }
1161
1162        if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1163            api = mCore->mConnectedApi;
1164            // If we're asked to disconnect the currently connected api but
1165            // nobody is connected, it's not really an error.
1166            if (api == BufferQueueCore::NO_CONNECTED_API) {
1167                return NO_ERROR;
1168            }
1169        }
1170
1171        switch (api) {
1172            case NATIVE_WINDOW_API_EGL:
1173            case NATIVE_WINDOW_API_CPU:
1174            case NATIVE_WINDOW_API_MEDIA:
1175            case NATIVE_WINDOW_API_CAMERA:
1176                if (mCore->mConnectedApi == api) {
1177                    mCore->freeAllBuffersLocked();
1178
1179                    // Remove our death notification callback if we have one
1180                    if (mCore->mConnectedProducerListener != NULL) {
1181                        sp<IBinder> token =
1182                                IInterface::asBinder(mCore->mConnectedProducerListener);
1183                        // This can fail if we're here because of the death
1184                        // notification, but we just ignore it
1185                        token->unlinkToDeath(
1186                                static_cast<IBinder::DeathRecipient*>(this));
1187                    }
1188                    mCore->mSharedBufferSlot =
1189                            BufferQueueCore::INVALID_BUFFER_SLOT;
1190                    mCore->mConnectedProducerListener = NULL;
1191                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1192                    mCore->mSidebandStream.clear();
1193                    mCore->mDequeueCondition.broadcast();
1194                    listener = mCore->mConsumerListener;
1195                } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1196                    BQ_LOGE("disconnect: still connected to another API "
1197                            "(cur=%d req=%d)", mCore->mConnectedApi, api);
1198                    status = BAD_VALUE;
1199                }
1200                break;
1201            default:
1202                BQ_LOGE("disconnect: unknown API %d", api);
1203                status = BAD_VALUE;
1204                break;
1205        }
1206    } // Autolock scope
1207
1208    // Call back without lock held
1209    if (listener != NULL) {
1210        listener->onBuffersReleased();
1211    }
1212
1213    return status;
1214}
1215
1216status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1217    sp<IConsumerListener> listener;
1218    { // Autolock scope
1219        Mutex::Autolock _l(mCore->mMutex);
1220        mCore->mSidebandStream = stream;
1221        listener = mCore->mConsumerListener;
1222    } // Autolock scope
1223
1224    if (listener != NULL) {
1225        listener->onSidebandStreamChanged();
1226    }
1227    return NO_ERROR;
1228}
1229
1230void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1231        PixelFormat format, uint32_t usage) {
1232    ATRACE_CALL();
1233    while (true) {
1234        size_t newBufferCount = 0;
1235        uint32_t allocWidth = 0;
1236        uint32_t allocHeight = 0;
1237        PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1238        uint32_t allocUsage = 0;
1239        { // Autolock scope
1240            Mutex::Autolock lock(mCore->mMutex);
1241            mCore->waitWhileAllocatingLocked();
1242
1243            if (!mCore->mAllowAllocation) {
1244                BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1245                        "BufferQueue");
1246                return;
1247            }
1248
1249            newBufferCount = mCore->mFreeSlots.size();
1250            if (newBufferCount == 0) {
1251                return;
1252            }
1253
1254            allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1255            allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1256            allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1257            allocUsage = usage | mCore->mConsumerUsageBits;
1258
1259            mCore->mIsAllocating = true;
1260        } // Autolock scope
1261
1262        Vector<sp<GraphicBuffer>> buffers;
1263        for (size_t i = 0; i <  newBufferCount; ++i) {
1264            status_t result = NO_ERROR;
1265            sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
1266                    allocWidth, allocHeight, allocFormat, allocUsage,
1267                    {mConsumerName.string(), mConsumerName.size()}, &result));
1268            if (result != NO_ERROR) {
1269                BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1270                        " %u, usage %u)", width, height, format, usage);
1271                Mutex::Autolock lock(mCore->mMutex);
1272                mCore->mIsAllocating = false;
1273                mCore->mIsAllocatingCondition.broadcast();
1274                return;
1275            }
1276            buffers.push_back(graphicBuffer);
1277        }
1278
1279        { // Autolock scope
1280            Mutex::Autolock lock(mCore->mMutex);
1281            uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1282            uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1283            PixelFormat checkFormat = format != 0 ?
1284                    format : mCore->mDefaultBufferFormat;
1285            uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
1286            if (checkWidth != allocWidth || checkHeight != allocHeight ||
1287                checkFormat != allocFormat || checkUsage != allocUsage) {
1288                // Something changed while we released the lock. Retry.
1289                BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1290                mCore->mIsAllocating = false;
1291                mCore->mIsAllocatingCondition.broadcast();
1292                continue;
1293            }
1294
1295            for (size_t i = 0; i < newBufferCount; ++i) {
1296                if (mCore->mFreeSlots.empty()) {
1297                    BQ_LOGV("allocateBuffers: a slot was occupied while "
1298                            "allocating. Dropping allocated buffer.");
1299                    continue;
1300                }
1301                auto slot = mCore->mFreeSlots.begin();
1302                mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1303                mSlots[*slot].mGraphicBuffer = buffers[i];
1304                mSlots[*slot].mFence = Fence::NO_FENCE;
1305
1306                // freeBufferLocked puts this slot on the free slots list. Since
1307                // we then attached a buffer, move the slot to free buffer list.
1308                mCore->mFreeBuffers.push_front(*slot);
1309
1310                BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1311                        *slot);
1312
1313                // Make sure the erase is done after all uses of the slot
1314                // iterator since it will be invalid after this point.
1315                mCore->mFreeSlots.erase(slot);
1316            }
1317
1318            mCore->mIsAllocating = false;
1319            mCore->mIsAllocatingCondition.broadcast();
1320            VALIDATE_CONSISTENCY();
1321        } // Autolock scope
1322    }
1323}
1324
1325status_t BufferQueueProducer::allowAllocation(bool allow) {
1326    ATRACE_CALL();
1327    BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1328
1329    Mutex::Autolock lock(mCore->mMutex);
1330    mCore->mAllowAllocation = allow;
1331    return NO_ERROR;
1332}
1333
1334status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1335    ATRACE_CALL();
1336    BQ_LOGV("setGenerationNumber: %u", generationNumber);
1337
1338    Mutex::Autolock lock(mCore->mMutex);
1339    mCore->mGenerationNumber = generationNumber;
1340    return NO_ERROR;
1341}
1342
1343String8 BufferQueueProducer::getConsumerName() const {
1344    ATRACE_CALL();
1345    Mutex::Autolock lock(mCore->mMutex);
1346    BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1347    return mConsumerName;
1348}
1349
1350status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1351    ATRACE_CALL();
1352    BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1353
1354    Mutex::Autolock lock(mCore->mMutex);
1355    if (!sharedBufferMode) {
1356        mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1357    }
1358    mCore->mSharedBufferMode = sharedBufferMode;
1359    return NO_ERROR;
1360}
1361
1362status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1363    ATRACE_CALL();
1364    BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1365
1366    Mutex::Autolock lock(mCore->mMutex);
1367
1368    mCore->mAutoRefresh = autoRefresh;
1369    return NO_ERROR;
1370}
1371
1372status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1373    ATRACE_CALL();
1374    BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1375
1376    Mutex::Autolock lock(mCore->mMutex);
1377    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
1378            mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1379    if (!mCore->adjustAvailableSlotsLocked(delta)) {
1380        BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1381                "available slots. Delta = %d", delta);
1382        return BAD_VALUE;
1383    }
1384
1385    mDequeueTimeout = timeout;
1386    mCore->mDequeueBufferCannotBlock = false;
1387
1388    VALIDATE_CONSISTENCY();
1389    return NO_ERROR;
1390}
1391
1392status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1393        sp<Fence>* outFence, float outTransformMatrix[16]) {
1394    ATRACE_CALL();
1395    BQ_LOGV("getLastQueuedBuffer");
1396
1397    Mutex::Autolock lock(mCore->mMutex);
1398    if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1399        *outBuffer = nullptr;
1400        *outFence = Fence::NO_FENCE;
1401        return NO_ERROR;
1402    }
1403
1404    *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1405    *outFence = mLastQueueBufferFence;
1406
1407    // Currently only SurfaceFlinger internally ever changes
1408    // GLConsumer's filtering mode, so we just use 'true' here as
1409    // this is slightly specialized for the current client of this API,
1410    // which does want filtering.
1411    GLConsumer::computeTransformMatrix(outTransformMatrix,
1412            mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1413            mLastQueuedTransform, true /* filter */);
1414
1415    return NO_ERROR;
1416}
1417
1418bool BufferQueueProducer::getFrameTimestamps(uint64_t frameNumber,
1419        FrameTimestamps* outTimestamps) const {
1420    ATRACE_CALL();
1421    BQ_LOGV("getFrameTimestamps, %" PRIu64, frameNumber);
1422    sp<IConsumerListener> listener;
1423
1424    {
1425        Mutex::Autolock lock(mCore->mMutex);
1426        listener = mCore->mConsumerListener;
1427    }
1428    if (listener != NULL) {
1429        return listener->getFrameTimestamps(frameNumber, outTimestamps);
1430    }
1431    return false;
1432}
1433
1434void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1435    // If we're here, it means that a producer we were connected to died.
1436    // We're guaranteed that we are still connected to it because we remove
1437    // this callback upon disconnect. It's therefore safe to read mConnectedApi
1438    // without synchronization here.
1439    int api = mCore->mConnectedApi;
1440    disconnect(api);
1441}
1442
1443status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1444    BQ_LOGV("getUniqueId");
1445
1446    *outId = mCore->mUniqueId;
1447    return NO_ERROR;
1448}
1449
1450} // namespace android
1451