Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright (C) 2012 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 #define LOG_TAG "BufferQueue"
     18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     19 //#define LOG_NDEBUG 0
     20 
     21 #define GL_GLEXT_PROTOTYPES
     22 #define EGL_EGLEXT_PROTOTYPES
     23 
     24 #include <EGL/egl.h>
     25 #include <EGL/eglext.h>
     26 
     27 #include <gui/BufferQueue.h>
     28 #include <gui/ISurfaceComposer.h>
     29 #include <private/gui/ComposerService.h>
     30 
     31 #include <utils/Log.h>
     32 #include <gui/SurfaceTexture.h>
     33 #include <utils/Trace.h>
     34 
     35 // Macros for including the BufferQueue name in log messages
     36 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
     37 #define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
     38 #define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
     39 #define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
     40 #define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
     41 
     42 #define ATRACE_BUFFER_INDEX(index)                                            \
     43     if (ATRACE_ENABLED()) {                                                   \
     44         char ___traceBuf[1024];                                               \
     45         snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(),         \
     46                 (index));                                                     \
     47         android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf);           \
     48     }
     49 
     50 namespace android {
     51 
     52 // Get an ID that's unique within this process.
     53 static int32_t createProcessUniqueId() {
     54     static volatile int32_t globalCounter = 0;
     55     return android_atomic_inc(&globalCounter);
     56 }
     57 
     58 static const char* scalingModeName(int scalingMode) {
     59     switch (scalingMode) {
     60         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
     61         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
     62         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
     63         default: return "Unknown";
     64     }
     65 }
     66 
     67 BufferQueue::BufferQueue(bool allowSynchronousMode,
     68         const sp<IGraphicBufferAlloc>& allocator) :
     69     mDefaultWidth(1),
     70     mDefaultHeight(1),
     71     mMaxAcquiredBufferCount(1),
     72     mDefaultMaxBufferCount(2),
     73     mOverrideMaxBufferCount(0),
     74     mSynchronousMode(false),
     75     mAllowSynchronousMode(allowSynchronousMode),
     76     mConnectedApi(NO_CONNECTED_API),
     77     mAbandoned(false),
     78     mFrameCounter(0),
     79     mBufferHasBeenQueued(false),
     80     mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
     81     mConsumerUsageBits(0),
     82     mTransformHint(0)
     83 {
     84     // Choose a name using the PID and a process-unique ID.
     85     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
     86 
     87     ST_LOGV("BufferQueue");
     88     if (allocator == NULL) {
     89         sp<ISurfaceComposer> composer(ComposerService::getComposerService());
     90         mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
     91         if (mGraphicBufferAlloc == 0) {
     92             ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
     93         }
     94     } else {
     95         mGraphicBufferAlloc = allocator;
     96     }
     97 }
     98 
     99 BufferQueue::~BufferQueue() {
    100     ST_LOGV("~BufferQueue");
    101 }
    102 
    103 status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
    104     if (count < 2 || count > NUM_BUFFER_SLOTS)
    105         return BAD_VALUE;
    106 
    107     mDefaultMaxBufferCount = count;
    108     mDequeueCondition.broadcast();
    109 
    110     return OK;
    111 }
    112 
    113 bool BufferQueue::isSynchronousMode() const {
    114     Mutex::Autolock lock(mMutex);
    115     return mSynchronousMode;
    116 }
    117 
    118 void BufferQueue::setConsumerName(const String8& name) {
    119     Mutex::Autolock lock(mMutex);
    120     mConsumerName = name;
    121 }
    122 
    123 status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
    124     Mutex::Autolock lock(mMutex);
    125     mDefaultBufferFormat = defaultFormat;
    126     return OK;
    127 }
    128 
    129 status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
    130     Mutex::Autolock lock(mMutex);
    131     mConsumerUsageBits = usage;
    132     return OK;
    133 }
    134 
    135 status_t BufferQueue::setTransformHint(uint32_t hint) {
    136     ST_LOGV("setTransformHint: %02x", hint);
    137     Mutex::Autolock lock(mMutex);
    138     mTransformHint = hint;
    139     return OK;
    140 }
    141 
    142 status_t BufferQueue::setBufferCount(int bufferCount) {
    143     ST_LOGV("setBufferCount: count=%d", bufferCount);
    144 
    145     sp<ConsumerListener> listener;
    146     {
    147         Mutex::Autolock lock(mMutex);
    148 
    149         if (mAbandoned) {
    150             ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
    151             return NO_INIT;
    152         }
    153         if (bufferCount > NUM_BUFFER_SLOTS) {
    154             ST_LOGE("setBufferCount: bufferCount larger than slots available");
    155             return BAD_VALUE;
    156         }
    157 
    158         // Error out if the user has dequeued buffers
    159         int maxBufferCount = getMaxBufferCountLocked();
    160         for (int i=0 ; i<maxBufferCount; i++) {
    161             if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
    162                 ST_LOGE("setBufferCount: client owns some buffers");
    163                 return -EINVAL;
    164             }
    165         }
    166 
    167         const int minBufferSlots = getMinMaxBufferCountLocked();
    168         if (bufferCount == 0) {
    169             mOverrideMaxBufferCount = 0;
    170             mDequeueCondition.broadcast();
    171             return OK;
    172         }
    173 
    174         if (bufferCount < minBufferSlots) {
    175             ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
    176                     "minimum (%d)", bufferCount, minBufferSlots);
    177             return BAD_VALUE;
    178         }
    179 
    180         // here we're guaranteed that the client doesn't have dequeued buffers
    181         // and will release all of its buffer references.
    182         //
    183         // XXX: Should this use drainQueueAndFreeBuffersLocked instead?
    184         freeAllBuffersLocked();
    185         mOverrideMaxBufferCount = bufferCount;
    186         mBufferHasBeenQueued = false;
    187         mDequeueCondition.broadcast();
    188         listener = mConsumerListener;
    189     } // scope for lock
    190 
    191     if (listener != NULL) {
    192         listener->onBuffersReleased();
    193     }
    194 
    195     return OK;
    196 }
    197 
    198 int BufferQueue::query(int what, int* outValue)
    199 {
    200     ATRACE_CALL();
    201     Mutex::Autolock lock(mMutex);
    202 
    203     if (mAbandoned) {
    204         ST_LOGE("query: SurfaceTexture has been abandoned!");
    205         return NO_INIT;
    206     }
    207 
    208     int value;
    209     switch (what) {
    210     case NATIVE_WINDOW_WIDTH:
    211         value = mDefaultWidth;
    212         break;
    213     case NATIVE_WINDOW_HEIGHT:
    214         value = mDefaultHeight;
    215         break;
    216     case NATIVE_WINDOW_FORMAT:
    217         value = mDefaultBufferFormat;
    218         break;
    219     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
    220         value = getMinUndequeuedBufferCountLocked();
    221         break;
    222     case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
    223         value = (mQueue.size() >= 2);
    224         break;
    225     default:
    226         return BAD_VALUE;
    227     }
    228     outValue[0] = value;
    229     return NO_ERROR;
    230 }
    231 
    232 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    233     ATRACE_CALL();
    234     ST_LOGV("requestBuffer: slot=%d", slot);
    235     Mutex::Autolock lock(mMutex);
    236     if (mAbandoned) {
    237         ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
    238         return NO_INIT;
    239     }
    240     int maxBufferCount = getMaxBufferCountLocked();
    241     if (slot < 0 || maxBufferCount <= slot) {
    242         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
    243                 maxBufferCount, slot);
    244         return BAD_VALUE;
    245     } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
    246         // XXX: I vaguely recall there was some reason this can be valid, but
    247         // for the life of me I can't recall under what circumstances that's
    248         // the case.
    249         ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)",
    250                 slot, mSlots[slot].mBufferState);
    251         return BAD_VALUE;
    252     }
    253     mSlots[slot].mRequestBufferCalled = true;
    254     *buf = mSlots[slot].mGraphicBuffer;
    255     return NO_ERROR;
    256 }
    257 
    258 status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
    259         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
    260     ATRACE_CALL();
    261     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
    262 
    263     if ((w && !h) || (!w && h)) {
    264         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
    265         return BAD_VALUE;
    266     }
    267 
    268     status_t returnFlags(OK);
    269     EGLDisplay dpy = EGL_NO_DISPLAY;
    270     EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    271 
    272     { // Scope for the lock
    273         Mutex::Autolock lock(mMutex);
    274 
    275         if (format == 0) {
    276             format = mDefaultBufferFormat;
    277         }
    278         // turn on usage bits the consumer requested
    279         usage |= mConsumerUsageBits;
    280 
    281         int found = -1;
    282         int dequeuedCount = 0;
    283         bool tryAgain = true;
    284         while (tryAgain) {
    285             if (mAbandoned) {
    286                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
    287                 return NO_INIT;
    288             }
    289 
    290             const int maxBufferCount = getMaxBufferCountLocked();
    291 
    292             // Free up any buffers that are in slots beyond the max buffer
    293             // count.
    294             for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
    295                 assert(mSlots[i].mBufferState == BufferSlot::FREE);
    296                 if (mSlots[i].mGraphicBuffer != NULL) {
    297                     freeBufferLocked(i);
    298                     returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
    299                 }
    300             }
    301 
    302             // look for a free buffer to give to the client
    303             found = INVALID_BUFFER_SLOT;
    304             dequeuedCount = 0;
    305             for (int i = 0; i < maxBufferCount; i++) {
    306                 const int state = mSlots[i].mBufferState;
    307                 if (state == BufferSlot::DEQUEUED) {
    308                     dequeuedCount++;
    309                 }
    310 
    311                 if (state == BufferSlot::FREE) {
    312                     /* We return the oldest of the free buffers to avoid
    313                      * stalling the producer if possible.  This is because
    314                      * the consumer may still have pending reads of the
    315                      * buffers in flight.
    316                      */
    317                     bool isOlder = mSlots[i].mFrameNumber <
    318                             mSlots[found].mFrameNumber;
    319                     if (found < 0 || isOlder) {
    320                         found = i;
    321                     }
    322                 }
    323             }
    324 
    325             // clients are not allowed to dequeue more than one buffer
    326             // if they didn't set a buffer count.
    327             if (!mOverrideMaxBufferCount && dequeuedCount) {
    328                 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
    329                         "setting the buffer count");
    330                 return -EINVAL;
    331             }
    332 
    333             // See whether a buffer has been queued since the last
    334             // setBufferCount so we know whether to perform the min undequeued
    335             // buffers check below.
    336             if (mBufferHasBeenQueued) {
    337                 // make sure the client is not trying to dequeue more buffers
    338                 // than allowed.
    339                 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
    340                 const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
    341                 if (newUndequeuedCount < minUndequeuedCount) {
    342                     ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
    343                             "exceeded (dequeued=%d undequeudCount=%d)",
    344                             minUndequeuedCount, dequeuedCount,
    345                             newUndequeuedCount);
    346                     return -EBUSY;
    347                 }
    348             }
    349 
    350             // If no buffer is found, wait for a buffer to be released or for
    351             // the max buffer count to change.
    352             tryAgain = found == INVALID_BUFFER_SLOT;
    353             if (tryAgain) {
    354                 mDequeueCondition.wait(mMutex);
    355             }
    356         }
    357 
    358 
    359         if (found == INVALID_BUFFER_SLOT) {
    360             // This should not happen.
    361             ST_LOGE("dequeueBuffer: no available buffer slots");
    362             return -EBUSY;
    363         }
    364 
    365         const int buf = found;
    366         *outBuf = found;
    367 
    368         ATRACE_BUFFER_INDEX(buf);
    369 
    370         const bool useDefaultSize = !w && !h;
    371         if (useDefaultSize) {
    372             // use the default size
    373             w = mDefaultWidth;
    374             h = mDefaultHeight;
    375         }
    376 
    377         // buffer is now in DEQUEUED (but can also be current at the same time,
    378         // if we're in synchronous mode)
    379         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
    380 
    381         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
    382         if ((buffer == NULL) ||
    383             (uint32_t(buffer->width)  != w) ||
    384             (uint32_t(buffer->height) != h) ||
    385             (uint32_t(buffer->format) != format) ||
    386             ((uint32_t(buffer->usage) & usage) != usage))
    387         {
    388             mSlots[buf].mAcquireCalled = false;
    389             mSlots[buf].mGraphicBuffer = NULL;
    390             mSlots[buf].mRequestBufferCalled = false;
    391             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
    392             mSlots[buf].mFence.clear();
    393             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
    394 
    395             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
    396         }
    397 
    398         dpy = mSlots[buf].mEglDisplay;
    399         eglFence = mSlots[buf].mEglFence;
    400         outFence = mSlots[buf].mFence;
    401         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
    402         mSlots[buf].mFence.clear();
    403     }  // end lock scope
    404 
    405     if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) {
    406         status_t error;
    407         sp<GraphicBuffer> graphicBuffer(
    408                 mGraphicBufferAlloc->createGraphicBuffer(
    409                         w, h, format, usage, &error));
    410         if (graphicBuffer == 0) {
    411             ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
    412                     "failed");
    413             return error;
    414         }
    415 
    416         { // Scope for the lock
    417             Mutex::Autolock lock(mMutex);
    418 
    419             if (mAbandoned) {
    420                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
    421                 return NO_INIT;
    422             }
    423 
    424             mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
    425         }
    426     }
    427 
    428 
    429     if (eglFence != EGL_NO_SYNC_KHR) {
    430         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
    431         // If something goes wrong, log the error, but return the buffer without
    432         // synchronizing access to it.  It's too late at this point to abort the
    433         // dequeue operation.
    434         if (result == EGL_FALSE) {
    435             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
    436         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
    437             ST_LOGE("dequeueBuffer: timeout waiting for fence");
    438         }
    439         eglDestroySyncKHR(dpy, eglFence);
    440     }
    441 
    442     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
    443             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
    444 
    445     return returnFlags;
    446 }
    447 
    448 status_t BufferQueue::setSynchronousMode(bool enabled) {
    449     ATRACE_CALL();
    450     ST_LOGV("setSynchronousMode: enabled=%d", enabled);
    451     Mutex::Autolock lock(mMutex);
    452 
    453     if (mAbandoned) {
    454         ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
    455         return NO_INIT;
    456     }
    457 
    458     status_t err = OK;
    459     if (!mAllowSynchronousMode && enabled)
    460         return err;
    461 
    462     if (!enabled) {
    463         // going to asynchronous mode, drain the queue
    464         err = drainQueueLocked();
    465         if (err != NO_ERROR)
    466             return err;
    467     }
    468 
    469     if (mSynchronousMode != enabled) {
    470         // - if we're going to asynchronous mode, the queue is guaranteed to be
    471         // empty here
    472         // - if the client set the number of buffers, we're guaranteed that
    473         // we have at least 3 (because we don't allow less)
    474         mSynchronousMode = enabled;
    475         mDequeueCondition.broadcast();
    476     }
    477     return err;
    478 }
    479 
    480 status_t BufferQueue::queueBuffer(int buf,
    481         const QueueBufferInput& input, QueueBufferOutput* output) {
    482     ATRACE_CALL();
    483     ATRACE_BUFFER_INDEX(buf);
    484 
    485     Rect crop;
    486     uint32_t transform;
    487     int scalingMode;
    488     int64_t timestamp;
    489     sp<Fence> fence;
    490 
    491     input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
    492 
    493     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
    494             "scale=%s",
    495             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
    496             transform, scalingModeName(scalingMode));
    497 
    498     sp<ConsumerListener> listener;
    499 
    500     { // scope for the lock
    501         Mutex::Autolock lock(mMutex);
    502         if (mAbandoned) {
    503             ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
    504             return NO_INIT;
    505         }
    506         int maxBufferCount = getMaxBufferCountLocked();
    507         if (buf < 0 || buf >= maxBufferCount) {
    508             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
    509                     maxBufferCount, buf);
    510             return -EINVAL;
    511         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
    512             ST_LOGE("queueBuffer: slot %d is not owned by the client "
    513                     "(state=%d)", buf, mSlots[buf].mBufferState);
    514             return -EINVAL;
    515         } else if (!mSlots[buf].mRequestBufferCalled) {
    516             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
    517                     "buffer", buf);
    518             return -EINVAL;
    519         }
    520 
    521         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);
    522         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
    523         Rect croppedCrop;
    524         crop.intersect(bufferRect, &croppedCrop);
    525         if (croppedCrop != crop) {
    526             ST_LOGE("queueBuffer: crop rect is not contained within the "
    527                     "buffer in slot %d", buf);
    528             return -EINVAL;
    529         }
    530 
    531         if (mSynchronousMode) {
    532             // In synchronous mode we queue all buffers in a FIFO.
    533             mQueue.push_back(buf);
    534 
    535             // Synchronous mode always signals that an additional frame should
    536             // be consumed.
    537             listener = mConsumerListener;
    538         } else {
    539             // In asynchronous mode we only keep the most recent buffer.
    540             if (mQueue.empty()) {
    541                 mQueue.push_back(buf);
    542 
    543                 // Asynchronous mode only signals that a frame should be
    544                 // consumed if no previous frame was pending. If a frame were
    545                 // pending then the consumer would have already been notified.
    546                 listener = mConsumerListener;
    547             } else {
    548                 Fifo::iterator front(mQueue.begin());
    549                 // buffer currently queued is freed
    550                 mSlots[*front].mBufferState = BufferSlot::FREE;
    551                 // and we record the new buffer index in the queued list
    552                 *front = buf;
    553             }
    554         }
    555 
    556         mSlots[buf].mTimestamp = timestamp;
    557         mSlots[buf].mCrop = crop;
    558         mSlots[buf].mTransform = transform;
    559         mSlots[buf].mFence = fence;
    560 
    561         switch (scalingMode) {
    562             case NATIVE_WINDOW_SCALING_MODE_FREEZE:
    563             case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
    564             case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
    565                 break;
    566             default:
    567                 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
    568                 scalingMode = mSlots[buf].mScalingMode;
    569                 break;
    570         }
    571 
    572         mSlots[buf].mBufferState = BufferSlot::QUEUED;
    573         mSlots[buf].mScalingMode = scalingMode;
    574         mFrameCounter++;
    575         mSlots[buf].mFrameNumber = mFrameCounter;
    576 
    577         mBufferHasBeenQueued = true;
    578         mDequeueCondition.broadcast();
    579 
    580         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
    581                 mQueue.size());
    582 
    583         ATRACE_INT(mConsumerName.string(), mQueue.size());
    584     } // scope for the lock
    585 
    586     // call back without lock held
    587     if (listener != 0) {
    588         listener->onFrameAvailable();
    589     }
    590     return OK;
    591 }
    592 
    593 void BufferQueue::cancelBuffer(int buf, sp<Fence> fence) {
    594     ATRACE_CALL();
    595     ST_LOGV("cancelBuffer: slot=%d", buf);
    596     Mutex::Autolock lock(mMutex);
    597 
    598     if (mAbandoned) {
    599         ST_LOGW("cancelBuffer: BufferQueue has been abandoned!");
    600         return;
    601     }
    602 
    603     int maxBufferCount = getMaxBufferCountLocked();
    604     if (buf < 0 || buf >= maxBufferCount) {
    605         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
    606                 maxBufferCount, buf);
    607         return;
    608     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
    609         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
    610                 buf, mSlots[buf].mBufferState);
    611         return;
    612     }
    613     mSlots[buf].mBufferState = BufferSlot::FREE;
    614     mSlots[buf].mFrameNumber = 0;
    615     mSlots[buf].mFence = fence;
    616     mDequeueCondition.broadcast();
    617 }
    618 
    619 status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
    620     ATRACE_CALL();
    621     ST_LOGV("connect: api=%d", api);
    622     Mutex::Autolock lock(mMutex);
    623 
    624     if (mAbandoned) {
    625         ST_LOGE("connect: BufferQueue has been abandoned!");
    626         return NO_INIT;
    627     }
    628 
    629     if (mConsumerListener == NULL) {
    630         ST_LOGE("connect: BufferQueue has no consumer!");
    631         return NO_INIT;
    632     }
    633 
    634     int err = NO_ERROR;
    635     switch (api) {
    636         case NATIVE_WINDOW_API_EGL:
    637         case NATIVE_WINDOW_API_CPU:
    638         case NATIVE_WINDOW_API_MEDIA:
    639         case NATIVE_WINDOW_API_CAMERA:
    640             if (mConnectedApi != NO_CONNECTED_API) {
    641                 ST_LOGE("connect: already connected (cur=%d, req=%d)",
    642                         mConnectedApi, api);
    643                 err = -EINVAL;
    644             } else {
    645                 mConnectedApi = api;
    646                 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
    647                         mQueue.size());
    648             }
    649             break;
    650         default:
    651             err = -EINVAL;
    652             break;
    653     }
    654 
    655     mBufferHasBeenQueued = false;
    656 
    657     return err;
    658 }
    659 
    660 status_t BufferQueue::disconnect(int api) {
    661     ATRACE_CALL();
    662     ST_LOGV("disconnect: api=%d", api);
    663 
    664     int err = NO_ERROR;
    665     sp<ConsumerListener> listener;
    666 
    667     { // Scope for the lock
    668         Mutex::Autolock lock(mMutex);
    669 
    670         if (mAbandoned) {
    671             // it is not really an error to disconnect after the surface
    672             // has been abandoned, it should just be a no-op.
    673             return NO_ERROR;
    674         }
    675 
    676         switch (api) {
    677             case NATIVE_WINDOW_API_EGL:
    678             case NATIVE_WINDOW_API_CPU:
    679             case NATIVE_WINDOW_API_MEDIA:
    680             case NATIVE_WINDOW_API_CAMERA:
    681                 if (mConnectedApi == api) {
    682                     drainQueueAndFreeBuffersLocked();
    683                     mConnectedApi = NO_CONNECTED_API;
    684                     mDequeueCondition.broadcast();
    685                     listener = mConsumerListener;
    686                 } else {
    687                     ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
    688                             mConnectedApi, api);
    689                     err = -EINVAL;
    690                 }
    691                 break;
    692             default:
    693                 ST_LOGE("disconnect: unknown API %d", api);
    694                 err = -EINVAL;
    695                 break;
    696         }
    697     }
    698 
    699     if (listener != NULL) {
    700         listener->onBuffersReleased();
    701     }
    702 
    703     return err;
    704 }
    705 
    706 void BufferQueue::dump(String8& result) const
    707 {
    708     char buffer[1024];
    709     BufferQueue::dump(result, "", buffer, 1024);
    710 }
    711 
    712 void BufferQueue::dump(String8& result, const char* prefix,
    713         char* buffer, size_t SIZE) const
    714 {
    715     Mutex::Autolock _l(mMutex);
    716 
    717     String8 fifo;
    718     int fifoSize = 0;
    719     Fifo::const_iterator i(mQueue.begin());
    720     while (i != mQueue.end()) {
    721        snprintf(buffer, SIZE, "%02d ", *i++);
    722        fifoSize++;
    723        fifo.append(buffer);
    724     }
    725 
    726     int maxBufferCount = getMaxBufferCountLocked();
    727 
    728     snprintf(buffer, SIZE,
    729             "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
    730             "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n",
    731             prefix, maxBufferCount, mSynchronousMode, mDefaultWidth,
    732             mDefaultHeight, mDefaultBufferFormat, mTransformHint,
    733             fifoSize, fifo.string());
    734     result.append(buffer);
    735 
    736 
    737     struct {
    738         const char * operator()(int state) const {
    739             switch (state) {
    740                 case BufferSlot::DEQUEUED: return "DEQUEUED";
    741                 case BufferSlot::QUEUED: return "QUEUED";
    742                 case BufferSlot::FREE: return "FREE";
    743                 case BufferSlot::ACQUIRED: return "ACQUIRED";
    744                 default: return "Unknown";
    745             }
    746         }
    747     } stateName;
    748 
    749     for (int i=0 ; i<maxBufferCount ; i++) {
    750         const BufferSlot& slot(mSlots[i]);
    751         snprintf(buffer, SIZE,
    752                 "%s%s[%02d] "
    753                 "state=%-8s, crop=[%d,%d,%d,%d], "
    754                 "xform=0x%02x, time=%#llx, scale=%s",
    755                 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
    756                 stateName(slot.mBufferState),
    757                 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
    758                 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp,
    759                 scalingModeName(slot.mScalingMode)
    760         );
    761         result.append(buffer);
    762 
    763         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
    764         if (buf != NULL) {
    765             snprintf(buffer, SIZE,
    766                     ", %p [%4ux%4u:%4u,%3X]",
    767                     buf->handle, buf->width, buf->height, buf->stride,
    768                     buf->format);
    769             result.append(buffer);
    770         }
    771         result.append("\n");
    772     }
    773 }
    774 
    775 void BufferQueue::freeBufferLocked(int slot) {
    776     ST_LOGV("freeBufferLocked: slot=%d", slot);
    777     mSlots[slot].mGraphicBuffer = 0;
    778     if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
    779         mSlots[slot].mNeedsCleanupOnRelease = true;
    780     }
    781     mSlots[slot].mBufferState = BufferSlot::FREE;
    782     mSlots[slot].mFrameNumber = 0;
    783     mSlots[slot].mAcquireCalled = false;
    784 
    785     // destroy fence as BufferQueue now takes ownership
    786     if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
    787         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
    788         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
    789     }
    790     mSlots[slot].mFence.clear();
    791 }
    792 
    793 void BufferQueue::freeAllBuffersLocked() {
    794     ALOGW_IF(!mQueue.isEmpty(),
    795             "freeAllBuffersLocked called but mQueue is not empty");
    796     mQueue.clear();
    797     mBufferHasBeenQueued = false;
    798     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    799         freeBufferLocked(i);
    800     }
    801 }
    802 
    803 status_t BufferQueue::acquireBuffer(BufferItem *buffer) {
    804     ATRACE_CALL();
    805     Mutex::Autolock _l(mMutex);
    806 
    807     // Check that the consumer doesn't currently have the maximum number of
    808     // buffers acquired.  We allow the max buffer count to be exceeded by one
    809     // buffer, so that the consumer can successfully set up the newly acquired
    810     // buffer before releasing the old one.
    811     int numAcquiredBuffers = 0;
    812     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    813         if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) {
    814             numAcquiredBuffers++;
    815         }
    816     }
    817     if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) {
    818         ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)",
    819                 numAcquiredBuffers, mMaxAcquiredBufferCount);
    820         return INVALID_OPERATION;
    821     }
    822 
    823     // check if queue is empty
    824     // In asynchronous mode the list is guaranteed to be one buffer
    825     // deep, while in synchronous mode we use the oldest buffer.
    826     if (!mQueue.empty()) {
    827         Fifo::iterator front(mQueue.begin());
    828         int buf = *front;
    829 
    830         ATRACE_BUFFER_INDEX(buf);
    831 
    832         if (mSlots[buf].mAcquireCalled) {
    833             buffer->mGraphicBuffer = NULL;
    834         } else {
    835             buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
    836         }
    837         buffer->mCrop = mSlots[buf].mCrop;
    838         buffer->mTransform = mSlots[buf].mTransform;
    839         buffer->mScalingMode = mSlots[buf].mScalingMode;
    840         buffer->mFrameNumber = mSlots[buf].mFrameNumber;
    841         buffer->mTimestamp = mSlots[buf].mTimestamp;
    842         buffer->mBuf = buf;
    843         buffer->mFence = mSlots[buf].mFence;
    844 
    845         mSlots[buf].mAcquireCalled = true;
    846         mSlots[buf].mNeedsCleanupOnRelease = false;
    847         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
    848         mSlots[buf].mFence.clear();
    849 
    850         mQueue.erase(front);
    851         mDequeueCondition.broadcast();
    852 
    853         ATRACE_INT(mConsumerName.string(), mQueue.size());
    854     } else {
    855         return NO_BUFFER_AVAILABLE;
    856     }
    857 
    858     return OK;
    859 }
    860 
    861 status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
    862         EGLSyncKHR eglFence, const sp<Fence>& fence) {
    863     ATRACE_CALL();
    864     ATRACE_BUFFER_INDEX(buf);
    865 
    866     Mutex::Autolock _l(mMutex);
    867 
    868     if (buf == INVALID_BUFFER_SLOT) {
    869         return -EINVAL;
    870     }
    871 
    872     mSlots[buf].mEglDisplay = display;
    873     mSlots[buf].mEglFence = eglFence;
    874     mSlots[buf].mFence = fence;
    875 
    876     // The buffer can now only be released if its in the acquired state
    877     if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
    878         mSlots[buf].mBufferState = BufferSlot::FREE;
    879     } else if (mSlots[buf].mNeedsCleanupOnRelease) {
    880         ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState);
    881         mSlots[buf].mNeedsCleanupOnRelease = false;
    882         return STALE_BUFFER_SLOT;
    883     } else {
    884         ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState);
    885         return -EINVAL;
    886     }
    887 
    888     mDequeueCondition.broadcast();
    889     return OK;
    890 }
    891 
    892 status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
    893     ST_LOGV("consumerConnect");
    894     Mutex::Autolock lock(mMutex);
    895 
    896     if (mAbandoned) {
    897         ST_LOGE("consumerConnect: BufferQueue has been abandoned!");
    898         return NO_INIT;
    899     }
    900 
    901     mConsumerListener = consumerListener;
    902 
    903     return OK;
    904 }
    905 
    906 status_t BufferQueue::consumerDisconnect() {
    907     ST_LOGV("consumerDisconnect");
    908     Mutex::Autolock lock(mMutex);
    909 
    910     if (mConsumerListener == NULL) {
    911         ST_LOGE("consumerDisconnect: No consumer is connected!");
    912         return -EINVAL;
    913     }
    914 
    915     mAbandoned = true;
    916     mConsumerListener = NULL;
    917     mQueue.clear();
    918     freeAllBuffersLocked();
    919     mDequeueCondition.broadcast();
    920     return OK;
    921 }
    922 
    923 status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) {
    924     ST_LOGV("getReleasedBuffers");
    925     Mutex::Autolock lock(mMutex);
    926 
    927     if (mAbandoned) {
    928         ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!");
    929         return NO_INIT;
    930     }
    931 
    932     uint32_t mask = 0;
    933     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    934         if (!mSlots[i].mAcquireCalled) {
    935             mask |= 1 << i;
    936         }
    937     }
    938     *slotMask = mask;
    939 
    940     ST_LOGV("getReleasedBuffers: returning mask %#x", mask);
    941     return NO_ERROR;
    942 }
    943 
    944 status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
    945 {
    946     ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
    947     if (!w || !h) {
    948         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
    949                 w, h);
    950         return BAD_VALUE;
    951     }
    952 
    953     Mutex::Autolock lock(mMutex);
    954     mDefaultWidth = w;
    955     mDefaultHeight = h;
    956     return OK;
    957 }
    958 
    959 status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
    960     ATRACE_CALL();
    961     Mutex::Autolock lock(mMutex);
    962     return setDefaultMaxBufferCountLocked(bufferCount);
    963 }
    964 
    965 status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
    966     ATRACE_CALL();
    967     Mutex::Autolock lock(mMutex);
    968     if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) {
    969         ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d",
    970                 maxAcquiredBuffers);
    971         return BAD_VALUE;
    972     }
    973     if (mConnectedApi != NO_CONNECTED_API) {
    974         return INVALID_OPERATION;
    975     }
    976     mMaxAcquiredBufferCount = maxAcquiredBuffers;
    977     return OK;
    978 }
    979 
    980 void BufferQueue::freeAllBuffersExceptHeadLocked() {
    981     int head = -1;
    982     if (!mQueue.empty()) {
    983         Fifo::iterator front(mQueue.begin());
    984         head = *front;
    985     }
    986     mBufferHasBeenQueued = false;
    987     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    988         if (i != head) {
    989             freeBufferLocked(i);
    990         }
    991     }
    992 }
    993 
    994 status_t BufferQueue::drainQueueLocked() {
    995     while (mSynchronousMode && !mQueue.isEmpty()) {
    996         mDequeueCondition.wait(mMutex);
    997         if (mAbandoned) {
    998             ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!");
    999             return NO_INIT;
   1000         }
   1001         if (mConnectedApi == NO_CONNECTED_API) {
   1002             ST_LOGE("drainQueueLocked: BufferQueue is not connected!");
   1003             return NO_INIT;
   1004         }
   1005     }
   1006     return NO_ERROR;
   1007 }
   1008 
   1009 status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
   1010     status_t err = drainQueueLocked();
   1011     if (err == NO_ERROR) {
   1012         if (mSynchronousMode) {
   1013             freeAllBuffersLocked();
   1014         } else {
   1015             freeAllBuffersExceptHeadLocked();
   1016         }
   1017     }
   1018     return err;
   1019 }
   1020 
   1021 int BufferQueue::getMinMaxBufferCountLocked() const {
   1022     return getMinUndequeuedBufferCountLocked() + 1;
   1023 }
   1024 
   1025 int BufferQueue::getMinUndequeuedBufferCountLocked() const {
   1026     return mSynchronousMode ? mMaxAcquiredBufferCount :
   1027             mMaxAcquiredBufferCount + 1;
   1028 }
   1029 
   1030 int BufferQueue::getMaxBufferCountLocked() const {
   1031     int minMaxBufferCount = getMinMaxBufferCountLocked();
   1032 
   1033     int maxBufferCount = mDefaultMaxBufferCount;
   1034     if (maxBufferCount < minMaxBufferCount) {
   1035         maxBufferCount = minMaxBufferCount;
   1036     }
   1037     if (mOverrideMaxBufferCount != 0) {
   1038         assert(mOverrideMaxBufferCount >= minMaxBufferCount);
   1039         maxBufferCount = mOverrideMaxBufferCount;
   1040     }
   1041 
   1042     // Any buffers that are dequeued by the producer or sitting in the queue
   1043     // waiting to be consumed need to have their slots preserved.  Such
   1044     // buffers will temporarily keep the max buffer count up until the slots
   1045     // no longer need to be preserved.
   1046     for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) {
   1047         BufferSlot::BufferState state = mSlots[i].mBufferState;
   1048         if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) {
   1049             maxBufferCount = i + 1;
   1050         }
   1051     }
   1052 
   1053     return maxBufferCount;
   1054 }
   1055 
   1056 BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
   1057         const wp<BufferQueue::ConsumerListener>& consumerListener):
   1058         mConsumerListener(consumerListener) {}
   1059 
   1060 BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
   1061 
   1062 void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
   1063     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
   1064     if (listener != NULL) {
   1065         listener->onFrameAvailable();
   1066     }
   1067 }
   1068 
   1069 void BufferQueue::ProxyConsumerListener::onBuffersReleased() {
   1070     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());
   1071     if (listener != NULL) {
   1072         listener->onBuffersReleased();
   1073     }
   1074 }
   1075 
   1076 }; // namespace android
   1077