diff options
author | Andy McFadden <fadden@android.com> | 2013-10-18 16:57:01 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-10-18 16:57:01 -0700 |
commit | 251b11c2045b2ae97f2ab270a65e11b4ca49b1b6 (patch) | |
tree | fffe68425812b8aa2183584bacbff6816d9bfc9c /libs/gui | |
parent | afd0debe4bdf47dc0f968282ca1261842bb65d60 (diff) | |
parent | 8507586903fa803abf535853a169913f2cf2e555 (diff) | |
download | frameworks_native-251b11c2045b2ae97f2ab270a65e11b4ca49b1b6.zip frameworks_native-251b11c2045b2ae97f2ab270a65e11b4ca49b1b6.tar.gz frameworks_native-251b11c2045b2ae97f2ab270a65e11b4ca49b1b6.tar.bz2 |
am 85075869: Wait for buffers to drain
* commit '8507586903fa803abf535853a169913f2cf2e555':
Wait for buffers to drain
Diffstat (limited to 'libs/gui')
-rw-r--r-- | libs/gui/BufferQueue.cpp | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index c165a68..2aecb67 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -644,6 +644,7 @@ status_t BufferQueue::connect(const sp<IBinder>& token, producerControlledByApp ? "true" : "false"); Mutex::Autolock lock(mMutex); +retry: if (mAbandoned) { ST_LOGE("connect: BufferQueue has been abandoned!"); return NO_INIT; @@ -654,29 +655,41 @@ status_t BufferQueue::connect(const sp<IBinder>& token, return NO_INIT; } + if (mConnectedApi != NO_CONNECTED_API) { + ST_LOGE("connect: already connected (cur=%d, req=%d)", + mConnectedApi, api); + return -EINVAL; + } + + // If we disconnect and reconnect quickly, we can be in a state where our slots are + // empty but we have many buffers in the queue. This can cause us to run out of + // memory if we outrun the consumer. Wait here if it looks like we have too many + // buffers queued up. + int maxBufferCount = getMaxBufferCountLocked(false); // worst-case, i.e. largest value + if (mQueue.size() > (size_t) maxBufferCount) { + // TODO: make this bound tighter? + ST_LOGV("queue size is %d, waiting", mQueue.size()); + mDequeueCondition.wait(mMutex); + goto retry; + } + int err = NO_ERROR; switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: - if (mConnectedApi != NO_CONNECTED_API) { - ST_LOGE("connect: already connected (cur=%d, req=%d)", - mConnectedApi, api); - err = -EINVAL; - } else { - mConnectedApi = api; - output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); - - // set-up a death notification so that we can disconnect - // automatically when/if the remote producer dies. - if (token != NULL && token->remoteBinder() != NULL) { - status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); - if (err == NO_ERROR) { - mConnectedProducerToken = token; - } else { - ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err); - } + mConnectedApi = api; + output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); + + // set-up a death notification so that we can disconnect + // automatically when/if the remote producer dies. + if (token != NULL && token->remoteBinder() != NULL) { + status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)); + if (err == NO_ERROR) { + mConnectedProducerToken = token; + } else { + ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err); } } break; |