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

Commit 44c85e09 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 7629638 from 810d1937 to sc-qpr1-release

Change-Id: I7553d002678684b484cf18e0b68ad46c99472b35
parents cebf2e6c 810d1937
Loading
Loading
Loading
Loading
+2 −17
Original line number Diff line number Diff line
@@ -425,7 +425,8 @@ bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTex

    if (mDrawingState.buffer) {
        mReleasePreviousBuffer = true;
        if (mDrawingState.buffer != mBufferInfo.mBuffer) {
        if (mDrawingState.buffer != mBufferInfo.mBuffer ||
            mDrawingState.frameNumber != mBufferInfo.mFrameNumber) {
            // If mDrawingState has a buffer, and we are about to update again
            // before swapping to drawing state, then the first buffer will be
            // dropped and we should decrement the pending buffer count and
@@ -963,22 +964,6 @@ void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) {
    ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
}

void BufferStateLayer::bufferMayChange(const sp<GraphicBuffer>& newBuffer) {
    if (mDrawingState.buffer != nullptr &&
        (!mBufferInfo.mBuffer ||
         mDrawingState.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) &&
        newBuffer != mDrawingState.buffer->getBuffer()) {
        // If we are about to update mDrawingState.buffer but it has not yet latched
        // then we will drop a buffer and should decrement the pending buffer count and
        // call any release buffer callbacks if set.
        callReleaseBufferCallback(mDrawingState.releaseBufferListener,
                                  mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
                                  mDrawingState.acquireFence, mTransformHint,
                                  mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
                                          mOwnerUid));
        decrementPendingBufferCount();
    }
}

/*
 * We don't want to send the layer's transform to input, but rather the
+0 −1
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ public:

    // See mPendingBufferTransactions
    void decrementPendingBufferCount();
    void bufferMayChange(const sp<GraphicBuffer>& newBuffer) override;
    std::atomic<int32_t>* getPendingBufferCounter() override { return &mPendingBufferTransactions; }
    std::string getPendingBufferCounterName() override { return mBlastTransactionName; }

+60 −66
Original line number Diff line number Diff line
@@ -1117,46 +1117,59 @@ StretchEffect Layer::getStretchEffect() const {
    return StretchEffect{};
}

void Layer::updateTreeHasFrameRateVote() {
    const auto traverseTree = [&](const LayerVector::Visitor& visitor) {
        auto parent = getParent();
        while (parent) {
            visitor(parent.get());
            parent = parent->getParent();
bool Layer::propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool* transactionNeeded) {
    // The frame rate for layer tree is this layer's frame rate if present, or the parent frame rate
    const auto frameRate = [&] {
        if (mDrawingState.frameRate.rate.isValid() ||
            mDrawingState.frameRate.type == FrameRateCompatibility::NoVote) {
            return mDrawingState.frameRate;
        }

        traverse(LayerVector::StateSet::Current, visitor);
    };
        return parentFrameRate;
    }();

    // update parents and children about the vote
    // First traverse the tree and count how many layers has votes.
    int layersWithVote = 0;
    traverseTree([&layersWithVote](Layer* layer) {
    *transactionNeeded |= setFrameRateForLayerTree(frameRate);

    // The frame rate is propagated to the children
    bool childrenHaveFrameRate = false;
    for (const sp<Layer>& child : mCurrentChildren) {
        childrenHaveFrameRate |=
                child->propagateFrameRateForLayerTree(frameRate, transactionNeeded);
    }

    // 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 (!frameRate.rate.isValid() && frameRate.type != FrameRateCompatibility::NoVote &&
        childrenHaveFrameRate) {
        *transactionNeeded |=
                setFrameRateForLayerTree(FrameRate(Fps(0.0f), FrameRateCompatibility::NoVote));
    }

    // We return whether this layer ot its children has a vote. We ignore ExactOrMultiple votes for
    // the same reason we are allowing touch boost for those layers. See
    // RefreshRateConfigs::getBestRefreshRate for more details.
    const auto layerVotedWithDefaultCompatibility =
                layer->mDrawingState.frameRate.rate.isValid() &&
                layer->mDrawingState.frameRate.type == FrameRateCompatibility::Default;
        const auto layerVotedWithNoVote =
                layer->mDrawingState.frameRate.type == FrameRateCompatibility::NoVote;
            frameRate.rate.isValid() && frameRate.type == FrameRateCompatibility::Default;
    const auto layerVotedWithNoVote = frameRate.type == FrameRateCompatibility::NoVote;
    const auto layerVotedWithExactCompatibility =
                layer->mDrawingState.frameRate.type == FrameRateCompatibility::Exact;
            frameRate.rate.isValid() && frameRate.type == FrameRateCompatibility::Exact;
    return layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
            layerVotedWithExactCompatibility || childrenHaveFrameRate;
}

        // We do not count layers that are ExactOrMultiple for the same reason
        // we are allowing touch boost for those layers. See
        // RefreshRateConfigs::getBestRefreshRate for more details.
        if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
            layerVotedWithExactCompatibility) {
            layersWithVote++;
void Layer::updateTreeHasFrameRateVote() {
    const auto root = [&]() -> sp<Layer> {
        sp<Layer> layer = this;
        while (auto parent = layer->getParent()) {
            layer = parent;
        }
    });
        return layer;
    }();

    // Now we can update the tree frame rate vote for each layer in the tree
    const bool treeHasFrameRateVote = layersWithVote > 0;
    bool transactionNeeded = false;
    root->propagateFrameRateForLayerTree({}, &transactionNeeded);

    traverseTree([treeHasFrameRateVote, &transactionNeeded](Layer* layer) {
        transactionNeeded = layer->updateFrameRateForLayerTree(treeHasFrameRateVote);
    });

    // TODO(b/195668952): we probably don't need eTraversalNeeded here
    if (transactionNeeded) {
        mFlinger->setTransactionFlags(eTraversalNeeded);
    }
@@ -1283,13 +1296,15 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer(
    return surfaceFrame;
}

bool Layer::updateFrameRateForLayerTree(bool treeHasFrameRateVote) {
    const auto updateDrawingState = [&](FrameRate frameRate) {
bool Layer::setFrameRateForLayerTree(FrameRate frameRate) {
    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);
@@ -1298,27 +1313,6 @@ bool Layer::updateFrameRateForLayerTree(bool treeHasFrameRateVote) {
                                             LayerHistory::LayerUpdateType::SetFrameRate);

    return true;
    };

    const auto frameRate = mDrawingState.frameRate;
    if (frameRate.rate.isValid() || frameRate.type == FrameRateCompatibility::NoVote) {
        return updateDrawingState(frameRate);
    }

    // This layer doesn't have a frame rate. Check if its ancestors have a vote
    for (sp<Layer> parent = getParent(); parent; parent = parent->getParent()) {
        if (parent->mDrawingState.frameRate.rate.isValid()) {
            return updateDrawingState(parent->mDrawingState.frameRate);
        }
    }

    // This layer and its ancestors don't have a frame rate. If one of successors
    // has a vote, return a NoVote for successors to set the vote
    if (treeHasFrameRateVote) {
        return updateDrawingState(FrameRate(Fps(0.0f), FrameRateCompatibility::NoVote));
    }

    return updateDrawingState(frameRate);
}

Layer::FrameRate Layer::getFrameRateForLayerTree() const {
+2 −8
Original line number Diff line number Diff line
@@ -702,12 +702,6 @@ public:
     */
    virtual uint32_t doTransaction(uint32_t transactionFlags);

    /*
     * Called before updating the drawing state buffer. Used by BufferStateLayer to release any
     * unlatched buffers in the drawing state.
     */
    virtual void bufferMayChange(const sp<GraphicBuffer>& /* newBuffer */){};

    /*
     * Remove relative z for the layer if its relative parent is not part of the
     * provided layer tree.
@@ -1053,6 +1047,8 @@ private:
                                          const std::vector<Layer*>& layersInTree);

    void updateTreeHasFrameRateVote();
    bool propagateFrameRateForLayerTree(FrameRate parentFrameRate, bool* transactionNeeded);
    bool setFrameRateForLayerTree(FrameRate);
    void setZOrderRelativeOf(const wp<Layer>& relativeOf);
    bool isTrustedOverlay() const;

@@ -1071,8 +1067,6 @@ private:
    // Fills in the frame and transform info for the InputWindowInfo
    void fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay);

    bool updateFrameRateForLayerTree(bool treeHasFrameRateVote);

    // Cached properties computed from drawing state
    // Effective transform taking into account parent transforms and any parent scaling, which is
    // a transform from the current layer coordinate space to display(screen) coordinate space.
+35 −0
Original line number Diff line number Diff line
@@ -485,5 +485,40 @@ TEST_P(SetFrameRateTest, SetOnParentActivatesTree) {
    EXPECT_TRUE(FRAME_RATE_VOTE1.rate.equalsWithMargin(layerHistorySummary[1].desiredRefreshRate));
}

TEST_P(SetFrameRateTest, addChildForParentWithTreeVote) {
    EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);

    const auto& layerFactory = GetParam();

    const auto parent = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
    const auto child1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
    const auto child2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
    const auto childOfChild1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));

    addChild(parent, child1);
    addChild(child1, childOfChild1);

    childOfChild1->setFrameRate(FRAME_RATE_VOTE1);
    commitTransaction();
    EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_VOTE1, childOfChild1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree());

    addChild(parent, child2);
    commitTransaction();
    EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_VOTE1, childOfChild1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree());

    childOfChild1->setFrameRate(FRAME_RATE_NO_VOTE);
    commitTransaction();
    EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_NO_VOTE, childOfChild1->getFrameRateForLayerTree());
    EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree());
}

} // namespace
} // namespace android