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

Commit 6afffb20 authored by Chris Craik's avatar Chris Craik Committed by android-build-merger
Browse files

Merge \\"Handle post-record-time clipPath scaling\\" into nyc-mr1-dev am: a6b011e9

am: ab9e74bb

Change-Id: Ic204ce482a8324367e8a27e3c332b5b5797321a5
parents 00888522 ab9e74bb
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -464,10 +464,7 @@ const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator,
            }
            case ClipMode::Region:
                other = getRegion(recordedClip);

                // TODO: handle non-translate transforms properly!
                other.translate(recordedClipTransform.getTranslateX(),
                        recordedClipTransform.getTranslateY());
                applyTransformToRegion(recordedClipTransform, &other);
            }

            ClipRegion* regionClip = allocator.create<ClipRegion>();
@@ -527,11 +524,29 @@ void ClipArea::applyClip(const ClipBase* clip, const Matrix4& transform) {
        }
    } else {
        SkRegion region(getRegion(clip));
        // TODO: handle non-translate transforms properly!
        region.translate(transform.getTranslateX(), transform.getTranslateY());
        applyTransformToRegion(transform, &region);
        clipRegion(region, SkRegion::kIntersect_Op);
    }
}

void ClipArea::applyTransformToRegion(const Matrix4& transform, SkRegion* region) {
    if (transform.isSimple() && !transform.isPureTranslate()) {
        // handle matrices with scale manually by mapping each rect
        SkRegion other;
        SkRegion::Iterator it(*region);
        while (!it.done()) {
            Rect rect(it.rect());
            transform.mapRect(rect);
            rect.roundOut();
            other.op(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kUnion_Op);
            it.next();
        }
        region->swap(other);
    } else {
        // TODO: handle non-translate transforms properly!
        region->translate(transform.getTranslateX(), transform.getTranslateY());
    }
}

} /* namespace uirenderer */
} /* namespace android */
+2 −0
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ public:
            const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
    void applyClip(const ClipBase* recordedClip, const Matrix4& recordedClipTransform);

    static void applyTransformToRegion(const Matrix4& transform, SkRegion* region);

private:
    void enterRectangleMode();
    void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
+7 −0
Original line number Diff line number Diff line
@@ -73,6 +73,13 @@ public:
            bottom(height) {
    }

    inline Rect(const SkIRect& rect):
            left(rect.fLeft),
            top(rect.fTop),
            right(rect.fRight),
            bottom(rect.fBottom) {
    }

    inline Rect(const SkRect& rect):
            left(rect.fLeft),
            top(rect.fTop),
+59 −0
Original line number Diff line number Diff line
@@ -275,5 +275,64 @@ TEST(ClipArea, serializeIntersectedClip_snap) {
    }
}

TEST(ClipArea, serializeIntersectedClip_scale) {
    ClipArea area(createClipArea());
    area.setClip(0, 0, 400, 400);
    LinearAllocator allocator;

    SkPath circlePath;
    circlePath.addCircle(50, 50, 50);

    ClipRegion recordedClip;
    recordedClip.region.setPath(circlePath, SkRegion(SkIRect::MakeWH(100, 100)));
    recordedClip.rect = Rect(100, 100);

    Matrix4 translateScale;
    translateScale.loadTranslate(100, 100, 0);
    translateScale.scale(2, 2, 1);
    auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);

    ASSERT_NE(nullptr, resolvedClip);
    EXPECT_EQ(ClipMode::Region, resolvedClip->mode);
    EXPECT_EQ(Rect(100, 100, 300, 300), resolvedClip->rect);
    auto clipRegion = reinterpret_cast<const ClipRegion*>(resolvedClip);
    EXPECT_EQ(SkIRect::MakeLTRB(100, 100, 300, 300), clipRegion->region.getBounds());
}

TEST(ClipArea, applyTransformToRegion_identity) {
    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
    ClipArea::applyTransformToRegion(Matrix4::identity(), &region);
    EXPECT_TRUE(region.isRect());
    EXPECT_EQ(SkIRect::MakeLTRB(1, 2, 3, 4), region.getBounds());
}

TEST(ClipArea, applyTransformToRegion_translate) {
    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
    Matrix4 transform;
    transform.loadTranslate(10, 20, 0);
    ClipArea::applyTransformToRegion(transform, &region);
    EXPECT_TRUE(region.isRect());
    EXPECT_EQ(SkIRect::MakeLTRB(11, 22, 13, 24), region.getBounds());
}

TEST(ClipArea, applyTransformToRegion_scale) {
    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
    Matrix4 transform;
    transform.loadScale(2, 3, 1);
    ClipArea::applyTransformToRegion(transform, &region);
    EXPECT_TRUE(region.isRect());
    EXPECT_EQ(SkIRect::MakeLTRB(2, 6, 6, 12), region.getBounds());
}

TEST(ClipArea, applyTransformToRegion_translateScale) {
    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
    Matrix4 transform;
    transform.translate(10, 20);
    transform.scale(2, 3, 1);
    ClipArea::applyTransformToRegion(transform, &region);
    EXPECT_TRUE(region.isRect());
    EXPECT_EQ(SkIRect::MakeLTRB(12, 26, 16, 32), region.getBounds());
}

} // namespace uirenderer
} // namespace android