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

Commit 023c188f authored by Alec Mouri's avatar Alec Mouri
Browse files

Support toggling layer caching at runtime

The use-case for this is dynamically enabling and disabling layer
caching when a bad layer state is encountered that is difficult to
reproduce.

Bug: 187448777
Test: adb shell service call SurfaceFlinger 1040 i32 1
Test: libcompositionengine_test
Change-Id: Id441a0894ff5a4c654db9fd706ceb1c0d1c343f0
Merged-In: Id441a0894ff5a4c654db9fd706ceb1c0d1c343f0
parent 08b6b20a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -163,6 +163,9 @@ public:
    // Enables (or disables) composition on this output
    virtual void setCompositionEnabled(bool) = 0;

    // Enables (or disables) layer caching on this output
    virtual void setLayerCachingEnabled(bool) = 0;

    // Sets the projection state to use
    virtual void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
                               const Rect& orientedDisplaySpaceRect) = 0;
+3 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <compositionengine/Output.h>
#include <compositionengine/impl/ClientCompositionRequestCache.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/planner/Planner.h>
#include <renderengine/DisplaySettings.h>
#include <renderengine/LayerSettings.h>
#include <memory>
@@ -28,21 +29,18 @@

namespace android::compositionengine::impl {

namespace planner {
class Planner;
} // namespace planner

// The implementation class contains the common implementation, but does not
// actually contain the final output state.
class Output : public virtual compositionengine::Output {
public:
    Output();
    Output() = default;
    ~Output() override;

    // compositionengine::Output overrides
    bool isValid() const override;
    std::optional<DisplayId> getDisplayId() const override;
    void setCompositionEnabled(bool) override;
    void setLayerCachingEnabled(bool) override;
    void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
                       const Rect& orientedDisplaySpaceRect) override;
    void setDisplaySize(const ui::Size&) override;
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ public:
    MOCK_CONST_METHOD0(getDisplayId, std::optional<DisplayId>());

    MOCK_METHOD1(setCompositionEnabled, void(bool));
    MOCK_METHOD1(setLayerCachingEnabled, void(bool));
    MOCK_METHOD3(setProjection, void(ui::Rotation, const Rect&, const Rect&));
    MOCK_METHOD1(setDisplaySize, void(const ui::Size&));
    MOCK_METHOD2(setLayerStackFilter, void(uint32_t, bool));
+15 −12
Original line number Diff line number Diff line
@@ -55,18 +55,6 @@ Output::~Output() = default;

namespace impl {

Output::Output() {
    const bool enableLayerCaching = [] {
        const bool enable =
                android::sysprop::SurfaceFlingerProperties::enable_layer_caching().value_or(false);
        return base::GetBoolProperty(std::string("debug.sf.enable_layer_caching"), enable);
    }();

    if (enableLayerCaching) {
        mPlanner = std::make_unique<planner::Planner>();
    }
}

namespace {

template <typename T>
@@ -135,6 +123,21 @@ void Output::setCompositionEnabled(bool enabled) {
    dirtyEntireOutput();
}

void Output::setLayerCachingEnabled(bool enabled) {
    if (enabled == (mPlanner != nullptr)) {
        return;
    }

    if (enabled) {
        mPlanner = std::make_unique<planner::Planner>();
        if (mRenderSurface) {
            mPlanner->setDisplaySize(mRenderSurface->getSize());
        }
    } else {
        mPlanner.reset();
    }
}

void Output::setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
                           const Rect& orientedDisplaySpaceRect) {
    auto& outputState = editState();
+23 −3
Original line number Diff line number Diff line
@@ -237,6 +237,28 @@ TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
    EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
}

/*
 * Output::setLayerCachingEnabled()
 */

TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
    const auto kSize = ui::Size(1, 1);
    EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
    mOutput->setLayerCachingEnabled(false);
    mOutput->setLayerCachingEnabled(true);

    EXPECT_TRUE(mOutput->plannerEnabled());
}

TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
    const auto kSize = ui::Size(1, 1);
    EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
    mOutput->setLayerCachingEnabled(true);
    mOutput->setLayerCachingEnabled(false);

    EXPECT_FALSE(mOutput->plannerEnabled());
}

/*
 * Output::setProjection()
 */
@@ -972,9 +994,7 @@ TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurf
    mOutput.editState().usesDeviceComposition = true;

    EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
    if (mOutput.plannerEnabled()) {
        EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
    }
    EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
    EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));

    mOutput.prepareFrame();
Loading