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