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