diff options
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 33 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.h | 18 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 24 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 |
5 files changed, 75 insertions, 7 deletions
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index b6c59cde03..0b9cabae3d 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -347,6 +347,12 @@ bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence if (mCurrentState.buffer) { mReleasePreviousBuffer = true; + if (mCurrentState.buffer != mDrawingState.buffer) { + // If mCurrentState has a buffer, and we are about to update again + // before swapping to drawing state, then the first buffer will be + // dropped and we should decrement the pending buffer count. + decrementPendingBufferCount(); + } } mCurrentState.frameNumber = frameNumber; @@ -629,6 +635,7 @@ status_t BufferStateLayer::updateActiveBuffer() { if (s.buffer == nullptr) { return BAD_VALUE; } + decrementPendingBufferCount(); mPreviousBufferId = getCurrentBufferId(); mBufferInfo.mBuffer = s.buffer; @@ -826,6 +833,32 @@ bool BufferStateLayer::bufferNeedsFiltering() const { const Rect layerSize{getBounds()}; return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight; } + +void BufferStateLayer::incrementPendingBufferCount() { + mPendingBufferTransactions++; + tracePendingBufferCount(); +} + +void BufferStateLayer::decrementPendingBufferCount() { + mPendingBufferTransactions--; + tracePendingBufferCount(); +} + +void BufferStateLayer::tracePendingBufferCount() { + ATRACE_INT(mBlastTransactionName.c_str(), mPendingBufferTransactions); +} + +uint32_t BufferStateLayer::doTransaction(uint32_t flags) { + if (mDrawingState.buffer != nullptr && mDrawingState.buffer != mBufferInfo.mBuffer) { + // If we are about to update mDrawingState.buffer but it has not yet latched + // then we will drop a buffer and should decrement the pending buffer count. + // This logic may not work perfectly in the face of a BufferStateLayer being the + // deferred side of a deferred transaction, but we don't expect this use case. + decrementPendingBufferCount(); + } + return Layer::doTransaction(flags); +} + } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 69b27e4467..ad00c65651 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -112,6 +112,11 @@ public: bool onPreComposition(nsecs_t refreshStartTime) override; uint32_t getEffectiveScalingMode() const override; + // See mPendingBufferTransactions + void incrementPendingBufferCount() override; + void decrementPendingBufferCount(); + uint32_t doTransaction(uint32_t flags) override; + protected: void gatherBufferInfo() override; uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const; @@ -119,6 +124,7 @@ protected: private: friend class SlotGenerationTest; + inline void tracePendingBufferCount(); bool updateFrameEventHistory(const sp<Fence>& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime); @@ -163,6 +169,18 @@ private: std::deque<std::shared_ptr<android::frametimeline::SurfaceFrame>> mPendingJankClassifications; + const std::string mBlastTransactionName{"BufferTX - " + mName}; + // This integer is incremented everytime a buffer arrives at the server for this layer, + // and decremented when a buffer is dropped or latched. When changed the integer is exported + // to systrace with ATRACE_INT and mBlastTransactionName. This way when debugging perf it is + // possible to see when a buffer arrived at the server, and in which frame it latched. + // + // You can understand the trace this way: + // - If the integer increases, a buffer arrived at the server. + // - If the integer decreases in latchBuffer, that buffer was latched + // - If the integer decreases in setBuffer or doTransaction, a buffer was dropped + uint64_t mPendingBufferTransactions{0}; + // TODO(marissaw): support sticky transform for LEGACY camera mode class HwcSlotGenerator : public ClientCache::ErasedRecipient { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2cfdba3e50..bb897d59b1 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -481,6 +481,8 @@ public: virtual void useSurfaceDamage() {} virtual void useEmptyDamage() {} + virtual void incrementPendingBufferCount() {} + /* * isOpaque - true if this surface is opaque * @@ -745,7 +747,7 @@ public: * doTransaction - process the transaction. This is a good place to figure * out which attributes of the surface have changed. */ - uint32_t doTransaction(uint32_t transactionFlags); + virtual uint32_t doTransaction(uint32_t transactionFlags); /* * Remove relative z for the layer if its relative parent is not part of the diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 85c98a58fb..23ddf0a4ba 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3273,14 +3273,16 @@ bool SurfaceFlinger::transactionFlushNeeded() { bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, - const Vector<ComposerState>& states) { + const Vector<ComposerState>& states, + bool updateTransactionCounters) { const nsecs_t expectedPresentTime = mExpectedPresentTime.load(); + bool ready = true; // Do not present if the desiredPresentTime has not passed unless it is more than one second // in the future. We ignore timestamps more than 1 second in the future for stability reasons. if (desiredPresentTime >= 0 && desiredPresentTime >= expectedPresentTime && desiredPresentTime < expectedPresentTime + s2ns(1)) { - return false; + ready = false; } for (const ComposerState& state : states) { @@ -3289,10 +3291,22 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, continue; } if (s.acquireFence && s.acquireFence->getStatus() == Fence::Status::Unsignaled) { - return false; + ready = false; + } + if (updateTransactionCounters) { + sp<Layer> layer = nullptr; + if (s.surface) { + layer = fromHandleLocked(s.surface).promote(); + } else { + ALOGW("Transaction with buffer, but no Layer?"); + continue; + } + // See BufferStateLayer::mPendingBufferTransactions + if (layer) layer->incrementPendingBufferCount(); + } } - return true; + return ready; } status_t SurfaceFlinger::setTransactionState( @@ -3336,7 +3350,7 @@ status_t SurfaceFlinger::setTransactionState( const int originPid = ipc->getCallingPid(); const int originUid = ipc->getCallingUid(); - if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) { + if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states, true)) { mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags, desiredPresentTime, uncacheBuffer, postTime, privileged, hasListenerCallbacks, listenerCallbacks, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 2e4d1cef43..542ba987e6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -745,7 +745,8 @@ private: void commitTransaction() REQUIRES(mStateLock); void commitOffscreenLayers(); bool transactionIsReadyToBeApplied(int64_t desiredPresentTime, - const Vector<ComposerState>& states); + const Vector<ComposerState>& states, + bool updateTransactionCounters = false) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); |