1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gm.h" 9 #include "sk_tool_utils.h" 10 #include "SkGradientShader.h" 11 #include "SkImage.h" 12 #include "SkPath.h" 13 #include "SkSurface.h" 14 15 static sk_sp<SkImage> make_image(SkCanvas* origCanvas, int w, int h) { 16 SkImageInfo info = SkImageInfo::MakeN32Premul(w, h); 17 auto surface(origCanvas->makeSurface(info)); 18 if (nullptr == surface) { 19 surface = SkSurface::MakeRaster(info); 20 } 21 SkCanvas* canvas = surface->getCanvas(); 22 23 sk_tool_utils::draw_checkerboard(canvas, SK_ColorRED, SK_ColorGREEN, w/10); 24 return surface->makeImageSnapshot(); 25 } 26 27 namespace skiagm { 28 29 class PerspShadersGM : public GM { 30 public: 31 PerspShadersGM(bool doAA) : fDoAA(doAA) { } 32 33 protected: 34 SkString onShortName() override { 35 SkString name; 36 name.printf("persp_shaders_%s", 37 fDoAA ? "aa" : "bw"); 38 return name; 39 } 40 41 SkISize onISize() override { 42 return SkISize::Make(kCellSize*kNumCols, kCellSize*kNumRows); 43 } 44 45 void onOnceBeforeDraw() override { 46 fBitmap = sk_tool_utils::create_checkerboard_bitmap(kCellSize, kCellSize, 47 SK_ColorBLUE, SK_ColorYELLOW, 48 kCellSize/10); 49 50 fBitmapShader = SkShader::MakeBitmapShader(fBitmap, SkShader::kClamp_TileMode, 51 SkShader::kClamp_TileMode); 52 SkPoint pts1[] = { 53 { 0, 0 }, 54 { SkIntToScalar(kCellSize), SkIntToScalar(kCellSize) } 55 }; 56 SkPoint pts2[] = { 57 { 0, 0 }, 58 { 0, SkIntToScalar(kCellSize) } 59 }; 60 constexpr SkColor colors[] = { 61 SK_ColorRED, SK_ColorGREEN, SK_ColorRED, SK_ColorGREEN, SK_ColorRED 62 }; 63 constexpr SkScalar pos[] = { 0, 0.25f, 0.5f, 0.75f, SK_Scalar1 }; 64 65 fLinearGrad1 = SkGradientShader::MakeLinear(pts1, colors, pos, SK_ARRAY_COUNT(colors), 66 SkShader::kClamp_TileMode); 67 fLinearGrad2 = SkGradientShader::MakeLinear(pts2, colors, pos, SK_ARRAY_COUNT(colors), 68 SkShader::kClamp_TileMode); 69 70 fPerspMatrix.reset(); 71 fPerspMatrix.setPerspY(SK_Scalar1 / 50); 72 73 fPath.moveTo(0, 0); 74 fPath.lineTo(0, SkIntToScalar(kCellSize)); 75 fPath.lineTo(kCellSize/2.0f, kCellSize/2.0f); 76 fPath.lineTo(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize)); 77 fPath.lineTo(SkIntToScalar(kCellSize), 0); 78 fPath.close(); 79 } 80 81 void drawRow(SkCanvas* canvas, SkFilterQuality filterQ) { 82 SkPaint filterPaint; 83 filterPaint.setFilterQuality(filterQ); 84 filterPaint.setAntiAlias(fDoAA); 85 86 SkPaint pathPaint; 87 pathPaint.setShader(fBitmapShader); 88 pathPaint.setFilterQuality(filterQ); 89 pathPaint.setAntiAlias(fDoAA); 90 91 SkPaint gradPaint1; 92 gradPaint1.setShader(fLinearGrad1); 93 gradPaint1.setAntiAlias(fDoAA); 94 SkPaint gradPaint2; 95 gradPaint2.setShader(fLinearGrad2); 96 gradPaint2.setAntiAlias(fDoAA); 97 98 SkRect r = SkRect::MakeWH(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize)); 99 100 canvas->save(); 101 102 canvas->save(); 103 canvas->concat(fPerspMatrix); 104 canvas->drawBitmapRect(fBitmap, r, &filterPaint); 105 canvas->restore(); 106 107 canvas->translate(SkIntToScalar(kCellSize), 0); 108 canvas->save(); 109 canvas->concat(fPerspMatrix); 110 canvas->drawImage(fImage.get(), 0, 0, &filterPaint); 111 canvas->restore(); 112 113 canvas->translate(SkIntToScalar(kCellSize), 0); 114 canvas->save(); 115 canvas->concat(fPerspMatrix); 116 canvas->drawRect(r, pathPaint); 117 canvas->restore(); 118 119 canvas->translate(SkIntToScalar(kCellSize), 0); 120 canvas->save(); 121 canvas->concat(fPerspMatrix); 122 canvas->drawPath(fPath, pathPaint); 123 canvas->restore(); 124 125 canvas->translate(SkIntToScalar(kCellSize), 0); 126 canvas->save(); 127 canvas->concat(fPerspMatrix); 128 canvas->drawRect(r, gradPaint1); 129 canvas->restore(); 130 131 canvas->translate(SkIntToScalar(kCellSize), 0); 132 canvas->save(); 133 canvas->concat(fPerspMatrix); 134 canvas->drawPath(fPath, gradPaint2); 135 canvas->restore(); 136 137 canvas->restore(); 138 } 139 140 void onDraw(SkCanvas* canvas) override { 141 if (!fImage) { 142 fImage = make_image(canvas, kCellSize, kCellSize); 143 } 144 145 this->drawRow(canvas, kNone_SkFilterQuality); 146 canvas->translate(0, SkIntToScalar(kCellSize)); 147 this->drawRow(canvas, kLow_SkFilterQuality); 148 canvas->translate(0, SkIntToScalar(kCellSize)); 149 this->drawRow(canvas, kMedium_SkFilterQuality); 150 canvas->translate(0, SkIntToScalar(kCellSize)); 151 this->drawRow(canvas, kHigh_SkFilterQuality); 152 canvas->translate(0, SkIntToScalar(kCellSize)); 153 } 154 private: 155 static constexpr int kCellSize = 50; 156 static constexpr int kNumRows = 4; 157 static constexpr int kNumCols = 6; 158 159 bool fDoAA; 160 SkPath fPath; 161 sk_sp<SkShader> fBitmapShader; 162 sk_sp<SkShader> fLinearGrad1; 163 sk_sp<SkShader> fLinearGrad2; 164 SkMatrix fPerspMatrix; 165 sk_sp<SkImage> fImage; 166 SkBitmap fBitmap; 167 168 typedef GM INHERITED; 169 }; 170 171 ////////////////////////////////////////////////////////////////////////////// 172 173 DEF_GM(return new PerspShadersGM(true);) 174 DEF_GM(return new PerspShadersGM(false);) 175 } 176