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

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

Merge "Handle unbounded drawPaint/drawGLFunction operations safely" into nyc-dev

parents 6f54b224 4c3980b6
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -82,6 +82,16 @@ ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& s
    }
}

ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
        const Matrix4& localTransform, const ClipBase* localClip) {
    transform.loadMultiply(*snapshot.transform, localTransform);
    clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator,
            localClip, *(snapshot.transform));
    clippedBounds = clipState->rect;
    clipSideFlags = OpClipSideFlags::Full;
    localProjectionPathMask = nullptr;
}

ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot)
        : transform(*snapshot.transform)
        , clipState(snapshot.mutateClipArea().serializeClip(allocator))
+18 −1
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ public:
    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
            const RecordedOp& recordedOp, bool expandForStroke);

    // Constructor for unbounded ops *with* transform/clip
    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
            const Matrix4& localTransform, const ClipBase* localClip);

    // Constructor for unbounded ops without transform/clip (namely shadows)
    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);

@@ -111,8 +115,14 @@ public:
        return bakedState;
    }

    static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator,
            Snapshot& snapshot, const RecordedOp& recordedOp) {
        if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
        return allocator.create_trivial<BakedOpState>(allocator, snapshot, recordedOp);
    }

    enum class StrokeBehavior {
        // stroking is forced, regardless of style on paint
        // stroking is forced, regardless of style on paint (such as for lines)
        Forced,
        // stroking is defined by style on paint
        StyleDefined,
@@ -167,6 +177,13 @@ private:
            , roundRectClipState(snapshot.roundRectClipState)
            , op(&recordedOp) {}

    // TODO: fix this brittleness
    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
            : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
            , alpha(snapshot.alpha)
            , roundRectClipState(snapshot.roundRectClipState)
            , op(&recordedOp) {}

    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
            : computedState(allocator, snapshot)
            , alpha(snapshot.alpha)
+2 −2
Original line number Diff line number Diff line
@@ -574,7 +574,7 @@ void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) {
}

void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Functor);
}
@@ -663,7 +663,7 @@ void FrameBuilder::deferTextOp(const TextOp& op) {
}

void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint)));
}
+4 −0
Original line number Diff line number Diff line
@@ -173,6 +173,10 @@ private:
    BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) {
        return BakedOpState::tryConstruct(mAllocator, *mCanvasState.writableSnapshot(), recordedOp);
    }
    BakedOpState* tryBakeUnboundedOpState(const RecordedOp& recordedOp) {
        return BakedOpState::tryConstructUnbounded(mAllocator, *mCanvasState.writableSnapshot(), recordedOp);
    }


    // should always be surrounded by a save/restore pair, and not called if DisplayList is null
    void deferNodePropsAndOps(RenderNode& node);
+8 −5
Original line number Diff line number Diff line
@@ -257,8 +257,10 @@ struct CirclePropsOp : RecordedOp {
};

struct FunctorOp : RecordedOp {
    FunctorOp(BASE_PARAMS_PAINTLESS, Functor* functor)
            : SUPER_PAINTLESS(FunctorOp)
    // Note: undefined record-time bounds, since this op fills the clip
    // TODO: explicitly define bounds
    FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor)
            : RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr)
            , functor(functor) {}
    Functor* functor;
};
@@ -385,9 +387,10 @@ struct TextOp : RecordedOp {
};

struct TextOnPathOp : RecordedOp {
    TextOnPathOp(BASE_PARAMS, const glyph_t* glyphs, int glyphCount,
            const SkPath* path, float hOffset, float vOffset)
            : SUPER(TextOnPathOp)
    // TODO: explicitly define bounds
    TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint,
            const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset, float vOffset)
            : RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint)
            , glyphs(glyphs)
            , glyphCount(glyphCount)
            , path(path)
Loading