1 /* 2 * Copyright 2012 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/gm.h" 9 #include "include/core/SkBitmap.h" 10 #include "include/core/SkBlurTypes.h" 11 #include "include/core/SkCanvas.h" 12 #include "include/core/SkColor.h" 13 #include "include/core/SkFont.h" 14 #include "include/core/SkMaskFilter.h" 15 #include "include/core/SkPaint.h" 16 #include "include/core/SkPath.h" 17 #include "include/core/SkRect.h" 18 #include "include/core/SkRefCnt.h" 19 #include "include/core/SkScalar.h" 20 #include "include/core/SkShader.h" 21 #include "include/core/SkSize.h" 22 #include "include/core/SkString.h" 23 #include "include/core/SkTileMode.h" 24 #include "include/core/SkTypeface.h" 25 #include "tools/ToolUtils.h" 26 #include "tools/fonts/FontToolUtils.h" 27 28 namespace skiagm { 29 30 /** 31 * Stress test the GPU samplers by rendering a textured glyph with a mask and 32 * an AA clip 33 */ 34 class SamplerStressGM : public GM { 35 public: SamplerStressGM()36 SamplerStressGM() 37 : fTextureCreated(false) 38 , fMaskFilter(nullptr) { 39 } 40 41 protected: getName() const42 SkString getName() const override { return SkString("gpusamplerstress"); } 43 getISize()44 SkISize getISize() override { return SkISize::Make(640, 480); } 45 46 /** 47 * Create a red & green stripes on black texture 48 */ createTexture()49 void createTexture() { 50 if (fTextureCreated) { 51 return; 52 } 53 54 constexpr int xSize = 16; 55 constexpr int ySize = 16; 56 57 fTexture.allocN32Pixels(xSize, ySize); 58 SkPMColor* addr = fTexture.getAddr32(0, 0); 59 60 for (int y = 0; y < ySize; ++y) { 61 for (int x = 0; x < xSize; ++x) { 62 addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK); 63 64 if ((y % 5) == 0) { 65 addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED); 66 } 67 if ((x % 7) == 0) { 68 addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN); 69 } 70 } 71 } 72 73 fTextureCreated = true; 74 } 75 createShader()76 void createShader() { 77 if (fShader) { 78 return; 79 } 80 81 createTexture(); 82 83 fShader = fTexture.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, 84 SkSamplingOptions()); 85 } 86 createMaskFilter()87 void createMaskFilter() { 88 if (fMaskFilter) { 89 return; 90 } 91 92 const SkScalar sigma = 1; 93 fMaskFilter = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma); 94 } 95 onDraw(SkCanvas * canvas)96 void onDraw(SkCanvas* canvas) override { 97 createShader(); 98 createMaskFilter(); 99 100 canvas->save(); 101 102 // draw a letter "M" with a green & red striped texture and a 103 // stipple mask with a round rect soft clip 104 SkPaint paint; 105 paint.setAntiAlias(true); 106 paint.setShader(fShader); 107 paint.setMaskFilter(fMaskFilter); 108 SkFont font(ToolUtils::DefaultPortableTypeface(), 72); 109 110 SkRect temp; 111 temp.setLTRB(115, 75, 144, 110); 112 113 SkPath path; 114 path.addRoundRect(temp, SkIntToScalar(5), SkIntToScalar(5)); 115 116 canvas->clipPath(path, true); // AA is on 117 118 canvas->drawString("M", 100.0f, 100.0f, font, paint); 119 120 canvas->restore(); 121 122 // Now draw stroked versions of the "M" and the round rect so we can 123 // see what is going on 124 SkPaint paint2; 125 paint2.setColor(SK_ColorBLACK); 126 paint2.setAntiAlias(true); 127 paint2.setStyle(SkPaint::kStroke_Style); 128 paint2.setStrokeWidth(1); 129 canvas->drawString("M", 100.0f, 100.0f, font, paint2); 130 131 paint2.setColor(SK_ColorGRAY); 132 133 canvas->drawPath(path, paint2); 134 } 135 136 private: 137 SkBitmap fTexture; 138 bool fTextureCreated; 139 sk_sp<SkShader> fShader; 140 sk_sp<SkMaskFilter> fMaskFilter; 141 142 using INHERITED = GM; 143 }; 144 145 ////////////////////////////////////////////////////////////////////////////// 146 147 DEF_GM( return new SamplerStressGM; ) 148 149 } // namespace skiagm 150