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

Commit 741c9e01 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Add LayerSnapshotGuard to manage layer snapshot"

parents edfce733 377c0146
Loading
Loading
Loading
Loading
+22 −8
Original line number Diff line number Diff line
@@ -3535,14 +3535,6 @@ const compositionengine::LayerFECompositionState* Layer::getCompositionState() c
    return mSnapshot.get();
}

void Layer::moveSnapshotToLayerFE() {
    mLayerFE->mSnapshot = std::move(mSnapshot);
}

void Layer::moveSnapshotToLayer() {
    mSnapshot = std::move(mLayerFE->mSnapshot);
}

void Layer::useSurfaceDamage() {
    if (mFlinger->mForceFullDamage) {
        surfaceDamageRegion = Region::INVALID_REGION;
@@ -4007,6 +3999,28 @@ void Layer::updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMet
    }
}

LayerSnapshotGuard::LayerSnapshotGuard(Layer* layer) : mLayer(layer) {
    if (mLayer) {
        mLayer->mLayerFE->mSnapshot = std::move(mLayer->mSnapshot);
    }
}

LayerSnapshotGuard::~LayerSnapshotGuard() {
    if (mLayer) {
        mLayer->mSnapshot = std::move(mLayer->mLayerFE->mSnapshot);
    }
}

LayerSnapshotGuard::LayerSnapshotGuard(LayerSnapshotGuard&& other) : mLayer(other.mLayer) {
    other.mLayer = nullptr;
}

LayerSnapshotGuard& LayerSnapshotGuard::operator=(LayerSnapshotGuard&& other) {
    mLayer = other.mLayer;
    other.mLayer = nullptr;
    return *this;
}

// ---------------------------------------------------------------------------

std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
+25 −9
Original line number Diff line number Diff line
@@ -379,15 +379,6 @@ public:

    virtual sp<LayerFE> getCompositionEngineLayerFE() const;

    // Move LayerSnapshot from this layer into its LayerFE. This must be called before passing the
    // LayerFE to CompositionEngine. Moving the snapshot instead of sharing common state
    // prevents use of LayerFE outside the main thread by making errors obvious (i.e. use outside
    // the main thread results in SEGFAULTs due to nullptr dereference).
    void moveSnapshotToLayerFE();
    // Move LayerSnapshot into this layer from its LayerFE. This must be called after
    // CompositionEngine has presented the layer.
    void moveSnapshotToLayer();

    const LayerSnapshot* getLayerSnapshot() const;
    LayerSnapshot* editLayerSnapshot();

@@ -1188,6 +1179,31 @@ private:

    sp<LayerFE> mLayerFE;
    std::unique_ptr<LayerSnapshot> mSnapshot = std::make_unique<LayerSnapshot>();

    friend class LayerSnapshotGuard;
};

// LayerSnapshotGuard manages the movement of LayerSnapshot between a Layer and its corresponding
// LayerFE. This class must be used whenever LayerFEs are passed to CompositionEngine. Instances of
// LayerSnapshotGuard should only be constructed on the main thread and should not be moved outside
// the main thread.
//
// Moving the snapshot instead of sharing common state prevents use of LayerFE outside the main
// thread by making errors obvious (i.e. use outside the main thread results in SEGFAULTs due to
// nullptr dereference).
class LayerSnapshotGuard {
public:
    LayerSnapshotGuard(Layer* layer) REQUIRES(kMainThreadContext);
    ~LayerSnapshotGuard() REQUIRES(kMainThreadContext);

    LayerSnapshotGuard(const LayerSnapshotGuard&) = delete;
    LayerSnapshotGuard& operator=(const LayerSnapshotGuard&) = delete;

    LayerSnapshotGuard(LayerSnapshotGuard&& other) REQUIRES(kMainThreadContext);
    LayerSnapshotGuard& operator=(LayerSnapshotGuard&& other) REQUIRES(kMainThreadContext);

private:
    Layer* mLayer;
};

