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

Commit 3786b829 authored by guodalin's avatar guodalin Committed by Melody Hsu
Browse files

Fix SurfaceFlinger crash caused by layerleak



when add layer more than 4096,surfaceflinger will crash and some log dont finish save

Bug: 382620055
Flag: EXEMPT, bug fix
Test: manually test
Test: create layer more than 4096

Change-Id: Ic6234567520fea06ed5af1b549ccc5b86461fec1
Signed-off-by: default avatarguodalin <guodalin@xiaomi.corp-partner.google.com>
parent a234a4a6
Loading
Loading
Loading
Loading
+38 −27
Original line number Diff line number Diff line
@@ -4605,27 +4605,6 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co
status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
                                        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([&]() 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;
    }

    if (outTransformHint) {
        *outTransformHint = mActiveDisplayTransformHint;
    }
@@ -5408,16 +5387,15 @@ status_t SurfaceFlinger::mirrorDisplay(DisplayId displayId, const LayerCreationA
        mirrorArgs.addToRoot = true;
        mirrorArgs.layerStackToMirror = layerStack;
        result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer);
        if (result != NO_ERROR) {
            return result;
        }
        outResult.layerId = rootMirrorLayer->sequence;
        outResult.layerName = String16(rootMirrorLayer->getDebugName());
        result |= addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
        addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
                       nullptr /* parent */, nullptr /* outTransformHint */);
    }

    if (result != NO_ERROR) {
        return result;
    }

    setTransactionFlags(eTransactionFlushNeeded);
    return NO_ERROR;
}
@@ -5435,6 +5413,9 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurface
            [[fallthrough]];
        case ISurfaceComposerClient::eFXSurfaceEffect: {
            result = createBufferStateLayer(args, &outResult.handle, &layer);
            if (result != NO_ERROR) {
                return result;
            }
            std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
            if (pendingBufferCounter) {
                std::string counterName = layer->getPendingBufferCounterName();
@@ -5475,6 +5456,9 @@ status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurface

status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    if (checkLayerLeaks() != NO_ERROR) {
        return NO_MEMORY;
    }
    *outLayer = getFactory().createBufferStateLayer(args);
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
@@ -5482,11 +5466,38 @@ status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBin

status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
                                           sp<Layer>* outLayer) {
    if (checkLayerLeaks() != NO_ERROR) {
        return NO_MEMORY;
    }
    *outLayer = getFactory().createEffectLayer(args);
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
}

status_t SurfaceFlinger::checkLayerLeaks() {
    if (mNumLayers >= MAX_LAYERS) {
        static std::atomic<nsecs_t> lasttime{0};
        nsecs_t now = systemTime();
        if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
            ALOGE("CreateLayer already dumped 10s before");
            return NO_MEMORY;
        } else {
            lasttime = now;
        }

        ALOGE("CreateLayer 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;
    }
    return NO_ERROR;
}

void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) {
    {
        // Used to remove stalled transactions which uses an internal lock.
+3 −0
Original line number Diff line number Diff line
@@ -845,6 +845,9 @@ private:
    status_t createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* outHandle,
                               sp<Layer>* outLayer);

    // Checks if there are layer leaks before creating layer
    status_t checkLayerLeaks();

    status_t mirrorLayer(const LayerCreationArgs& args, const sp<IBinder>& mirrorFromHandle,
                         gui::CreateSurfaceResult& outResult);