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