From fb1e7f1b6aa772c0d579cc8f2d21791f421cba54 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Fri, 6 Nov 2020 22:49:42 -0800 Subject: [PATCH] Add canvas ops 3 Added the following --DrawPoint --DrawPath --DrawRegion --DrawDoubleRoundRect --DrawLine --DrawVertices Test: Added tests to CanvasOpTests Change-Id: I5844c61bc8d2dacf74e504f7bac7946398174ed2 --- libs/hwui/canvas/CanvasOpTypes.h | 6 + libs/hwui/canvas/CanvasOps.h | 66 ++++++++- libs/hwui/tests/common/CallCountingCanvas.h | 8 +- libs/hwui/tests/unit/CanvasOpTests.cpp | 149 ++++++++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h index 895c6d069bf7f..efcb3739ab5d9 100644 --- a/libs/hwui/canvas/CanvasOpTypes.h +++ b/libs/hwui/canvas/CanvasOpTypes.h @@ -37,13 +37,19 @@ enum class CanvasOpType : int8_t { // Drawing ops DrawColor, DrawRect, + DrawRegion, DrawRoundRect, DrawRoundRectProperty, + DrawDoubleRoundRect, DrawCircleProperty, DrawCircle, DrawOval, DrawArc, DrawPaint, + DrawPoint, + DrawPath, + DrawLine, + DrawVertices, // TODO: Rest diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h index afd88c04a8580..6a76539589815 100644 --- a/libs/hwui/canvas/CanvasOps.h +++ b/libs/hwui/canvas/CanvasOps.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include "CanvasProperty.h" @@ -149,6 +151,15 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template <> +struct CanvasOp { + float x; + float y; + SkPaint paint; + void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); } + ASSERT_DRAWABLE() +}; + template <> struct CanvasOp { SkRect rect; @@ -157,6 +168,14 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template <> +struct CanvasOp { + SkRegion region; + SkPaint paint; + void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); } + ASSERT_DRAWABLE() +}; + template<> struct CanvasOp { SkRect rect; @@ -169,6 +188,17 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template<> +struct CanvasOp { + SkRRect outer; + SkRRect inner; + SkPaint paint; + void draw(SkCanvas* canvas) const { + canvas->drawDRRect(outer, inner, paint); + } + ASSERT_DRAWABLE() +}; + template<> struct CanvasOp { SkScalar cx; @@ -205,7 +235,41 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template<> +struct CanvasOp { + SkPath path; + SkPaint paint; + + void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); } + ASSERT_DRAWABLE() +}; + +template<> +struct CanvasOp { + float startX; + float startY; + float endX; + float endY; + SkPaint paint; + + void draw(SkCanvas* canvas) const { + canvas->drawLine(startX, startY, endX, endY, paint); + } + ASSERT_DRAWABLE() +}; + +template<> +struct CanvasOp { + sk_sp vertices; + SkBlendMode mode; + SkPaint paint; + void draw(SkCanvas* canvas) const { + canvas->drawVertices(vertices, mode, paint); + } + ASSERT_DRAWABLE() +}; + // cleanup our macros #undef ASSERT_DRAWABLE -} // namespace android::uirenderer \ No newline at end of file +} // namespace android::uirenderer diff --git a/libs/hwui/tests/common/CallCountingCanvas.h b/libs/hwui/tests/common/CallCountingCanvas.h index a96557141ef54..594afd04860bb 100644 --- a/libs/hwui/tests/common/CallCountingCanvas.h +++ b/libs/hwui/tests/common/CallCountingCanvas.h @@ -80,7 +80,7 @@ public: int drawPathCount = 0; void onDrawPath(const SkPath& path, const SkPaint& paint) override { - drawPaintCount++; + drawPathCount++; } int drawRegionCount = 0; @@ -159,6 +159,12 @@ public: drawPictureCount++; } + int drawVerticesCount = 0; + void onDrawVerticesObject (const SkVertices *vertices, SkBlendMode mode, + const SkPaint &paint) override { + drawVerticesCount++; + } + private: int END_MARKER; }; diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp index 231192444caf8..60c8628ea966d 100644 --- a/libs/hwui/tests/unit/CanvasOpTests.cpp +++ b/libs/hwui/tests/unit/CanvasOpTests.cpp @@ -196,6 +196,40 @@ TEST(CanvasOp, simpleDrawPaint) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawPoint) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + buffer.push(CanvasOp { + .x = 12, + .y = 42, + .paint = SkPaint{} + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawPoints); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + +TEST(CanvasOp, simpleDrawLine) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + buffer.push(CanvasOp { + .startX = 16, + .startY = 28, + .endX = 12, + .endY = 30, + .paint = SkPaint{} + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawPoints); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + TEST(CanvasOp, simpleDrawRect) { CanvasOpBuffer buffer; EXPECT_EQ(buffer.size(), 0); @@ -211,6 +245,45 @@ TEST(CanvasOp, simpleDrawRect) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawRegionRect) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + SkRegion region; + region.setRect(SkIRect::MakeWH(12, 50)); + buffer.push(CanvasOp { + .paint = SkPaint{}, + .region = region + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + // If the region is a rectangle, drawRegion calls into drawRect as a fast path + EXPECT_EQ(1, canvas.drawRectCount); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + +TEST(CanvasOp, simpleDrawRegionPath) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + SkPath path; + path.addCircle(50, 50, 50); + SkRegion clip; + clip.setRect(SkIRect::MakeWH(100, 100)); + SkRegion region; + region.setPath(path, clip); + buffer.push(CanvasOp { + .paint = SkPaint{}, + .region = region + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawRegionCount); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + TEST(CanvasOp, simpleDrawRoundRect) { CanvasOpBuffer buffer; EXPECT_EQ(buffer.size(), 0); @@ -228,6 +301,44 @@ TEST(CanvasOp, simpleDrawRoundRect) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawDoubleRoundRect) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + SkRect outer = SkRect::MakeLTRB(0, 0, 100, 100); + SkRect inner = SkRect::MakeLTRB(20, 20, 80, 80); + + const int numPts = 4; + SkRRect outerRRect; + + auto outerPts = std::make_unique(numPts); + outerPts[0].set(32, 16); + outerPts[1].set(48, 48); + outerPts[2].set(16, 32); + outerPts[3].set(20, 20); + outerRRect.setRectRadii(outer, outerPts.get()); + outerRRect.setRect(outer); + + SkRRect innerRRect; + auto innerPts = std::make_unique(numPts); + innerPts[0].set(16, 8); + innerPts[1].set(24, 24); + innerPts[2].set(8, 16); + innerPts[3].set(10, 10); + innerRRect.setRectRadii(inner, innerPts.get()); + + buffer.push(CanvasOp { + .outer = outerRRect, + .inner = innerRRect, + .paint = SkPaint{} + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawDRRectCount); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + TEST(CanvasOp, simpleDrawCircle) { CanvasOpBuffer buffer; EXPECT_EQ(buffer.size(), 0); @@ -278,6 +389,23 @@ TEST(CanvasOp, simpleDrawArc) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawPath) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + SkPath path; + path.addCircle(50, 50, 30); + buffer.push(CanvasOp { + .path = path, + .paint = SkPaint{} + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawPathCount); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + TEST(CanvasOp, simpleDrawRoundRectProperty) { CanvasOpBuffer buffer; EXPECT_EQ(buffer.size(), 0); @@ -332,6 +460,27 @@ TEST(CanvasOp, simpleDrawCircleProperty) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawVertices) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + + SkPoint pts[3] = {{64, 32}, {0, 224}, {128, 224}}; + SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN}; + sk_sp vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, + nullptr, colors); + buffer.push(CanvasOp { + .vertices = vertices, + .mode = SkBlendMode::kSrcOver, + .paint = SkPaint{} + }); + + CallCountingCanvas canvas; + EXPECT_EQ(0, canvas.sumTotalDrawCalls()); + rasterizeCanvasBuffer(buffer, &canvas); + EXPECT_EQ(1, canvas.drawVerticesCount); + EXPECT_EQ(1, canvas.sumTotalDrawCalls()); +} + TEST(CanvasOp, immediateRendering) { auto canvas = std::make_shared();