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