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