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

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

Merge "Support projection in OpReorderer"

parents befb4d7c 8d1f2120
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -276,7 +276,9 @@ LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := hwuimicro
LOCAL_MODULE_STEM_64 := hwuimicro64
LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
LOCAL_CFLAGS := $(hwui_cflags)
LOCAL_CFLAGS := \
        $(hwui_cflags) \
        -DHWUI_NULL_GPU
LOCAL_C_INCLUDES += bionic/benchmarks/

LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static_null_gpu
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ public:
    DisplayList();
    ~DisplayList();

    // index of DisplayListOp restore, after which projected descendents should be drawn
    // index of DisplayListOp restore, after which projected descendants should be drawn
    int projectionReceiveIndex;

    const LsaVector<Chunk>& getChunks() const { return chunks; }
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ class DeferredDisplayList;
class DeferredLayerUpdater;
class DisplayListOp;
class DrawOp;
class DrawRenderNodeOp;
class RenderNode;
class StateOp;

+7 −7
Original line number Diff line number Diff line
@@ -1386,19 +1386,19 @@ public:
            : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
            , renderNode(renderNode)
            , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple())
            , mTransformFromParent(transformFromParent)
            , mSkipInOrderDraw(false) {}
            , localMatrix(transformFromParent)
            , skipInOrderDraw(false) {}

    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
            bool useQuickReject) override {
        if (renderNode->isRenderable() && !mSkipInOrderDraw) {
        if (renderNode->isRenderable() && !skipInOrderDraw) {
            renderNode->defer(deferStruct, level + 1);
        }
    }

    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
            bool useQuickReject) override {
        if (renderNode->isRenderable() && !mSkipInOrderDraw) {
        if (renderNode->isRenderable() && !skipInOrderDraw) {
            renderNode->replay(replayStruct, level + 1);
        }
    }
@@ -1439,7 +1439,7 @@ private:
    /**
     * Records transform vs parent, used for computing total transform without rerunning DL contents
     */
    const mat4 mTransformFromParent;
    const mat4 localMatrix;

    /**
     * Holds the transformation between the projection surface ViewGroup and this RenderNode
@@ -1449,8 +1449,8 @@ private:
     *
     * Note: doesn't include transformation within the RenderNode, or its properties.
     */
    mat4 mTransformFromCompositingAncestor;
    bool mSkipInOrderDraw;
    mat4 transformFromCompositingAncestor;
    bool skipInOrderDraw;
};

/**
+49 −20
Original line number Diff line number Diff line
@@ -330,6 +330,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
    for (int i = layers.entries().size() - 1; i >= 0; i--) {
        RenderNode* layerNode = layers.entries()[i].renderNode;
        const Rect& layerDamage = layers.entries()[i].damage;
        layerNode->computeOrdering();

        // map current light center into RenderNode's coordinate space
        Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter();
@@ -339,7 +340,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
                layerDamage, lightCenter, nullptr, layerNode);

        if (layerNode->getDisplayList()) {
            deferDisplayList(*(layerNode->getDisplayList()));
            deferNodeOps(*layerNode);
        }
        restoreForLayer();
    }
@@ -347,6 +348,7 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
    // Defer Fbo0
    for (const sp<RenderNode>& node : nodes) {
        if (node->nothingToDraw()) continue;
        node->computeOrdering();

        int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
        deferNodePropsAndOps(*node);
@@ -354,20 +356,6 @@ OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
    }
}

OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList,
        const Vector3& lightCenter)
        : mCanvasState(*this) {
    ATRACE_NAME("prepare drawing commands");
    // Prepare to defer Fbo0
    mLayerReorderers.emplace_back(viewportWidth, viewportHeight,
            Rect(viewportWidth, viewportHeight));
    mLayerStack.push_back(0);
    mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
            0, 0, viewportWidth, viewportHeight, lightCenter);

    deferDisplayList(displayList);
}

void OpReorderer::onViewportInitialized() {}

void OpReorderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
@@ -462,10 +450,10 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) {
                    Matrix4::identity(),
                    saveLayerBounds,
                    &saveLayerPaint));
            deferDisplayList(*(node.getDisplayList()));
            deferNodeOps(node);
            onEndLayerOp(*new (mAllocator) EndLayerOp());
        } else {
            deferDisplayList(*(node.getDisplayList()));
            deferNodeOps(node);
        }
    }
}
@@ -610,18 +598,53 @@ void OpReorderer::deferShadow(const RenderNodeOp& casterNodeOp) {
    }
}

void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) {
    const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath();
    int count = mCanvasState.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);

    // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
    const DisplayList& displayList = *(renderNode.getDisplayList());

    const RecordedOp* op = (displayList.getOps()[displayList.projectionReceiveIndex]);
    const RenderNodeOp* backgroundOp = static_cast<const RenderNodeOp*>(op);
    const RenderProperties& backgroundProps = backgroundOp->renderNode->properties();

    // Transform renderer to match background we're projecting onto
    // (by offsetting canvas by translationX/Y of background rendernode, since only those are set)
    mCanvasState.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY());

    // If the projection receiver has an outline, we mask projected content to it
    // (which we know, apriori, are all tessellated paths)
    mCanvasState.setProjectionPathMask(mAllocator, projectionReceiverOutline);

    // draw projected nodes
    for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
        RenderNodeOp* childOp = renderNode.mProjectedNodes[i];

        int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag);
        mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
        deferRenderNodeOp(*childOp);
        mCanvasState.restoreToCount(restoreTo);
    }

    mCanvasState.restoreToCount(count);
}

/**
 * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods.
 *
 * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas. E.g. a
 * BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&)
 * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas.
 * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&)
 */
#define OP_RECEIVER(Type) \
        [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); },
void OpReorderer::deferDisplayList(const DisplayList& displayList) {
void OpReorderer::deferNodeOps(const RenderNode& renderNode) {
    static std::function<void(OpReorderer& reorderer, const RecordedOp&)> receivers[] = {
        MAP_OPS(OP_RECEIVER)
    };

    // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
    const DisplayList& displayList = *(renderNode.getDisplayList());
    for (const DisplayList::Chunk& chunk : displayList.getChunks()) {
        FatVector<ZRenderNodeOpPair, 16> zTranslatedNodes;
        buildZSortedChildList(&zTranslatedNodes, displayList, chunk);
@@ -630,6 +653,12 @@ void OpReorderer::deferDisplayList(const DisplayList& displayList) {
        for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
            const RecordedOp* op = displayList.getOps()[opIndex];
            receivers[op->opId](*this, *op);

            if (CC_UNLIKELY(!renderNode.mProjectedNodes.empty()
                    && displayList.projectionReceiveIndex >= 0
                    && static_cast<int>(opIndex) == displayList.projectionReceiveIndex)) {
                deferProjectedChildren(renderNode);
            }
        }
        defer3dChildren(ChildrenSelectMode::Positive, zTranslatedNodes);
    }
Loading