Home | History | Annotate | Download | only in gui
      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 #define EGL_EGLEXT_PROTOTYPES
     24 
     25 #include <gui/BufferItem.h>
     26 #include <gui/BufferQueueCore.h>
     27 #include <gui/BufferQueueProducer.h>
     28 #include <gui/IConsumerListener.h>
     29 #include <gui/IGraphicBufferAlloc.h>
     30 #include <gui/IProducerListener.h>
     31 
     32 #include <utils/Log.h>
     33 #include <utils/Trace.h>
     34 
     35 namespace android {
     36 
     37 BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
     38     mCore(core),
     39     mSlots(core->mSlots),
     40     mConsumerName(),
     41     mStickyTransform(0),
     42     mLastQueueBufferFence(Fence::NO_FENCE),
     43     mCallbackMutex(),
     44     mNextCallbackTicket(0),
     45     mCurrentCallbackTicket(0),
     46     mCallbackCondition() {}
     47 
     48 BufferQueueProducer::~BufferQueueProducer() {}
     49 
     50 status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
     51     ATRACE_CALL();
     52     BQ_LOGV("requestBuffer: slot %d", slot);
     53     Mutex::Autolock lock(mCore->mMutex);
     54 
     55     if (mCore->mIsAbandoned) {
     56         BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
     57         return NO_INIT;
     58     }
     59 
     60     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
     61         BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
     62                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
     63         return BAD_VALUE;
     64     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
     65         BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
     66                 "(state = %d)", slot, mSlots[slot].mBufferState);
     67         return BAD_VALUE;
     68     }
     69 
     70     mSlots[slot].mRequestBufferCalled = true;
     71     *buf = mSlots[slot].mGraphicBuffer;
     72     return NO_ERROR;
     73 }
     74 
     75 status_t BufferQueueProducer::setBufferCount(int bufferCount) {
     76     ATRACE_CALL();
     77     BQ_LOGV("setBufferCount: count = %d", bufferCount);
     78 
     79     sp<IConsumerListener> listener;
     80     { // Autolock scope
     81         Mutex::Autolock lock(mCore->mMutex);
     82         mCore->waitWhileAllocatingLocked();
     83 
     84         if (mCore->mIsAbandoned) {
     85             BQ_LOGE("setBufferCount: BufferQueue has been abandoned");
     86             return NO_INIT;
     87         }
     88 
     89         if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
     90             BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)",
     91                     bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
     92             return BAD_VALUE;
     93         }
     94 
     95         // There must be no dequeued buffers when changing the buffer count.
     96         for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
     97             if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) {
     98                 BQ_LOGE("setBufferCount: buffer owned by producer");
     99                 return BAD_VALUE;
    100             }
    101         }
    102 
    103         if (bufferCount == 0) {
    104             mCore->mOverrideMaxBufferCount = 0;
    105             mCore->mDequeueCondition.broadcast();
    106             return NO_ERROR;
    107         }
    108 
    109         const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false);
    110         if (bufferCount < minBufferSlots) {
    111             BQ_LOGE("setBufferCount: requested buffer count %d is less than "
    112                     "minimum %d", bufferCount, minBufferSlots);
    113             return BAD_VALUE;
    114         }
    115 
    116         // Here we are guaranteed that the producer doesn't have any dequeued
    117         // buffers and will release all of its buffer references. We don't
    118         // clear the queue, however, so that currently queued buffers still
    119         // get displayed.
    120         mCore->freeAllBuffersLocked();
    121         mCore->mOverrideMaxBufferCount = bufferCount;
    122         mCore->mDequeueCondition.broadcast();
    123         listener = mCore->mConsumerListener;
    124     } // Autolock scope
    125 
    126     // Call back without lock held
    127     if (listener != NULL) {
    128         listener->onBuffersReleased();
    129     }
    130 
    131     return NO_ERROR;
    132 }
    133 
    134 status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
    135         bool async, int* found, status_t* returnFlags) const {
    136     bool tryAgain = true;
    137     while (tryAgain) {
    138         if (mCore->mIsAbandoned) {
    139             BQ_LOGE("%s: BufferQueue has been abandoned", caller);
    140             return NO_INIT;
    141         }
    142 
    143         const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
    144         if (async && mCore->mOverrideMaxBufferCount) {
    145             // FIXME: Some drivers are manually setting the buffer count
    146             // (which they shouldn't), so we do this extra test here to
    147             // handle that case. This is TEMPORARY until we get this fixed.
    148             if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
    149                 BQ_LOGE("%s: async mode is invalid with buffer count override",
    150                         caller);
    151                 return BAD_VALUE;
    152             }
    153         }
    154 
    155         // Free up any buffers that are in slots beyond the max buffer count
    156         for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
    157             assert(mSlots[s].mBufferState == BufferSlot::FREE);
    158             if (mSlots[s].mGraphicBuffer != NULL) {
    159                 mCore->freeBufferLocked(s);
    160                 *returnFlags |= RELEASE_ALL_BUFFERS;
    161             }
    162         }
    163 
    164         // Look for a free buffer to give to the client
    165         *found = BufferQueueCore::INVALID_BUFFER_SLOT;
    166         int dequeuedCount = 0;
    167         int acquiredCount = 0;
    168         for (int s = 0; s < maxBufferCount; ++s) {
    169             switch (mSlots[s].mBufferState) {
    170                 case BufferSlot::DEQUEUED:
    171                     ++dequeuedCount;
    172                     break;
    173                 case BufferSlot::ACQUIRED:
    174                     ++acquiredCount;
    175                     break;
    176                 case BufferSlot::FREE:
    177                     // We return the oldest of the free buffers to avoid
    178                     // stalling the producer if possible, since the consumer
    179                     // may still have pending reads of in-flight buffers
    180                     if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||
    181                             mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {
    182                         *found = s;
    183                     }
    184                     break;
    185                 default:
    186                     break;
    187             }
    188         }
    189 
    190         // Producers are not allowed to dequeue more than one buffer if they
    191         // did not set a buffer count
    192         if (!mCore->mOverrideMaxBufferCount && dequeuedCount) {
    193             BQ_LOGE("%s: can't dequeue multiple buffers without setting the "
    194                     "buffer count", caller);
    195             return INVALID_OPERATION;
    196         }
    197 
    198         // See whether a buffer has been queued since the last
    199         // setBufferCount so we know whether to perform the min undequeued
    200         // buffers check below
    201         if (mCore->mBufferHasBeenQueued) {
    202             // Make sure the producer is not trying to dequeue more buffers
    203             // than allowed
    204             const int newUndequeuedCount =
    205                 maxBufferCount - (dequeuedCount + 1);
    206             const int minUndequeuedCount =
    207                 mCore->getMinUndequeuedBufferCountLocked(async);
    208             if (newUndequeuedCount < minUndequeuedCount) {
    209                 BQ_LOGE("%s: min undequeued buffer count (%d) exceeded "
    210                         "(dequeued=%d undequeued=%d)",
    211                         caller, minUndequeuedCount,
    212                         dequeuedCount, newUndequeuedCount);
    213                 return INVALID_OPERATION;
    214             }
    215         }
    216 
    217         // If we disconnect and reconnect quickly, we can be in a state where
    218         // our slots are empty but we have many buffers in the queue. This can
    219         // cause us to run out of memory if we outrun the consumer. Wait here if
    220         // it looks like we have too many buffers queued up.
    221         bool tooManyBuffers = mCore->mQueue.size()
    222                             > static_cast<size_t>(maxBufferCount);
    223         if (tooManyBuffers) {
    224             BQ_LOGV("%s: queue size is %zu, waiting", caller,
    225                     mCore->mQueue.size());
    226         }
    227 
    228         // If no buffer is found, or if the queue has too many buffers
    229         // outstanding, wait for a buffer to be acquired or released, or for the
    230         // max buffer count to change.
    231         tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
    232                    tooManyBuffers;
    233         if (tryAgain) {
    234             // Return an error if we're in non-blocking mode (producer and
    235             // consumer are controlled by the application).
    236             // However, the consumer is allowed to briefly acquire an extra
    237             // buffer (which could cause us to have to wait here), which is
    238             // okay, since it is only used to implement an atomic acquire +
    239             // release (e.g., in GLConsumer::updateTexImage())
    240             if (mCore->mDequeueBufferCannotBlock &&
    241                     (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
    242                 return WOULD_BLOCK;
    243             }
    244             mCore->mDequeueCondition.wait(mCore->mMutex);
    245         }
    246     } // while (tryAgain)
    247 
    248     return NO_ERROR;
    249 }
    250 
    251 status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
    252         sp<android::Fence> *outFence, bool async,
    253         uint32_t width, uint32_t height, uint32_t format, uint32_t usage) {
    254     ATRACE_CALL();
    255     { // Autolock scope
    256         Mutex::Autolock lock(mCore->mMutex);
    257         mConsumerName = mCore->mConsumerName;
    258     } // Autolock scope
    259 
    260     BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x",
    261             async ? "true" : "false", width, height, format, usage);
    262 
    263     if ((width && !height) || (!width && height)) {
    264         BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
    265         return BAD_VALUE;
    266     }
    267 
    268     status_t returnFlags = NO_ERROR;
    269     EGLDisplay eglDisplay = EGL_NO_DISPLAY;
    270     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    271     bool attachedByConsumer = false;
    272 
    273     { // Autolock scope
    274         Mutex::Autolock lock(mCore->mMutex);
    275         mCore->waitWhileAllocatingLocked();
    276 
    277         if (format == 0) {
    278             format = mCore->mDefaultBufferFormat;
    279         }
    280 
    281         // Enable the usage bits the consumer requested
    282         usage |= mCore->mConsumerUsageBits;
    283 
    284         int found;
    285         status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
    286                 &found, &returnFlags);
    287         if (status != NO_ERROR) {
    288             return status;
    289         }
    290 
    291         // This should not happen
    292         if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    293             BQ_LOGE("dequeueBuffer: no available buffer slots");
    294             return -EBUSY;
    295         }
    296 
    297         *outSlot = found;
    298         ATRACE_BUFFER_INDEX(found);
    299 
    300         attachedByConsumer = mSlots[found].mAttachedByConsumer;
    301 
    302         const bool useDefaultSize = !width && !height;
    303         if (useDefaultSize) {
    304             width = mCore->mDefaultWidth;
    305             height = mCore->mDefaultHeight;
    306         }
    307 
    308         mSlots[found].mBufferState = BufferSlot::DEQUEUED;
    309 
    310         const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
    311         if ((buffer == NULL) ||
    312                 (static_cast<uint32_t>(buffer->width) != width) ||
    313                 (static_cast<uint32_t>(buffer->height) != height) ||
    314                 (static_cast<uint32_t>(buffer->format) != format) ||
    315                 ((static_cast<uint32_t>(buffer->usage) & usage) != usage))
    316         {
    317             mSlots[found].mAcquireCalled = false;
    318             mSlots[found].mGraphicBuffer = NULL;
    319             mSlots[found].mRequestBufferCalled = false;
    320             mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
    321             mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
    322             mSlots[found].mFence = Fence::NO_FENCE;
    323 
    324             returnFlags |= BUFFER_NEEDS_REALLOCATION;
    325         }
    326 
    327         if (CC_UNLIKELY(mSlots[found].mFence == NULL)) {
    328             BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
    329                     "slot=%d w=%d h=%d format=%u",
    330                     found, buffer->width, buffer->height, buffer->format);
    331         }
    332 
    333         eglDisplay = mSlots[found].mEglDisplay;
    334         eglFence = mSlots[found].mEglFence;
    335         *outFence = mSlots[found].mFence;
    336         mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
    337         mSlots[found].mFence = Fence::NO_FENCE;
    338     } // Autolock scope
    339 
    340     if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
    341         status_t error;
    342         BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
    343         sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
    344                     width, height, format, usage, &error));
    345         if (graphicBuffer == NULL) {
    346             BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
    347             return error;
    348         }
    349 
    350         { // Autolock scope
    351             Mutex::Autolock lock(mCore->mMutex);
    352 
    353             if (mCore->mIsAbandoned) {
    354                 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
    355                 return NO_INIT;
    356             }
    357 
    358             mSlots[*outSlot].mFrameNumber = UINT32_MAX;
    359             mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
    360         } // Autolock scope
    361     }
    362 
    363     if (attachedByConsumer) {
    364         returnFlags |= BUFFER_NEEDS_REALLOCATION;
    365     }
    366 
    367     if (eglFence != EGL_NO_SYNC_KHR) {
    368         EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
    369                 1000000000);
    370         // If something goes wrong, log the error, but return the buffer without
    371         // synchronizing access to it. It's too late at this point to abort the
    372         // dequeue operation.
    373         if (result == EGL_FALSE) {
    374             BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
    375                     eglGetError());
    376         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
    377             BQ_LOGE("dequeueBuffer: timeout waiting for fence");
    378         }
    379         eglDestroySyncKHR(eglDisplay, eglFence);
    380     }
    381 
    382     BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
    383             *outSlot,
    384             mSlots[*outSlot].mFrameNumber,
    385             mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
    386 
    387     return returnFlags;
    388 }
    389 
    390 status_t BufferQueueProducer::detachBuffer(int slot) {
    391     ATRACE_CALL();
    392     ATRACE_BUFFER_INDEX(slot);
    393     BQ_LOGV("detachBuffer(P): slot %d", slot);
    394     Mutex::Autolock lock(mCore->mMutex);
    395 
    396     if (mCore->mIsAbandoned) {
    397         BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned");
    398         return NO_INIT;
    399     }
    400 
    401     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    402         BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)",
    403                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    404         return BAD_VALUE;
    405     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
    406         BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer "
    407                 "(state = %d)", slot, mSlots[slot].mBufferState);
    408         return BAD_VALUE;
    409     } else if (!mSlots[slot].mRequestBufferCalled) {
    410         BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested",
    411                 slot);
    412         return BAD_VALUE;
    413     }
    414 
    415     mCore->freeBufferLocked(slot);
    416     mCore->mDequeueCondition.broadcast();
    417 
    418     return NO_ERROR;
    419 }
    420 
    421 status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
    422         sp<Fence>* outFence) {
    423     ATRACE_CALL();
    424 
    425     if (outBuffer == NULL) {
    426         BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
    427         return BAD_VALUE;
    428     } else if (outFence == NULL) {
    429         BQ_LOGE("detachNextBuffer: outFence must not be NULL");
    430         return BAD_VALUE;
    431     }
    432 
    433     Mutex::Autolock lock(mCore->mMutex);
    434     mCore->waitWhileAllocatingLocked();
    435 
    436     if (mCore->mIsAbandoned) {
    437         BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
    438         return NO_INIT;
    439     }
    440 
    441     // Find the oldest valid slot
    442     int found = BufferQueueCore::INVALID_BUFFER_SLOT;
    443     for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
    444         if (mSlots[s].mBufferState == BufferSlot::FREE &&
    445                 mSlots[s].mGraphicBuffer != NULL) {
    446             if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
    447                     mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
    448                 found = s;
    449             }
    450         }
    451     }
    452 
    453     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    454         return NO_MEMORY;
    455     }
    456 
    457     BQ_LOGV("detachNextBuffer detached slot %d", found);
    458 
    459     *outBuffer = mSlots[found].mGraphicBuffer;
    460     *outFence = mSlots[found].mFence;
    461     mCore->freeBufferLocked(found);
    462 
    463     return NO_ERROR;
    464 }
    465 
    466 status_t BufferQueueProducer::attachBuffer(int* outSlot,
    467         const sp<android::GraphicBuffer>& buffer) {
    468     ATRACE_CALL();
    469 
    470     if (outSlot == NULL) {
    471         BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
    472         return BAD_VALUE;
    473     } else if (buffer == NULL) {
    474         BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
    475         return BAD_VALUE;
    476     }
    477 
    478     Mutex::Autolock lock(mCore->mMutex);
    479     mCore->waitWhileAllocatingLocked();
    480 
    481     status_t returnFlags = NO_ERROR;
    482     int found;
    483     // TODO: Should we provide an async flag to attachBuffer? It seems
    484     // unlikely that buffers which we are attaching to a BufferQueue will
    485     // be asynchronous (droppable), but it may not be impossible.
    486     status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false,
    487             &found, &returnFlags);
    488     if (status != NO_ERROR) {
    489         return status;
    490     }
    491 
    492     // This should not happen
    493     if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    494         BQ_LOGE("attachBuffer(P): no available buffer slots");
    495         return -EBUSY;
    496     }
    497 
    498     *outSlot = found;
    499     ATRACE_BUFFER_INDEX(*outSlot);
    500     BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x",
    501             *outSlot, returnFlags);
    502 
    503     mSlots[*outSlot].mGraphicBuffer = buffer;
    504     mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED;
    505     mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
    506     mSlots[*outSlot].mFence = Fence::NO_FENCE;
    507     mSlots[*outSlot].mRequestBufferCalled = true;
    508 
    509     return returnFlags;
    510 }
    511 
    512 status_t BufferQueueProducer::queueBuffer(int slot,
    513         const QueueBufferInput &input, QueueBufferOutput *output) {
    514     ATRACE_CALL();
    515     ATRACE_BUFFER_INDEX(slot);
    516 
    517     int64_t timestamp;
    518     bool isAutoTimestamp;
    519     Rect crop;
    520     int scalingMode;
    521     uint32_t transform;
    522     uint32_t stickyTransform;
    523     bool async;
    524     sp<Fence> fence;
    525     input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
    526             &async, &fence, &stickyTransform);
    527 
    528     if (fence == NULL) {
    529         BQ_LOGE("queueBuffer: fence is NULL");
    530         return BAD_VALUE;
    531     }
    532 
    533     switch (scalingMode) {
    534         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
    535         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
    536         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
    537         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
    538             break;
    539         default:
    540             BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode);
    541             return BAD_VALUE;
    542     }
    543 
    544     sp<IConsumerListener> frameAvailableListener;
    545     sp<IConsumerListener> frameReplacedListener;
    546     int callbackTicket = 0;
    547     BufferItem item;
    548     { // Autolock scope
    549         Mutex::Autolock lock(mCore->mMutex);
    550 
    551         if (mCore->mIsAbandoned) {
    552             BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
    553             return NO_INIT;
    554         }
    555 
    556         const int maxBufferCount = mCore->getMaxBufferCountLocked(async);
    557         if (async && mCore->mOverrideMaxBufferCount) {
    558             // FIXME: Some drivers are manually setting the buffer count
    559             // (which they shouldn't), so we do this extra test here to
    560             // handle that case. This is TEMPORARY until we get this fixed.
    561             if (mCore->mOverrideMaxBufferCount < maxBufferCount) {
    562                 BQ_LOGE("queueBuffer: async mode is invalid with "
    563                         "buffer count override");
    564                 return BAD_VALUE;
    565             }
    566         }
    567 
    568         if (slot < 0 || slot >= maxBufferCount) {
    569             BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
    570                     slot, maxBufferCount);
    571             return BAD_VALUE;
    572         } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
    573             BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
    574                     "(state = %d)", slot, mSlots[slot].mBufferState);
    575             return BAD_VALUE;
    576         } else if (!mSlots[slot].mRequestBufferCalled) {
    577             BQ_LOGE("queueBuffer: slot %d was queued without requesting "
    578                     "a buffer", slot);
    579             return BAD_VALUE;
    580         }
    581 
    582         BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
    583                 " crop=[%d,%d,%d,%d] transform=%#x scale=%s",
    584                 slot, mCore->mFrameCounter + 1, timestamp,
    585                 crop.left, crop.top, crop.right, crop.bottom,
    586                 transform, BufferItem::scalingModeName(scalingMode));
    587 
    588         const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
    589         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
    590         Rect croppedRect;
    591         crop.intersect(bufferRect, &croppedRect);
    592         if (croppedRect != crop) {
    593             BQ_LOGE("queueBuffer: crop rect is not contained within the "
    594                     "buffer in slot %d", slot);
    595             return BAD_VALUE;
    596         }
    597 
    598         mSlots[slot].mFence = fence;
    599         mSlots[slot].mBufferState = BufferSlot::QUEUED;
    600         ++mCore->mFrameCounter;
    601         mSlots[slot].mFrameNumber = mCore->mFrameCounter;
    602 
    603         item.mAcquireCalled = mSlots[slot].mAcquireCalled;
    604         item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
    605         item.mCrop = crop;
    606         item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
    607         item.mTransformToDisplayInverse =
    608                 bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
    609         item.mScalingMode = scalingMode;
    610         item.mTimestamp = timestamp;
    611         item.mIsAutoTimestamp = isAutoTimestamp;
    612         item.mFrameNumber = mCore->mFrameCounter;
    613         item.mSlot = slot;
    614         item.mFence = fence;
    615         item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
    616 
    617         mStickyTransform = stickyTransform;
    618 
    619         if (mCore->mQueue.empty()) {
    620             // When the queue is empty, we can ignore mDequeueBufferCannotBlock
    621             // and simply queue this buffer
    622             mCore->mQueue.push_back(item);
    623             frameAvailableListener = mCore->mConsumerListener;
    624         } else {
    625             // When the queue is not empty, we need to look at the front buffer
    626             // state to see if we need to replace it
    627             BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
    628             if (front->mIsDroppable) {
    629                 // If the front queued buffer is still being tracked, we first
    630                 // mark it as freed
    631                 if (mCore->stillTracking(front)) {
    632                     mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
    633                     // Reset the frame number of the freed buffer so that it is
    634                     // the first in line to be dequeued again
    635                     mSlots[front->mSlot].mFrameNumber = 0;
    636                 }
    637                 // Overwrite the droppable buffer with the incoming one
    638                 *front = item;
    639                 frameReplacedListener = mCore->mConsumerListener;
    640             } else {
    641                 mCore->mQueue.push_back(item);
    642                 frameAvailableListener = mCore->mConsumerListener;
    643             }
    644         }
    645 
    646         mCore->mBufferHasBeenQueued = true;
    647         mCore->mDequeueCondition.broadcast();
    648 
    649         output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
    650                 mCore->mTransformHint, mCore->mQueue.size());
    651 
    652         ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
    653 
    654         // Take a ticket for the callback functions
    655         callbackTicket = mNextCallbackTicket++;
    656     } // Autolock scope
    657 
    658     // Wait without lock held
    659     if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
    660         // Waiting here allows for two full buffers to be queued but not a
    661         // third. In the event that frames take varying time, this makes a
    662         // small trade-off in favor of latency rather than throughput.
    663         mLastQueueBufferFence->waitForever("Throttling EGL Production");
    664         mLastQueueBufferFence = fence;
    665     }
    666 
    667     // Don't send the GraphicBuffer through the callback, and don't send
    668     // the slot number, since the consumer shouldn't need it
    669     item.mGraphicBuffer.clear();
    670     item.mSlot = BufferItem::INVALID_BUFFER_SLOT;
    671 
    672     // Call back without the main BufferQueue lock held, but with the callback
    673     // lock held so we can ensure that callbacks occur in order
    674     {
    675         Mutex::Autolock lock(mCallbackMutex);
    676         while (callbackTicket != mCurrentCallbackTicket) {
    677             mCallbackCondition.wait(mCallbackMutex);
    678         }
    679 
    680         if (frameAvailableListener != NULL) {
    681             frameAvailableListener->onFrameAvailable(item);
    682         } else if (frameReplacedListener != NULL) {
    683             frameReplacedListener->onFrameReplaced(item);
    684         }
    685 
    686         ++mCurrentCallbackTicket;
    687         mCallbackCondition.broadcast();
    688     }
    689 
    690     return NO_ERROR;
    691 }
    692 
    693 void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
    694     ATRACE_CALL();
    695     BQ_LOGV("cancelBuffer: slot %d", slot);
    696     Mutex::Autolock lock(mCore->mMutex);
    697 
    698     if (mCore->mIsAbandoned) {
    699         BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
    700         return;
    701     }
    702 
    703     if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
    704         BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
    705                 slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
    706         return;
    707     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
    708         BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
    709                 "(state = %d)", slot, mSlots[slot].mBufferState);
    710         return;
    711     } else if (fence == NULL) {
    712         BQ_LOGE("cancelBuffer: fence is NULL");
    713         return;
    714     }
    715 
    716     mSlots[slot].mBufferState = BufferSlot::FREE;
    717     mSlots[slot].mFrameNumber = 0;
    718     mSlots[slot].mFence = fence;
    719     mCore->mDequeueCondition.broadcast();
    720 }
    721 
    722 int BufferQueueProducer::query(int what, int *outValue) {
    723     ATRACE_CALL();
    724     Mutex::Autolock lock(mCore->mMutex);
    725 
    726     if (outValue == NULL) {
    727         BQ_LOGE("query: outValue was NULL");
    728         return BAD_VALUE;
    729     }
    730 
    731     if (mCore->mIsAbandoned) {
    732         BQ_LOGE("query: BufferQueue has been abandoned");
    733         return NO_INIT;
    734     }
    735 
    736     int value;
    737     switch (what) {
    738         case NATIVE_WINDOW_WIDTH:
    739             value = mCore->mDefaultWidth;
    740             break;
    741         case NATIVE_WINDOW_HEIGHT:
    742             value = mCore->mDefaultHeight;
    743             break;
    744         case NATIVE_WINDOW_FORMAT:
    745             value = mCore->mDefaultBufferFormat;
    746             break;
    747         case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
    748             value = mCore->getMinUndequeuedBufferCountLocked(false);
    749             break;
    750         case NATIVE_WINDOW_STICKY_TRANSFORM:
    751             value = static_cast<int>(mStickyTransform);
    752             break;
    753         case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
    754             value = (mCore->mQueue.size() > 1);
    755             break;
    756         case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
    757             value = mCore->mConsumerUsageBits;
    758             break;
    759         default:
    760             return BAD_VALUE;
    761     }
    762 
    763     BQ_LOGV("query: %d? %d", what, value);
    764     *outValue = value;
    765     return NO_ERROR;
    766 }
    767 
    768 status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
    769         int api, bool producerControlledByApp, QueueBufferOutput *output) {
    770     ATRACE_CALL();
    771     Mutex::Autolock lock(mCore->mMutex);
    772     mConsumerName = mCore->mConsumerName;
    773     BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api,
    774             producerControlledByApp ? "true" : "false");
    775 
    776     if (mCore->mIsAbandoned) {
    777         BQ_LOGE("connect(P): BufferQueue has been abandoned");
    778         return NO_INIT;
    779     }
    780 
    781     if (mCore->mConsumerListener == NULL) {
    782         BQ_LOGE("connect(P): BufferQueue has no consumer");
    783         return NO_INIT;
    784     }
    785 
    786     if (output == NULL) {
    787         BQ_LOGE("connect(P): output was NULL");
    788         return BAD_VALUE;
    789     }
    790 
    791     if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
    792         BQ_LOGE("connect(P): already connected (cur=%d req=%d)",
    793                 mCore->mConnectedApi, api);
    794         return BAD_VALUE;
    795     }
    796 
    797     int status = NO_ERROR;
    798     switch (api) {
    799         case NATIVE_WINDOW_API_EGL:
    800         case NATIVE_WINDOW_API_CPU:
    801         case NATIVE_WINDOW_API_MEDIA:
    802         case NATIVE_WINDOW_API_CAMERA:
    803             mCore->mConnectedApi = api;
    804             output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
    805                     mCore->mTransformHint, mCore->mQueue.size());
    806 
    807             // Set up a death notification so that we can disconnect
    808             // automatically if the remote producer dies
    809             if (listener != NULL &&
    810                     listener->asBinder()->remoteBinder() != NULL) {
    811                 status = listener->asBinder()->linkToDeath(
    812                         static_cast<IBinder::DeathRecipient*>(this));
    813                 if (status != NO_ERROR) {
    814                     BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
    815                             strerror(-status), status);
    816                 }
    817             }
    818             mCore->mConnectedProducerListener = listener;
    819             break;
    820         default:
    821             BQ_LOGE("connect(P): unknown API %d", api);
    822             status = BAD_VALUE;
    823             break;
    824     }
    825 
    826     mCore->mBufferHasBeenQueued = false;
    827     mCore->mDequeueBufferCannotBlock =
    828             mCore->mConsumerControlledByApp && producerControlledByApp;
    829 
    830     return status;
    831 }
    832 
    833 status_t BufferQueueProducer::disconnect(int api) {
    834     ATRACE_CALL();
    835     BQ_LOGV("disconnect(P): api %d", api);
    836 
    837     int status = NO_ERROR;
    838     sp<IConsumerListener> listener;
    839     { // Autolock scope
    840         Mutex::Autolock lock(mCore->mMutex);
    841         mCore->waitWhileAllocatingLocked();
    842 
    843         if (mCore->mIsAbandoned) {
    844             // It's not really an error to disconnect after the surface has
    845             // been abandoned; it should just be a no-op.
    846             return NO_ERROR;
    847         }
    848 
    849         switch (api) {
    850             case NATIVE_WINDOW_API_EGL:
    851             case NATIVE_WINDOW_API_CPU:
    852             case NATIVE_WINDOW_API_MEDIA:
    853             case NATIVE_WINDOW_API_CAMERA:
    854                 if (mCore->mConnectedApi == api) {
    855                     mCore->freeAllBuffersLocked();
    856 
    857                     // Remove our death notification callback if we have one
    858                     if (mCore->mConnectedProducerListener != NULL) {
    859                         sp<IBinder> token =
    860                                 mCore->mConnectedProducerListener->asBinder();
    861                         // This can fail if we're here because of the death
    862                         // notification, but we just ignore it
    863                         token->unlinkToDeath(
    864                                 static_cast<IBinder::DeathRecipient*>(this));
    865                     }
    866                     mCore->mConnectedProducerListener = NULL;
    867                     mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
    868                     mCore->mSidebandStream.clear();
    869                     mCore->mDequeueCondition.broadcast();
    870                     listener = mCore->mConsumerListener;
    871                 } else {
    872                     BQ_LOGE("disconnect(P): connected to another API "
    873                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
    874                     status = BAD_VALUE;
    875                 }
    876                 break;
    877             default:
    878                 BQ_LOGE("disconnect(P): unknown API %d", api);
    879                 status = BAD_VALUE;
    880                 break;
    881         }
    882     } // Autolock scope
    883 
    884     // Call back without lock held
    885     if (listener != NULL) {
    886         listener->onBuffersReleased();
    887     }
    888 
    889     return status;
    890 }
    891 
    892 status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
    893     sp<IConsumerListener> listener;
    894     { // Autolock scope
    895         Mutex::Autolock _l(mCore->mMutex);
    896         mCore->mSidebandStream = stream;
    897         listener = mCore->mConsumerListener;
    898     } // Autolock scope
    899 
    900     if (listener != NULL) {
    901         listener->onSidebandStreamChanged();
    902     }
    903     return NO_ERROR;
    904 }
    905 
    906 void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
    907         uint32_t height, uint32_t format, uint32_t usage) {
    908     ATRACE_CALL();
    909     while (true) {
    910         Vector<int> freeSlots;
    911         size_t newBufferCount = 0;
    912         uint32_t allocWidth = 0;
    913         uint32_t allocHeight = 0;
    914         uint32_t allocFormat = 0;
    915         uint32_t allocUsage = 0;
    916         { // Autolock scope
    917             Mutex::Autolock lock(mCore->mMutex);
    918             mCore->waitWhileAllocatingLocked();
    919 
    920             int currentBufferCount = 0;
    921             for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
    922                 if (mSlots[slot].mGraphicBuffer != NULL) {
    923                     ++currentBufferCount;
    924                 } else {
    925                     if (mSlots[slot].mBufferState != BufferSlot::FREE) {
    926                         BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE",
    927                                 slot);
    928                         continue;
    929                     }
    930 
    931                     freeSlots.push_back(slot);
    932                 }
    933             }
    934 
    935             int maxBufferCount = mCore->getMaxBufferCountLocked(async);
    936             BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers",
    937                     currentBufferCount, maxBufferCount);
    938             if (maxBufferCount <= currentBufferCount)
    939                 return;
    940             newBufferCount = maxBufferCount - currentBufferCount;
    941             if (freeSlots.size() < newBufferCount) {
    942                 BQ_LOGE("allocateBuffers: ran out of free slots");
    943                 return;
    944             }
    945             allocWidth = width > 0 ? width : mCore->mDefaultWidth;
    946             allocHeight = height > 0 ? height : mCore->mDefaultHeight;
    947             allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
    948             allocUsage = usage | mCore->mConsumerUsageBits;
    949 
    950             mCore->mIsAllocating = true;
    951         } // Autolock scope
    952 
    953         Vector<sp<GraphicBuffer> > buffers;
    954         for (size_t i = 0; i <  newBufferCount; ++i) {
    955             status_t result = NO_ERROR;
    956             sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
    957                     allocWidth, allocHeight, allocFormat, allocUsage, &result));
    958             if (result != NO_ERROR) {
    959                 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
    960                         " %u, usage %u)", width, height, format, usage);
    961                 Mutex::Autolock lock(mCore->mMutex);
    962                 mCore->mIsAllocating = false;
    963                 mCore->mIsAllocatingCondition.broadcast();
    964                 return;
    965             }
    966             buffers.push_back(graphicBuffer);
    967         }
    968 
    969         { // Autolock scope
    970             Mutex::Autolock lock(mCore->mMutex);
    971             uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
    972             uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
    973             uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
    974             uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
    975             if (checkWidth != allocWidth || checkHeight != allocHeight ||
    976                 checkFormat != allocFormat || checkUsage != allocUsage) {
    977                 // Something changed while we released the lock. Retry.
    978                 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
    979                 mCore->mIsAllocating = false;
    980                 mCore->mIsAllocatingCondition.broadcast();
    981                 continue;
    982             }
    983 
    984             for (size_t i = 0; i < newBufferCount; ++i) {
    985                 int slot = freeSlots[i];
    986                 if (mSlots[slot].mBufferState != BufferSlot::FREE) {
    987                     // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we
    988                     // allocated.
    989                     BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. "
    990                             "Dropping allocated buffer.", slot);
    991                     continue;
    992                 }
    993                 mCore->freeBufferLocked(slot); // Clean up the slot first
    994                 mSlots[slot].mGraphicBuffer = buffers[i];
    995                 mSlots[slot].mFrameNumber = 0;
    996                 mSlots[slot].mFence = Fence::NO_FENCE;
    997                 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
    998             }
    999 
   1000             mCore->mIsAllocating = false;
   1001             mCore->mIsAllocatingCondition.broadcast();
   1002         } // Autolock scope
   1003     }
   1004 }
   1005 
   1006 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
   1007     // If we're here, it means that a producer we were connected to died.
   1008     // We're guaranteed that we are still connected to it because we remove
   1009     // this callback upon disconnect. It's therefore safe to read mConnectedApi
   1010     // without synchronization here.
   1011     int api = mCore->mConnectedApi;
   1012     disconnect(api);
   1013 }
   1014 
   1015 } // namespace android
   1016