1 /* 2 * Copyright 2016 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 10 #if SK_SUPPORT_GPU 11 12 #include "GrContext.h" 13 #include "GrContextOptions.h" 14 #include "SkPath.h" 15 16 /** This tests the GPU backend's caching of path coverage masks */ 17 class PathMaskCache : public skiagm::GM { 18 public: PathMaskCache()19 PathMaskCache() {} 20 21 protected: onShortName()22 SkString onShortName() override { return SkString("path_mask_cache"); } 23 onISize()24 SkISize onISize() override { 25 return SkISize::Make(650, 950); 26 } 27 onDraw(SkCanvas * canvas)28 void onDraw(SkCanvas* canvas) override { 29 static constexpr SkScalar kPad = 5.f; 30 31 SkPaint paint; 32 paint.setAntiAlias(true); 33 auto drawPathSet = [canvas] (const SkPath& path, const SkMatrix& m) { 34 SkPaint paint; 35 paint.setAntiAlias(true); 36 SkRect bounds = path.getBounds(); 37 m.mapRect(&bounds); 38 bounds.roundOut(); 39 canvas->save(); 40 canvas->translate(-bounds.fLeft, -bounds.fTop); 41 42 canvas->save(); 43 canvas->concat(m); 44 canvas->drawPath(path, paint); 45 canvas->restore(); 46 47 // translate by integer 48 canvas->translate(bounds.width() + kPad, 0.f); 49 canvas->save(); 50 canvas->concat(m); 51 canvas->drawPath(path, paint); 52 canvas->restore(); 53 54 // translate by non-integer 55 canvas->translate(bounds.width() + kPad + 0.15f, 0.f); 56 canvas->save(); 57 canvas->concat(m); 58 canvas->drawPath(path, paint); 59 canvas->restore(); 60 61 // translate again so total translate fraction is almost identical to previous. 62 canvas->translate(bounds.width() + kPad + 0.002f, 0.f); 63 canvas->save(); 64 canvas->concat(m); 65 canvas->drawPath(path, paint); 66 canvas->restore(); 67 canvas->restore(); 68 return bounds.fBottom + kPad; 69 }; 70 71 72 SkTArray<SkPath> paths; 73 paths.push_back(); 74 paths.back().moveTo(0.f, 0.f); 75 paths.back().lineTo(98.f, 100.f); 76 paths.back().lineTo(100.f, 100.f); 77 paths.back().conicTo(150.f, 50.f, 100.f, 0.f, 0.6f); 78 paths.back().conicTo(148.f, 50.f, 100.f, 100.f, 0.6f); 79 paths.back().conicTo(50.f, 30.f, 0.f, 100.f, 0.9f); 80 81 paths.push_back(); 82 paths.back().addCircle(30.f, 30.f, 30.f); 83 paths.back().addRect(SkRect::MakeXYWH(45.f, 45.f, 50.f, 60.f)); 84 paths.back().setFillType(SkPath::kEvenOdd_FillType); 85 86 canvas->translate(kPad, kPad); 87 88 for (const SkPath& path : paths) { 89 SkScalar ty = drawPathSet(path, SkMatrix::I()); 90 canvas->translate(0, ty); 91 92 // Non-uniform scale. 93 SkMatrix s; 94 s.setScale(0.5f, 2.f); 95 ty = drawPathSet(path, s); 96 canvas->translate(0.f, ty); 97 98 // Rotation 99 SkMatrix r; 100 r.setRotate(60.f, path.getBounds().centerX(), path.getBounds().centerY()); 101 ty = drawPathSet(path, r); 102 canvas->translate(0.f, ty); 103 } 104 } 105 modifyGrContextOptions(GrContextOptions * options)106 void modifyGrContextOptions(GrContextOptions* options) override { 107 options->fGpuPathRenderers = GrContextOptions::GpuPathRenderers::kNone; 108 options->fAllowPathMaskCaching = true; 109 } 110 111 private: 112 typedef GM INHERITED; 113 }; 114 115 DEF_GM( return new PathMaskCache(); ) 116 117 #endif 118