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

Commit 70cf50c2 authored by Michael Ludwig's avatar Michael Ludwig
Browse files

Emulate replace clip ops using SkAndroidFrameworkUtils::ResetClip

At the JNI bridge, Region::Op::kReplace_Op is detected and sent
to new functions on Canvas.h -> emulateReplaceClip[Rect|Path].
The SkiaCanvas implementation calls
SkAndroidFrameworkUtils::ResetClip to turn the SkCanvas' clip
wide open (modulo the device clip restriction), followed by
an intersect op with the actual clip geometry.

SkiaCanvas is also updated to record the replace ops in its
Clip struct for partial saves.

This should result in no visible behavioral change at the Java
Canvas level, but allows the removal of the
SK_SUPPORT_DEPRECATED_CLIPOPS flag.

Test: Updated SkiaPipeline.clip_replace unit test to use the new
  emulateReplaceClipRect function instead of SkClipOp::kReplace.
  Builds and recently added CTS tests for clip ops pass.
Bug: b/151725198
Bug: b/143352151
Change-Id: I8fb8765b4ead92bbe8eceadb52710a5673b6cf6b
parent 311da53f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ X(ClipPath)
X(ClipRect)
X(ClipRRect)
X(ClipRegion)
X(ResetClip)
X(DrawPaint)
X(DrawBehind)
X(DrawPath)
+16 −0
Original line number Diff line number Diff line
@@ -187,6 +187,11 @@ struct ClipRegion final : Op {
    SkClipOp op;
    void draw(SkCanvas* c, const SkMatrix&) const { c->clipRegion(region, op); }
};
struct ResetClip final : Op {
    static const auto kType = Type::ResetClip;
    ResetClip() {}
    void draw(SkCanvas* c, const SkMatrix&) const { SkAndroidFrameworkUtils::ResetClip(c); }
};

struct DrawPaint final : Op {
    static const auto kType = Type::DrawPaint;
@@ -662,6 +667,9 @@ void DisplayListData::clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
void DisplayListData::clipRegion(const SkRegion& region, SkClipOp op) {
    this->push<ClipRegion>(0, region, op);
}
void DisplayListData::resetClip() {
    this->push<ResetClip>(0);
}

void DisplayListData::drawPaint(const SkPaint& paint) {
    this->push<DrawPaint>(0, paint);
@@ -969,6 +977,14 @@ void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
    fDL->clipRegion(region, op);
    this->INHERITED::onClipRegion(region, op);
}
void RecordingCanvas::onResetClip() {
    // This is part of "replace op" emulation, but rely on the following intersection
    // clip to potentially mark the clip as complex. If we are already complex, we do
    // not reset the complexity so that we don't break the contract that no higher
    // save point has a complex clip when "not complex".
    fDL->resetClip();
    this->INHERITED::onResetClip();
}

void RecordingCanvas::onDrawPaint(const SkPaint& paint) {
    fDL->drawPaint(paint);
+2 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ private:
    void clipRect(const SkRect&, SkClipOp, bool aa);
    void clipRRect(const SkRRect&, SkClipOp, bool aa);
    void clipRegion(const SkRegion&, SkClipOp);
    void resetClip();

    void drawPaint(const SkPaint&);
    void drawBehind(const SkPaint&);
@@ -169,6 +170,7 @@ public:
    void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
    void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
    void onClipRegion(const SkRegion&, SkClipOp) override;
    void onResetClip() override;

    void onDrawPaint(const SkPaint&) override;
    void onDrawBehind(const SkPaint&) override;
+16 −0
Original line number Diff line number Diff line
@@ -396,6 +396,22 @@ bool SkiaCanvas::clipPath(const SkPath* path, SkClipOp op) {
    return !mCanvas->isClipEmpty();
}

bool SkiaCanvas::replaceClipRect_deprecated(float left, float top, float right, float bottom) {
    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);

    // Emulated clip rects are not recorded for partial saves, since
    // partial saves have been removed from the public API.
    SkAndroidFrameworkUtils::ResetClip(mCanvas);
    mCanvas->clipRect(rect, SkClipOp::kIntersect);
    return !mCanvas->isClipEmpty();
}

bool SkiaCanvas::replaceClipPath_deprecated(const SkPath* path) {
    SkAndroidFrameworkUtils::ResetClip(mCanvas);
    mCanvas->clipPath(*path, SkClipOp::kIntersect, true);
    return !mCanvas->isClipEmpty();
}

// ----------------------------------------------------------------------------
// Canvas state operations: Filters
// ----------------------------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@ public:
    virtual bool quickRejectPath(const SkPath& path) const override;
    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
    virtual bool replaceClipRect_deprecated(float left, float top, float right,
                                            float bottom) override;
    virtual bool replaceClipPath_deprecated(const SkPath* path) override;

    virtual PaintFilter* getPaintFilter() override;
    virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) override;
Loading