From 4285c8a3a0ce31dcfab5a609820d08a51e7090ee Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Fri, 6 Nov 2020 22:49:42 -0800 Subject: [PATCH] Add support for CanvasOps to draw multiple lines or points in a single call --DrawPoints --DrawLines Introduced wrapper Points class to handle containing collections of SkPoints that is compatible with ref counted pointer implementations Bug: 174854640 Test: Added tests to CanvasOpTests Change-Id: Id4a47a470815d2970c54dac25e59af8512193348 --- libs/hwui/canvas/CanvasOpTypes.h | 2 ++ libs/hwui/canvas/CanvasOps.h | 33 +++++++++++++++++ libs/hwui/canvas/Points.h | 48 +++++++++++++++++++++++++ libs/hwui/tests/unit/CanvasOpTests.cpp | 49 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 libs/hwui/canvas/Points.h diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h index 2dfddaca0919a..f0aa7774a6ccd 100644 --- a/libs/hwui/canvas/CanvasOpTypes.h +++ b/libs/hwui/canvas/CanvasOpTypes.h @@ -47,8 +47,10 @@ enum class CanvasOpType : int8_t { DrawArc, DrawPaint, DrawPoint, + DrawPoints, DrawPath, DrawLine, + DrawLines, DrawVertices, DrawImage, DrawImageRect, diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h index b499733757a81..242dbdb27362a 100644 --- a/libs/hwui/canvas/CanvasOps.h +++ b/libs/hwui/canvas/CanvasOps.h @@ -26,6 +26,7 @@ #include #include #include "CanvasProperty.h" +#include "Points.h" #include "CanvasOpTypes.h" #include "Layer.h" @@ -165,6 +166,22 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template <> +struct CanvasOp { + size_t count; + SkPaint paint; + sk_sp points; + void draw(SkCanvas* canvas) const { + canvas->drawPoints( + SkCanvas::kPoints_PointMode, + count, + points->data(), + paint + ); + } + ASSERT_DRAWABLE() +}; + template <> struct CanvasOp { SkRect rect; @@ -263,6 +280,22 @@ struct CanvasOp { ASSERT_DRAWABLE() }; +template<> +struct CanvasOp { + size_t count; + SkPaint paint; + sk_sp points; + void draw(SkCanvas* canvas) const { + canvas->drawPoints( + SkCanvas::kLines_PointMode, + count, + points->data(), + paint + ); + } + ASSERT_DRAWABLE() +}; + template<> struct CanvasOp { sk_sp vertices; diff --git a/libs/hwui/canvas/Points.h b/libs/hwui/canvas/Points.h new file mode 100644 index 0000000000000..05e6a7dd58848 --- /dev/null +++ b/libs/hwui/canvas/Points.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "SkPoint.h" +#include "SkRefCnt.h" + +/** + * Collection of points that are ref counted and to be used with + * various drawing calls that consume SkPoint as inputs like + * drawLines/drawPoints + */ +class Points: public SkNVRefCnt { +public: + Points(int size){ + skPoints.resize(size); + } + + Points(std::initializer_list init): skPoints(init) { } + + SkPoint& operator[](int index) { + return skPoints[index]; + } + + const SkPoint* data() const { + return skPoints.data(); + } + + size_t size() const { + return skPoints.size(); + } +private: + // Initialize the size to contain 2 SkPoints on the stack for optimized + // drawLine calls that require 2 SkPoints for start/end points of the line + android::FatVector skPoints; +}; diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp index f186e55ec2e37..033a5872ead3d 100644 --- a/libs/hwui/tests/unit/CanvasOpTests.cpp +++ b/libs/hwui/tests/unit/CanvasOpTests.cpp @@ -245,6 +245,31 @@ TEST(CanvasOp, simpleDrawPoint) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawPoints) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + size_t numPts = 3; + auto pts = sk_ref_sp( + new Points({ + {32, 16}, + {48, 48}, + {16, 32} + }) + ); + + buffer.push(CanvasOp { + .count = numPts, + .paint = SkPaint{}, + .points = pts + }); + + 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); @@ -263,6 +288,30 @@ TEST(CanvasOp, simpleDrawLine) { EXPECT_EQ(1, canvas.sumTotalDrawCalls()); } +TEST(CanvasOp, simpleDrawLines) { + CanvasOpBuffer buffer; + EXPECT_EQ(buffer.size(), 0); + size_t numPts = 3; + auto pts = sk_ref_sp( + new Points({ + {32, 16}, + {48, 48}, + {16, 32} + }) + ); + buffer.push(CanvasOp { + .count = numPts, + .paint = SkPaint{}, + .points = pts + }); + + 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);