diff options
| -rw-r--r-- | services/surfaceflinger/FrontEnd/LayerHierarchy.cpp | 51 | ||||
| -rw-r--r-- | services/surfaceflinger/FrontEnd/LayerHierarchy.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 15 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 142 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 |
6 files changed, 69 insertions, 149 deletions
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp index f4335f36bc..d709530990 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 @@ LayerHierarchy* LayerHierarchyBuilder::getHierarchyFromId(uint32_t layerId, bool 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 d023f9e9f5..47d0041a8b 100644 --- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h +++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h @@ -211,8 +211,11 @@ public: 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 abdf92cd40..3ca2e5b6ec 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1350,14 +1350,6 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const { 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 @@ sp<GraphicBuffer> Layer::getBuffer() const { 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 948c62df3c..f6eed6332b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -687,10 +687,6 @@ public: */ 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 @@ private: 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 9eca01a453..d197f15249 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3932,51 +3932,6 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { 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 @@ status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinde 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 @@ void SurfaceFlinger::logFrameStats(TimePoint now) { 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 @@ perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t t .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 @@ void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state, Vs } 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 651f2d32ba..71278764dc 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1147,7 +1147,6 @@ private: 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); |