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