diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c06043d4f..88ef3928c 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -258,6 +258,17 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp* fence, bool Source source = fbSourceForCompositionType(mCompositionType); if (source == SOURCE_SINK) { + + if (mOutputProducerSlot < 0) { + // Last chance bailout if something bad happened earlier. For example, + // in a GLES configuration, if the sink disappears then dequeueBuffer + // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger + // will soldier on. So we end up here without a buffer. There should + // be lots of scary messages in the log just before this. + VDS_LOGE("dequeueBuffer: no buffer, bailing out"); + return NO_MEMORY; + } + // We already dequeued the output buffer. If the GLES driver wants // something incompatible, we have to cancel and get a new one. This // will mean that HWC will see a different output buffer between diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 240c08ae9..ca4b80cd6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -964,6 +964,12 @@ void SurfaceFlinger::postFramebuffer() hwc.commit(); } + // make the default display current because the VirtualDisplayDevice code cannot + // deal with dequeueBuffer() being called outside of the composition loop; however + // the code below can call glFlush() which is allowed (and does in some case) call + // dequeueBuffer(). + getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); + for (size_t dpy=0 ; dpy hw(mDisplays[dpy]); const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ());