Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "gm.h" | 8 #include "gm.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkRandom.h" | 10 #include "SkRandom.h" |
| 11 #include "SkShader.h" | 11 #include "SkShader.h" |
| 12 #include "SkXfermode.h" | 12 #include "SkXfermode.h" |
| 13 | 13 |
| 14 namespace skiagm { | 14 namespace skiagm { |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * Renders overlapping circles with random SkXfermode::Modes against a checkerbo ard. | 17 * Renders overlapping shapes with random SkXfermode::Modes against a checkerboa rd. |
| 18 */ | 18 */ |
| 19 class MixedXfermodesGM : public GM { | 19 class MixedXfermodesGM : public GM { |
| 20 public: | 20 public: |
| 21 MixedXfermodesGM() { | 21 MixedXfermodesGM() { |
|
robertphillips
2013/05/14 21:49:37
Move this into an initialization method to make th
bsalomon
2013/05/15 13:10:20
Done.
| |
| 22 static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCC CC, 0xFFFFFFFF }; | 22 static uint32_t kCheckerPixelData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCC CC, 0xFFFFFFFF }; |
| 23 SkBitmap bitmap; | 23 SkBitmap bitmap; |
| 24 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 2 * sizeof(uint32_t) ); | 24 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 2 * sizeof(uint32_t) ); |
| 25 bitmap.allocPixels(); | 25 bitmap.allocPixels(); |
| 26 bitmap.lockPixels(); | 26 bitmap.lockPixels(); |
| 27 memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData)) ; | 27 memcpy(bitmap.getPixels(), kCheckerPixelData, sizeof(kCheckerPixelData)) ; |
| 28 bitmap.unlockPixels(); | 28 bitmap.unlockPixels(); |
| 29 fBG.reset(SkShader::CreateBitmapShader(bitmap, | 29 fBG.reset(SkShader::CreateBitmapShader(bitmap, |
| 30 SkShader::kRepeat_TileMode, | 30 SkShader::kRepeat_TileMode, |
| 31 SkShader::kRepeat_TileMode)); | 31 SkShader::kRepeat_TileMode)); |
| 32 SkASSERT(NULL != fBG); | 32 SkASSERT(NULL != fBG); |
| 33 SkMatrix lm; | 33 SkMatrix lm; |
| 34 lm.setScale(SkIntToScalar(20), SkIntToScalar(20)); | 34 lm.setScale(SkIntToScalar(20), SkIntToScalar(20)); |
| 35 fBG->setLocalMatrix(lm); | 35 fBG->setLocalMatrix(lm); |
| 36 } | 36 } |
| 37 | 37 |
| 38 protected: | 38 protected: |
|
robertphillips
2013/05/14 21:49:37
overrides?
bsalomon
2013/05/15 13:10:20
Done.
| |
| 39 virtual SkString onShortName() { | 39 virtual SkString onShortName() { |
| 40 return SkString("mixed_xfermodes"); | 40 return SkString("mixed_xfermodes"); |
| 41 } | 41 } |
| 42 | 42 |
| 43 virtual SkISize onISize() { | 43 virtual SkISize onISize() { |
| 44 return make_isize(790, 640); | 44 return make_isize(790, 640); |
| 45 } | 45 } |
| 46 | 46 |
| 47 virtual void drawShape(SkCanvas* canvas, | |
| 48 const SkPaint& paint, | |
| 49 SkMWCRandom* random) { | |
| 50 static const SkRect kRect = SkRect::MakeXYWH(SkIntToScalar(-50), SkIntTo Scalar(-50), | |
| 51 SkIntToScalar(75), SkIntToS calar(105)); | |
|
robertphillips
2013/05/14 21:49:37
x -> drawOption? geometry?
bsalomon
2013/05/15 13:10:20
shape
| |
| 52 int x = random->nextULessThan(5); | |
| 53 switch (x) { | |
| 54 case 0: | |
| 55 canvas->drawCircle(0, 0, 50, paint); | |
| 56 break; | |
| 57 case 1: | |
| 58 canvas->drawRoundRect(kRect, SkIntToScalar(10), SkIntToScalar(20), p aint); | |
| 59 break; | |
| 60 case 2: | |
| 61 canvas->drawRect(kRect, paint); | |
| 62 break; | |
| 63 case 3: | |
| 64 if (fConvexPath.isEmpty()) { | |
| 65 SkPoint points[4]; | |
| 66 kRect.toQuad(points); | |
| 67 fConvexPath.moveTo(points[0]); | |
| 68 fConvexPath.quadTo(points[1], points[2]); | |
| 69 fConvexPath.quadTo(points[3], points[0]); | |
|
robertphillips
2013/05/14 21:49:37
assert that 'fConvexPath' is indeed convex?
bsalomon
2013/05/15 13:10:20
Done.
| |
| 70 } | |
| 71 canvas->drawPath(fConvexPath, paint); | |
| 72 break; | |
| 73 case 4: | |
| 74 if (fConcavePath.isEmpty()) { | |
| 75 SkPoint points[5] = {{0, SkIntToScalar(-50)} }; | |
| 76 SkMatrix rot; | |
| 77 rot.setRotate(SkIntToScalar(360) / 5); | |
| 78 for (int i = 1; i < 5; ++i) { | |
| 79 rot.mapPoints(points + i, points + i - 1, 1); | |
| 80 } | |
| 81 fConcavePath.moveTo(points[0]); | |
| 82 for (int i = 0; i < 5; ++i) { | |
| 83 fConcavePath.lineTo(points[(2 * i) % 5]); | |
| 84 } | |
| 85 fConcavePath.setFillType(SkPath::kEvenOdd_FillType); | |
|
robertphillips
2013/05/14 21:49:37
assert that 'fConcavePath' is non-convex?
bsalomon
2013/05/15 13:10:20
Done.
| |
| 86 } | |
| 87 canvas->drawPath(fConcavePath, paint); | |
| 88 break; | |
| 89 } | |
| 90 } | |
| 91 | |
| 47 virtual void onDraw(SkCanvas* canvas) { | 92 virtual void onDraw(SkCanvas* canvas) { |
| 48 SkPaint bgPaint; | 93 SkPaint bgPaint; |
| 49 bgPaint.setShader(fBG.get()); | 94 bgPaint.setShader(fBG.get()); |
| 50 canvas->drawPaint(bgPaint); | 95 canvas->drawPaint(bgPaint); |
| 51 SkISize size = canvas->getDeviceSize(); | 96 SkISize size = canvas->getDeviceSize(); |
| 52 SkScalar areaSqrt = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeig ht))); | 97 SkScalar maxScale = SkScalarSqrt((SkIntToScalar(size.fWidth * size.fHeig ht))) / 300; |
| 53 SkScalar minR = areaSqrt / 10; | |
| 54 SkScalar maxR = areaSqrt / 4; | |
| 55 SkMWCRandom random; | 98 SkMWCRandom random; |
| 56 for (int i = 0; i < kNumCircles; ++i) { | 99 for (int i = 0; i < kNumShapes; ++i) { |
| 57 SkScalar cx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth)); | 100 SkScalar s = random.nextRangeScalar(SK_Scalar1 / 8, SK_Scalar1) * ma xScale; |
| 58 SkScalar cy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight)) ; | 101 SkScalar r = random.nextRangeScalar(0, SkIntToScalar(360)); |
| 59 SkScalar r = random.nextRangeScalar(minR, maxR); | 102 SkScalar dx = random.nextRangeScalar(0, SkIntToScalar(size.fWidth)); |
| 103 SkScalar dy = random.nextRangeScalar(0, SkIntToScalar(size.fHeight)) ; | |
| 60 SkColor color = random.nextU(); | 104 SkColor color = random.nextU(); |
| 61 | |
| 62 SkXfermode::Mode mode = | 105 SkXfermode::Mode mode = |
| 63 static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::k LastMode + 1)); | 106 static_cast<SkXfermode::Mode>(random.nextULessThan(SkXfermode::k LastMode + 1)); |
| 64 // FIXME: Currently testing kDarken on GPU. | |
| 65 mode = SkXfermode::kDarken_Mode; | |
| 66 | 107 |
| 67 SkPaint p; | 108 SkPaint p; |
| 68 p.setAntiAlias(true); | 109 p.setAntiAlias(true); |
| 69 p.setColor(color); | 110 p.setColor(color); |
| 70 p.setXfermodeMode(mode); | 111 p.setXfermodeMode(mode); |
| 71 canvas->drawCircle(cx, cy, r, p); | 112 canvas->save(); |
| 113 canvas->translate(dx, dy); | |
| 114 canvas->scale(s, s); | |
| 115 canvas->rotate(r); | |
| 116 this->drawShape(canvas, p, &random); | |
| 117 canvas->restore(); | |
| 72 } | 118 } |
| 73 | |
| 74 // FIXME: Remove text draw once this GM is finished. | |
| 75 SkPaint txtPaint; | |
| 76 txtPaint.setTextSize(areaSqrt / 20); | |
| 77 txtPaint.setAntiAlias(true); | |
| 78 static const char kTxt[] = "Work in progres... Do not baseline."; | |
| 79 canvas->drawText(kTxt, strlen(kTxt), | |
| 80 areaSqrt/50, | |
| 81 SkIntToScalar(size.fHeight / 2), | |
| 82 txtPaint); | |
| 83 } | 119 } |
| 84 | 120 |
| 85 private: | 121 private: |
| 86 enum { | 122 enum { |
| 87 kMinR = 10, | 123 kNumShapes = 100, |
| 88 kMaxR = 50, | |
| 89 kNumCircles = 50, | |
| 90 }; | 124 }; |
| 91 SkAutoTUnref<SkShader> fBG; | 125 SkAutoTUnref<SkShader> fBG; |
| 126 SkPath fConcavePath; | |
| 127 SkPath fConvexPath; | |
| 92 typedef GM INHERITED; | 128 typedef GM INHERITED; |
| 93 }; | 129 }; |
| 94 | 130 |
| 95 ////////////////////////////////////////////////////////////////////////////// | 131 ////////////////////////////////////////////////////////////////////////////// |
| 96 | 132 |
| 97 static GM* MyFactory(void*) { return new MixedXfermodesGM; } | 133 static GM* MyFactory(void*) { return new MixedXfermodesGM; } |
| 98 static GMRegistry reg(MyFactory); | 134 static GMRegistry reg(MyFactory); |
| 99 | 135 |
| 100 } | 136 } |
| OLD | NEW |