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
This commit is contained in:
Jesse Hall 2013-11-07 12:28:26 -08:00
parent 356c23865d
commit 14e8b01a76

View File

@ -174,14 +174,8 @@ status_t VirtualDisplaySurface::advanceFrame() {
}
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 @@ status_t VirtualDisplaySurface::advanceFrame() {
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 @@ status_t VirtualDisplaySurface::advanceFrame() {
// 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 @@ void VirtualDisplaySurface::resetPerFrameState() {
mCompositionType = COMPOSITION_UNKNOWN;
mSinkBufferWidth = 0;
mSinkBufferHeight = 0;
mFbFence = Fence::NO_FENCE;
mOutputFence = Fence::NO_FENCE;
mFbProducerSlot = -1;
mOutputProducerSlot = -1;
}