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

Commit 74b03178 authored by chaviw's avatar chaviw
Browse files

[Mirror Layers] Added functions to update mirrored layers info (2/4)

Added updateMirrorInfo and updateBufferInfoFromClone to ensure the state
and buffer of the clones are updated properly. updateMirrorInfo is
called when commitTransaction is called to update the drawing state,
children, and relatives. updateBufferInfoFromClone is called in
handlePageFlip after the real layer calls latchBuffer to ensure the
cloned layer gets the updated buffer and buffer info.

Test: No mirror request yet so everything runs normally
Bug: 131622422
Change-Id: Ic2b1f66cab98175dbdccf90f2f8310c7f19d8cff
parent e2930c4a
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId,
                                    const CompositorTiming& compositorTiming) {
    // mFrameLatencyNeeded is true when a new frame was latched for the
    // composition.
    if (!mFrameLatencyNeeded) return false;
    if (!mBufferInfo.mFrameLatencyNeeded) return false;

    // Update mFrameEventHistory.
    {
@@ -337,7 +337,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId,
    }

    mFrameTracker.advanceFrame();
    mFrameLatencyNeeded = false;
    mBufferInfo.mFrameLatencyNeeded = false;
    return true;
}

@@ -401,7 +401,7 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
    gatherBufferInfo();

    mRefreshPending = true;
    mFrameLatencyNeeded = true;
    mBufferInfo.mFrameLatencyNeeded = true;
    if (oldBufferInfo.mBuffer == nullptr) {
        // the first time we receive a buffer, we need to trigger a
        // geometry invalidation.
@@ -735,6 +735,35 @@ void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) {
    mPremultipliedAlpha = bufferClonedFrom->mPremultipliedAlpha;
    mPotentialCursor = bufferClonedFrom->mPotentialCursor;
    mProtectedByApp = bufferClonedFrom->mProtectedByApp;

    updateCloneBufferInfo();
}

void BufferLayer::updateCloneBufferInfo() {
    if (!isClone() || !isClonedFromAlive()) {
        return;
    }

    sp<BufferLayer> clonedFrom = static_cast<BufferLayer*>(getClonedFrom().get());
    mBufferInfo = clonedFrom->mBufferInfo;
    mSidebandStream = clonedFrom->mSidebandStream;
    surfaceDamageRegion = clonedFrom->surfaceDamageRegion;
    mCurrentFrameNumber = clonedFrom->mCurrentFrameNumber.load();
    mPreviousFrameNumber = clonedFrom->mPreviousFrameNumber;

    // After buffer info is updated, the drawingState from the real layer needs to be copied into
    // the cloned. This is because some properties of drawingState can change when latchBuffer is
    // called. However, copying the drawingState would also overwrite the cloned layer's relatives.
    // Therefore, temporarily store the relatives so they can be set in the cloned drawingState
    // again.
    wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf;
    SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives;
    mDrawingState = clonedFrom->mDrawingState;
    // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple
    // InputWindows per client token yet.
    mDrawingState.inputInfo.token = nullptr;
    mDrawingState.zOrderRelativeOf = tmpZOrderRelativeOf;
    mDrawingState.zOrderRelatives = tmpZOrderRelatives;
}

} // namespace android
+4 −0
Original line number Diff line number Diff line
@@ -165,6 +165,8 @@ protected:

        sp<GraphicBuffer> mBuffer;
        int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};

        bool mFrameLatencyNeeded{false};
    };

    BufferInfo mBufferInfo;
@@ -195,6 +197,8 @@ protected:

    ui::Dataspace translateDataspace(ui::Dataspace dataspace);
    void setInitialValuesForClone(const sp<Layer>& clonedFrom);
    void updateCloneBufferInfo() override;
    uint64_t mPreviousFrameNumber = 0;

private:
    // Returns true if this layer requires filtering
+0 −2
Original line number Diff line number Diff line
@@ -111,8 +111,6 @@ private:

    PixelFormat mFormat{PIXEL_FORMAT_NONE};

    // Only accessed on the main thread.
    uint64_t mPreviousFrameNumber{0};
    bool mUpdateTexImageFailed{false};

    uint64_t mPreviousBufferId = 0;
+0 −1
Original line number Diff line number Diff line
@@ -143,7 +143,6 @@ private:

    sp<Fence> mPreviousReleaseFence;
    uint64_t mPreviousBufferId = 0;
    uint64_t mPreviousFrameNumber = 0;
    uint64_t mPreviousReleasedFrameNumber = 0;

    mutable bool mCurrentStateModified = false;
+112 −0
Original line number Diff line number Diff line
@@ -2025,6 +2025,118 @@ void Layer::setInitialValuesForClone(const sp<Layer>& clonedFrom) {
    // InputWindows per client token yet.
    mDrawingState.inputInfo.token = nullptr;
}

