Merge "Update pending buffer counts immediately" into sc-dev
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 3137ee7..296085a 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -869,18 +869,13 @@
return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight;
}
-void BufferStateLayer::incrementPendingBufferCount() {
- mPendingBufferTransactions++;
- tracePendingBufferCount();
-}
-
void BufferStateLayer::decrementPendingBufferCount() {
- mPendingBufferTransactions--;
- tracePendingBufferCount();
+ int32_t pendingBuffers = --mPendingBufferTransactions;
+ tracePendingBufferCount(pendingBuffers);
}
-void BufferStateLayer::tracePendingBufferCount() {
- ATRACE_INT(mBlastTransactionName.c_str(), mPendingBufferTransactions);
+void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) {
+ ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
}
uint32_t BufferStateLayer::doTransaction(uint32_t flags) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 175a40b..6b422ea 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -113,9 +113,10 @@
uint32_t getEffectiveScalingMode() const override;
// See mPendingBufferTransactions
- void incrementPendingBufferCount() override;
void decrementPendingBufferCount();
uint32_t doTransaction(uint32_t flags) override;
+ std::atomic<int32_t>* getPendingBufferCounter() override { return &mPendingBufferTransactions; }
+ std::string getPendingBufferCounterName() override { return mBlastTransactionName; }
protected:
void gatherBufferInfo() override;
@@ -127,7 +128,7 @@
friend class TransactionFrameTracerTest;
friend class TransactionSurfaceFrameTest;
- inline void tracePendingBufferCount();
+ inline void tracePendingBufferCount(int32_t pendingBuffers);
bool updateFrameEventHistory(const sp<Fence>& acquireFence, nsecs_t postedTime,
nsecs_t requestedPresentTime);
@@ -184,7 +185,7 @@
// - 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};
+ std::atomic<int32_t> mPendingBufferTransactions{0};
// TODO(marissaw): support sticky transform for LEGACY camera mode
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index a072554..ce97155 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -503,8 +503,6 @@
virtual void useEmptyDamage() {}
Region getVisibleRegion(const DisplayDevice*) const;
- virtual void incrementPendingBufferCount() {}
-
/*
* isOpaque - true if this surface is opaque
*
@@ -948,6 +946,9 @@
bool setStretchEffect(const StretchEffect& effect);
StretchEffect getStretchEffect() const;
+ virtual std::atomic<int32_t>* getPendingBufferCounter() { return nullptr; }
+ virtual std::string getPendingBufferCounterName() { return ""; }
+
protected:
class SyncPoint {
public:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 350a3c8..bac79bf 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3271,7 +3271,6 @@
if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp,
transaction.desiredPresentTime,
transaction.states,
- false /* updateTransactionCounters*/,
pendingBuffers)) {
setTransactionFlags(eTransactionFlushNeeded);
break;
@@ -3296,13 +3295,9 @@
const auto& transaction = mTransactionQueue.front();
bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) !=
mPendingTransactionQueues.end();
- // Call transactionIsReadyToBeApplied first in case we need to
- // incrementPendingBufferCount and keep track of pending buffers
- // if the transaction contains a buffer.
if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp,
transaction.desiredPresentTime,
transaction.states,
- true /* updateTransactionCounters */,
pendingBuffers) ||
pendingTransactions) {
mPendingTransactionQueues[transaction.applyToken].push(transaction);
@@ -3334,7 +3329,6 @@
bool SurfaceFlinger::transactionIsReadyToBeApplied(
bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states,
- bool updateTransactionCounters,
std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& pendingBuffers) {
const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
bool ready = true;
@@ -3373,10 +3367,6 @@
ATRACE_NAME("!isVsyncValidForUid");
ready = false;
}
- if (updateTransactionCounters) {
- // See BufferStateLayer::mPendingBufferTransactions
- layer->incrementPendingBufferCount();
- }
// If backpressure is enabled and we already have a buffer to commit, keep the transaction
// in the queue.
@@ -3467,6 +3457,13 @@
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
ATRACE_CALL();
+ // Check for incoming buffer updates and increment the pending buffer count.
+ for (const auto& state : states) {
+ if ((state.state.what & layer_state_t::eAcquireFenceChanged) && (state.state.surface)) {
+ mBufferCountTracker.increment(state.state.surface->localBinder());
+ }
+ }
+
uint32_t permissions =
callingThreadHasUnscopedSurfaceFlingerAccess() ? Permission::ACCESS_SURFACE_FLINGER : 0;
// Avoid checking for rotation permissions if the caller already has ACCESS_SURFACE_FLINGER
@@ -4044,10 +4041,16 @@
std::move(metadata), format, handle, gbp, &layer);
break;
- case ISurfaceComposerClient::eFXSurfaceBufferState:
+ case ISurfaceComposerClient::eFXSurfaceBufferState: {
result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
- break;
+ std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
+ if (pendingBufferCounter) {
+ std::string counterName = layer->getPendingBufferCounterName();
+ mBufferCountTracker.add((*handle)->localBinder(), counterName,
+ pendingBufferCounter);
+ }
+ } break;
case ISurfaceComposerClient::eFXSurfaceEffect:
// check if buffer size is set for color layer.
if (w > 0 || h > 0) {
@@ -4214,6 +4217,7 @@
auto it = mLayersByLocalBinderToken.begin();
while (it != mLayersByLocalBinderToken.end()) {
if (it->second == layer) {
+ mBufferCountTracker.remove(it->first->localBinder());
it = mLayersByLocalBinderToken.erase(it);
} else {
it++;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1615ab6..131721d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -416,6 +416,43 @@
void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
};
+ // Keeps track of pending buffers per layer handle in the transaction queue or current/drawing
+ // state before the buffers are latched. The layer owns the atomic counters and decrements the
+ // count in the main thread when dropping or latching a buffer.
+ //
+ // The binder threads increment the same counter when a new transaction containing a buffer is
+ // added to the transaction queue. The map is updated with the layer handle lifecycle updates.
+ // This is done to avoid lock contention with the main thread.
+ class BufferCountTracker {
+ public:
+ void increment(BBinder* layerHandle) {
+ std::lock_guard<std::mutex> lock(mLock);
+ auto it = mCounterByLayerHandle.find(layerHandle);
+ if (it != mCounterByLayerHandle.end()) {
+ auto [name, pendingBuffers] = it->second;
+ int32_t count = ++(*pendingBuffers);
+ ATRACE_INT(name.c_str(), count);
+ } else {
+ ALOGW("Handle not found! %p", layerHandle);
+ }
+ }
+
+ void add(BBinder* layerHandle, const std::string& name, std::atomic<int32_t>* counter) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mCounterByLayerHandle[layerHandle] = std::make_pair(name, counter);
+ }
+
+ void remove(BBinder* layerHandle) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mCounterByLayerHandle.erase(layerHandle);
+ }
+
+ private:
+ std::mutex mLock;
+ std::unordered_map<BBinder*, std::pair<std::string, std::atomic<int32_t>*>>
+ mCounterByLayerHandle GUARDED_BY(mLock);
+ };
+
struct ActiveModeInfo {
DisplayModeId modeId;
Scheduler::ModeEvent event = Scheduler::ModeEvent::None;
@@ -764,7 +801,6 @@
void commitOffscreenLayers();
bool transactionIsReadyToBeApplied(
bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states,
- bool updateTransactionCounters,
std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& pendingBuffers)
REQUIRES(mStateLock);
uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock);
@@ -1314,6 +1350,8 @@
int mFrameRateFlexibilityTokenCount = 0;
sp<IBinder> mDebugFrameRateFlexibilityToken;
+
+ BufferCountTracker mBufferCountTracker;
};
} // namespace android