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

Commit ea552eda authored by Melody Hsu's avatar Melody Hsu Committed by Android (Google) Code Review
Browse files

Merge "Remove release fence flags" into main

parents e94579b3 0077fde3
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -198,7 +198,6 @@ void CompositionEngine::preComposition(CompositionRefreshArgs& args) {
// these buffers and fire a NO_FENCE to release it. This ensures that all
// promises for buffer releases are fulfilled at the end of composition.
void CompositionEngine::postComposition(CompositionRefreshArgs& args) {
    if (FlagManager::getInstance().ce_fence_promise()) {
    SFTRACE_CALL();
    ALOGV(__FUNCTION__);

@@ -219,7 +218,6 @@ void CompositionEngine::postComposition(CompositionRefreshArgs& args) {
        }
    }
}
}

FeatureFlags CompositionEngine::getFeatureFlags() const {
    return {};
+2 −13
Original line number Diff line number Diff line
@@ -1610,13 +1610,7 @@ void Output::presentFrameAndReleaseLayers(bool flushEvenWhenDisabled) {
            releaseFence =
                    Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
        }
        if (FlagManager::getInstance().ce_fence_promise()) {
        layer->getLayerFE().setReleaseFence(releaseFence);
        } else {
            layer->getLayerFE()
                    .onLayerDisplayed(ftl::yield<FenceResult>(std::move(releaseFence)).share(),
                                      outputState.layerFilter.layerStack);
        }
    }

    // We've got a list of layers needing fences, that are disjoint with
@@ -1624,12 +1618,7 @@ void Output::presentFrameAndReleaseLayers(bool flushEvenWhenDisabled) {
    // supply them with the present fence.
    for (auto& weakLayer : mReleasedLayers) {
        if (const auto layer = weakLayer.promote()) {
            if (FlagManager::getInstance().ce_fence_promise()) {
            layer->setReleaseFence(frame.presentFence);
            } else {
                layer->onLayerDisplayed(ftl::yield<FenceResult>(frame.presentFence).share(),
                                        outputState.layerFilter.layerStack);
            }
        }
    }

+0 −5
Original line number Diff line number Diff line
@@ -30,8 +30,6 @@
#include "TimeStats/TimeStats.h"
#include "gmock/gmock.h"

#include <variant>

using namespace com::android::graphics::surfaceflinger;

namespace android::compositionengine {
@@ -494,9 +492,6 @@ struct CompositionEnginePostCompositionTest : public CompositionEngineTest {
};

TEST_F(CompositionEnginePostCompositionTest, postCompositionReleasesAllFences) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
    ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());

    EXPECT_CALL(*mLayer1FE, getReleaseFencePromiseStatus)
            .WillOnce(Return(LayerFE::ReleaseFencePromiseStatus::FULFILLED));
    EXPECT_CALL(*mLayer2FE, getReleaseFencePromiseStatus)
+0 −134
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@
#include <ui/Rect.h>
#include <ui/Region.h>

#include <cmath>
#include <cstdint>
#include <variant>

@@ -3263,57 +3262,9 @@ TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCom
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}

TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
    ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());
    // Simulate getting release fences from each layer, and ensure they are passed to the
    // front-end layer interface for each layer correctly.

    mOutput.mState.isEnabled = true;

    // Create three unique fence instances
    sp<Fence> layer1Fence = sp<Fence>::make();
    sp<Fence> layer2Fence = sp<Fence>::make();
    sp<Fence> layer3Fence = sp<Fence>::make();

    Output::FrameFences frameFences;
    frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
    frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
    frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);

    EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
    EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());

    // Compare the pointers values of each fence to make sure the correct ones
    // are passed. This happens to work with the current implementation, but
    // would not survive certain calls like Fence::merge() which would return a
    // new instance.
    EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_, _))
            .WillOnce([&layer1Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                     ui::LayerStack) {
                EXPECT_EQ(FenceResult(layer1Fence), futureFenceResult.get());
            });
    EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_, _))
            .WillOnce([&layer2Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                     ui::LayerStack) {
                EXPECT_EQ(FenceResult(layer2Fence), futureFenceResult.get());
            });
    EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_, _))
            .WillOnce([&layer3Fence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                     ui::LayerStack) {
                EXPECT_EQ(FenceResult(layer3Fence), futureFenceResult.get());
            });

    constexpr bool kFlushEvenWhenDisabled = false;
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}

TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
    ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
    // Simulate getting release fences from each layer, and ensure they are passed to the
    // front-end layer interface for each layer correctly.

    mOutput.mState.isEnabled = true;

    // Create three unique fence instances
@@ -3350,37 +3301,7 @@ TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}

TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
    ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());

    mOutput.mState.isEnabled = true;
    mOutput.mState.usesClientComposition = true;

    Output::FrameFences frameFences;
    frameFences.clientTargetAcquireFence = sp<Fence>::make();
    frameFences.layerFences.emplace(&mLayer1.hwc2Layer, sp<Fence>::make());
    frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
    frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());

    EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
    EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());

    // Fence::merge is called, and since none of the fences are actually valid,
    // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
    // This is the best we can do without creating a real kernel fence object.
    EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
    EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
    EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());

    constexpr bool kFlushEvenWhenDisabled = false;
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}

TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFence) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
    ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());

    mOutput.mState.isEnabled = true;
    mOutput.mState.usesClientComposition = true;

@@ -3403,62 +3324,7 @@ TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFenc
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}

TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, false);
    ASSERT_FALSE(FlagManager::getInstance().ce_fence_promise());

    mOutput.mState.isEnabled = true;
    mOutput.mState.usesClientComposition = true;

    // This should happen even if there are no (current) output layers.
    EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));

    // Load up the released layers with some mock instances
    sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
    sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
    sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
    Output::ReleasedLayers layers;
    layers.push_back(releasedLayer1);
    layers.push_back(releasedLayer2);
    layers.push_back(releasedLayer3);
    mOutput.setReleasedLayers(std::move(layers));

    // Set up a fake present fence
    sp<Fence> presentFence = sp<Fence>::make();
    Output::FrameFences frameFences;
    frameFences.presentFence = presentFence;

    EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
    EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());

    // Each released layer should be given the presentFence.
    EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_, _))
            .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                      ui::LayerStack) {
                EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
            });
    EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_, _))
            .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                      ui::LayerStack) {
                EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
            });
    EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_, _))
            .WillOnce([&presentFence](ftl::SharedFuture<FenceResult> futureFenceResult,
                                      ui::LayerStack) {
                EXPECT_EQ(FenceResult(presentFence), futureFenceResult.get());
            });

    constexpr bool kFlushEvenWhenDisabled = false;
    mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);

    // After the call the list of released layers should have been cleared.
    EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
}

TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
    SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
    ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());

    mOutput.mState.isEnabled = true;
    mOutput.mState.usesClientComposition = true;

+1 −58
Original line number Diff line number Diff line
@@ -751,54 +751,6 @@ void Layer::prepareReleaseCallbacks(ftl::Future<FenceResult> futureFenceResult,
    }
}

void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,
                             ui::LayerStack layerStack,
                             std::function<FenceResult(FenceResult)>&& continuation) {
    sp<CallbackHandle> ch = findCallbackHandle();

    if (!FlagManager::getInstance().screenshot_fence_preservation() && continuation) {
        futureFenceResult = ftl::Future(futureFenceResult).then(std::move(continuation)).share();
    }

    if (ch != nullptr) {
        ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
        ch->previousSharedReleaseFences.emplace_back(std::move(futureFenceResult));
        ch->name = mName;
    } else if (FlagManager::getInstance().screenshot_fence_preservation()) {
        // If we didn't get a release callback yet, e.g. some scenarios when capturing screenshots
        // asynchronously, then make sure we don't drop the fence.
        mPreviousReleaseFenceAndContinuations.emplace_back(std::move(futureFenceResult),
                                                           std::move(continuation));
        std::vector<FenceAndContinuation> mergedFences;
        sp<Fence> prevFence = nullptr;
        // For a layer that's frequently screenshotted, try to merge fences to make sure we don't
        // grow unbounded.
        for (const auto& futureAndContinuation : mPreviousReleaseFenceAndContinuations) {
            auto result = futureAndContinuation.future.wait_for(0s);
            if (result != std::future_status::ready) {
                mergedFences.emplace_back(futureAndContinuation);
                continue;
            }

            mergeFence(getDebugName(),
                       futureAndContinuation.chain().get().value_or(Fence::NO_FENCE), prevFence);
        }
        if (prevFence != nullptr) {
            mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))).share());
        }

        mPreviousReleaseFenceAndContinuations.swap(mergedFences);
    }

    if (mBufferInfo.mBuffer) {
        mPreviouslyPresentedLayerStacks.push_back(layerStack);
    }

    if (mDrawingState.frameNumber > 0) {
        mDrawingState.previousFrameNumber = mDrawingState.frameNumber;
    }
}

void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
    for (const auto& handle : mDrawingState.callbackHandles) {
        handle->bufferReleaseChannel = mBufferReleaseChannel;
@@ -1111,22 +1063,13 @@ bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle
            handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
            handle->frameNumber = mDrawingState.frameNumber;
            handle->previousFrameNumber = mDrawingState.previousFrameNumber;
            if (FlagManager::getInstance().ce_fence_promise() &&
                mPreviousReleaseBufferEndpoint == handle->listener) {
            if (mPreviousReleaseBufferEndpoint == handle->listener) {
                // Add fence from previous screenshot now so that it can be dispatched to the
                // client.
                for (auto& [_, future] : mAdditionalPreviousReleaseFences) {
                    handle->previousReleaseFences.emplace_back(std::move(future));
                }
                mAdditionalPreviousReleaseFences.clear();
            } else if (FlagManager::getInstance().screenshot_fence_preservation() &&
                       mPreviousReleaseBufferEndpoint == handle->listener) {
                // Add fences from previous screenshots now so that they can be dispatched to the
                // client.
                for (const auto& futureAndContinution : mPreviousReleaseFenceAndContinuations) {
                    handle->previousSharedReleaseFences.emplace_back(futureAndContinution.chain());
                }
                mPreviousReleaseFenceAndContinuations.clear();
            }
            // Store so latched time and release fence can be set
            mDrawingState.callbackHandles.push_back(handle);
Loading