BufferQueueProducer.cpp revision f8b4ca51111cd2e566d1774ac464da859db78976
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        FrameEventHistoryDelta* outTimestamps) {
353    ATRACE_CALL();
354    { // Autolock scope
355        Mutex::Autolock lock(mCore->mMutex);
356        mConsumerName = mCore->mConsumerName;
357
358        if (mCore->mIsAbandoned) {
359            BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
360            return NO_INIT;
361        }
362
363        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
364            BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
365            return NO_INIT;
366        }
367    } // Autolock scope
368
369    BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height,
370            format, usage);
371
372    if ((width && !height) || (!width && height)) {
373        BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
374        return BAD_VALUE;
375    }
376
377    status_t returnFlags = NO_ERROR;
378    EGLDisplay eglDisplay = EGL_NO_DISPLAY;
379    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
380    bool attachedByConsumer = false;
381
382    { // Autolock scope
383        Mutex::Autolock lock(mCore->mMutex);
384        mCore->waitWhileAllocatingLocked();
385
386        if (format == 0) {
387            format = mCore->mDefaultBufferFormat;
388        }
389
390        // Enable the usage bits the consumer requested
391        usage |= mCore->mConsumerUsageBits;
392
393        const bool useDefaultSize = !width && !height;
394        if (useDefaultSize) {
395            width = mCore->mDefaultWidth;
396            height = mCore->mDefaultHeight;
397        }
398
399        int found = BufferItem::INVALID_BUFFER_SLOT;
400        while (found == BufferItem::INVALID_BUFFER_SLOT) {
401            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
402                    &found);
403            if (status != NO_ERROR) {
404                return status;
405            }
406
407            // This should not happen
408            if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
409                BQ_LOGE("dequeueBuffer: no available buffer slots");
410                return -EBUSY;
411            }
412
413            const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
414
415            // If we are not allowed to allocate new buffers,
416            // waitForFreeSlotThenRelock must have returned a slot containing a
417            // buffer. If this buffer would require reallocation to meet the
418            // requested attributes, we free it and attempt to get another one.
419            if (!mCore->mAllowAllocation) {
420                if (buffer->needsReallocation(width, height, format,
421                        BQ_LAYER_COUNT, usage)) {
422                    if (mCore->mSharedBufferSlot == found) {
423                        BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
424                                "buffer");
425                        return BAD_VALUE;
426                    }
427                    mCore->mFreeSlots.insert(found);
428                    mCore->clearBufferSlotLocked(found);
429                    found = BufferItem::INVALID_BUFFER_SLOT;
430                    continue;
431                }
432            }
433        }
434
435        const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
436        if (mCore->mSharedBufferSlot == found &&
437                buffer->needsReallocation(width, height, format,
438                        BQ_LAYER_COUNT, usage)) {
439            BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
440                    "buffer");
441
442            return BAD_VALUE;
443        }
444
445        if (mCore->mSharedBufferSlot != found) {
446            mCore->mActiveBuffers.insert(found);
447        }
448        *outSlot = found;
449        ATRACE_BUFFER_INDEX(found);
450
451        attachedByConsumer = mSlots[found].mNeedsReallocation;
452        mSlots[found].mNeedsReallocation = false;
453
454        mSlots[found].mBufferState.dequeue();
455
456        if ((buffer == NULL) ||
457                buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT,
458                usage))
459        {
460            mSlots[found].mAcquireCalled = false;
461            mSlots[found].mGraphicBuffer = NULL;
462            mSlots[found].mRequestBufferCalled = false;
463            mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
464            mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
465            mSlots[found].mFence = Fence::NO_FENCE;
466            mCore->mBufferAge = 0;
467            mCore->mIsAllocating = true;
468
469            returnFlags |= BUFFER_NEEDS_REALLOCATION;
470        } else {
471            // We add 1 because that will be the frame number when this buffer
472            // is queued
473            mCore->mBufferAge =
474                    mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
475        }
476
477        BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
478                mCore->mBufferAge);
479
480        if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
481            BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
482                    "slot=%d w=%d h=%d format=%u",
483                    found, buffer->width, buffer->height, buffer->format);
484        }
485
486        eglDisplay = mSlots[found].mEglDisplay;
487        eglFence = mSlots[found].mEglFence;
488        // Don't return a fence in shared buffer mode, except for the first
489        // frame.
490        *outFence = (mCore->mSharedBufferMode &&
491                mCore->mSharedBufferSlot == found) ?
492                Fence::NO_FENCE : mSlots[found].mFence;
493        mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
494        mSlots[found].mFence = Fence::NO_FENCE;
495
496        // If shared buffer mode has just been enabled, cache the slot of the
497        // first buffer that is dequeued and mark it as the shared buffer.
498        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
499                BufferQueueCore::INVALID_BUFFER_SLOT) {
500            mCore->mSharedBufferSlot = found;
501            mSlots[found].mBufferState.mShared = true;
502        }
503    } // Autolock scope
504
505    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
506        status_t error;
507        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
508        sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
509                width, height, format, BQ_LAYER_COUNT, usage,
510                {mConsumerName.string(), mConsumerName.size()}, &error));
511        { // Autolock scope
512            Mutex::Autolock lock(mCore->mMutex);
513
514            if (graphicBuffer != NULL && !mCore->mIsAbandoned) {
515                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
516                mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
517            }
518
519            mCore->mIsAllocating = false;
520            mCore->mIsAllocatingCondition.broadcast();
521
522            if (graphicBuffer == NULL) {
523                mCore->mFreeSlots.insert(*outSlot);
524                mCore->clearBufferSlotLocked(*outSlot);
525                BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
526                return error;
527            }
528
529            if (mCore->mIsAbandoned) {
530                mCore->mFreeSlots.insert(*outSlot);
531                mCore->clearBufferSlotLocked(*outSlot);
532                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
533                return NO_INIT;
534            }
535
536            VALIDATE_CONSISTENCY();
537        } // Autolock scope
538    }
539
540    if (attachedByConsumer) {
541        returnFlags |= BUFFER_NEEDS_REALLOCATION;
542    }
543
544    if (eglFence != EGL_NO_SYNC_KHR) {
545        EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
546                1000000000);
547        // If something goes wrong, log the error, but return the buffer without
548        // synchronizing access to it. It's too late at this point to abort the
549        // dequeue operation.
550        if (result == EGL_FALSE) {
551            BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
552                    eglGetError());
553        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
554            BQ_LOGE("dequeueBuffer: timeout waiting for fence");
555        }
556        eglDestroySyncKHR(eglDisplay, eglFence);
557    }
558
559    BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
560            *outSlot,
561            mSlots[*outSlot].mFrameNumber,
562            mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
563
564    addAndGetFrameTimestamps(nullptr, outTimestamps);
565
566    return returnFlags;
567}
568
569status_t BufferQueueProducer::detachBuffer(int slot) {
570    ATRACE_CALL();
571    ATRACE_BUFFER_INDEX(slot);
572    BQ_LOGV("detachBuffer: slot %d", slot);
573
574    sp<IConsumerListener> listener;
575    {
576        Mutex::Autolock lock(mCore->mMutex);
577
578        if (mCore->mIsAbandoned) {
579            BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
580            return NO_INIT;
581        }
582
583        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
584            BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
585            return NO_INIT;
586        }
587
588        if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) {
589            BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode");
590            return BAD_VALUE;
591        }
592
593        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
594            BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
595                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
596            return BAD_VALUE;
597        } else if (!mSlots[slot].mBufferState.isDequeued()) {
598            BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
599                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
600            return BAD_VALUE;
601        } else if (!mSlots[slot].mRequestBufferCalled) {
602            BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
603                    slot);
604            return BAD_VALUE;
605        }
606
607        mSlots[slot].mBufferState.detachProducer();
608        mCore->mActiveBuffers.erase(slot);
609        mCore->mFreeSlots.insert(slot);
610        mCore->clearBufferSlotLocked(slot);
611        mCore->mDequeueCondition.broadcast();
612        VALIDATE_CONSISTENCY();
613        listener = mCore->mConsumerListener;
614    }
615
616    if (listener != NULL) {
617        listener->onBuffersReleased();
618    }
619
620    return NO_ERROR;
621}
622
623status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
624        sp<Fence>* outFence) {
625    ATRACE_CALL();
626
627    if (outBuffer == NULL) {
628        BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
629        return BAD_VALUE;
630    } else if (outFence == NULL) {
631        BQ_LOGE("detachNextBuffer: outFence must not be NULL");
632        return BAD_VALUE;
633    }
634
635    Mutex::Autolock lock(mCore->mMutex);
636
637    if (mCore->mIsAbandoned) {
638        BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
639        return NO_INIT;
640    }
641
642    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
643        BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
644        return NO_INIT;
645    }
646
647    if (mCore->mSharedBufferMode) {
648        BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
649            "mode");
650        return BAD_VALUE;
651    }
652
653    mCore->waitWhileAllocatingLocked();
654
655    if (mCore->mFreeBuffers.empty()) {
656        return NO_MEMORY;
657    }
658
659    int found = mCore->mFreeBuffers.front();
660    mCore->mFreeBuffers.remove(found);
661    mCore->mFreeSlots.insert(found);
662
663    BQ_LOGV("detachNextBuffer detached slot %d", found);
664
665    *outBuffer = mSlots[found].mGraphicBuffer;
666    *outFence = mSlots[found].mFence;
667    mCore->clearBufferSlotLocked(found);
668    VALIDATE_CONSISTENCY();
669
670    return NO_ERROR;
671}
672
673status_t BufferQueueProducer::attachBuffer(int* outSlot,
674        const sp<android::GraphicBuffer>& buffer) {
675    ATRACE_CALL();
676
677    if (outSlot == NULL) {
678        BQ_LOGE("attachBuffer: outSlot must not be NULL");
679        return BAD_VALUE;
680    } else if (buffer == NULL) {
681        BQ_LOGE("attachBuffer: cannot attach NULL buffer");
682        return BAD_VALUE;
683    }
684
685    Mutex::Autolock lock(mCore->mMutex);
686
687    if (mCore->mIsAbandoned) {
688        BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
689        return NO_INIT;
690    }
691
692    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
693        BQ_LOGE("attachBuffer: BufferQueue has no connected producer");
694        return NO_INIT;
695    }
696
697    if (mCore->mSharedBufferMode) {
698        BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
699        return BAD_VALUE;
700    }
701
702    if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
703        BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
704                "[queue %u]", buffer->getGenerationNumber(),
705                mCore->mGenerationNumber);
706        return BAD_VALUE;
707    }
708
709    mCore->waitWhileAllocatingLocked();
710
711    status_t returnFlags = NO_ERROR;
712    int found;
713    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
714    if (status != NO_ERROR) {
715        return status;
716    }
717
718    // This should not happen
719    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
720        BQ_LOGE("attachBuffer: no available buffer slots");
721        return -EBUSY;
722    }
723
724    *outSlot = found;
725    ATRACE_BUFFER_INDEX(*outSlot);
726    BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
727            *outSlot, returnFlags);
728
729    mSlots[*outSlot].mGraphicBuffer = buffer;
730    mSlots[*outSlot].mBufferState.attachProducer();
731    mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
732    mSlots[*outSlot].mFence = Fence::NO_FENCE;
733    mSlots[*outSlot].mRequestBufferCalled = true;
734    mSlots[*outSlot].mAcquireCalled = false;
735    mCore->mActiveBuffers.insert(found);
736    VALIDATE_CONSISTENCY();
737
738    return returnFlags;
739}
740
741status_t BufferQueueProducer::queueBuffer(int slot,
742        const QueueBufferInput &input, QueueBufferOutput *output) {
743    ATRACE_CALL();
744    ATRACE_BUFFER_INDEX(slot);
745
746    int64_t requestedPresentTimestamp;
747    bool isAutoTimestamp;
748    android_dataspace dataSpace;
749    Rect crop(Rect::EMPTY_RECT);
750    int scalingMode;
751    uint32_t transform;
752    uint32_t stickyTransform;
753    sp<Fence> acquireFence;
754    bool getFrameTimestamps = false;
755    input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
756            &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
757            &getFrameTimestamps);
758    Region surfaceDamage = input.getSurfaceDamage();
759
760    if (acquireFence == NULL) {
761        BQ_LOGE("queueBuffer: fence is NULL");
762        return BAD_VALUE;
763    }
764
765    auto acquireFenceTime = std::make_shared<FenceTime>(acquireFence);
766
767    switch (scalingMode) {
768        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
769        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
770        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
771        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
772            break;
773        default:
774            BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
775            return BAD_VALUE;
776    }
777
778    sp<IConsumerListener> frameAvailableListener;
779    sp<IConsumerListener> frameReplacedListener;
780    int callbackTicket = 0;
781    uint64_t currentFrameNumber = 0;
782    BufferItem item;
783    { // Autolock scope
784        Mutex::Autolock lock(mCore->mMutex);
785
786        if (mCore->mIsAbandoned) {
787            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
788            return NO_INIT;
789        }
790
791        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
792            BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
793            return NO_INIT;
794        }
795
796        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
797            BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
798                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
799            return BAD_VALUE;
800        } else if (!mSlots[slot].mBufferState.isDequeued()) {
801            BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
802                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
803            return BAD_VALUE;
804        } else if (!mSlots[slot].mRequestBufferCalled) {
805            BQ_LOGE("queueBuffer: slot %d was queued without requesting "
806                    "a buffer", slot);
807            return BAD_VALUE;
808        }
809
810        // If shared buffer mode has just been enabled, cache the slot of the
811        // first buffer that is queued and mark it as the shared buffer.
812        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
813                BufferQueueCore::INVALID_BUFFER_SLOT) {
814            mCore->mSharedBufferSlot = slot;
815            mSlots[slot].mBufferState.mShared = true;
816        }
817
818        BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
819                " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
820                slot, mCore->mFrameCounter + 1, requestedPresentTimestamp,
821                dataSpace, crop.left, crop.top, crop.right, crop.bottom,
822                transform,
823                BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
824
825        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
826        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
827        Rect croppedRect(Rect::EMPTY_RECT);
828        crop.intersect(bufferRect, &croppedRect);
829        if (croppedRect != crop) {
830            BQ_LOGE("queueBuffer: crop rect is not contained within the "
831                    "buffer in slot %d", slot);
832            return BAD_VALUE;
833        }
834
835        // Override UNKNOWN dataspace with consumer default
836        if (dataSpace == HAL_DATASPACE_UNKNOWN) {
837            dataSpace = mCore->mDefaultBufferDataSpace;
838        }
839
840        mSlots[slot].mFence = acquireFence;
841        mSlots[slot].mBufferState.queue();
842
843        // Increment the frame counter and store a local version of it
844        // for use outside the lock on mCore->mMutex.
845        ++mCore->mFrameCounter;
846        currentFrameNumber = mCore->mFrameCounter;
847        mSlots[slot].mFrameNumber = currentFrameNumber;
848
849        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
850        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
851        item.mCrop = crop;
852        item.mTransform = transform &
853                ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
854        item.mTransformToDisplayInverse =
855                (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
856        item.mScalingMode = static_cast<uint32_t>(scalingMode);
857        item.mTimestamp = requestedPresentTimestamp;
858        item.mIsAutoTimestamp = isAutoTimestamp;
859        item.mDataSpace = dataSpace;
860        item.mFrameNumber = currentFrameNumber;
861        item.mSlot = slot;
862        item.mFence = acquireFence;
863        item.mFenceTime = acquireFenceTime;
864        item.mIsDroppable = mCore->mAsyncMode ||
865                mCore->mDequeueBufferCannotBlock ||
866                (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
867        item.mSurfaceDamage = surfaceDamage;
868        item.mQueuedBuffer = true;
869        item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
870
871        mStickyTransform = stickyTransform;
872
873        // Cache the shared buffer data so that the BufferItem can be recreated.
874        if (mCore->mSharedBufferMode) {
875            mCore->mSharedBufferCache.crop = crop;
876            mCore->mSharedBufferCache.transform = transform;
877            mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
878                    scalingMode);
879            mCore->mSharedBufferCache.dataspace = dataSpace;
880        }
881
882        output->bufferReplaced = false;
883        if (mCore->mQueue.empty()) {
884            // When the queue is empty, we can ignore mDequeueBufferCannotBlock
885            // and simply queue this buffer
886            mCore->mQueue.push_back(item);
887            frameAvailableListener = mCore->mConsumerListener;
888        } else {
889            // When the queue is not empty, we need to look at the last buffer
890            // in the queue to see if we need to replace it
891            const BufferItem& last = mCore->mQueue.itemAt(
892                    mCore->mQueue.size() - 1);
893            if (last.mIsDroppable) {
894
895                if (!last.mIsStale) {
896                    mSlots[last.mSlot].mBufferState.freeQueued();
897
898                    // After leaving shared buffer mode, the shared buffer will
899                    // still be around. Mark it as no longer shared if this
900                    // operation causes it to be free.
901                    if (!mCore->mSharedBufferMode &&
902                            mSlots[last.mSlot].mBufferState.isFree()) {
903                        mSlots[last.mSlot].mBufferState.mShared = false;
904                    }
905                    // Don't put the shared buffer on the free list.
906                    if (!mSlots[last.mSlot].mBufferState.isShared()) {
907                        mCore->mActiveBuffers.erase(last.mSlot);
908                        mCore->mFreeBuffers.push_back(last.mSlot);
909                        output->bufferReplaced = true;
910                    }
911                }
912
913                // Overwrite the droppable buffer with the incoming one
914                mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
915                frameReplacedListener = mCore->mConsumerListener;
916            } else {
917                mCore->mQueue.push_back(item);
918                frameAvailableListener = mCore->mConsumerListener;
919            }
920        }
921
922        mCore->mBufferHasBeenQueued = true;
923        mCore->mDequeueCondition.broadcast();
924        mCore->mLastQueuedSlot = slot;
925
926        output->width = mCore->mDefaultWidth;
927        output->height = mCore->mDefaultHeight;
928        output->transformHint = mCore->mTransformHint;
929        output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
930        output->nextFrameNumber = mCore->mFrameCounter + 1;
931
932        ATRACE_INT(mCore->mConsumerName.string(),
933                static_cast<int32_t>(mCore->mQueue.size()));
934        mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size());
935
936        // Take a ticket for the callback functions
937        callbackTicket = mNextCallbackTicket++;
938
939        VALIDATE_CONSISTENCY();
940    } // Autolock scope
941
942    // It is okay not to clear the GraphicBuffer when the consumer is SurfaceFlinger because
943    // it is guaranteed that the BufferQueue is inside SurfaceFlinger's process and
944    // there will be no Binder call
945    if (!mConsumerIsSurfaceFlinger) {
946        item.mGraphicBuffer.clear();
947    }
948
949    // Don't send the slot number through the callback since the consumer shouldn't need it
950    item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
951
952    // Call back without the main BufferQueue lock held, but with the callback
953    // lock held so we can ensure that callbacks occur in order
954    {
955        Mutex::Autolock lock(mCallbackMutex);
956        while (callbackTicket != mCurrentCallbackTicket) {
957            mCallbackCondition.wait(mCallbackMutex);
958        }
959
960        if (frameAvailableListener != NULL) {
961            frameAvailableListener->onFrameAvailable(item);
962        } else if (frameReplacedListener != NULL) {
963            frameReplacedListener->onFrameReplaced(item);
964        }
965
966        ++mCurrentCallbackTicket;
967        mCallbackCondition.broadcast();
968    }
969
970    // Wait without lock held
971    if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
972        // Waiting here allows for two full buffers to be queued but not a
973        // third. In the event that frames take varying time, this makes a
974        // small trade-off in favor of latency rather than throughput.
975        mLastQueueBufferFence->waitForever("Throttling EGL Production");
976    }
977    mLastQueueBufferFence = std::move(acquireFence);
978    mLastQueuedCrop = item.mCrop;
979    mLastQueuedTransform = item.mTransform;
980
981    // Update and get FrameEventHistory.
982    nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC);
983    NewFrameEventsEntry newFrameEventsEntry = {
984        currentFrameNumber,
985        postedTime,
986        requestedPresentTimestamp,
987        std::move(acquireFenceTime)
988    };
989    addAndGetFrameTimestamps(&newFrameEventsEntry,
990            getFrameTimestamps ? &output->frameTimestamps : nullptr);
991
992    return NO_ERROR;
993}
994
995status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
996    ATRACE_CALL();
997    BQ_LOGV("cancelBuffer: slot %d", slot);
998    Mutex::Autolock lock(mCore->mMutex);
999
1000    if (mCore->mIsAbandoned) {
1001        BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
1002        return NO_INIT;
1003    }
1004
1005    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
1006        BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
1007        return NO_INIT;
1008    }
1009
1010    if (mCore->mSharedBufferMode) {
1011        BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
1012        return BAD_VALUE;
1013    }
1014
1015    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
1016        BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
1017                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
1018        return BAD_VALUE;
1019    } else if (!mSlots[slot].mBufferState.isDequeued()) {
1020        BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
1021                "(state = %s)", slot, mSlots[slot].mBufferState.string());
1022        return BAD_VALUE;
1023    } else if (fence == NULL) {
1024        BQ_LOGE("cancelBuffer: fence is NULL");
1025        return BAD_VALUE;
1026    }
1027
1028    mSlots[slot].mBufferState.cancel();
1029
1030    // After leaving shared buffer mode, the shared buffer will still be around.
1031    // Mark it as no longer shared if this operation causes it to be free.
1032    if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
1033        mSlots[slot].mBufferState.mShared = false;
1034    }
1035
1036    // Don't put the shared buffer on the free list.
1037    if (!mSlots[slot].mBufferState.isShared()) {
1038        mCore->mActiveBuffers.erase(slot);
1039        mCore->mFreeBuffers.push_back(slot);
1040    }
1041
1042    mSlots[slot].mFence = fence;
1043    mCore->mDequeueCondition.broadcast();
1044    VALIDATE_CONSISTENCY();
1045
1046    return NO_ERROR;
1047}
1048
1049int BufferQueueProducer::query(int what, int *outValue) {
1050    ATRACE_CALL();
1051    Mutex::Autolock lock(mCore->mMutex);
1052
1053    if (outValue == NULL) {
1054        BQ_LOGE("query: outValue was NULL");
1055        return BAD_VALUE;
1056    }
1057
1058    if (mCore->mIsAbandoned) {
1059        BQ_LOGE("query: BufferQueue has been abandoned");
1060        return NO_INIT;
1061    }
1062
1063    int value;
1064    switch (what) {
1065        case NATIVE_WINDOW_WIDTH:
1066            value = static_cast<int32_t>(mCore->mDefaultWidth);
1067            break;
1068        case NATIVE_WINDOW_HEIGHT:
1069            value = static_cast<int32_t>(mCore->mDefaultHeight);
1070            break;
1071        case NATIVE_WINDOW_FORMAT:
1072            value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
1073            break;
1074        case NATIVE_WINDOW_LAYER_COUNT:
1075            // All BufferQueue buffers have a single layer.
1076            value = BQ_LAYER_COUNT;
1077            break;
1078        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1079            value = mCore->getMinUndequeuedBufferCountLocked();
1080            break;
1081        case NATIVE_WINDOW_STICKY_TRANSFORM:
1082            value = static_cast<int32_t>(mStickyTransform);
1083            break;
1084        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
1085            value = (mCore->mQueue.size() > 1);
1086            break;
1087        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
1088            value = static_cast<int32_t>(mCore->mConsumerUsageBits);
1089            break;
1090        case NATIVE_WINDOW_DEFAULT_DATASPACE:
1091            value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
1092            break;
1093        case NATIVE_WINDOW_BUFFER_AGE:
1094            if (mCore->mBufferAge > INT32_MAX) {
1095                value = 0;
1096            } else {
1097                value = static_cast<int32_t>(mCore->mBufferAge);
1098            }
1099            break;
1100        default:
1101            return BAD_VALUE;
1102    }
1103
1104    BQ_LOGV("query: %d? %d", what, value);
1105    *outValue = value;
1106    return NO_ERROR;
1107}
1108
1109status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
1110        int api, bool producerControlledByApp, QueueBufferOutput *output) {
1111    ATRACE_CALL();
1112    Mutex::Autolock lock(mCore->mMutex);
1113    mConsumerName = mCore->mConsumerName;
1114    BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
1115            producerControlledByApp ? "true" : "false");
1116
1117    if (mCore->mIsAbandoned) {
1118        BQ_LOGE("connect: BufferQueue has been abandoned");
1119        return NO_INIT;
1120    }
1121
1122    if (mCore->mConsumerListener == NULL) {
1123        BQ_LOGE("connect: BufferQueue has no consumer");
1124        return NO_INIT;
1125    }
1126
1127    if (output == NULL) {
1128        BQ_LOGE("connect: output was NULL");
1129        return BAD_VALUE;
1130    }
1131
1132    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1133        BQ_LOGE("connect: already connected (cur=%d req=%d)",
1134                mCore->mConnectedApi, api);
1135        return BAD_VALUE;
1136    }
1137
1138    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
1139            mDequeueTimeout < 0 ?
1140            mCore->mConsumerControlledByApp && producerControlledByApp : false,
1141            mCore->mMaxBufferCount) -
1142            mCore->getMaxBufferCountLocked();
1143    if (!mCore->adjustAvailableSlotsLocked(delta)) {
1144        BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
1145                "slots. Delta = %d", delta);
1146        return BAD_VALUE;
1147    }
1148
1149    int status = NO_ERROR;
1150    switch (api) {
1151        case NATIVE_WINDOW_API_EGL:
1152        case NATIVE_WINDOW_API_CPU:
1153        case NATIVE_WINDOW_API_MEDIA:
1154        case NATIVE_WINDOW_API_CAMERA:
1155            mCore->mConnectedApi = api;
1156
1157            output->width = mCore->mDefaultWidth;
1158            output->height = mCore->mDefaultHeight;
1159            output->transformHint = mCore->mTransformHint;
1160            output->numPendingBuffers =
1161                    static_cast<uint32_t>(mCore->mQueue.size());
1162            output->nextFrameNumber = mCore->mFrameCounter + 1;
1163            output->bufferReplaced = false;
1164
1165            if (listener != NULL) {
1166                // Set up a death notification so that we can disconnect
1167                // automatically if the remote producer dies
1168                if (IInterface::asBinder(listener)->remoteBinder() != NULL) {
1169                    status = IInterface::asBinder(listener)->linkToDeath(
1170                            static_cast<IBinder::DeathRecipient*>(this));
1171                    if (status != NO_ERROR) {
1172                        BQ_LOGE("connect: linkToDeath failed: %s (%d)",
1173                                strerror(-status), status);
1174                    }
1175                    mCore->mLinkedToDeath = listener;
1176                }
1177                if (listener->needsReleaseNotify()) {
1178                    mCore->mConnectedProducerListener = listener;
1179                }
1180            }
1181            break;
1182        default:
1183            BQ_LOGE("connect: unknown API %d", api);
1184            status = BAD_VALUE;
1185            break;
1186    }
1187    mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
1188    mCore->mBufferHasBeenQueued = false;
1189    mCore->mDequeueBufferCannotBlock = false;
1190    if (mDequeueTimeout < 0) {
1191        mCore->mDequeueBufferCannotBlock =
1192                mCore->mConsumerControlledByApp && producerControlledByApp;
1193    }
1194
1195    mCore->mAllowAllocation = true;
1196    VALIDATE_CONSISTENCY();
1197    return status;
1198}
1199
1200status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
1201    ATRACE_CALL();
1202    BQ_LOGV("disconnect: api %d", api);
1203
1204    int status = NO_ERROR;
1205    sp<IConsumerListener> listener;
1206    { // Autolock scope
1207        Mutex::Autolock lock(mCore->mMutex);
1208
1209        if (mode == DisconnectMode::AllLocal) {
1210            if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) {
1211                return NO_ERROR;
1212            }
1213            api = BufferQueueCore::CURRENTLY_CONNECTED_API;
1214        }
1215
1216        mCore->waitWhileAllocatingLocked();
1217
1218        if (mCore->mIsAbandoned) {
1219            // It's not really an error to disconnect after the surface has
1220            // been abandoned; it should just be a no-op.
1221            return NO_ERROR;
1222        }
1223
1224        if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
1225            if (mCore->mConnectedApi == NATIVE_WINDOW_API_MEDIA) {
1226                ALOGD("About to force-disconnect API_MEDIA, mode=%d", mode);
1227            }
1228            api = mCore->mConnectedApi;
1229            // If we're asked to disconnect the currently connected api but
1230            // nobody is connected, it's not really an error.
1231            if (api == BufferQueueCore::NO_CONNECTED_API) {
1232                return NO_ERROR;
1233            }
1234        }
1235
1236        switch (api) {
1237            case NATIVE_WINDOW_API_EGL:
1238            case NATIVE_WINDOW_API_CPU:
1239            case NATIVE_WINDOW_API_MEDIA:
1240            case NATIVE_WINDOW_API_CAMERA:
1241                if (mCore->mConnectedApi == api) {
1242                    mCore->freeAllBuffersLocked();
1243
1244                    // Remove our death notification callback if we have one
1245                    if (mCore->mLinkedToDeath != NULL) {
1246                        sp<IBinder> token =
1247                                IInterface::asBinder(mCore->mLinkedToDeath);
1248                        // This can fail if we're here because of the death
1249                        // notification, but we just ignore it
1250                        token->unlinkToDeath(
1251                                static_cast<IBinder::DeathRecipient*>(this));
1252                    }
1253                    mCore->mSharedBufferSlot =
1254                            BufferQueueCore::INVALID_BUFFER_SLOT;
1255                    mCore->mLinkedToDeath = NULL;
1256                    mCore->mConnectedProducerListener = NULL;
1257                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
1258                    mCore->mConnectedPid = -1;
1259                    mCore->mSidebandStream.clear();
1260                    mCore->mDequeueCondition.broadcast();
1261                    listener = mCore->mConsumerListener;
1262                } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
1263                    BQ_LOGE("disconnect: still connected to another API "
1264                            "(cur=%d req=%d)", mCore->mConnectedApi, api);
1265                    status = BAD_VALUE;
1266                }
1267                break;
1268            default:
1269                BQ_LOGE("disconnect: unknown API %d", api);
1270                status = BAD_VALUE;
1271                break;
1272        }
1273    } // Autolock scope
1274
1275    // Call back without lock held
1276    if (listener != NULL) {
1277        listener->onBuffersReleased();
1278        listener->onDisconnect();
1279    }
1280
1281    return status;
1282}
1283
1284status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
1285    sp<IConsumerListener> listener;
1286    { // Autolock scope
1287        Mutex::Autolock _l(mCore->mMutex);
1288        mCore->mSidebandStream = stream;
1289        listener = mCore->mConsumerListener;
1290    } // Autolock scope
1291
1292    if (listener != NULL) {
1293        listener->onSidebandStreamChanged();
1294    }
1295    return NO_ERROR;
1296}
1297
1298void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
1299        PixelFormat format, uint32_t usage) {
1300    ATRACE_CALL();
1301    while (true) {
1302        size_t newBufferCount = 0;
1303        uint32_t allocWidth = 0;
1304        uint32_t allocHeight = 0;
1305        PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
1306        uint32_t allocUsage = 0;
1307        { // Autolock scope
1308            Mutex::Autolock lock(mCore->mMutex);
1309            mCore->waitWhileAllocatingLocked();
1310
1311            if (!mCore->mAllowAllocation) {
1312                BQ_LOGE("allocateBuffers: allocation is not allowed for this "
1313                        "BufferQueue");
1314                return;
1315            }
1316
1317            newBufferCount = mCore->mFreeSlots.size();
1318            if (newBufferCount == 0) {
1319                return;
1320            }
1321
1322            allocWidth = width > 0 ? width : mCore->mDefaultWidth;
1323            allocHeight = height > 0 ? height : mCore->mDefaultHeight;
1324            allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
1325            allocUsage = usage | mCore->mConsumerUsageBits;
1326
1327            mCore->mIsAllocating = true;
1328        } // Autolock scope
1329
1330        Vector<sp<GraphicBuffer>> buffers;
1331        for (size_t i = 0; i <  newBufferCount; ++i) {
1332            status_t result = NO_ERROR;
1333            sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
1334                    allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,
1335                    allocUsage, {mConsumerName.string(), mConsumerName.size()},
1336                    &result));
1337            if (result != NO_ERROR) {
1338                BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
1339                        " %u, usage %u)", width, height, format, usage);
1340                Mutex::Autolock lock(mCore->mMutex);
1341                mCore->mIsAllocating = false;
1342                mCore->mIsAllocatingCondition.broadcast();
1343                return;
1344            }
1345            buffers.push_back(graphicBuffer);
1346        }
1347
1348        { // Autolock scope
1349            Mutex::Autolock lock(mCore->mMutex);
1350            uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
1351            uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
1352            PixelFormat checkFormat = format != 0 ?
1353                    format : mCore->mDefaultBufferFormat;
1354            uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
1355            if (checkWidth != allocWidth || checkHeight != allocHeight ||
1356                checkFormat != allocFormat || checkUsage != allocUsage) {
1357                // Something changed while we released the lock. Retry.
1358                BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
1359                mCore->mIsAllocating = false;
1360                mCore->mIsAllocatingCondition.broadcast();
1361                continue;
1362            }
1363
1364            for (size_t i = 0; i < newBufferCount; ++i) {
1365                if (mCore->mFreeSlots.empty()) {
1366                    BQ_LOGV("allocateBuffers: a slot was occupied while "
1367                            "allocating. Dropping allocated buffer.");
1368                    continue;
1369                }
1370                auto slot = mCore->mFreeSlots.begin();
1371                mCore->clearBufferSlotLocked(*slot); // Clean up the slot first
1372                mSlots[*slot].mGraphicBuffer = buffers[i];
1373                mSlots[*slot].mFence = Fence::NO_FENCE;
1374
1375                // freeBufferLocked puts this slot on the free slots list. Since
1376                // we then attached a buffer, move the slot to free buffer list.
1377                mCore->mFreeBuffers.push_front(*slot);
1378
1379                BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d",
1380                        *slot);
1381
1382                // Make sure the erase is done after all uses of the slot
1383                // iterator since it will be invalid after this point.
1384                mCore->mFreeSlots.erase(slot);
1385            }
1386
1387            mCore->mIsAllocating = false;
1388            mCore->mIsAllocatingCondition.broadcast();
1389            VALIDATE_CONSISTENCY();
1390        } // Autolock scope
1391    }
1392}
1393
1394status_t BufferQueueProducer::allowAllocation(bool allow) {
1395    ATRACE_CALL();
1396    BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
1397
1398    Mutex::Autolock lock(mCore->mMutex);
1399    mCore->mAllowAllocation = allow;
1400    return NO_ERROR;
1401}
1402
1403status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
1404    ATRACE_CALL();
1405    BQ_LOGV("setGenerationNumber: %u", generationNumber);
1406
1407    Mutex::Autolock lock(mCore->mMutex);
1408    mCore->mGenerationNumber = generationNumber;
1409    return NO_ERROR;
1410}
1411
1412String8 BufferQueueProducer::getConsumerName() const {
1413    ATRACE_CALL();
1414    Mutex::Autolock lock(mCore->mMutex);
1415    BQ_LOGV("getConsumerName: %s", mConsumerName.string());
1416    return mConsumerName;
1417}
1418
1419status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
1420    ATRACE_CALL();
1421    BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
1422
1423    Mutex::Autolock lock(mCore->mMutex);
1424    if (!sharedBufferMode) {
1425        mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
1426    }
1427    mCore->mSharedBufferMode = sharedBufferMode;
1428    return NO_ERROR;
1429}
1430
1431status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
1432    ATRACE_CALL();
1433    BQ_LOGV("setAutoRefresh: %d", autoRefresh);
1434
1435    Mutex::Autolock lock(mCore->mMutex);
1436
1437    mCore->mAutoRefresh = autoRefresh;
1438    return NO_ERROR;
1439}
1440
1441status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
1442    ATRACE_CALL();
1443    BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
1444
1445    Mutex::Autolock lock(mCore->mMutex);
1446    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
1447            mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
1448    if (!mCore->adjustAvailableSlotsLocked(delta)) {
1449        BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
1450                "available slots. Delta = %d", delta);
1451        return BAD_VALUE;
1452    }
1453
1454    mDequeueTimeout = timeout;
1455    mCore->mDequeueBufferCannotBlock = false;
1456
1457    VALIDATE_CONSISTENCY();
1458    return NO_ERROR;
1459}
1460
1461status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
1462        sp<Fence>* outFence, float outTransformMatrix[16]) {
1463    ATRACE_CALL();
1464    BQ_LOGV("getLastQueuedBuffer");
1465
1466    Mutex::Autolock lock(mCore->mMutex);
1467    if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
1468        *outBuffer = nullptr;
1469        *outFence = Fence::NO_FENCE;
1470        return NO_ERROR;
1471    }
1472
1473    *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer;
1474    *outFence = mLastQueueBufferFence;
1475
1476    // Currently only SurfaceFlinger internally ever changes
1477    // GLConsumer's filtering mode, so we just use 'true' here as
1478    // this is slightly specialized for the current client of this API,
1479    // which does want filtering.
1480    GLConsumer::computeTransformMatrix(outTransformMatrix,
1481            mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop,
1482            mLastQueuedTransform, true /* filter */);
1483
1484    return NO_ERROR;
1485}
1486
1487void BufferQueueProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
1488    addAndGetFrameTimestamps(nullptr, outDelta);
1489}
1490
1491void BufferQueueProducer::addAndGetFrameTimestamps(
1492        const NewFrameEventsEntry* newTimestamps,
1493        FrameEventHistoryDelta* outDelta) {
1494    if (newTimestamps == nullptr && outDelta == nullptr) {
1495        return;
1496    }
1497
1498    ATRACE_CALL();
1499    BQ_LOGV("addAndGetFrameTimestamps");
1500    sp<IConsumerListener> listener;
1501    {
1502        Mutex::Autolock lock(mCore->mMutex);
1503        listener = mCore->mConsumerListener;
1504    }
1505    if (listener != NULL) {
1506        listener->addAndGetFrameTimestamps(newTimestamps, outDelta);
1507    }
1508}
1509
1510void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
1511    // If we're here, it means that a producer we were connected to died.
1512    // We're guaranteed that we are still connected to it because we remove
1513    // this callback upon disconnect. It's therefore safe to read mConnectedApi
1514    // without synchronization here.
1515    int api = mCore->mConnectedApi;
1516    disconnect(api);
1517}
1518
1519status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
1520    BQ_LOGV("getUniqueId");
1521
1522    *outId = mCore->mUniqueId;
1523    return NO_ERROR;
1524}
1525
1526} // namespace android
1527