void Layer::updateMirrorInfo() {
    if (mClonedChild == nullptr || !mClonedChild->isClonedFromAlive()) {
        // If mClonedChild is null, there is nothing to mirror. If isClonedFromAlive returns false,
        // it means that there is a clone, but the layer it was cloned from has been destroyed. In
        // that case, we want to delete the reference to the clone since we want it to get
        // destroyed. The root, this layer, will still be around since the client can continue
        // to hold a reference, but no cloned layers will be displayed.
        mClonedChild = nullptr;
        return;
    }

    std::map<sp<Layer>, sp<Layer>> clonedLayersMap;
    // If the real layer exists and is in current state, add the clone as a child of the root.
    // There's no need to remove from drawingState when the layer is offscreen since currentState is
    // copied to drawingState for the root layer. So the clonedChild is always removed from
    // drawingState and then needs to be added back each traversal.
    if (!mClonedChild->getClonedFrom()->isRemovedFromCurrentState()) {
        addChildToDrawing(mClonedChild);
    }

    mClonedChild->updateClonedDrawingState(clonedLayersMap);
    mClonedChild->updateClonedChildren(this, clonedLayersMap);
    mClonedChild->updateClonedRelatives(clonedLayersMap);
}

void Layer::updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
    // If the layer the clone was cloned from is alive, copy the content of the drawingState
    // to the clone. If the real layer is no longer alive, continue traversing the children
    // since we may be able to pull out other children that are still alive.
    if (isClonedFromAlive()) {
        sp<Layer> clonedFrom = getClonedFrom();
        mDrawingState = clonedFrom->mDrawingState;
        // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple
        // InputWindows per client token yet.
        mDrawingState.inputInfo.token = nullptr;
        clonedLayersMap.emplace(clonedFrom, this);
    }

    // The clone layer may have children in drawingState since they may have been created and
    // added from a previous request to updateMirorInfo. This is to ensure we don't recreate clones
    // that already exist, since we can just re-use them.
    // The drawingChildren will not get overwritten by the currentChildren since the clones are
    // not updated in the regular traversal. They are skipped since the root will lose the
    // reference to them when it copies its currentChildren to drawing.
    for (sp<Layer>& child : mDrawingChildren) {
        child->updateClonedDrawingState(clonedLayersMap);
    }
}

void Layer::updateClonedChildren(const sp<Layer>& mirrorRoot,
                                 std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
    mDrawingChildren.clear();

    if (!isClonedFromAlive()) {
        return;
    }

    sp<Layer> clonedFrom = getClonedFrom();
    for (sp<Layer>& child : clonedFrom->mDrawingChildren) {
        if (child == mirrorRoot) {
            // This is to avoid cyclical mirroring.
            continue;
        }
        sp<Layer> clonedChild = clonedLayersMap[child];
        if (clonedChild == nullptr) {
            clonedChild = child->createClone();
            clonedLayersMap[child] = clonedChild;
        }
        addChildToDrawing(clonedChild);
        clonedChild->updateClonedChildren(mirrorRoot, clonedLayersMap);
    }
}

void Layer::updateClonedRelatives(std::map<sp<Layer>, sp<Layer>> clonedLayersMap) {
    mDrawingState.zOrderRelativeOf = nullptr;
    mDrawingState.zOrderRelatives.clear();

    if (!isClonedFromAlive()) {
        return;
    }

    sp<Layer> clonedFrom = getClonedFrom();
    for (wp<Layer>& relativeWeak : clonedFrom->mDrawingState.zOrderRelatives) {
        sp<Layer> relative = relativeWeak.promote();
        auto clonedRelative = clonedLayersMap[relative];
        if (clonedRelative != nullptr) {
            mDrawingState.zOrderRelatives.add(clonedRelative);
        }
    }

    // Check if the relativeLayer for the real layer is part of the cloned hierarchy.
    // It's possible that the layer it's relative to is outside the requested cloned hierarchy.
    // In that case, we treat the layer as if the relativeOf has been removed. This way, it will
    // still traverse the children, but the layer with the missing relativeOf will not be shown
    // on screen.
    sp<Layer> relativeOf = clonedFrom->mDrawingState.zOrderRelativeOf.promote();
    sp<Layer> clonedRelativeOf = clonedLayersMap[relativeOf];
    if (clonedRelativeOf != nullptr) {
        mDrawingState.zOrderRelativeOf = clonedRelativeOf;
    }

    for (sp<Layer>& child : mDrawingChildren) {
        child->updateClonedRelatives(clonedLayersMap);
    }
}

void Layer::addChildToDrawing(const sp<Layer>& layer) {
    mDrawingChildren.add(layer);
    layer->mDrawingParent = this;
}

// ---------------------------------------------------------------------------

}; // namespace android
Loading