Add canvas ops 3

Added the following
--DrawPoint
--DrawPath
--DrawRegion
--DrawDoubleRoundRect
--DrawLine
--DrawVertices

Test: Added tests to CanvasOpTests
Change-Id: I5844c61bc8d2dacf74e504f7bac7946398174ed2
This commit is contained in:
Nader Jawad
2020-11-06 22:49:42 -08:00
parent fbbd652eb6
commit fb1e7f1b6a
4 changed files with 227 additions and 2 deletions

View File

@@ -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

View File

@@ -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"
@@ -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;
@@ -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;
@@ -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;
@@ -205,7 +235,41 @@ 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
} // namespace android::uirenderer
} // namespace android::uirenderer

View File

@@ -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;
};

View File

@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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>();