Index: gm/mixedxfermodes.cpp |
diff --git a/gm/mixedxfermodes.cpp b/gm/mixedxfermodes.cpp |
index a5023e1b0b07218ad6b2acc171568ecae7d35de4..3e5ee7d1d3943b5dab2d57dfcbfd843d9dcdfd87 100644 |
--- a/gm/mixedxfermodes.cpp |
+++ b/gm/mixedxfermodes.cpp |
@@ -22,6 +22,15 @@ public: |
} |
protected: |
+ enum ShapeType { |
+ kShapeTypeCircle, |
+ kShapeTypeRoundRect, |
+ kShapeTypeRect, |
+ kShapeTypeConvexPath, |
+ kShapeTypeConcavePath, |
+ kNumShapeTypes |
+ }; |
+ |
virtual SkString onShortName() SK_OVERRIDE { |
return SkString("mixed_xfermodes"); |
} |
@@ -32,48 +41,49 @@ protected: |
void drawShape(SkCanvas* canvas, |
const SkPaint& paint, |
- SkRandom* random) { |
+ ShapeType type) { |
static const SkRect kRect = SkRect::MakeXYWH(SkIntToScalar(-50), SkIntToScalar(-50), |
SkIntToScalar(75), SkIntToScalar(105)); |
- int shape = random->nextULessThan(5); |
- switch (shape) { |
- case 0: |
- canvas->drawCircle(0, 0, 50, paint); |
- break; |
- case 1: |
- canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), paint); |
- break; |
- case 2: |
- canvas->drawRect(kRect, paint); |
- break; |
- case 3: |
- if (fConvexPath.isEmpty()) { |
- SkPoint points[4]; |
- kRect.toQuad(points); |
- fConvexPath.moveTo(points[0]); |
- fConvexPath.quadTo(points[1], points[2]); |
- fConvexPath.quadTo(points[3], points[0]); |
- SkASSERT(fConvexPath.isConvex()); |
- } |
- canvas->drawPath(fConvexPath, paint); |
- break; |
- case 4: |
- if (fConcavePath.isEmpty()) { |
- SkPoint points[5] = {{0, SkIntToScalar(-50)} }; |
- SkMatrix rot; |
- rot.setRotate(SkIntToScalar(360) / 5); |
- for (int i = 1; i < 5; ++i) { |
- rot.mapPoints(points + i, points + i - 1, 1); |
+ switch (type) { |
+ case kShapeTypeCircle: |
+ canvas->drawCircle(0, 0, 50, paint); |
+ break; |
+ case kShapeTypeRoundRect: |
+ canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), paint); |
+ break; |
+ case kShapeTypeRect: |
+ canvas->drawRect(kRect, paint); |
+ break; |
+ case kShapeTypeConvexPath: |
+ if (fConvexPath.isEmpty()) { |
+ SkPoint points[4]; |
+ kRect.toQuad(points); |
+ fConvexPath.moveTo(points[0]); |
+ fConvexPath.quadTo(points[1], points[2]); |
+ fConvexPath.quadTo(points[3], points[0]); |
+ SkASSERT(fConvexPath.isConvex()); |
} |
- fConcavePath.moveTo(points[0]); |
- for (int i = 0; i < 5; ++i) { |
- fConcavePath.lineTo(points[(2 * i) % 5]); |
+ canvas->drawPath(fConvexPath, paint); |
+ break; |
+ case kShapeTypeConcavePath: |
+ if (fConcavePath.isEmpty()) { |
+ SkPoint points[5] = {{0, SkIntToScalar(-50)} }; |
+ SkMatrix rot; |
+ rot.setRotate(SkIntToScalar(360) / 5); |
+ for (int i = 1; i < 5; ++i) { |
+ rot.mapPoints(points + i, points + i - 1, 1); |
+ } |
+ fConcavePath.moveTo(points[0]); |
+ for (int i = 0; i < 5; ++i) { |
+ fConcavePath.lineTo(points[(2 * i) % 5]); |
+ } |
+ fConcavePath.setFillType(SkPath::kEvenOdd_FillType); |
+ SkASSERT(!fConcavePath.isConvex()); |
} |
- fConcavePath.setFillType(SkPath::kEvenOdd_FillType); |
- SkASSERT(!fConcavePath.isConvex()); |
- } |
- canvas->drawPath(fConcavePath, paint); |
- break; |
+ canvas->drawPath(fConcavePath, paint); |
+ break; |
+ default: |
+ break; |
} |
} |
@@ -108,6 +118,7 @@ protected: |
SkColor color = random.nextU(); |
SkXfermode::Mode mode = |
static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::kLastMode + 1)); |
+ ShapeType shapeType = static_cast<ShapeType>(random.nextULessThan(kNumShapeTypes)); |
SkPaint p; |
p.setAntiAlias(true); |
@@ -117,9 +128,40 @@ protected: |
canvas->translate(dx, dy); |
canvas->scale(s, s); |
canvas->rotate(r); |
- this->drawShape(canvas, p, &random); |
+ this->drawShape(canvas, p, shapeType); |
canvas->restore(); |
} |
+ |
+ // This draw should not affect the test's result. |
+ drawWithHueOnWhite(canvas); |
+ } |
+ |
+ /** |
+ * Draws white color into a white square using the hue blend mode. |
+ * The result color should be white, so it doesn't change the expectations. |
+ * This will test a divide by 0 bug in shaders' setLum function, |
+ * which used to output black pixels. |
+ */ |
+ void drawWithHueOnWhite(SkCanvas* canvas) { |
+ SkColor color = SkColorSetARGBMacro(225, 255, 255, 255); |
+ SkXfermode::Mode mode = SkXfermode::kHue_Mode; |
+ ShapeType shapeType = kShapeTypeConvexPath; |
+ |
+ // Make it fit into a square. |
+ SkScalar s = 0.15f; |
+ // Look for a clean white square. |
+ SkScalar dx = 30.f; |
+ SkScalar dy = 350.f; |
+ |
+ SkPaint p; |
+ p.setAntiAlias(true); |
+ p.setColor(color); |
+ p.setXfermodeMode(mode); |
+ canvas->save(); |
+ canvas->translate(dx, dy); |
+ canvas->scale(s, s); |
+ this->drawShape(canvas, p, shapeType); |
+ canvas->restore(); |
} |
virtual uint32_t onGetFlags() const { |