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

Commit 50c44062 authored by Matt Buckley's avatar Matt Buckley
Browse files

Change SF power hints to use early frame predictions

Currently we issue hints at the end of the frame reporting what happened
that frame. However, this is often too late anyway and lacks critical
information not known until after the frame completes, like gpu timing.
By waiting until the next frame start and using those timings along with
information about gpu duration, the new expected present time, and the
new wakeup time, we can instead use those timings to predict the
duration of the upcoming frame and signal in advance of a frame drop.
This patch also changes how and where frame timing is done and measures
gpu duration so we can predict if a cpu speedup can help gpu composition
happen earlier, preventing a drop that way.

Bug: b/195990840
Test: manual

Change-Id: I5f0ae796198631fced503dce8e6c495885fb256a
parent 7b2bea28
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFE.h>
#include <renderengine/LayerSettings.h>
#include <renderengine/LayerSettings.h>
#include <ui/Fence.h>
#include <ui/Fence.h>
#include <ui/FenceTime.h>
#include <ui/GraphicTypes.h>
#include <ui/GraphicTypes.h>
#include <ui/LayerStack.h>
#include <ui/LayerStack.h>
#include <ui/Region.h>
#include <ui/Region.h>
@@ -311,6 +312,8 @@ protected:
            const Region& flashRegion,
            const Region& flashRegion,
            std::vector<LayerFE::LayerSettings>& clientCompositionLayers) = 0;
            std::vector<LayerFE::LayerSettings>& clientCompositionLayers) = 0;
    virtual void setExpensiveRenderingExpected(bool enabled) = 0;
    virtual void setExpensiveRenderingExpected(bool enabled) = 0;
    virtual void setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) = 0;
    virtual bool isPowerHintSessionEnabled() = 0;
    virtual void cacheClientCompositionRequests(uint32_t cacheSize) = 0;
    virtual void cacheClientCompositionRequests(uint32_t cacheSize) = 0;
    virtual bool canPredictCompositionStrategy(const CompositionRefreshArgs&) = 0;
    virtual bool canPredictCompositionStrategy(const CompositionRefreshArgs&) = 0;
};
};
+2 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,8 @@ public:
    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;


private:
private:
    bool isPowerHintSessionEnabled() override;
    void setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) override;
    DisplayId mId;
    DisplayId mId;
    bool mIsDisconnected = false;
    bool mIsDisconnected = false;
    Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
    Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
+2 −0
Original line number Original line Diff line number Diff line
@@ -140,6 +140,8 @@ protected:
          std::vector<LayerFE*> &outLayerFEs) override;
          std::vector<LayerFE*> &outLayerFEs) override;
    void appendRegionFlashRequests(const Region&, std::vector<LayerFE::LayerSettings>&) override;
    void appendRegionFlashRequests(const Region&, std::vector<LayerFE::LayerSettings>&) override;
    void setExpensiveRenderingExpected(bool enabled) override;
    void setExpensiveRenderingExpected(bool enabled) override;
    void setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) override;
    bool isPowerHintSessionEnabled() override;
    void dumpBase(std::string&) const;
    void dumpBase(std::string&) const;


    // Implemented by the final implementation for the final state it uses.
    // Implemented by the final implementation for the final state it uses.
+2 −0
Original line number Original line Diff line number Diff line
@@ -133,6 +133,8 @@ public:
    MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
    MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
    MOCK_METHOD1(setPredictCompositionStrategy, void(bool));
    MOCK_METHOD1(setPredictCompositionStrategy, void(bool));
    MOCK_METHOD1(setTreat170mAsSrgb, void(bool));
    MOCK_METHOD1(setTreat170mAsSrgb, void(bool));
    MOCK_METHOD(void, setHintSessionGpuFence, (std::unique_ptr<FenceTime> && gpuFence));
    MOCK_METHOD(bool, isPowerHintSessionEnabled, ());
};
};


} // namespace android::compositionengine::mock
} // namespace android::compositionengine::mock
+39 −1
Original line number Original line Diff line number Diff line
@@ -243,11 +243,14 @@ bool Display::chooseCompositionStrategy(
        return false;
        return false;
    }
    }


    const nsecs_t startTime = systemTime();

    // Get any composition changes requested by the HWC device, and apply them.
    // Get any composition changes requested by the HWC device, and apply them.
    std::optional<android::HWComposer::DeviceRequestedChanges> changes;
    std::optional<android::HWComposer::DeviceRequestedChanges> changes;
    auto& hwc = getCompositionEngine().getHwComposer();
    auto& hwc = getCompositionEngine().getHwComposer();
    const bool requiresClientComposition = anyLayersRequireClientComposition();
    if (status_t result =
    if (status_t result =
                hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
                hwc.getDeviceCompositionChanges(*halDisplayId, requiresClientComposition,
                                                getState().earliestPresentTime,
                                                getState().earliestPresentTime,
                                                getState().previousPresentFence,
                                                getState().previousPresentFence,
                                                getState().expectedPresentTime, outChanges);
                                                getState().expectedPresentTime, outChanges);
@@ -257,6 +260,11 @@ bool Display::chooseCompositionStrategy(
        return false;
        return false;
    }
    }


    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setValidateTiming(mId, startTime, systemTime());
        mPowerAdvisor->setRequiresClientComposition(mId, requiresClientComposition);
    }

    return true;
    return true;
}
}


@@ -356,9 +364,24 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
    }
    }


    auto& hwc = getCompositionEngine().getHwComposer();
    auto& hwc = getCompositionEngine().getHwComposer();

    const nsecs_t startTime = systemTime();

    if (isPowerHintSessionEnabled()) {
        if (!getCompositionEngine().getHwComposer().getComposer()->isSupported(
                    Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
            getState().previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
            mPowerAdvisor->setPresentDelayedTime(mId, getState().earliestPresentTime);
        }
    }

    hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime,
    hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime,
                                   getState().previousPresentFence);
                                   getState().previousPresentFence);


    if (isPowerHintSessionEnabled()) {
        mPowerAdvisor->setPresentTiming(mId, startTime, systemTime());
    }

    fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
    fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);


    // TODO(b/121291683): Change HWComposer call to return entire map
    // TODO(b/121291683): Change HWComposer call to return entire map
@@ -384,6 +407,14 @@ void Display::setExpensiveRenderingExpected(bool enabled) {
    }
    }
}
}


bool Display::isPowerHintSessionEnabled() {
    return mPowerAdvisor != nullptr && mPowerAdvisor->usePowerHintSession();
}

void Display::setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) {
    mPowerAdvisor->setGpuFenceTime(mId, std::move(gpuFence));
}

void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs,
void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs,
                          GpuCompositionResult&& result) {
                          GpuCompositionResult&& result) {
    // We only need to actually compose the display if:
    // We only need to actually compose the display if:
@@ -396,6 +427,13 @@ void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refre
    }
    }


    impl::Output::finishFrame(refreshArgs, std::move(result));
    impl::Output::finishFrame(refreshArgs, std::move(result));

    if (isPowerHintSessionEnabled()) {
        auto& hwc = getCompositionEngine().getHwComposer();
        if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
            mPowerAdvisor->setSkippedValidate(mId, hwc.getValidateSkipped(*halDisplayId));
        }
    }
}
}


} // namespace android::compositionengine::impl
} // namespace android::compositionengine::impl
Loading