1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_GUI_BLAST_BUFFER_QUEUE_H
18 #define ANDROID_GUI_BLAST_BUFFER_QUEUE_H
19 
20 #include <gui/BufferItem.h>
21 #include <gui/BufferItemConsumer.h>
22 
23 #include <gui/IGraphicBufferProducer.h>
24 #include <gui/SurfaceComposerClient.h>
25 
26 #include <utils/Condition.h>
27 #include <utils/Mutex.h>
28 #include <utils/RefBase.h>
29 
30 #include <system/window.h>
31 #include <thread>
32 #include <queue>
33 
34 #include <com_android_graphics_libgui_flags.h>
35 
36 namespace android {
37 
38 class BLASTBufferQueue;
39 class BufferItemConsumer;
40 
41 class BLASTBufferItemConsumer : public BufferItemConsumer {
42 public:
BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer> & consumer,uint64_t consumerUsage,int bufferCount,bool controlledByApp,wp<BLASTBufferQueue> bbq)43     BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
44                             int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq)
45           : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
46             mBLASTBufferQueue(std::move(bbq)),
47             mCurrentlyConnected(false),
48             mPreviouslyConnected(false) {}
49 
50     void onDisconnect() override EXCLUDES(mMutex);
51     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
52                                   FrameEventHistoryDelta* outDelta) override EXCLUDES(mMutex);
53     void updateFrameTimestamps(uint64_t frameNumber, uint64_t previousFrameNumber,
54                                nsecs_t refreshStartTime, const sp<Fence>& gpuCompositionDoneFence,
55                                const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence,
56                                CompositorTiming compositorTiming, nsecs_t latchTime,
57                                nsecs_t dequeueReadyTime) EXCLUDES(mMutex);
58     void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect) EXCLUDES(mMutex);
59 
60     void resizeFrameEventHistory(size_t newSize);
61 
62 protected:
63     void onSidebandStreamChanged() override EXCLUDES(mMutex);
64 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_SETFRAMERATE)
65     void onSetFrameRate(float frameRate, int8_t compatibility,
66                         int8_t changeFrameRateStrategy) override;
67 #endif
68 
69 private:
70     const wp<BLASTBufferQueue> mBLASTBufferQueue;
71 
72     uint64_t mCurrentFrameNumber GUARDED_BY(mMutex) = 0;
73 
74     Mutex mMutex;
75     ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex);
76     std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mMutex);
77     bool mCurrentlyConnected GUARDED_BY(mMutex);
78     bool mPreviouslyConnected GUARDED_BY(mMutex);
79 };
80 
81 class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener {
82 public:
83     BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true);
84     BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
85                      int height, int32_t format);
86 
getIGraphicBufferProducer()87     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
88         return mProducer;
89     }
90     sp<Surface> getSurface(bool includeSurfaceControlHandle);
91     bool isSameSurfaceControl(const sp<SurfaceControl>& surfaceControl) const;
92 
93     void onFrameReplaced(const BufferItem& item) override;
94     void onFrameAvailable(const BufferItem& item) override;
95     void onFrameDequeued(const uint64_t) override;
96     void onFrameCancelled(const uint64_t) override;
97 
98     void transactionCommittedCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
99                                       const std::vector<SurfaceControlStats>& stats);
100     virtual void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
101                                      const std::vector<SurfaceControlStats>& stats);
102     void releaseBufferCallback(const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
103                                std::optional<uint32_t> currentMaxAcquiredBufferCount);
104     void releaseBufferCallbackLocked(const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
105                                      std::optional<uint32_t> currentMaxAcquiredBufferCount,
106                                      bool fakeRelease) REQUIRES(mMutex);
107     bool syncNextTransaction(std::function<void(SurfaceComposerClient::Transaction*)> callback,
108                              bool acquireSingleBuffer = true);
109     void stopContinuousSyncTransaction();
110     void clearSyncTransaction();
111 
112     void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber);
113     void applyPendingTransactions(uint64_t frameNumber);
114     SurfaceComposerClient::Transaction* gatherPendingTransactions(uint64_t frameNumber);
115 
116     void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format);
117 
118     status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
119     status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info);
120 
121     void setSidebandStream(const sp<NativeHandle>& stream);
122 
123     uint32_t getLastTransformHint() const;
124     uint64_t getLastAcquiredFrameNum();
125 
126     /**
127      * Set a callback to be invoked when we are hung. The string parameter
128      * indicates the reason for the hang.
129      */
130     void setTransactionHangCallback(std::function<void(const std::string&)> callback);
131 
132     virtual ~BLASTBufferQueue();
133 
134 private:
135     friend class BLASTBufferQueueHelper;
136     friend class BBQBufferQueueProducer;
137 
138     // can't be copied
139     BLASTBufferQueue& operator = (const BLASTBufferQueue& rhs);
140     BLASTBufferQueue(const BLASTBufferQueue& rhs);
141     void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
142                            sp<IGraphicBufferConsumer>* outConsumer);
143 
144     void resizeFrameEventHistory(size_t newSize);
145 
146     status_t acquireNextBufferLocked(
147             const std::optional<SurfaceComposerClient::Transaction*> transaction) REQUIRES(mMutex);
148     Rect computeCrop(const BufferItem& item) REQUIRES(mMutex);
149     // Return true if we need to reject the buffer based on the scaling mode and the buffer size.
150     bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex);
151     static PixelFormat convertBufferFormat(PixelFormat& format);
152     void mergePendingTransactions(SurfaceComposerClient::Transaction* t, uint64_t frameNumber)
153             REQUIRES(mMutex);
154 
155     void flushShadowQueue() REQUIRES(mMutex);
156     void acquireAndReleaseBuffer() REQUIRES(mMutex);
157     void releaseBuffer(const ReleaseCallbackId& callbackId, const sp<Fence>& releaseFence)
158             REQUIRES(mMutex);
159 
160     std::string mName;
161     // Represents the queued buffer count from buffer queue,
162     // pre-BLAST. This is mNumFrameAvailable (buffers that queued to blast) +
163     // mNumAcquired (buffers that queued to SF)  mPendingRelease.size() (buffers that are held by
164     // blast). This counter is read by android studio profiler.
165     std::string mQueuedBufferTrace;
166     sp<SurfaceControl> mSurfaceControl GUARDED_BY(mMutex);
167 
168     mutable std::mutex mMutex;
169     std::condition_variable mCallbackCV;
170 
171     // BufferQueue internally allows 1 more than
172     // the max to be acquired
173     int32_t mMaxAcquiredBuffers = 1;
174 
175     int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0;
176     int32_t mNumAcquired GUARDED_BY(mMutex) = 0;
177 
178     // A value used to identify if a producer has been changed for the same SurfaceControl.
179     // This is needed to know when the frame number has been reset to make sure we don't
180     // latch stale buffers and that we don't wait on barriers from an old producer.
181     uint32_t mProducerId = 0;
182 
183     // Keep a reference to the submitted buffers so we can release when surfaceflinger drops the
184     // buffer or the buffer has been presented and a new buffer is ready to be presented.
185     std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted
186             GUARDED_BY(mMutex);
187 
188     // Keep a queue of the released buffers instead of immediately releasing
189     // the buffers back to the buffer queue. This would be controlled by SF
190     // setting the max acquired buffer count.
191     struct ReleasedBuffer {
192         ReleaseCallbackId callbackId;
193         sp<Fence> releaseFence;
194         bool operator==(const ReleasedBuffer& rhs) const {
195             // Only compare Id so if we somehow got two callbacks
196             // with different fences we don't decrement mNumAcquired
197             // too far.
198             return rhs.callbackId == callbackId;
199         }
200     };
201     std::deque<ReleasedBuffer> mPendingRelease GUARDED_BY(mMutex);
202 
203     ui::Size mSize GUARDED_BY(mMutex);
204     ui::Size mRequestedSize GUARDED_BY(mMutex);
205     int32_t mFormat GUARDED_BY(mMutex);
206 
207     struct BufferInfo {
208         bool hasBuffer = false;
209         uint32_t width;
210         uint32_t height;
211         uint32_t transform;
212         // This is used to check if we should update the blast layer size immediately or wait until
213         // we get the next buffer. This will support scenarios where the layer can change sizes
214         // and the buffer will scale to fit the new size.
215         uint32_t scalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
216         Rect crop;
217 
updateBufferInfo218         void update(bool hasBuffer, uint32_t width, uint32_t height, uint32_t transform,
219                     uint32_t scalingMode, const Rect& crop) {
220             this->hasBuffer = hasBuffer;
221             this->width = width;
222             this->height = height;
223             this->transform = transform;
224             this->scalingMode = scalingMode;
225             if (!crop.isEmpty()) {
226                 this->crop = crop;
227             } else {
228                 this->crop = Rect(width, height);
229             }
230         }
231     };
232 
233     // Last acquired buffer's info. This is used to calculate the correct scale when size change is
234     // requested. We need to use the old buffer's info to determine what scale we need to apply to
235     // ensure the correct size.
236     BufferInfo mLastBufferInfo GUARDED_BY(mMutex);
237     void setMatrix(SurfaceComposerClient::Transaction* t, const BufferInfo& bufferInfo)
238             REQUIRES(mMutex);
239 
240     uint32_t mTransformHint GUARDED_BY(mMutex);
241 
242     sp<IGraphicBufferConsumer> mConsumer;
243     sp<IGraphicBufferProducer> mProducer;
244     sp<BLASTBufferItemConsumer> mBufferItemConsumer;
245 
246     std::function<void(SurfaceComposerClient::Transaction*)> mTransactionReadyCallback
247             GUARDED_BY(mMutex);
248     SurfaceComposerClient::Transaction* mSyncTransaction GUARDED_BY(mMutex);
249     std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>>
250             mPendingTransactions GUARDED_BY(mMutex);
251 
252     std::queue<std::pair<uint64_t, FrameTimelineInfo>> mPendingFrameTimelines GUARDED_BY(mMutex);
253 
254     // Tracks the last acquired frame number
255     uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0;
256 
257     // Queues up transactions using this token in SurfaceFlinger. This prevents queued up
258     // transactions from other parts of the client from blocking this transaction.
259     const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = sp<BBinder>::make();
260 
261     // Guards access to mDequeueTimestamps since we cannot hold to mMutex in onFrameDequeued or
262     // we will deadlock.
263     std::mutex mTimestampMutex;
264     // Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses
265     // it for debugging purposes.
266     std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps
267             GUARDED_BY(mTimestampMutex);
268 
269     // Keep track of SurfaceControls that have submitted a transaction and BBQ is waiting on a
270     // callback for them.
271     std::queue<sp<SurfaceControl>> mSurfaceControlsWithPendingCallback GUARDED_BY(mMutex);
272 
273     uint32_t mCurrentMaxAcquiredBufferCount GUARDED_BY(mMutex);
274 
275     // Flag to determine if syncTransaction should only acquire a single buffer and then clear or
276     // continue to acquire buffers until explicitly cleared
277     bool mAcquireSingleBuffer GUARDED_BY(mMutex) = true;
278 
279     // True if BBQ will update the destination frame used to scale the buffer to the requested size.
280     // If false, the caller is responsible for updating the destination frame on the BBQ
281     // surfacecontol. This is useful if the caller wants to synchronize the buffer scale with
282     // additional scales in the hierarchy.
283     bool mUpdateDestinationFrame GUARDED_BY(mMutex) = true;
284 
285     // We send all transactions on our apply token over one-way binder calls to avoid blocking
286     // client threads. All of our transactions remain in order, since they are one-way binder calls
287     // from a single process, to a single interface. However once we give up a Transaction for sync
288     // we can start to have ordering issues. When we return from sync to normal frame production,
289     // we wait on the commit callback of sync frames ensuring ordering, however we don't want to
290     // wait on the commit callback for every normal frame (since even emitting them has a
291     // performance cost) this means we need a method to ensure frames are in order when switching
292     // from one-way application on our apply token, to application on some other apply token. We
293     // make use of setBufferHasBarrier to declare this ordering. This boolean simply tracks when we
294     // need to set this flag, notably only in the case where we are transitioning from a previous
295     // transaction applied by us (one way, may not yet have reached server) and an upcoming
296     // transaction that will be applied by some sync consumer.
297     bool mAppliedLastTransaction GUARDED_BY(mMutex) = false;
298     uint64_t mLastAppliedFrameNumber GUARDED_BY(mMutex) = 0;
299 
300     std::function<void(const std::string&)> mTransactionHangCallback;
301 
302     std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);
303 };
304 
305 } // namespace android
306 
307 #endif  // ANDROID_GUI_SURFACE_H
308