SF: Look up buffer caches in binder thread
Avoid locking inside the main thread and contention
with binder thread (via client token binder died).
Test: presubmit
Bug: 238781169
Change-Id: I8a440e9fe3e6f41761d90196ec6128d756735eee
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cfebec7..849fd9c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -104,6 +104,7 @@
#include <optional>
#include <type_traits>
#include <unordered_map>
+#include <vector>
#include <ui/DisplayIdentification.h>
#include "BackgroundExecutor.h"
@@ -3878,7 +3879,7 @@
}
status_t SurfaceFlinger::setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
+ const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
@@ -3910,7 +3911,24 @@
IPCThreadState* ipc = IPCThreadState::self();
const int originPid = ipc->getCallingPid();
const int originUid = ipc->getCallingUid();
- TransactionState state{frameTimelineInfo, states,
+
+ std::vector<ResolvedComposerState> resolvedStates;
+ resolvedStates.reserve(states.size());
+ for (auto& state : states) {
+ resolvedStates.emplace_back(std::move(state));
+ auto& resolvedState = resolvedStates.back();
+ if (resolvedState.state.hasBufferChanges() && resolvedState.state.hasValidBuffer() &&
+ resolvedState.state.surface) {
+ resolvedState.externalTexture =
+ getExternalTextureFromBufferData(*resolvedState.state.bufferData,
+ std::to_string(resolvedState.state.layerId)
+ .c_str(),
+ transactionId);
+ mBufferCountTracker.increment(resolvedState.state.surface->localBinder());
+ }
+ }
+
+ TransactionState state{frameTimelineInfo, resolvedStates,
displays, flags,
applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp,
@@ -3919,11 +3937,6 @@
listenerCallbacks, originPid,
originUid, transactionId};
- // Check for incoming buffer updates and increment the pending buffer count.
- state.traverseStatesWithBuffers([&](const layer_state_t& state) {
- mBufferCountTracker.increment(state.surface->localBinder());
- });
-
if (mTransactionTracing) {
mTransactionTracing->addQueuedTransaction(state);
}
@@ -3942,7 +3955,7 @@
}
bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
- Vector<ComposerState>& states,
+ std::vector<ResolvedComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
@@ -3964,13 +3977,12 @@
}
uint32_t clientStateFlags = 0;
- for (int i = 0; i < states.size(); i++) {
- ComposerState& state = states.editItemAt(i);
+ for (auto& resolvedState : states) {
clientStateFlags |=
- setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
- postTime, permissions, transactionId);
- if ((flags & eAnimation) && state.state.surface) {
- if (const auto layer = LayerHandle::getLayer(state.state.surface)) {
+ setClientStateLocked(frameTimelineInfo, resolvedState, desiredPresentTime,
+ isAutoTimestamp, postTime, permissions, transactionId);
+ if ((flags & eAnimation) && resolvedState.state.surface) {
+ if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) {
using LayerUpdateType = scheduler::LayerHistory::LayerUpdateType;
mScheduler->recordLayerHistory(layer.get(),
isAutoTimestamp ? 0 : desiredPresentTime,
@@ -4082,7 +4094,7 @@
}
uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,
- ComposerState& composerState,
+ ResolvedComposerState& composerState,
int64_t desiredPresentTime, bool isAutoTimestamp,
int64_t postTime, uint32_t permissions,
uint64_t transactionId) {
@@ -4377,11 +4389,9 @@
}
if (what & layer_state_t::eBufferChanged) {
- std::shared_ptr<renderengine::ExternalTexture> buffer =
- getExternalTextureFromBufferData(*s.bufferData, layer->getDebugName(),
- transactionId);
- if (layer->setBuffer(buffer, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp,
- dequeueBufferTimestamp, frameTimelineInfo)) {
+ if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
+ desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp,
+ frameTimelineInfo)) {
flags |= eTraversalNeeded;
}
} else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
@@ -4589,7 +4599,7 @@
LOG_ALWAYS_FATAL_IF(token == nullptr);
// reset screen orientation and use primary layer stack
- Vector<ComposerState> state;
+ std::vector<ResolvedComposerState> state;
Vector<DisplayState> displays;
DisplayState d;
d.what = DisplayState::eDisplayProjectionChanged |
@@ -6974,9 +6984,12 @@
}
if (result.error() == ClientCache::AddError::CacheFull) {
- mTransactionHandler
- .onTransactionQueueStalled(transactionId, bufferData.releaseBufferListener,
- "Buffer processing hung due to full buffer cache");
+ ALOGE("Attempted to create an ExternalTexture for layer %s but CacheFull", layerName);
+
+ if (bufferData.releaseBufferListener) {
+ bufferData.releaseBufferListener->onTransactionQueueStalled(
+ String8("Buffer processing hung due to full buffer cache"));
+ }
}
return nullptr;