SF: Modify transaction/buffer sync logic

Reorganizes the transaction/buffer synchronization logic to only
consider the head of the incoming BufferQueue instead of all buffers,
and fixes some potential race conditions.

Bug: 25951593
Change-Id: Ib2b08e7be571eb8bbd8c364fb85acf0e046b439c
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9e3c4db..d91e94e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -356,10 +356,6 @@
     virtual void onFrameReplaced(const BufferItem& item) override;
     virtual void onSidebandStreamChanged() override;
 
-    // Move frames made available by item in to a list which will
-    // be signalled at the beginning of the next transaction
-    virtual void markSyncPointsAvailable(const BufferItem& item);
-
     void commitTransaction();
 
     // needsLinearFiltering - true if this surface's state requires filtering
@@ -413,19 +409,24 @@
         std::atomic<bool> mTransactionIsApplied;
     };
 
+    // SyncPoints which will be signaled when the correct frame is at the head
+    // of the queue and dropped after the frame has been latched. Protected by
+    // mLocalSyncPointMutex.
+    Mutex mLocalSyncPointMutex;
     std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints;
 
-    // Guarded by mPendingStateMutex
+    // SyncPoints which will be signaled and then dropped when the transaction
+    // is applied
     std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints;
 
-    void addSyncPoint(std::shared_ptr<SyncPoint> point);
+    uint64_t getHeadFrameNumber() const;
+
+    // Returns false if the relevant frame has already been latched
+    bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
     void pushPendingState();
     void popPendingState();
     bool applyPendingStates();
-
-    Mutex mAvailableFrameMutex;
-    std::list<std::shared_ptr<SyncPoint>> mAvailableFrames;
 public:
     void notifyAvailableFrames();
 private:
@@ -461,6 +462,7 @@
     uint32_t mCurrentTransform;
     uint32_t mCurrentScalingMode;
     bool mCurrentOpacity;
+    std::atomic<uint64_t> mCurrentFrameNumber;
     bool mRefreshPending;
     bool mFrameLatencyNeeded;
     // Whether filtering is forced on or not
@@ -488,7 +490,7 @@
     mutable Mutex mQueueItemLock;
     Condition mQueueItemCondition;
     Vector<BufferItem> mQueueItems;
-    uint64_t mLastFrameNumberReceived;
+    std::atomic<uint64_t> mLastFrameNumberReceived;
     bool mUpdateTexImageFailed; // This is only modified from the main thread
 
     bool mSingleBufferMode;