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

Commit 2aaa71f4 authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge changes Ie9d7e9a3,I88d60484 into main

* changes:
  Migrate legacy framerate tests
  Fix framerate propagation from child to parent layers
parents 9d934309 5c61a01b
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -561,6 +561,7 @@ const LayerSnapshot& LayerSnapshotBuilder::updateSnapshotsInHierarchy(
        updateSnapshot(*snapshot, args, *layer, parentSnapshot, traversalPath);
    }

    bool childHasValidFrameRate = false;
    for (auto& [childHierarchy, variant] : hierarchy.mChildren) {
        LayerHierarchy::ScopedAddToTraversalPath addChildToPath(traversalPath,
                                                                childHierarchy->getLayer()->id,
@@ -568,7 +569,8 @@ const LayerSnapshot& LayerSnapshotBuilder::updateSnapshotsInHierarchy(
        const LayerSnapshot& childSnapshot =
                updateSnapshotsInHierarchy(args, *childHierarchy, traversalPath, *snapshot,
                                           depth + 1);
        updateFrameRateFromChildSnapshot(*snapshot, childSnapshot, args);
        updateFrameRateFromChildSnapshot(*snapshot, childSnapshot, *childHierarchy->getLayer(),
                                         args, &childHasValidFrameRate);
    }

    return *snapshot;
@@ -675,9 +677,10 @@ void LayerSnapshotBuilder::updateRelativeState(LayerSnapshot& snapshot,
    }
}

void LayerSnapshotBuilder::updateFrameRateFromChildSnapshot(LayerSnapshot& snapshot,
                                                            const LayerSnapshot& childSnapshot,
                                                            const Args& args) {
void LayerSnapshotBuilder::updateFrameRateFromChildSnapshot(
        LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
        const RequestedLayerState& /* requestedChildState */, const Args& args,
        bool* outChildHasValidFrameRate) {
    if (args.forceUpdate == ForceUpdateFlags::NONE &&
        !args.layerLifecycleManager.getGlobalChanges().any(
                RequestedLayerState::Changes::Hierarchy) &&
@@ -687,7 +690,7 @@ void LayerSnapshotBuilder::updateFrameRateFromChildSnapshot(LayerSnapshot& snaps
    }

    using FrameRateCompatibility = scheduler::FrameRateCompatibility;
    if (snapshot.frameRate.isValid()) {
    if (snapshot.inheritedFrameRate.isValid() || *outChildHasValidFrameRate) {
        // we already have a valid framerate.
        return;
    }
@@ -704,13 +707,18 @@ void LayerSnapshotBuilder::updateFrameRateFromChildSnapshot(LayerSnapshot& snaps
    const auto layerVotedWithExactCompatibility = childSnapshot.frameRate.vote.rate.isValid() &&
            childSnapshot.frameRate.vote.type == FrameRateCompatibility::Exact;

    bool childHasValidFrameRate = layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
    *outChildHasValidFrameRate |= layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
            layerVotedWithCategory || 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 (childHasValidFrameRate) {
        snapshot.frameRate = scheduler::LayerInfo::FrameRate(Fps(), FrameRateCompatibility::NoVote);
    static const auto noVote =
            scheduler::LayerInfo::FrameRate(Fps(), FrameRateCompatibility::NoVote);
    if (*outChildHasValidFrameRate) {
        snapshot.frameRate = noVote;
        snapshot.changes |= RequestedLayerState::Changes::FrameRate;
    } else if (snapshot.frameRate != snapshot.inheritedFrameRate) {
        snapshot.frameRate = snapshot.inheritedFrameRate;
        snapshot.changes |= RequestedLayerState::Changes::FrameRate;
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -130,7 +130,9 @@ private:
                                  const RequestedLayerState& layer,
                                  const LayerSnapshot& parentSnapshot);
    void updateFrameRateFromChildSnapshot(LayerSnapshot& snapshot,
                                          const LayerSnapshot& childSnapshot, const Args& args);
                                          const LayerSnapshot& childSnapshot,
                                          const RequestedLayerState& requestedCHildState,
                                          const Args& args, bool* outChildHasValidFrameRate);
    void updateTouchableRegionCrop(const Args& args);

    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,
+1 −222
Original line number Diff line number Diff line
@@ -316,7 +316,7 @@ void Layer::onRemovedFromCurrentState() {
void Layer::addToCurrentState() {
    if (mRemovedFromDrawingState) {
        mRemovedFromDrawingState = false;
        mFlinger->mScheduler->registerLayer(this);
        mFlinger->mScheduler->registerLayer(this, FrameRateCompatibility::Default);
        mFlinger->removeFromOffscreenLayers(this);
    }

@@ -1100,42 +1100,6 @@ bool Layer::setDimmingEnabled(const bool dimmingEnabled) {
    return true;
}

bool Layer::setFrameRateSelectionPriority(int32_t priority) {
    if (mDrawingState.frameRateSelectionPriority == priority) return false;
    mDrawingState.frameRateSelectionPriority = priority;
    mDrawingState.sequence++;
    mDrawingState.modified = true;
    setTransactionFlags(eTransactionNeeded);
    return true;
}

int32_t Layer::getFrameRateSelectionPriority() const {
    // Check if layer has priority set.
    if (mDrawingState.frameRateSelectionPriority != PRIORITY_UNSET) {
        return mDrawingState.frameRateSelectionPriority;
    }
    // If not, search whether its parents have it set.
    sp<Layer> parent = getParent();
    if (parent != nullptr) {
        return parent->getFrameRateSelectionPriority();
    }

    return Layer::PRIORITY_UNSET;
}

bool Layer::setDefaultFrameRateCompatibility(FrameRateCompatibility compatibility) {
    if (mDrawingState.defaultFrameRateCompatibility == compatibility) return false;
    mDrawingState.defaultFrameRateCompatibility = compatibility;
    mDrawingState.modified = true;
    mFlinger->mScheduler->setDefaultFrameRateCompatibility(sequence, compatibility);
    setTransactionFlags(eTransactionNeeded);
    return true;
}

scheduler::FrameRateCompatibility Layer::getDefaultFrameRateCompatibility() const {
    return mDrawingState.defaultFrameRateCompatibility;
}

bool Layer::isLayerFocusedBasedOnPriority(int32_t priority) {
    return priority == PRIORITY_FOCUSED_WITH_MODE || priority == PRIORITY_FOCUSED_WITHOUT_MODE;
};
@@ -1202,117 +1166,6 @@ StretchEffect Layer::getStretchEffect() const {
    return StretchEffect{};
}

bool Layer::propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool overrideChildren,
                                           bool* transactionNeeded) {
    // Gets the frame rate to propagate to children.
    const auto frameRate = [&] {
        if (overrideChildren && parentFrameRate.isValid()) {
            return parentFrameRate;
        }

        if (mDrawingState.frameRate.isValid()) {
            return mDrawingState.frameRate;
        }

        return parentFrameRate;
    }();

    auto now = systemTime();
    *transactionNeeded |= setFrameRateForLayerTreeLegacy(frameRate, now);

    // The frame rate is propagated to the children by default, but some properties may override it.
    bool childrenHaveFrameRate = false;
    const bool overrideChildrenFrameRate = overrideChildren || shouldOverrideChildrenFrameRate();
    const bool canPropagateFrameRate = shouldPropagateFrameRate() || overrideChildrenFrameRate;
    for (const sp<Layer>& child : mCurrentChildren) {
        childrenHaveFrameRate |=
                child->propagateFrameRateForLayerTree(canPropagateFrameRate ? frameRate
                                                                            : FrameRate(),
                                                      overrideChildrenFrameRate, transactionNeeded);
    }

    // If we don't have a valid frame rate specification, but the children do, we set this
    // layer as NoVote to allow the children to control the refresh rate
    if (!frameRate.isValid() && childrenHaveFrameRate) {
        *transactionNeeded |=
                setFrameRateForLayerTreeLegacy(FrameRate(Fps(), FrameRateCompatibility::NoVote),
                                               now);
    }

    // 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.
    const auto layerVotedWithDefaultCompatibility =
            frameRate.vote.rate.isValid() && frameRate.vote.type == FrameRateCompatibility::Default;
    const auto layerVotedWithNoVote = frameRate.vote.type == FrameRateCompatibility::NoVote;
    const auto layerVotedWithCategory = frameRate.category != FrameRateCategory::Default;
    const auto layerVotedWithExactCompatibility =
            frameRate.vote.rate.isValid() && frameRate.vote.type == FrameRateCompatibility::Exact;
    return layerVotedWithDefaultCompatibility || layerVotedWithNoVote || layerVotedWithCategory ||
            layerVotedWithExactCompatibility || childrenHaveFrameRate;
}

void Layer::updateTreeHasFrameRateVote() {
    const auto root = [&]() -> sp<Layer> {
        sp<Layer> layer = sp<Layer>::fromExisting(this);
        while (auto parent = layer->getParent()) {
            layer = parent;
        }
        return layer;
    }();

    bool transactionNeeded = false;
    root->propagateFrameRateForLayerTree({}, false, &transactionNeeded);

    // TODO(b/195668952): we probably don't need eTraversalNeeded here
    if (transactionNeeded) {
        mFlinger->setTransactionFlags(eTraversalNeeded);
    }
}

bool Layer::setFrameRate(FrameRate::FrameRateVote frameRateVote) {
    if (mDrawingState.frameRate.vote == frameRateVote) {
        return false;
    }

    mDrawingState.sequence++;
    mDrawingState.frameRate.vote = frameRateVote;
    mDrawingState.modified = true;

    updateTreeHasFrameRateVote();

    setTransactionFlags(eTransactionNeeded);
    return true;
}

bool Layer::setFrameRateCategory(FrameRateCategory category, bool smoothSwitchOnly) {
    if (mDrawingState.frameRate.category == category &&
        mDrawingState.frameRate.categorySmoothSwitchOnly == smoothSwitchOnly) {
        return false;
    }

    mDrawingState.sequence++;
    mDrawingState.frameRate.category = category;
    mDrawingState.frameRate.categorySmoothSwitchOnly = smoothSwitchOnly;
    mDrawingState.modified = true;

    updateTreeHasFrameRateVote();

    setTransactionFlags(eTransactionNeeded);
    return true;
}

bool Layer::setFrameRateSelectionStrategy(FrameRateSelectionStrategy strategy) {
    if (mDrawingState.frameRateSelectionStrategy == strategy) return false;
    mDrawingState.frameRateSelectionStrategy = strategy;
    mDrawingState.sequence++;
    mDrawingState.modified = true;

    updateTreeHasFrameRateVote();
    setTransactionFlags(eTransactionNeeded);
    return true;
}

void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
                                                      nsecs_t postTime, gui::GameMode gameMode) {
    mDrawingState.postTime = postTime;
@@ -1446,25 +1299,6 @@ void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info,
    addSurfaceFrameDroppedForBuffer(surfaceFrame, postTime);
}

bool Layer::setFrameRateForLayerTreeLegacy(FrameRate frameRate, nsecs_t now) {
    if (mDrawingState.frameRateForLayerTree == frameRate) {
        return false;
    }

    mDrawingState.frameRateForLayerTree = frameRate;

    // TODO(b/195668952): we probably don't need to dirty visible regions here
    // or even store frameRateForLayerTree in mDrawingState
    mDrawingState.sequence++;
    mDrawingState.modified = true;
    setTransactionFlags(eTransactionNeeded);

    mFlinger->mScheduler
            ->recordLayerHistory(sequence, getLayerProps(), now, now,
                                 scheduler::LayerHistory::LayerUpdateType::SetFrameRate);
    return true;
}

bool Layer::setFrameRateForLayerTree(FrameRate frameRate, const scheduler::LayerProps& layerProps,
                                     nsecs_t now) {
    if (mDrawingState.frameRateForLayerTree == frameRate) {
@@ -1543,57 +1377,6 @@ void Layer::miniDumpHeader(std::string& result) {
    result.append("\n");
}

void Layer::miniDumpLegacy(std::string& result, const DisplayDevice& display) const {
    const auto outputLayer = findOutputLayerForDisplay(&display);
    if (!outputLayer) {
        return;
    }

    std::string name;
    if (mName.length() > 77) {
        std::string shortened;
        shortened.append(mName, 0, 36);
        shortened.append("[...]");
        shortened.append(mName, mName.length() - 36);
        name = std::move(shortened);
    } else {
        name = mName;
    }

    StringAppendF(&result, " %s\n", name.c_str());

    const State& layerState(getDrawingState());
    const auto& outputLayerState = outputLayer->getState();

    if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) {
        StringAppendF(&result, "  rel %6d | ", layerState.z);
    } else {
        StringAppendF(&result, "  %10d | ", layerState.z);
    }
    StringAppendF(&result, "  %10d | ", mWindowType);
    StringAppendF(&result, "%10s | ", toString(getCompositionType(display)).c_str());
    StringAppendF(&result, "%10s | ", toString(outputLayerState.bufferTransform).c_str());
    const Rect& frame = outputLayerState.displayFrame;
    StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
    const FloatRect& crop = outputLayerState.sourceCrop;
    StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f | ", crop.left, crop.top, crop.right,
                  crop.bottom);
    const auto frameRate = getFrameRateForLayerTree();
    if (frameRate.vote.rate.isValid() || frameRate.vote.type != FrameRateCompatibility::Default) {
        StringAppendF(&result, "%s %15s %17s", to_string(frameRate.vote.rate).c_str(),
                      ftl::enum_string(frameRate.vote.type).c_str(),
                      ftl::enum_string(frameRate.vote.seamlessness).c_str());
    } else {
        result.append(41, ' ');
    }

    const auto focused = isLayerFocusedBasedOnPriority(getFrameRateSelectionPriority());
    StringAppendF(&result, "    [%s]\n", focused ? "*" : " ");

    result.append(kDumpTableRowLength, '-');
    result.append("\n");
}

void Layer::miniDump(std::string& result, const frontend::LayerSnapshot& snapshot,
                     const DisplayDevice& display) const {
    const auto outputLayer = findOutputLayerForDisplay(&display, snapshot.path);
@@ -1679,7 +1462,6 @@ void Layer::addChild(const sp<Layer>& layer) {

    mCurrentChildren.add(layer);
    layer->setParent(sp<Layer>::fromExisting(this));
    updateTreeHasFrameRateVote();
}

ssize_t Layer::removeChild(const sp<Layer>& layer) {
@@ -1689,9 +1471,6 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) {
    layer->setParent(nullptr);
    const auto removeResult = mCurrentChildren.remove(layer);

    updateTreeHasFrameRateVote();
    layer->updateTreeHasFrameRateVote();

    return removeResult;
}

+0 −25
Original line number Diff line number Diff line
@@ -330,18 +330,10 @@ public:
            REQUIRES(mFlinger->mStateLock);
    virtual bool setColorSpaceAgnostic(const bool agnostic);
    virtual bool setDimmingEnabled(const bool dimmingEnabled);
    virtual bool setDefaultFrameRateCompatibility(FrameRateCompatibility compatibility);
    virtual bool setFrameRateSelectionPriority(int32_t priority);
    virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
    void setAutoRefresh(bool /* autoRefresh */);
    bool setDropInputMode(gui::DropInputMode);

    //  If the variable is not set on the layer, it traverses up the tree to inherit the frame
    //  rate priority from its parent.
    virtual int32_t getFrameRateSelectionPriority() const;
    //
    virtual FrameRateCompatibility getDefaultFrameRateCompatibility() const;
    //
    ui::Dataspace getDataSpace() const;

    virtual bool isFrontBuffered() const;
@@ -702,7 +694,6 @@ public:
    inline const State& getDrawingState() const { return mDrawingState; }
    inline State& getDrawingState() { return mDrawingState; }

    void miniDumpLegacy(std::string& result, const DisplayDevice&) const;
    void miniDump(std::string& result, const frontend::LayerSnapshot&, const DisplayDevice&) const;
    void dumpFrameStats(std::string& result) const;
    void dumpOffscreenDebugInfo(std::string& result) const;
@@ -789,11 +780,6 @@ public:
     */
    Rect getCroppedBufferSize(const Layer::State& s) const;

    bool setFrameRate(FrameRate::FrameRateVote);
    bool setFrameRateCategory(FrameRateCategory, bool smoothSwitchOnly);

    bool setFrameRateSelectionStrategy(FrameRateSelectionStrategy);

    virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {}
    void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime,
                                                   gui::GameMode gameMode);
@@ -905,19 +891,9 @@ public:
    void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
                                   const sp<GraphicBuffer>& buffer, uint64_t framenumber,
                                   const sp<Fence>& releaseFence);
    bool setFrameRateForLayerTreeLegacy(FrameRate, nsecs_t now);
    bool setFrameRateForLayerTree(FrameRate, const scheduler::LayerProps&, nsecs_t now);
    void recordLayerHistoryBufferUpdate(const scheduler::LayerProps&, nsecs_t now);
    void recordLayerHistoryAnimationTx(const scheduler::LayerProps&, nsecs_t now);
    auto getLayerProps() const {
        return scheduler::LayerProps{.visible = isVisible(),
                                     .bounds = getBounds(),
                                     .transform = getTransform(),
                                     .setFrameRateVote = getFrameRateForLayerTree(),
                                     .frameRateSelectionPriority = getFrameRateSelectionPriority(),
                                     .isSmallDirty = mSmallDirty,
                                     .isFrontBuffered = isFrontBuffered()};
    };
    bool hasBuffer() const { return mBufferInfo.mBuffer != nullptr; }
    void setTransformHint(std::optional<ui::Transform::RotationFlags> transformHint) {
        mTransformHint = transformHint;
@@ -1128,7 +1104,6 @@ private:
    LayerVector makeChildrenTraversalList(LayerVector::StateSet,
                                          const std::vector<Layer*>& layersInTree);

    void updateTreeHasFrameRateVote();
    bool propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool overrideChildren,
                                        bool* transactionNeeded);
    void setZOrderRelativeOf(const wp<Layer>& relativeOf);
+3 −3
Original line number Diff line number Diff line
@@ -109,12 +109,12 @@ LayerHistory::LayerHistory()

LayerHistory::~LayerHistory() = default;

void LayerHistory::registerLayer(Layer* layer, bool contentDetectionEnabled) {
void LayerHistory::registerLayer(Layer* layer, bool contentDetectionEnabled,
                                 FrameRateCompatibility frameRateCompatibility) {
    std::lock_guard lock(mLock);
    LOG_ALWAYS_FATAL_IF(findLayer(layer->getSequence()).first != LayerStatus::NotFound,
                        "%s already registered", layer->getName().c_str());
    LayerVoteType type =
            getVoteType(layer->getDefaultFrameRateCompatibility(), contentDetectionEnabled);
    LayerVoteType type = getVoteType(frameRateCompatibility, contentDetectionEnabled);
    auto info = std::make_unique<LayerInfo>(layer->getName(), layer->getOwnerUid(), type);

    // The layer can be placed on either map, it is assumed that partitionLayers() will be called
Loading