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