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