diff options
author | Jamie Gennis <jgennis@google.com> | 2012-10-04 18:34:01 -0700 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2012-10-11 20:08:26 -0700 |
commit | 1efe099a51e2231bd938a6afcf66e6584deec0f2 (patch) | |
tree | df27ff5a7c0c2b30a1f65cd16e1c964045695f34 | |
parent | f0c89b28be2e74c26d74b2a21b7228516f8c236f (diff) | |
download | frameworks_native-1efe099a51e2231bd938a6afcf66e6584deec0f2.zip frameworks_native-1efe099a51e2231bd938a6afcf66e6584deec0f2.tar.gz frameworks_native-1efe099a51e2231bd938a6afcf66e6584deec0f2.tar.bz2 |
BufferQueue: alloc without holding the lock
This change makes BufferQueue::dequeueBuffer release its mutex before
allocating new buffers. This should alleviate lock contention in
SurfaceFlinger where SF's main thread can get blocked waiting for an allocation
operation to complete.
Bug: 7335075
Change-Id: I1b000539cc616a695afab2e9c68507db69e57b13
-rw-r--r-- | libs/gui/BufferQueue.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index d408476..590946a 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -385,18 +385,8 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, (uint32_t(buffer->format) != format) || ((uint32_t(buffer->usage) & usage) != usage)) { - status_t error; - sp<GraphicBuffer> graphicBuffer( - mGraphicBufferAlloc->createGraphicBuffer( - w, h, format, usage, &error)); - if (graphicBuffer == 0) { - ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " - "failed"); - return error; - } - mSlots[buf].mAcquireCalled = false; - mSlots[buf].mGraphicBuffer = graphicBuffer; + mSlots[buf].mGraphicBuffer = NULL; mSlots[buf].mRequestBufferCalled = false; mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; mSlots[buf].mFence.clear(); @@ -412,6 +402,30 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence, mSlots[buf].mFence.clear(); } // end lock scope + if (returnFlags & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) { + status_t error; + sp<GraphicBuffer> graphicBuffer( + mGraphicBufferAlloc->createGraphicBuffer( + w, h, format, usage, &error)); + if (graphicBuffer == 0) { + ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " + "failed"); + return error; + } + + { // Scope for the lock + Mutex::Autolock lock(mMutex); + + if (mAbandoned) { + ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); + return NO_INIT; + } + + mSlots[*outBuf].mGraphicBuffer = graphicBuffer; + } + } + + if (eglFence != EGL_NO_SYNC_KHR) { EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); // If something goes wrong, log the error, but return the buffer without |