diff options
Diffstat (limited to 'libs/gui/include/gui/BLASTBufferQueue.h')
-rw-r--r-- | libs/gui/include/gui/BLASTBufferQueue.h | 154 |
1 files changed, 130 insertions, 24 deletions
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 2320771a38..0d6a673b02 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -28,9 +28,11 @@ #include <system/window.h> #include <thread> +#include <queue> namespace android { +class BLASTBufferQueue; class BufferItemConsumer; class BLASTBufferItemConsumer : public BufferItemConsumer { @@ -39,51 +41,72 @@ public: int bufferCount, bool controlledByApp) : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp), mCurrentlyConnected(false), - mPreviouslyConnected(false) {} + mPreviouslyConnected(false), + mBLASTBufferQueue(nullptr) {} void onDisconnect() override; void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, - FrameEventHistoryDelta* outDelta) override - REQUIRES(mFrameEventHistoryMutex); + FrameEventHistoryDelta* outDelta) override REQUIRES(mMutex); void updateFrameTimestamps(uint64_t frameNumber, nsecs_t refreshStartTime, const sp<Fence>& gpuCompositionDoneFence, const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence, CompositorTiming compositorTiming, nsecs_t latchTime, - nsecs_t dequeueReadyTime) REQUIRES(mFrameEventHistoryMutex); + nsecs_t dequeueReadyTime) REQUIRES(mMutex); void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect); + void setBlastBufferQueue(BLASTBufferQueue* blastbufferqueue) REQUIRES(mMutex); + +protected: + void onSidebandStreamChanged() override REQUIRES(mMutex); private: uint64_t mCurrentFrameNumber = 0; - Mutex mFrameEventHistoryMutex; - ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mFrameEventHistoryMutex); - std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mFrameEventHistoryMutex); - bool mCurrentlyConnected GUARDED_BY(mFrameEventHistoryMutex); - bool mPreviouslyConnected GUARDED_BY(mFrameEventHistoryMutex); + Mutex mMutex; + ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex); + std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mMutex); + bool mCurrentlyConnected GUARDED_BY(mMutex); + bool mPreviouslyConnected GUARDED_BY(mMutex); + BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mMutex); }; class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener { public: - BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height, - bool enableTripleBuffering = true); + BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width, + int height, int32_t format); sp<IGraphicBufferProducer> getIGraphicBufferProducer() const { return mProducer; } + sp<Surface> getSurface(bool includeSurfaceControlHandle); void onBufferFreed(const wp<GraphicBuffer>&/* graphicBuffer*/) override { /* TODO */ } - void onFrameReplaced(const BufferItem& item) override {onFrameAvailable(item);} + void onFrameReplaced(const BufferItem& item) override; void onFrameAvailable(const BufferItem& item) override; + void onFrameDequeued(const uint64_t) override; + void onFrameCancelled(const uint64_t) override; void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence, const std::vector<SurfaceControlStats>& stats); + void releaseBufferCallback(const ReleaseCallbackId& id, const sp<Fence>& releaseFence, + uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount); void setNextTransaction(SurfaceComposerClient::Transaction *t); + void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber); + void setTransactionCompleteCallback(uint64_t frameNumber, + std::function<void(int64_t)>&& transactionCompleteCallback); + + void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format); + void flushShadowQueue() {} + + status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); + status_t setFrameTimelineInfo(const FrameTimelineInfo& info); + + void setSidebandStream(const sp<NativeHandle>& stream); - void update(const sp<SurfaceControl>& surface, int width, int height); + uint32_t getLastTransformHint() const; - virtual ~BLASTBufferQueue() = default; + virtual ~BLASTBufferQueue(); private: friend class BLASTBufferQueueHelper; @@ -91,10 +114,22 @@ private: // can't be copied BLASTBufferQueue& operator = (const BLASTBufferQueue& rhs); BLASTBufferQueue(const BLASTBufferQueue& rhs); + void createBufferQueue(sp<IGraphicBufferProducer>* outProducer, + sp<IGraphicBufferConsumer>* outConsumer); void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex); - Rect computeCrop(const BufferItem& item); - + Rect computeCrop(const BufferItem& item) REQUIRES(mMutex); + // Return true if we need to reject the buffer based on the scaling mode and the buffer size. + bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex); + bool maxBuffersAcquired(bool includeExtraAcquire) const REQUIRES(mMutex); + static PixelFormat convertBufferFormat(PixelFormat& format); + + std::string mName; + // Represents the queued buffer count from buffer queue, + // pre-BLAST. This is mNumFrameAvailable (buffers that queued to blast) + + // mNumAcquired (buffers that queued to SF) mPendingRelease.size() (buffers that are held by + // blast). This counter is read by android studio profiler. + std::string mQueuedBufferTrace; sp<SurfaceControl> mSurfaceControl; std::mutex mMutex; @@ -102,21 +137,61 @@ private: // BufferQueue internally allows 1 more than // the max to be acquired - static const int MAX_ACQUIRED_BUFFERS = 1; + int32_t mMaxAcquiredBuffers = 1; int32_t mNumFrameAvailable GUARDED_BY(mMutex); int32_t mNumAcquired GUARDED_BY(mMutex); - struct PendingReleaseItem { - BufferItem item; + // Keep a reference to the submitted buffers so we can release when surfaceflinger drops the + // buffer or the buffer has been presented and a new buffer is ready to be presented. + std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted + GUARDED_BY(mMutex); + + // Keep a queue of the released buffers instead of immediately releasing + // the buffers back to the buffer queue. This would be controlled by SF + // setting the max acquired buffer count. + struct ReleasedBuffer { + ReleaseCallbackId callbackId; sp<Fence> releaseFence; }; + std::deque<ReleasedBuffer> mPendingRelease GUARDED_BY(mMutex); + + ui::Size mSize GUARDED_BY(mMutex); + ui::Size mRequestedSize GUARDED_BY(mMutex); + int32_t mFormat GUARDED_BY(mMutex); + + struct BufferInfo { + bool hasBuffer = false; + uint32_t width; + uint32_t height; + uint32_t transform; + // This is used to check if we should update the blast layer size immediately or wait until + // we get the next buffer. This will support scenarios where the layer can change sizes + // and the buffer will scale to fit the new size. + uint32_t scalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; + Rect crop; + + void update(bool hasBuffer, uint32_t width, uint32_t height, uint32_t transform, + uint32_t scalingMode, const Rect& crop) { + this->hasBuffer = hasBuffer; + this->width = width; + this->height = height; + this->transform = transform; + this->scalingMode = scalingMode; + if (!crop.isEmpty()) { + this->crop = crop; + } else { + this->crop = Rect(width, height); + } + } + }; - std::queue<const BufferItem> mSubmitted GUARDED_BY(mMutex); - PendingReleaseItem mPendingReleaseItem GUARDED_BY(mMutex); - - int mWidth GUARDED_BY(mMutex); - int mHeight GUARDED_BY(mMutex); + // Last acquired buffer's info. This is used to calculate the correct scale when size change is + // requested. We need to use the old buffer's info to determine what scale we need to apply to + // ensure the correct size. + BufferInfo mLastBufferInfo GUARDED_BY(mMutex); + void setMatrix(SurfaceComposerClient::Transaction* t, const BufferInfo& bufferInfo) + REQUIRES(mMutex); uint32_t mTransformHint GUARDED_BY(mMutex); @@ -125,6 +200,37 @@ private: sp<BLASTBufferItemConsumer> mBufferItemConsumer; SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex); + std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> + mPendingTransactions GUARDED_BY(mMutex); + + // Last requested auto refresh state set by the producer. The state indicates that the consumer + // should acquire the next frame as soon as it can and not wait for a frame to become available. + // This is only relevant for shared buffer mode. + bool mAutoRefresh GUARDED_BY(mMutex) = false; + + std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); + + // Tracks the last acquired frame number + uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; + + std::function<void(int64_t)> mTransactionCompleteCallback GUARDED_BY(mMutex) = nullptr; + uint64_t mTransactionCompleteFrameNumber GUARDED_BY(mMutex){0}; + + // Queues up transactions using this token in SurfaceFlinger. This prevents queued up + // transactions from other parts of the client from blocking this transaction. + const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = new BBinder(); + + // Guards access to mDequeueTimestamps since we cannot hold to mMutex in onFrameDequeued or + // we will deadlock. + std::mutex mTimestampMutex; + // Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses + // it for debugging purposes. + std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps + GUARDED_BY(mTimestampMutex); + + // Keep track of SurfaceControls that have submitted a transaction and BBQ is waiting on a + // callback for them. + std::queue<sp<SurfaceControl>> mSurfaceControlsWithPendingCallback GUARDED_BY(mMutex); }; } // namespace android |