Don't change the framebuffer target until we render a new one

Continuing to send the last-rendered framebuffer to HWC on subsequent
frames allows the HWC to read partially-composed regions that haven't
changed, instead of re-composing from scratch.

Bug: 11573910
Change-Id: I8829877d2a06001f1e1b3f168cbba71c7b217b2d
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 2bf7d21..be5cf4a 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -174,14 +174,8 @@
     }
     mDbgState = DBG_STATE_HWC;
 
-    if (mCompositionType == COMPOSITION_HWC) {
-        // Use the output buffer for the FB as well, though conceptually the
-        // FB is unused on this frame.
-        mFbProducerSlot = mOutputProducerSlot;
-        mFbFence = mOutputFence;
-    }
-
-    if (mFbProducerSlot < 0 || mOutputProducerSlot < 0) {
+    if (mOutputProducerSlot < 0 ||
+            (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 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
@@ -191,7 +185,8 @@
         return NO_MEMORY;
     }
 
-    sp<GraphicBuffer> fbBuffer = mProducerBuffers[mFbProducerSlot];
+    sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ?
+            mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(NULL);
     sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot];
     VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)",
             mFbProducerSlot, fbBuffer.get(),
@@ -201,7 +196,12 @@
     // so update HWC state with it.
     mHwc.setOutputBuffer(mDisplayId, mOutputFence, outBuffer);
 
-    return mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
+    status_t result = NO_ERROR;
+    if (fbBuffer != NULL) {
+        result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer);
+    }
+
+    return result;
 }
 
 void VirtualDisplaySurface::onFrameCommitted() {
@@ -458,9 +458,7 @@
     mCompositionType = COMPOSITION_UNKNOWN;
     mSinkBufferWidth = 0;
     mSinkBufferHeight = 0;
-    mFbFence = Fence::NO_FENCE;
     mOutputFence = Fence::NO_FENCE;
-    mFbProducerSlot = -1;
     mOutputProducerSlot = -1;
 }