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

Commit 3281442a authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Wrap ViewGroup content in save/restore to protect composited children"

parents 6ab7c1e7 80d49021
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1475,19 +1475,19 @@ public:
    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
            bool useQuickReject) {
        if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) {
            mDisplayList->deferNodeInParent(deferStruct, level + 1);
            mDisplayList->defer(deferStruct, level + 1);
        }
    }
    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
            bool useQuickReject) {
        if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) {
            mDisplayList->replayNodeInParent(replayStruct, level + 1);
            mDisplayList->replay(replayStruct, level + 1);
        }
    }

    // NOT USED since replay() is overridden
    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
        return DrawGlInfo::kStatusDone;
        LOG_ALWAYS_FATAL("should not be called, because replay() is overridden");
        return 0;
    }

    virtual void output(int level, uint32_t logFlags) const {
+1 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ void Layer::defer() {
            dirtyRect.right, dirtyRect.bottom, !isBlend());

    displayList->computeOrdering();
    displayList->deferNodeTree(deferredState);
    displayList->defer(deferredState, 0);

    deferredUpdateScheduled = false;
}
+2 −2
Original line number Diff line number Diff line
@@ -1942,14 +1942,14 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
        if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
            status = startFrame();
            ReplayStateStruct replayStruct(*this, dirty, replayFlags);
            displayList->replayNodeTree(replayStruct);
            displayList->replay(replayStruct, 0);
            return status | replayStruct.mDrawGlStatus;
        }

        bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!
        DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw);
        DeferStateStruct deferStruct(deferredList, *this, replayFlags);
        displayList->deferNodeTree(deferStruct);
        displayList->defer(deferStruct, 0);

        flushLayers();
        status = startFrame();
+38 −26
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */

#define ATRACE_TAG ATRACE_TAG_VIEW
#define LOG_TAG "RenderNode"
#define LOG_TAG "OpenGLRenderer"

#include "RenderNode.h"

@@ -536,15 +536,7 @@ private:
    const int mLevel;
};

void RenderNode::deferNodeTree(DeferStateStruct& deferStruct) {
    DeferOperationHandler handler(deferStruct, 0);
    if (MathUtils::isPositive(properties().getZ())) {
        issueDrawShadowOperation(Matrix4::identity(), handler);
    }
    issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler);
}

void RenderNode::deferNodeInParent(DeferStateStruct& deferStruct, const int level) {
void RenderNode::defer(DeferStateStruct& deferStruct, const int level) {
    DeferOperationHandler handler(deferStruct, level);
    issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler);
}
@@ -574,15 +566,7 @@ private:
    const int mLevel;
};

void RenderNode::replayNodeTree(ReplayStateStruct& replayStruct) {
    ReplayOperationHandler handler(replayStruct, 0);
    if (MathUtils::isPositive(properties().getZ())) {
        issueDrawShadowOperation(Matrix4::identity(), handler);
    }
    issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler);
}

void RenderNode::replayNodeInParent(ReplayStateStruct& replayStruct, const int level) {
void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
    ReplayOperationHandler handler(replayStruct, level);
    issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler);
}
@@ -641,6 +625,36 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T&
    handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}

template <class T>
int RenderNode::issueOperationsOfNegZChildren(
        const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
        OpenGLRenderer& renderer, T& handler) {
    if (zTranslatedNodes.isEmpty()) return -1;

    // create a save around the body of the ViewGroup's draw method, so that
    // matrix/clip methods don't affect composited children
    int shadowSaveCount = renderer.getSaveCount();
    handler(new (handler.allocator()) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
            PROPERTY_SAVECOUNT, properties().getClipToBounds());

    issueOperationsOf3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler);
    return shadowSaveCount;
}

template <class T>
void RenderNode::issueOperationsOfPosZChildren(int shadowRestoreTo,
        const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
        OpenGLRenderer& renderer, T& handler) {
    if (zTranslatedNodes.isEmpty()) return;

    LOG_ALWAYS_FATAL_IF(shadowRestoreTo < 0, "invalid save to restore to");
    handler(new (handler.allocator()) RestoreToCountOp(shadowRestoreTo),
            PROPERTY_SAVECOUNT, properties().getClipToBounds());
    renderer.setOverrideLayerAlpha(1.0f);

    issueOperationsOf3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler);
}

#define SHADOW_DELTA 0.1f

template <class T>
@@ -714,8 +728,6 @@ template <class T>
void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler) {
    DISPLAY_LIST_LOGD("%*s%d projected children:", (handler.level() + 1) * 2, "", mProjectedNodes.size());
    const SkPath* projectionReceiverOutline = properties().getOutline().getPath();
    bool maskProjecteesWithPath = projectionReceiverOutline != NULL
            && !projectionReceiverOutline->isRect(NULL);
    int restoreTo = renderer.getSaveCount();

    // If the projection reciever has an outline, we mask each of the projected rendernodes to it
@@ -736,7 +748,7 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T&
            SaveLayerOp* op = new (alloc) SaveLayerOp(
                    outlineBounds.left(), outlineBounds.top(),
                    outlineBounds.right(), outlineBounds.bottom(),
                    255, SkCanvas::kARGB_ClipLayer_SaveFlag);
                    255, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag | SkCanvas::kARGB_ClipLayer_SaveFlag);
            op->setMask(projectionReceiverOutline);
            handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());

@@ -825,7 +837,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
            buildZSortedChildList(zTranslatedNodes);

            // for 3d root, draw children with negative z values
            issueOperationsOf3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler);
            int shadowRestoreTo = issueOperationsOfNegZChildren(zTranslatedNodes, renderer, handler);

            DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
            const int saveCountOffset = renderer.getSaveCount() - 1;
@@ -845,7 +857,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
            }

            // for 3d root, draw children with positive z values
            issueOperationsOf3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler);
            issueOperationsOfPosZChildren(shadowRestoreTo, zTranslatedNodes, renderer, handler);
        }
    }

+10 −5
Original line number Diff line number Diff line
@@ -113,11 +113,8 @@ public:

    void computeOrdering();

    void deferNodeTree(DeferStateStruct& deferStruct);
    void deferNodeInParent(DeferStateStruct& deferStruct, const int level);

    void replayNodeTree(ReplayStateStruct& replayStruct);
    void replayNodeInParent(ReplayStateStruct& replayStruct, const int level);
    void defer(DeferStateStruct& deferStruct, const int level);
    void replay(ReplayStateStruct& replayStruct, const int level);

    ANDROID_API void output(uint32_t level = 1);
    ANDROID_API int getDebugSize();
@@ -227,6 +224,14 @@ private:
    template<class T>
    inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler);

    template <class T>
    inline int issueOperationsOfNegZChildren(
            const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
            OpenGLRenderer& renderer, T& handler);
    template <class T>
    inline void issueOperationsOfPosZChildren(int shadowRestoreTo,
            const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
            OpenGLRenderer& renderer, T& handler);
    template <class T>
    inline void issueOperationsOf3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
            ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler);