summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2012-10-04 18:34:01 -0700
committerJamie Gennis <jgennis@google.com>2012-10-11 20:08:26 -0700
commit1efe099a51e2231bd938a6afcf66e6584deec0f2 (patch)
treedf27ff5a7c0c2b30a1f65cd16e1c964045695f34 /libs
parentf0c89b28be2e74c26d74b2a21b7228516f8c236f (diff)
downloadframeworks_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
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/BufferQueue.cpp36
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