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

Commit e3721979 authored by guodalin's avatar guodalin Committed by Vishnu Nair
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

Test: manually test

create layer more than 4096

Change-Id: Ic6234567520fea06ed5af1b549ccc5b86461fec1
Merged-In: Ic6234567520fea06ed5af1b549ccc5b86461fec1
Signed-off-by: default avatarguodalin <guodalin@xiaomi.corp-partner.google.com>
parent 99871bfe
Loading
Loading
Loading
Loading
+37 −26
Original line number Diff line number Diff line
@@ -4354,27 +4354,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;
    }
@@ -5145,16 +5124,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;
}
@@ -5172,6 +5150,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();
@@ -5211,6 +5192,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;
@@ -5218,11 +5202,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(BBinder* handle, 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
@@ -835,6 +835,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);