OSDN Git Service

SF/HWC2: Reorder makeCurrent to avoid deadlock
authorDan Stoza <stoza@google.com>
Wed, 6 Apr 2016 21:05:37 +0000 (14:05 -0700)
committerDan Stoza <stoza@google.com>
Wed, 6 Apr 2016 21:05:37 +0000 (14:05 -0700)
Now that we are deferring the release of FramebufferSurface buffers
(so that we can return a non-speculative fence), we end up holding
two acquired buffers during the call into HWComposer::commit (whereas
we previously would have only been holding one, with the other having
been released). This means that if the EGL implementation dequeues a
buffer as part of eglMakeCurrent, neither of the FramebufferSurface
buffers will be free, and the call to dequeueBuffer will block.

This change fixes that issue by reordering eglMakeCurrent to occur
after the deferred release.

Bug: 25684127
Change-Id: I6ec55b3f7b7d0e0f5be6029751cb086feeb52fbe

services/surfaceflinger/SurfaceFlinger.cpp

index ea9fe21..40e9ae7 100644 (file)
@@ -1248,6 +1248,7 @@ void SurfaceFlinger::postFramebuffer()
         if (hwcId >= 0) {
             mHwc->commit(hwcId);
         }
+        displayDevice->onSwapBuffersCompleted();
         if (displayId == 0) {
             // Make the default display current because the VirtualDisplayDevice
             // code cannot deal with dequeueBuffer() being called outside of the
@@ -1255,7 +1256,6 @@ void SurfaceFlinger::postFramebuffer()
             // is allowed to (and does in some case) call dequeueBuffer().
             displayDevice->makeCurrent(mEGLDisplay, mEGLContext);
         }
-        displayDevice->onSwapBuffersCompleted();
         for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
             sp<Fence> releaseFence = Fence::NO_FENCE;
             if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {