Add more Skia pipeline unit tests.
Add more Skia pipeline unit tests and fix an issue
in backdrop/content bounds clip logic.
Test: built and run angler-eng and HWUI unit tests.
Change-Id: Ie41f80ff7ce9802a4d76e8b14f1695dbc9771a2b
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 7c14952..4d4705c 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -29,6 +29,7 @@
#include <SkSurface_Base.h>
#include <SkLiteRecorder.h>
#include <SkClipStack.h>
+#include "FatalTestCanvas.h"
#include <string.h>
@@ -89,11 +90,11 @@
ZReorderCanvas(int width, int height) : SkCanvas(width, height) {}
void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
int expectedOrder = SkColorGetB(paint.getColor()); // extract order from blue channel
- EXPECT_EQ(expectedOrder, mIndex++) << "An op was drawn out of order";
+ EXPECT_EQ(expectedOrder, mDrawCounter++) << "An op was drawn out of order";
}
- int getIndex() { return mIndex; }
+ int getIndex() { return mDrawCounter; }
protected:
- int mIndex = 0;
+ int mDrawCounter = 0;
};
} // end anonymous namespace
@@ -173,21 +174,6 @@
return new AnimationContext(clock);
}
};
-
-inline SkRect getBounds(const SkCanvas* canvas) {
- SkClipStack::BoundsType boundType;
- SkRect clipBounds;
- canvas->getClipStack()->getBounds(&clipBounds, &boundType);
- return clipBounds;
-}
-inline SkRect getLocalBounds(const SkCanvas* canvas) {
- SkMatrix invertedTotalMatrix;
- EXPECT_TRUE(canvas->getTotalMatrix().invert(&invertedTotalMatrix));
- SkRect outlineInDeviceCoord = getBounds(canvas);
- SkRect outlineInLocalCoord;
- invertedTotalMatrix.mapRect(&outlineInLocalCoord, outlineInDeviceCoord);
- return outlineInLocalCoord;
-}
} // end anonymous namespace
RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorder) {
@@ -197,26 +183,26 @@
public:
ProjectionTestCanvas(int width, int height) : SkCanvas(width, height) {}
void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
- const int index = mIndex++;
+ const int index = mDrawCounter++;
SkMatrix expectedMatrix;;
switch (index) {
case 0: //this is node "B"
EXPECT_EQ(SkRect::MakeWH(100, 100), rect);
EXPECT_EQ(SK_ColorWHITE, paint.getColor());
expectedMatrix.reset();
- EXPECT_EQ(SkRect::MakeLTRB(0, 0, 100, 100), getBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(0, 0, 100, 100), TestUtils::getClipBounds(this));
break;
case 1: //this is node "P"
EXPECT_EQ(SkRect::MakeLTRB(-10, -10, 60, 60), rect);
EXPECT_EQ(SK_ColorDKGRAY, paint.getColor());
expectedMatrix.setTranslate(50 - SCROLL_X, 50 - SCROLL_Y);
- EXPECT_EQ(SkRect::MakeLTRB(-35, -30, 45, 50), getLocalBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(-35, -30, 45, 50), TestUtils::getLocalClipBounds(this));
break;
case 2: //this is node "C"
EXPECT_EQ(SkRect::MakeWH(100, 50), rect);
EXPECT_EQ(SK_ColorBLUE, paint.getColor());
expectedMatrix.setTranslate(-SCROLL_X, 50 - SCROLL_Y);
- EXPECT_EQ(SkRect::MakeLTRB(0, 40, 95, 90), getBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(0, 40, 95, 90), TestUtils::getClipBounds(this));
break;
default:
ADD_FAILURE();
@@ -224,9 +210,9 @@
EXPECT_EQ(expectedMatrix, getTotalMatrix());
}
- int getIndex() { return mIndex; }
+ int getIndex() { return mDrawCounter; }
protected:
- int mIndex = 0;
+ int mDrawCounter = 0;
};
/**
@@ -315,23 +301,23 @@
public:
ProjectionTestCanvas(int* drawCounter)
: SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT)
- , mDrawCounter(drawCounter)
+ , mDrawCounter(drawCounter)
{}
void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
const SkPaint&) override {
EXPECT_EQ(0, (*mDrawCounter)++); //part of painting the layer
- EXPECT_EQ(SkRect::MakeLTRB(0, 0, LAYER_WIDTH, LAYER_HEIGHT), getBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(0, 0, LAYER_WIDTH, LAYER_HEIGHT), TestUtils::getClipBounds(this));
}
void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
EXPECT_EQ(1, (*mDrawCounter)++);
- EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), getBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), TestUtils::getClipBounds(this));
}
void onDrawOval(const SkRect&, const SkPaint&) override {
EXPECT_EQ(2, (*mDrawCounter)++);
SkMatrix expectedMatrix;
expectedMatrix.setTranslate(100 - SCROLL_X, 100 - SCROLL_Y);
EXPECT_EQ(expectedMatrix, getTotalMatrix());
- EXPECT_EQ(SkRect::MakeLTRB(-85, -80, 295, 300), getLocalBounds(this));
+ EXPECT_EQ(SkRect::MakeLTRB(-85, -80, 295, 300), TestUtils::getLocalClipBounds(this));
}
int* mDrawCounter;
};
@@ -345,7 +331,7 @@
void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override {
EXPECT_EQ(3, (*mDrawCounter)++);
EXPECT_EQ(SkRect::MakeLTRB(100 - SCROLL_X, 100 - SCROLL_Y, 300 - SCROLL_X,
- 300 - SCROLL_Y), getBounds(this->getCanvas()));
+ 300 - SCROLL_Y), TestUtils::getClipBounds(this->getCanvas()));
}
SkCanvas* onNewCanvas() override {
return new ProjectionTestCanvas(mDrawCounter);
@@ -440,15 +426,15 @@
public:
ProjectionChildScrollTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
- EXPECT_EQ(0, mIndex++);
+ EXPECT_EQ(0, mDrawCounter++);
EXPECT_TRUE(getTotalMatrix().isIdentity());
}
void onDrawOval(const SkRect&, const SkPaint&) override {
- EXPECT_EQ(1, mIndex++);
- EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), getBounds(this));
+ EXPECT_EQ(1, mDrawCounter++);
+ EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), TestUtils::getClipBounds(this));
EXPECT_TRUE(getTotalMatrix().isIdentity());
}
- int mIndex = 0;
+ int mDrawCounter = 0;
};
auto receiverBackground = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
@@ -494,7 +480,7 @@
std::unique_ptr<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
canvas->drawDrawable(&drawable);
- EXPECT_EQ(2, canvas->mIndex);
+ EXPECT_EQ(2, canvas->mDrawCounter);
}
namespace {
@@ -787,3 +773,124 @@
}); //nodeA
EXPECT_EQ(5, drawNode(renderThread, nodeA));
}
+
+RENDERTHREAD_TEST(RenderNodeDrawable, simple) {
+ static const int CANVAS_WIDTH = 100;
+ static const int CANVAS_HEIGHT = 200;
+ class SimpleTestCanvas : public TestCanvasBase {
+ public:
+ SimpleTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {
+ }
+ void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+ EXPECT_EQ(0, mDrawCounter++);
+ }
+ void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
+ EXPECT_EQ(1, mDrawCounter++);
+ }
+ };
+
+ auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ sk_sp<Bitmap> bitmap(TestUtils::createBitmap(25, 25));
+ canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, SkPaint());
+ canvas.drawBitmap(*bitmap, 10, 10, nullptr);
+ });
+
+ SimpleTestCanvas canvas;
+ RenderNodeDrawable drawable(node.get(), &canvas, true);
+ canvas.drawDrawable(&drawable);
+ EXPECT_EQ(2, canvas.mDrawCounter);
+}
+
+RENDERTHREAD_TEST(RenderNodeDrawable, colorOp_unbounded) {
+ static const int CANVAS_WIDTH = 200;
+ static const int CANVAS_HEIGHT = 200;
+ class ColorTestCanvas : public TestCanvasBase {
+ public:
+ ColorTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {
+ }
+ void onDrawPaint(const SkPaint&) {
+ switch (mDrawCounter++) {
+ case 0:
+ // While this mirrors FrameBuilder::colorOp_unbounded, this value is different
+ // because there is no root (root is clipped in SkiaPipeline::renderFrame).
+ // SkiaPipeline.clipped and clip_replace verify the root clip.
+ EXPECT_TRUE(TestUtils::getClipBounds(this).isEmpty());
+ break;
+ case 1:
+ EXPECT_EQ(SkRect::MakeWH(10, 10), TestUtils::getClipBounds(this));
+ break;
+ default:
+ ADD_FAILURE();
+ }
+ }
+ };
+
+ auto unclippedColorView = TestUtils::createSkiaNode(0, 0, 10, 10,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ props.setClipToBounds(false);
+ canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+ });
+
+ auto clippedColorView = TestUtils::createSkiaNode(0, 0, 10, 10,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+ });
+
+ ColorTestCanvas canvas;
+ RenderNodeDrawable drawable(unclippedColorView.get(), &canvas, true);
+ canvas.drawDrawable(&drawable);
+ EXPECT_EQ(1, canvas.mDrawCounter);
+ RenderNodeDrawable drawable2(clippedColorView.get(), &canvas, true);
+ canvas.drawDrawable(&drawable2);
+ EXPECT_EQ(2, canvas.mDrawCounter);
+}
+
+TEST(RenderNodeDrawable, renderNode) {
+ static const int CANVAS_WIDTH = 200;
+ static const int CANVAS_HEIGHT = 200;
+ class RenderNodeTestCanvas : public TestCanvasBase {
+ public:
+ RenderNodeTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {
+ }
+ void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+ switch(mDrawCounter++) {
+ case 0:
+ EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT), TestUtils::getClipBounds(this));
+ EXPECT_EQ(SK_ColorDKGRAY, paint.getColor());
+ break;
+ case 1:
+ EXPECT_EQ(SkRect::MakeLTRB(50, 50, 150, 150), TestUtils::getClipBounds(this));
+ EXPECT_EQ(SK_ColorWHITE, paint.getColor());
+ break;
+ default:
+ ADD_FAILURE();
+ }
+ }
+ };
+
+ auto child = TestUtils::createSkiaNode(10, 10, 110, 110,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ SkPaint paint;
+ paint.setColor(SK_ColorWHITE);
+ canvas.drawRect(0, 0, 100, 100, paint);
+ });
+
+ auto parent = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+ [&child](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ SkPaint paint;
+ paint.setColor(SK_ColorDKGRAY);
+ canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, paint);
+
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.translate(40, 40);
+ canvas.drawRenderNode(child.get());
+ canvas.restore();
+ });
+
+ RenderNodeTestCanvas canvas;
+ RenderNodeDrawable drawable(parent.get(), &canvas, true);
+ canvas.drawDrawable(&drawable);
+ EXPECT_EQ(2, canvas.mDrawCounter);
+}
+