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

Commit 8d1f2120 authored by Chris Craik's avatar Chris Craik
Browse files

Support projection in OpReorderer

bug:22480459

Change-Id: Iceb71732dc50957cfb47fa1ba9b8e18e6fc51132
parent 95cdbd6f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -275,7 +275,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