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