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