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