std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);
+47 −46
Original line number Diff line number Diff line
@@ -2181,7 +2181,6 @@ void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId)
    mDrawingState.traverseInZOrder([&refreshArgs, &layers](Layer* layer) {
        layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
        if (auto layerFE = layer->getCompositionEngineLayerFE()) {
            layer->moveSnapshotToLayerFE();
            refreshArgs.layers.push_back(layerFE);
            layers.push_back(layer);
        }
@@ -2213,10 +2212,15 @@ void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId)
    // the scheduler.
    const auto presentTime = systemTime();

    {
        std::vector<LayerSnapshotGuard> layerSnapshotGuards;
        for (Layer* layer : layers) {
            layerSnapshotGuards.emplace_back(layer);
        }
        mCompositionEngine->present(refreshArgs);
    }

    for (auto& layer : layers) {
        layer->moveSnapshotToLayer();
        CompositionResult compositionResult{
                layer->getCompositionEngineLayerFE()->stealCompositionResult()};
        layer->onPreComposition(compositionResult.refreshStartTime);
@@ -3312,21 +3316,16 @@ void SurfaceFlinger::updateCursorAsync() {
        }
    }

    std::vector<Layer*> cursorLayers;
    mDrawingState.traverse([&cursorLayers](Layer* layer) {
    std::vector<LayerSnapshotGuard> layerSnapshotGuards;
    mDrawingState.traverse([&layerSnapshotGuards](Layer* layer) {
        if (layer->getLayerSnapshot()->compositionType ==
            aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
            layer->updateSnapshot(false /* updateGeometry */);
            layer->moveSnapshotToLayerFE();
            cursorLayers.push_back(layer);
            layerSnapshotGuards.emplace_back(layer);
        }
    });

    mCompositionEngine->updateCursorAsync(refreshArgs);

    for (Layer* layer : cursorLayers) {
        layer->moveSnapshotToLayer();
    }
}

void SurfaceFlinger::requestDisplayModes(
@@ -6322,8 +6321,9 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(

    bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission();

    auto future = mScheduler->schedule([=, renderAreaFuture = std::move(renderAreaFuture)]() mutable
                                       -> ftl::SharedFuture<FenceResult> {
    auto future = mScheduler->schedule(
            [=, renderAreaFuture = std::move(renderAreaFuture)]() FTL_FAKE_GUARD(
                    kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
                ScreenCaptureResults captureResults;
                std::unique_ptr<RenderArea> renderArea = renderAreaFuture.get();
                if (!renderArea) {
@@ -6334,10 +6334,10 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
                }

                ftl::SharedFuture<FenceResult> renderFuture;
        renderArea->render([&] {
            renderFuture =
                    renderScreenImpl(*renderArea, traverseLayers, buffer, canCaptureBlackoutContent,
                                     regionSampling, grayscale, captureResults);
                renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) {
                    renderFuture = renderScreenImpl(*renderArea, traverseLayers, buffer,
                                                    canCaptureBlackoutContent, regionSampling,
                                                    grayscale, captureResults);
                });

                if (captureListener) {
@@ -6446,7 +6446,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
    const auto display = renderArea.getDisplayDevice();
    std::vector<Layer*> renderedLayers;
    bool disableBlurs = false;
    traverseLayers([&](Layer* layer) {
    traverseLayers([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) {
        // Layer::prepareClientComposition uses the layer's snapshot to populate the resulting
        // LayerSettings. Calling Layer::updateSnapshot ensures that LayerSettings are
        // generated with the layer's current buffer and geometry.
@@ -6477,10 +6477,11 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
            return;
        }

        layer->moveSnapshotToLayerFE();
        std::optional<compositionengine::LayerFE::LayerSettings> settings =
                layerFE->prepareClientComposition(targetSettings);
        layer->moveSnapshotToLayer();
        std::optional<compositionengine::LayerFE::LayerSettings> settings;
        {
            LayerSnapshotGuard layerSnapshotGuard(layer);
            settings = layerFE->prepareClientComposition(targetSettings);
        }

        if (!settings) {
            return;
+2 −1
Original line number Diff line number Diff line
@@ -798,7 +798,8 @@ private:
    ftl::SharedFuture<FenceResult> renderScreenImpl(
            const RenderArea&, TraverseLayersFunction,
            const std::shared_ptr<renderengine::ExternalTexture>&, bool canCaptureBlackoutContent,
            bool regionSampling, bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock);
            bool regionSampling, bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock)
            REQUIRES(kMainThreadContext);

    // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
    // matching ownerUid
+4 −3
Original line number Diff line number Diff line
@@ -401,9 +401,10 @@ public:
                                const std::shared_ptr<renderengine::ExternalTexture>& buffer,
                                bool forSystem, bool regionSampling) {
        ScreenCaptureResults captureResults;
        return mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer, forSystem,
                                                regionSampling, false /* grayscale */,
                                                captureResults);
        return FTL_FAKE_GUARD(kMainThreadContext,
                              mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer,
                                                         forSystem, regionSampling,
                                                         false /* grayscale */, captureResults));
    }

    auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,