am 85075869
: Wait for buffers to drain
* commit '8507586903fa803abf535853a169913f2cf2e555': Wait for buffers to drain
This commit is contained in:
commit
251b11c204
@ -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());
|
||||
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);
|
||||
}
|
||||
// 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;
|
||||
|
Loading…
Reference in New Issue
Block a user