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

Commit 42b918ef authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[sf] Update framerate correctly with new frontend

In order to optimize snapshot updates, we only
update the snapshot if the requested state has changed.
If the hierarchy changes, we force update the children's
snapshot but this is not sufficient because a parent's
framerate might be affect by the child's framerate.

To fix this explicitly update the framerate when the
hierarchy changes.

Test: presubmit
Test: atest android.graphics.cts.FrameRateOverrideTest
Bug: 238781169
Change-Id: Ia633e7800cf3169c944313b4220b889bec0c3c5f
parent d2bfbb32
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -41,10 +41,6 @@ struct RoundedCornerState {
    }
};

struct ChildState {
    bool hasValidFrameRate = false;
};

// LayerSnapshot stores Layer state used by CompositionEngine and RenderEngine. Composition
// Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
// passed to Render Engine are created using properties stored on this struct.
@@ -99,7 +95,6 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
    uint32_t touchCropId;
    gui::Uid uid = gui::Uid::INVALID;
    gui::Pid pid = gui::Pid::INVALID;
    ChildState childState;
    enum class Reachablilty : uint32_t {
        // Can traverse the hierarchy from a root node and reach this snapshot
        Reachable,
+36 −30
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@ const LayerSnapshot& LayerSnapshotBuilder::updateSnapshotsInHierarchy(
        const LayerSnapshot& childSnapshot =
                updateSnapshotsInHierarchy(args, *childHierarchy, traversalPath, *snapshot,
                                           depth + 1);
        updateChildState(*snapshot, childSnapshot, args);
        updateFrameRateFromChildSnapshot(*snapshot, childSnapshot, args);
    }

    if (oldFrameRate == snapshot->frameRate) {
@@ -666,17 +666,25 @@ void LayerSnapshotBuilder::updateRelativeState(LayerSnapshot& snapshot,
    }
}

void LayerSnapshotBuilder::updateChildState(LayerSnapshot& snapshot,
                                            const LayerSnapshot& childSnapshot, const Args& args) {
    if (snapshot.childState.hasValidFrameRate) {
void LayerSnapshotBuilder::updateFrameRateFromChildSnapshot(LayerSnapshot& snapshot,
                                                            const LayerSnapshot& childSnapshot,
                                                            const Args& args) {
    if (args.forceUpdate == ForceUpdateFlags::NONE &&
        !childSnapshot.changes.any(RequestedLayerState::Changes::FrameRate |
                                   RequestedLayerState::Changes::Hierarchy)) {
        return;
    }

    using FrameRateCompatibility = scheduler::LayerInfo::FrameRateCompatibility;
    if (snapshot.frameRate.rate.isValid() ||
        snapshot.frameRate.type == FrameRateCompatibility::NoVote) {
        // we already have a valid framerate.
        return;
    }
    if (args.forceUpdate == ForceUpdateFlags::ALL ||
        childSnapshot.changes.test(RequestedLayerState::Changes::FrameRate)) {
        // We return whether this layer ot its children has a vote. We ignore ExactOrMultiple votes

    // We return whether this layer or its children has a vote. We ignore ExactOrMultiple votes
    // for the same reason we are allowing touch boost for those layers. See
    // RefreshRateSelector::rankFrameRates for details.
        using FrameRateCompatibility = scheduler::LayerInfo::FrameRateCompatibility;
    const auto layerVotedWithDefaultCompatibility = childSnapshot.frameRate.rate.isValid() &&
            childSnapshot.frameRate.type == FrameRateCompatibility::Default;
    const auto layerVotedWithNoVote =
@@ -684,18 +692,14 @@ void LayerSnapshotBuilder::updateChildState(LayerSnapshot& snapshot,
    const auto layerVotedWithExactCompatibility = childSnapshot.frameRate.rate.isValid() &&
            childSnapshot.frameRate.type == FrameRateCompatibility::Exact;

        snapshot.childState.hasValidFrameRate |= layerVotedWithDefaultCompatibility ||
                layerVotedWithNoVote || layerVotedWithExactCompatibility;
    bool childHasValidFrameRate = layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
            layerVotedWithExactCompatibility;

    // If we don't have a valid frame rate, but the children do, we set this
    // layer as NoVote to allow the children to control the refresh rate
        if (!snapshot.frameRate.rate.isValid() &&
            snapshot.frameRate.type != FrameRateCompatibility::NoVote &&
            snapshot.childState.hasValidFrameRate) {
            snapshot.frameRate =
                    scheduler::LayerInfo::FrameRate(Fps(), FrameRateCompatibility::NoVote);
            snapshot.changes |= childSnapshot.changes & RequestedLayerState::Changes::FrameRate;
        }
    if (childHasValidFrameRate) {
        snapshot.frameRate = scheduler::LayerInfo::FrameRate(Fps(), FrameRateCompatibility::NoVote);
        snapshot.changes |= RequestedLayerState::Changes::FrameRate;
    }
}

@@ -812,7 +816,9 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a
        }
    }

    if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::FrameRate)) {
    if (forceUpdate ||
        snapshot.changes.any(RequestedLayerState::Changes::FrameRate |
                             RequestedLayerState::Changes::Hierarchy)) {
        snapshot.frameRate = (requested.requestedFrameRate.rate.isValid() ||
                              (requested.requestedFrameRate.type ==
                               scheduler::LayerInfo::FrameRateCompatibility::NoVote))
+2 −2
Original line number Diff line number Diff line
@@ -116,8 +116,8 @@ private:
    LayerSnapshot* createSnapshot(const LayerHierarchy::TraversalPath& id,
                                  const RequestedLayerState& layer,
                                  const LayerSnapshot& parentSnapshot);
    void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
                          const Args& args);
    void updateFrameRateFromChildSnapshot(LayerSnapshot& snapshot,
                                          const LayerSnapshot& childSnapshot, const Args& args);
    void updateTouchableRegionCrop(const Args& args);

    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,