Loading libs/hwui/canvas/CanvasOpTypes.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading libs/hwui/canvas/CanvasOps.h +65 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <SkAndroidFrameworkUtils.h> #include <SkCanvas.h> #include <SkPath.h> #include <SkRegion.h> #include <SkVertices.h> #include <log/log.h> #include "CanvasProperty.h" Loading Loading @@ -149,6 +151,15 @@ struct CanvasOp<CanvasOpType::DrawPaint> { ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawPoint> { float x; float y; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); } ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawRect> { SkRect rect; Loading @@ -157,6 +168,14 @@ struct CanvasOp<CanvasOpType::DrawRect> { ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawRegion> { SkRegion region; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawRoundRect> { SkRect rect; Loading @@ -169,6 +188,17 @@ struct CanvasOp<CanvasOpType::DrawRoundRect> { ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> { SkRRect outer; SkRRect inner; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawDRRect(outer, inner, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawCircle> { SkScalar cx; Loading Loading @@ -205,6 +235,40 @@ struct CanvasOp<CanvasOpType::DrawArc> { ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawPath> { SkPath path; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawLine> { 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<CanvasOpType::DrawVertices> { sk_sp<SkVertices> vertices; SkBlendMode mode; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawVertices(vertices, mode, paint); } ASSERT_DRAWABLE() }; // cleanup our macros #undef ASSERT_DRAWABLE Loading libs/hwui/tests/common/CallCountingCanvas.h +7 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ public: int drawPathCount = 0; void onDrawPath(const SkPath& path, const SkPaint& paint) override { drawPaintCount++; drawPathCount++; } int drawRegionCount = 0; Loading Loading @@ -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; }; Loading libs/hwui/tests/unit/CanvasOpTests.cpp +149 −0 Original line number Diff line number Diff line Loading @@ -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<Op::DrawPoint> { .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<Op::DrawLine> { .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); Loading @@ -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<Op::DrawRegion> { .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<Op::DrawRegion> { .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); Loading @@ -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<SkVector[]>(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<SkVector[]>(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<Op::DrawDoubleRoundRect> { .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); Loading Loading @@ -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<Op::DrawPath> { .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); Loading Loading @@ -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<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, nullptr, colors); buffer.push(CanvasOp<Op::DrawVertices> { .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<CallCountingCanvas>(); Loading Loading
libs/hwui/canvas/CanvasOpTypes.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/hwui/canvas/CanvasOps.h +65 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <SkAndroidFrameworkUtils.h> #include <SkCanvas.h> #include <SkPath.h> #include <SkRegion.h> #include <SkVertices.h> #include <log/log.h> #include "CanvasProperty.h" Loading Loading @@ -149,6 +151,15 @@ struct CanvasOp<CanvasOpType::DrawPaint> { ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawPoint> { float x; float y; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawPoint(x, y, paint); } ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawRect> { SkRect rect; Loading @@ -157,6 +168,14 @@ struct CanvasOp<CanvasOpType::DrawRect> { ASSERT_DRAWABLE() }; template <> struct CanvasOp<CanvasOpType::DrawRegion> { SkRegion region; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawRegion(region, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawRoundRect> { SkRect rect; Loading @@ -169,6 +188,17 @@ struct CanvasOp<CanvasOpType::DrawRoundRect> { ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawDoubleRoundRect> { SkRRect outer; SkRRect inner; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawDRRect(outer, inner, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawCircle> { SkScalar cx; Loading Loading @@ -205,6 +235,40 @@ struct CanvasOp<CanvasOpType::DrawArc> { ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawPath> { SkPath path; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawPath(path, paint); } ASSERT_DRAWABLE() }; template<> struct CanvasOp<CanvasOpType::DrawLine> { 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<CanvasOpType::DrawVertices> { sk_sp<SkVertices> vertices; SkBlendMode mode; SkPaint paint; void draw(SkCanvas* canvas) const { canvas->drawVertices(vertices, mode, paint); } ASSERT_DRAWABLE() }; // cleanup our macros #undef ASSERT_DRAWABLE Loading
libs/hwui/tests/common/CallCountingCanvas.h +7 −1 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ public: int drawPathCount = 0; void onDrawPath(const SkPath& path, const SkPaint& paint) override { drawPaintCount++; drawPathCount++; } int drawRegionCount = 0; Loading Loading @@ -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; }; Loading
libs/hwui/tests/unit/CanvasOpTests.cpp +149 −0 Original line number Diff line number Diff line Loading @@ -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<Op::DrawPoint> { .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<Op::DrawLine> { .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); Loading @@ -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<Op::DrawRegion> { .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<Op::DrawRegion> { .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); Loading @@ -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<SkVector[]>(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<SkVector[]>(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<Op::DrawDoubleRoundRect> { .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); Loading Loading @@ -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<Op::DrawPath> { .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); Loading Loading @@ -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<SkVertices> vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, nullptr, colors); buffer.push(CanvasOp<Op::DrawVertices> { .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<CallCountingCanvas>(); Loading