Fix an infinite loop in TextureView implementation
There is a possibilty for an infinite loop in TextureView
logic, which could dequeue forever buffers without ever
drawing anything. This could happen on devices without
EGL_ANDROID_native_fence_sync extension and for frames
that consume a lot of GPU time.
Test: Passed CTS. Ran a specific sequence of frames,
Test: that used to triggers an infinite loop.
Bug: 159921224
Change-Id: I1896e21f0d87fa2fa66bac53df4265a1018f0f61
diff --git a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
index 16afc68..365e788 100644
--- a/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/ImageConsumer.cpp
@@ -51,7 +51,15 @@
}
int slot = item.mSlot;
+ *outQueueEmpty = false;
if (item.mFence->isValid()) {
+ // If fence is not signaled, that means frame is not ready and
+ // outQueueEmpty is set to true. By the time the fence is signaled,
+ // there may be a new buffer queued. This is a proper detection for an
+ // empty queue and it is needed to avoid infinite loop in
+ // ASurfaceTexture_dequeueBuffer (see b/159921224).
+ *outQueueEmpty = item.mFence->getStatus() == Fence::Status::Unsignaled;
+
// Wait on the producer fence for the buffer to be ready.
err = fenceWait(item.mFence->get(), fencePassThroughHandle);
if (err != OK) {
@@ -112,7 +120,6 @@
st.mCurrentFrameNumber = item.mFrameNumber;
st.computeCurrentTransformMatrixLocked();
- *outQueueEmpty = false;
*outDataspace = item.mDataSpace;
*outSlotid = slot;
return st.mSlots[slot].mGraphicBuffer;