Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88681d08 authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge changes I728a94c5,I15af2888,I78169654 into main

* changes:
  Remove legacy transform hint
  Remove legacy layer traversal for FrameStats logging
  Adapt addClientLayer to LayerHierarchy.
parents a278f86e 0ae2eb89
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -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};

+3 −0
Original line number Diff line number Diff line
@@ -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*);
+0 −15
Original line number Diff line number Diff line
@@ -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;
}
+0 −6
Original line number Diff line number Diff line
@@ -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;
+15 −127
Original line number Diff line number Diff line
@@ -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) {
        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" : ""));
                        }
                    });
        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;
        }
            });

            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));
                }
            }
        ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
              MAX_LAYERS);
        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() {
Loading