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

Commit 2f10a26a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Put Vulkan WebViews on a HW layer if stencil clip"

parents c717bece f09ee58e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -759,6 +759,8 @@ RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {}
void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) {
    this->resetCanvas(bounds.right(), bounds.bottom());
    fDL = dl;
    mClipMayBeComplex = false;
    mSaveCount = mComplexSaveCount = 0;
}

sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
@@ -770,6 +772,7 @@ void RecordingCanvas::onFlush() {
}

void RecordingCanvas::willSave() {
    mSaveCount++;
    fDL->save();
}
SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
@@ -778,6 +781,11 @@ SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLaye
    return SkCanvas::kNoLayer_SaveLayerStrategy;
}
void RecordingCanvas::willRestore() {
    mSaveCount--;
    if (mSaveCount < mComplexSaveCount) {
        mClipMayBeComplex = false;
        mComplexSaveCount = 0;
    }
    fDL->restore();
}

@@ -798,17 +806,27 @@ void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) {

void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) {
    fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle);
    if (!getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    this->INHERITED::onClipRect(rect, op, style);
}
void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) {
    if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle);
    this->INHERITED::onClipRRect(rrect, op, style);
}
void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) {
    setClipMayBeComplex();
    fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle);
    this->INHERITED::onClipPath(path, op, style);
}
void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
    if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    fDL->clipRegion(region, op);
    this->INHERITED::onClipRegion(region, op);
}
+31 −0
Original line number Diff line number Diff line
@@ -203,10 +203,41 @@ public:

    void drawVectorDrawable(VectorDrawableRoot* tree);

    /**
     * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
     * If the return value is true, then clip may or may not be complex (there is no guarantee).
     */
    inline bool isClipMayBeComplex() { return mClipMayBeComplex; }

private:
    typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;

    inline void setClipMayBeComplex() {
        if (!mClipMayBeComplex) {
            mComplexSaveCount = mSaveCount;
            mClipMayBeComplex = true;
        }
    }

    DisplayListData* fDL;

    /**
     * mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote
     * FunctorDrawable to a layer, if it is clipped by a non-rect.
     */
    bool mClipMayBeComplex = false;

    /**
     * mSaveCount is the current level of our save tree.
     */
    int mSaveCount = 0;

    /**
     * mComplexSaveCount is the first save level, which has a complex clip. Every level below
     * mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount
     * is guaranteed to not be complex.
     */
    int mComplexSaveCount = 0;
};

}  // namespace uirenderer
+8 −0
Original line number Diff line number Diff line
@@ -151,6 +151,7 @@ public:
        // parent may have already dictated that a descendant layer is needed
        bool functorsNeedLayer =
                ancestorDictatesFunctorsNeedLayer
                || CC_UNLIKELY(isClipMayBeComplex())

                // Round rect clipping forces layer for functors
                || CC_UNLIKELY(getOutline().willRoundRectClip()) ||
@@ -193,6 +194,12 @@ public:

    bool isProjectionReceiver() const { return mPrimitiveFields.mProjectionReceiver; }

    bool setClipMayBeComplex(bool isClipMayBeComplex) {
        return RP_SET(mPrimitiveFields.mClipMayBeComplex, isClipMayBeComplex);
    }

    bool isClipMayBeComplex() const { return mPrimitiveFields.mClipMayBeComplex; }

    bool setStaticMatrix(const SkMatrix* matrix) {
        delete mStaticMatrix;
        if (matrix) {
@@ -563,6 +570,7 @@ private:
        bool mProjectBackwards = false;
        bool mProjectionReceiver = false;
        bool mAllowForceDark = true;
        bool mClipMayBeComplex = false;
        Rect mClipBounds;
        Outline mOutline;
        RevealClip mRevealClip;
+0 −1
Original line number Diff line number Diff line
@@ -73,7 +73,6 @@ bool SkiaDisplayList::prepareListAndChildren(
        RenderNode* childNode = child.getRenderNode();
        Matrix4 mat4(child.getRecordedMatrix());
        info.damageAccumulator->pushTransform(&mat4);
        // TODO: a layer is needed if the canvas is rotated or has a non-rect clip
        info.hasBackwardProjectedNodes = false;
        childFn(childNode, observer, info, functorsNeedLayer);
        hasBackwardProjectedNodesSubtree |= info.hasBackwardProjectedNodes;
+4 −0
Original line number Diff line number Diff line
@@ -113,6 +113,10 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
    // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
    mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
    auto& renderNodeDrawable = mDisplayList->mChildNodes.back();
    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
        // Put Vulkan WebViews with non-rectangular clips in a HW layer
        renderNode->mutateStagingProperties().setClipMayBeComplex(mRecorder.isClipMayBeComplex());
    }
    drawDrawable(&renderNodeDrawable);

    // use staging property, since recording on UI thread