Merge changes I728a94c5,I15af2888,I78169654 into main
* changes:
Remove legacy transform hint
Remove legacy layer traversal for FrameStats logging
Adapt addClientLayer to LayerHierarchy.
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
index f4335f3..d709530 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
@@ -18,6 +18,8 @@
#undef LOG_TAG
#define LOG_TAG "SurfaceFlinger"
+#include <android-base/logging.h>
+
#include "LayerHierarchy.h"
#include "LayerLog.h"
#include "SwapErase.h"
@@ -485,6 +487,55 @@
return it->second;
}
+void LayerHierarchyBuilder::logSampledChildren(const LayerHierarchy& hierarchy) const {
+ LOG(ERROR) << "Dumping random sampling of child layers.";
+ int sampleSize = static_cast<int>(hierarchy.mChildren.size() / 100 + 1);
+ for (const auto& [child, variant] : hierarchy.mChildren) {
+ if (rand() % sampleSize == 0) {
+ LOG(ERROR) << "Child Layer: " << *(child->mLayer);
+ }
+ }
+}
+
+void LayerHierarchyBuilder::dumpLayerSample(const LayerHierarchy& root) const {
+ LOG(ERROR) << "Dumping layer keeping > 20 children alive:";
+ // If mLayer is nullptr, it will be skipped while traversing.
+ if (!root.mLayer && root.mChildren.size() > 20) {
+ LOG(ERROR) << "ROOT has " << root.mChildren.size() << " children";
+ logSampledChildren(root);
+ }
+ root.traverse([&](const LayerHierarchy& hierarchy, const auto&) -> bool {
+ if (hierarchy.mChildren.size() <= 20) {
+ return true;
+ }
+ // mLayer is ensured to be non-null. See LayerHierarchy::traverse.
+ const auto* layer = hierarchy.mLayer;
+ const auto childrenCount = hierarchy.mChildren.size();
+ LOG(ERROR) << "Layer " << *layer << " has " << childrenCount << " children";
+
+ const auto* parent = hierarchy.mParent;
+ while (parent != nullptr) {
+ if (!parent->mLayer) break;
+ LOG(ERROR) << "Parent Layer: " << *(parent->mLayer);
+ parent = parent->mParent;
+ }
+
+ logSampledChildren(hierarchy);
+ // Stop traversing.
+ return false;
+ });
+ LOG(ERROR) << "Dumping random sampled layers.";
+ size_t numLayers = 0;
+ root.traverse([&](const LayerHierarchy& hierarchy, const auto&) -> bool {
+ if (hierarchy.mLayer) numLayers++;
+ if ((rand() % 20 == 13) && hierarchy.mLayer) {
+ LOG(ERROR) << "Layer: " << *(hierarchy.mLayer);
+ }
+ return true;
+ });
+ LOG(ERROR) << "Total layer count: " << numLayers;
+}
+
const LayerHierarchy::TraversalPath LayerHierarchy::TraversalPath::ROOT =
{.id = UNASSIGNED_LAYER_ID, .variant = LayerHierarchy::Attached};
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
index d023f9e..47d0041 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
@@ -211,8 +211,11 @@
const LayerHierarchy& getHierarchy() const;
const LayerHierarchy& getOffscreenHierarchy() const;
std::string getDebugString(uint32_t layerId, uint32_t depth = 0) const;
+ void dumpLayerSample(const LayerHierarchy& layerHierarchy) const;
private:
+ void logSampledChildren(const LayerHierarchy& hierarchy) const;
+
void onLayerAdded(RequestedLayerState* layer);
void attachToParent(LayerHierarchy*);
void detachFromParent(LayerHierarchy*);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index abdf92c..3ca2e5b 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1350,14 +1350,6 @@
return usage;
}
-void Layer::updateTransformHint(ui::Transform::RotationFlags transformHint) {
- if (mFlinger->mDebugDisableTransformHint || transformHint & ui::Transform::ROT_INVALID) {
- transformHint = ui::Transform::ROT_0;
- }
-
- setTransformHintLegacy(transformHint);
-}
-
// ----------------------------------------------------------------------------
// debugging
// ----------------------------------------------------------------------------
@@ -4001,13 +3993,6 @@
return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
}
-void Layer::setTransformHintLegacy(ui::Transform::RotationFlags displayTransformHint) {
- mTransformHintLegacy = getFixedTransformHint();
- if (mTransformHintLegacy == ui::Transform::ROT_INVALID) {
- mTransformHintLegacy = displayTransformHint;
- }
-}
-
const std::shared_ptr<renderengine::ExternalTexture>& Layer::getExternalTexture() const {
return mBufferInfo.mBuffer;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 948c62d..f6eed63 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -687,10 +687,6 @@
*/
void addToCurrentState();
- /*
- * Sets display transform hint on BufferLayerConsumer.
- */
- void updateTransformHint(ui::Transform::RotationFlags);
inline const State& getDrawingState() const { return mDrawingState; }
inline State& getDrawingState() { return mDrawingState; }
@@ -1212,13 +1208,11 @@
bool findInHierarchy(const sp<Layer>&);
- void setTransformHintLegacy(ui::Transform::RotationFlags);
void releasePreviousBuffer();
void resetDrawingStateBufferInfo();
// Transform hint provided to the producer. This must be accessed holding
// the mStateLock.
- ui::Transform::RotationFlags mTransformHintLegacy = ui::Transform::ROT_0;
std::optional<ui::Transform::RotationFlags> mTransformHint = std::nullopt;
ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9eca01a..d197f15 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3932,51 +3932,6 @@
mUpdateInputInfo = true;
}
- // Update transform hint.
- if (transactionFlags & (eTransformHintUpdateNeeded | eDisplayTransactionNeeded)) {
- // Layers and/or displays have changed, so update the transform hint for each layer.
- //
- // NOTE: we do this here, rather than when presenting the display so that
- // the hint is set before we acquire a buffer from the surface texture.
- //
- // NOTE: layer transactions have taken place already, so we use their
- // drawing state. However, SurfaceFlinger's own transaction has not
- // happened yet, so we must use the current state layer list
- // (soon to become the drawing state list).
- //
- sp<const DisplayDevice> hintDisplay;
- ui::LayerStack layerStack;
-
- mCurrentState.traverse([&](Layer* layer) REQUIRES(mStateLock) {
- // NOTE: we rely on the fact that layers are sorted by
- // layerStack first (so we don't have to traverse the list
- // of displays for every layer).
- if (const auto filter = layer->getOutputFilter(); layerStack != filter.layerStack) {
- layerStack = filter.layerStack;
- hintDisplay = nullptr;
-
- // Find the display that includes the layer.
- for (const auto& [token, display] : mDisplays) {
- if (!display->getCompositionDisplay()->includesLayer(filter)) {
- continue;
- }
-
- // Pick the primary display if another display mirrors the layer.
- if (hintDisplay) {
- hintDisplay = nullptr;
- break;
- }
-
- hintDisplay = display;
- }
- }
-
- if (hintDisplay) {
- layer->updateTransformHint(hintDisplay->getTransformHint());
- }
- });
- }
-
if (mLayersAdded) {
mLayersAdded = false;
// Layers have been added.
@@ -4473,65 +4428,26 @@
const sp<Layer>& layer, const wp<Layer>& parent,
uint32_t* outTransformHint) {
if (mNumLayers >= MAX_LAYERS) {
+ static std::atomic<nsecs_t> lasttime{0};
+ nsecs_t now = systemTime();
+ if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
+ ALOGE("AddClientLayer already dumped 10s before");
+ return NO_MEMORY;
+ } else {
+ lasttime = now;
+ }
+
ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
MAX_LAYERS);
- static_cast<void>(mScheduler->schedule([=, this] {
- ALOGE("Dumping layer keeping > 20 children alive:");
- bool leakingParentLayerFound = false;
- mDrawingState.traverse([&](Layer* layer) {
- if (leakingParentLayerFound) {
- return;
- }
- if (layer->getChildrenCount() > 20) {
- leakingParentLayerFound = true;
- sp<Layer> parent = sp<Layer>::fromExisting(layer);
- while (parent) {
- ALOGE("Parent Layer: %s%s", parent->getName().c_str(),
- (parent->isHandleAlive() ? "handleAlive" : ""));
- parent = parent->getParent();
- }
- // Sample up to 100 layers
- ALOGE("Dumping random sampling of child layers total(%zu): ",
- layer->getChildrenCount());
- int sampleSize = (layer->getChildrenCount() / 100) + 1;
- layer->traverseChildren([&](Layer* layer) {
- if (rand() % sampleSize == 0) {
- ALOGE("Child Layer: %s%s", layer->getName().c_str(),
- (layer->isHandleAlive() ? "handleAlive" : ""));
- }
- });
- }
- });
-
- int numLayers = 0;
- mDrawingState.traverse([&](Layer* layer) { numLayers++; });
-
- ALOGE("Dumping random sampling of on-screen layers total(%u):", numLayers);
- mDrawingState.traverse([&](Layer* layer) {
- // Aim to dump about 200 layers to avoid totally trashing
- // logcat. On the other hand, if there really are 4096 layers
- // something has gone totally wrong its probably the most
- // useful information in logcat.
- if (rand() % 20 == 13) {
- ALOGE("Layer: %s%s", layer->getName().c_str(),
- (layer->isHandleAlive() ? "handleAlive" : ""));
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- }
- });
- ALOGE("Dumping random sampling of off-screen layers total(%zu): ",
- mOffscreenLayers.size());
- for (Layer* offscreenLayer : mOffscreenLayers) {
- if (rand() % 20 == 13) {
- ALOGE("Offscreen-layer: %s%s", offscreenLayer->getName().c_str(),
- (offscreenLayer->isHandleAlive() ? "handleAlive" : ""));
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- }
- }
+ static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) {
+ ALOGE("Dumping on-screen layers.");
+ mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy());
+ ALOGE("Dumping off-screen layers.");
+ mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy());
}));
return NO_MEMORY;
}
- layer->updateTransformHint(mActiveDisplayTransformHint);
if (outTransformHint) {
*outTransformHint = mActiveDisplayTransformHint;
}
@@ -5746,7 +5662,7 @@
sTimestamp = now;
SFTRACE_CALL();
- mDrawingState.traverse([&](Layer* layer) { layer->logFrameStats(); });
+ traverseLegacyLayers([&](Layer* layer) { layer->logFrameStats(); });
}
void SurfaceFlinger::appendSfConfigString(std::string& result) const {
@@ -6049,20 +5965,6 @@
.get();
}
-void SurfaceFlinger::dumpOffscreenLayers(std::string& result) {
- auto future = mScheduler->schedule([this] {
- std::string result;
- for (Layer* offscreenLayer : mOffscreenLayers) {
- offscreenLayer->traverse(LayerVector::StateSet::Drawing,
- [&](Layer* layer) { layer->dumpOffscreenDebugInfo(result); });
- }
- return result;
- });
-
- result.append("Offscreen Layers:\n");
- result.append(future.get());
-}
-
void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
const auto displayId = HalDisplayId::tryCast(display->getId());
@@ -8195,20 +8097,6 @@
} else {
parent->addChild(layer);
}
-
- ui::LayerStack layerStack = layer->getLayerStack(LayerVector::StateSet::Current);
- sp<const DisplayDevice> hintDisplay;
- // Find the display that includes the layer.
- for (const auto& [token, display] : mDisplays) {
- if (display->getLayerStack() == layerStack) {
- hintDisplay = display;
- break;
- }
- }
-
- if (hintDisplay) {
- layer->updateTransformHint(hintDisplay->getTransformHint());
- }
}
void SurfaceFlinger::sample() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 651f2d3..7127876 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1147,7 +1147,6 @@
void dumpHwc(std::string& result) const;
perfetto::protos::LayersProto dumpProtoFromMainThread(
uint32_t traceFlags = LayerTracing::TRACE_ALL) EXCLUDES(mStateLock);
- void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
void dumpPlannerInfo(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock);
status_t doDump(int fd, const DumpArgs& args, bool asProto);