VirtualDisplaySurface propagate reallocation to VDS producer
When dequeuing from the source through refreshOutputBuffer(),
the dequeue result, BUFFER_NEEDS_REALLOCATION, is not propagated back up.
RenderSurface will not reallocate from VirtualDisplaySurface
in this situation, causing GLES to render to the wrong buffer.
Wrong buffer example,
beginFrame() -> refreshOutputBuffer() -> dequeueBuffer()
-> dequeueBuffer() needs reallocation.
but the result in refreshOuputBuffer() is overwritten by
mHwc.setOutputBuffer().
(the result is also not received by VDS itself)
We need a flag to indicate producer slot need reallocation,
so that we can sent reallocation to Consumer.
Bug: 157204337
Test: simulate second display with debug.sf.enable_hwc_vds = 1
Change-Id: Ibcbc3bd1ef857382ea9882dd10e0bd55759406f4
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index fba3261..c8cd442 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -73,6 +73,7 @@
mOutputUsage(GRALLOC_USAGE_HW_COMPOSER),
mProducerSlotSource(0),
mProducerBuffers(),
+ mProducerSlotNeedReallocation(0),
mQueueBufferOutput(),
mSinkBufferWidth(0),
mSinkBufferHeight(0),
@@ -335,10 +336,14 @@
dbgSourceStr(source), *sslot, pslot, result);
uint64_t sourceBit = static_cast<uint64_t>(source) << pslot;
+ // reset producer slot reallocation flag
+ mProducerSlotNeedReallocation &= ~(1ULL << pslot);
+
if ((mProducerSlotSource & (1ULL << pslot)) != sourceBit) {
// This slot was previously dequeued from the other source; must
// re-request the buffer.
- result |= BUFFER_NEEDS_REALLOCATION;
+ mProducerSlotNeedReallocation |= 1ULL << pslot;
+
mProducerSlotSource &= ~(1ULL << pslot);
mProducerSlotSource |= sourceBit;
}
@@ -360,6 +365,9 @@
dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(),
mProducerBuffers[pslot]->getPixelFormat(),
mProducerBuffers[pslot]->getUsage());
+
+ // propagate reallocation to VDS consumer
+ mProducerSlotNeedReallocation |= 1ULL << pslot;
}
return result;
@@ -434,6 +442,11 @@
if (outBufferAge) {
*outBufferAge = 0;
}
+
+ if ((mProducerSlotNeedReallocation & (1ULL << *pslot)) != 0) {
+ result |= BUFFER_NEEDS_REALLOCATION;
+ }
+
return result;
}
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 3cbad8f..22b5528 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -180,6 +180,10 @@
uint64_t mProducerSlotSource;
sp<GraphicBuffer> mProducerBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS];
+ // Need to propagate reallocation to VDS consumer.
+ // Each bit corresponds to a producer slot.
+ uint64_t mProducerSlotNeedReallocation;
+
// The QueueBufferOutput with the latest info from the sink, and with the
// transform hint cleared. Since we defer queueBuffer from the GPU driver
// to the sink, we have to return the previous version.