Remove RenderEngine::flush from latchBuffer()

Fence fd will be owned by SurfaceFlinger to be propagated down to
latchBuffer for merging sync fences. We can't store the fd at the
Layer-level & flush on every draw() invocation for some reason (I don't
fully understand what the gl driver does under the hood, but from what
it looks like file descriptors are reused when the command stream is
flushed too often which causes a memory leak when a buffer's sync fence
is merged), so we'll let SF backend store the flush fence for the
previous frame.

Bug: 116277151
Change-Id: I7901b0178aa0f11505650bf5e1df6f085a5d93bf
Test: SurfaceFlinger_test, libsurfaceflinger_unittest, go/wm-smoke
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index da9dcfb..730262d 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -378,7 +378,8 @@
     return NO_ERROR;
 }
 
-status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime) {
+status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
+                                          const sp<Fence>& releaseFence) {
     const State& s(getDrawingState());
 
     if (!s.buffer) {
@@ -420,16 +421,13 @@
     }
 
     // Handle sync fences
-    if (SyncFeatures::getInstance().useNativeFenceSync()) {
-        base::unique_fd fenceFd = engine.flush();
-        if (fenceFd == -1) {
-            ALOGE("failed to flush RenderEngine");
+    if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
+        // TODO(alecmouri): Fail somewhere upstream if the fence is invalid.
+        if (!releaseFence->isValid()) {
             mTimeStats.clearLayerRecord(getName().c_str());
             return UNKNOWN_ERROR;
         }
 
-        sp<Fence> fence(new Fence(std::move(fenceFd)));
-
         // Check status of fences first because merging is expensive.
         // Merging an invalid fence with any other fence results in an
         // invalid fence.
@@ -440,10 +438,10 @@
             return BAD_VALUE;
         }
 
-        auto incomingStatus = fence->getStatus();
+        auto incomingStatus = releaseFence->getStatus();
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
-            mDrawingState.acquireFence = fence;
+            mDrawingState.acquireFence = releaseFence;
             mTimeStats.clearLayerRecord(getName().c_str());
             return BAD_VALUE;
         }
@@ -453,12 +451,13 @@
         if (currentStatus == incomingStatus) {
             char fenceName[32] = {};
             snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
-            sp<Fence> mergedFence = Fence::merge(fenceName, mDrawingState.acquireFence, fence);
+            sp<Fence> mergedFence =
+                    Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
             if (!mergedFence.get()) {
                 ALOGE("failed to merge release fences");
                 // synchronization is broken, the best we can do is hope fences
                 // signal in order so the new fence will act like a union
-                mDrawingState.acquireFence = fence;
+                mDrawingState.acquireFence = releaseFence;
                 mTimeStats.clearLayerRecord(getName().c_str());
                 return BAD_VALUE;
             }
@@ -471,7 +470,7 @@
             // by this point, they will have both signaled and only the timestamp
             // will be slightly off; any dependencies after this point will
             // already have been met.
-            mDrawingState.acquireFence = fence;
+            mDrawingState.acquireFence = releaseFence;
         }
     } else {
         // Bind the new buffer to the GL texture.