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