libgui: disallow NULL Fence pointers

This change eliminates the uses of a NULL sp<Fence> indicating that no waiting
is required.  Instead we use a non-NULL but invalid Fence object for which the
wait methods will return immediately.

Bug: 7892871
Change-Id: I5360aebe3090422ef6920d56c99fc4eedc642e48
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 4be655b..d93c067 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -372,8 +372,6 @@
             h = mDefaultHeight;
         }
 
-        // buffer is now in DEQUEUED (but can also be current at the same time,
-        // if we're in synchronous mode)
         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
 
         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
@@ -387,7 +385,7 @@
             mSlots[buf].mGraphicBuffer = NULL;
             mSlots[buf].mRequestBufferCalled = false;
             mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
-            mSlots[buf].mFence.clear();
+            mSlots[buf].mFence = Fence::NO_FENCE;
             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
 
             returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
@@ -397,7 +395,7 @@
         eglFence = mSlots[buf].mEglFence;
         outFence = mSlots[buf].mFence;
         mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
-        mSlots[buf].mFence.clear();
+        mSlots[buf].mFence = Fence::NO_FENCE;
     }  // end lock scope
 
     if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
@@ -423,7 +421,6 @@
         }
     }
 
-
     if (eglFence != EGL_NO_SYNC_KHR) {
         EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000);
         // If something goes wrong, log the error, but return the buffer without
@@ -488,6 +485,11 @@
 
     input.deflate(&timestamp, &crop, &scalingMode, &transform, &fence);
 
+    if (fence == NULL) {
+        ST_LOGE("queueBuffer: fence is NULL");
+        return BAD_VALUE;
+    }
+
     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "
             "scale=%s",
             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,
@@ -607,6 +609,9 @@
         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
                 buf, mSlots[buf].mBufferState);
         return;
+    } else if (fence == NULL) {
+        ST_LOGE("cancelBuffer: fence is NULL");
+        return;
     }
     mSlots[buf].mBufferState = BufferSlot::FREE;
     mSlots[buf].mFrameNumber = 0;
@@ -785,7 +790,7 @@
         eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
         mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
     }
-    mSlots[slot].mFence.clear();
+    mSlots[slot].mFence = Fence::NO_FENCE;
 }
 
 void BufferQueue::freeAllBuffersLocked() {
@@ -843,7 +848,7 @@
         mSlots[buf].mAcquireCalled = true;
         mSlots[buf].mNeedsCleanupOnRelease = false;
         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
-        mSlots[buf].mFence.clear();
+        mSlots[buf].mFence = Fence::NO_FENCE;
 
         mQueue.erase(front);
         mDequeueCondition.broadcast();
@@ -863,8 +868,8 @@
 
     Mutex::Autolock _l(mMutex);
 
-    if (buf == INVALID_BUFFER_SLOT) {
-        return -EINVAL;
+    if (buf == INVALID_BUFFER_SLOT || fence == NULL) {
+        return BAD_VALUE;
     }
 
     mSlots[buf].mEglDisplay = display;