Index: gm/pathmaskcache.cpp |
diff --git a/gm/pathmaskcache.cpp b/gm/pathmaskcache.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..21397f077d9cc970003592cbcbf0207becedfa32 |
--- /dev/null |
+++ b/gm/pathmaskcache.cpp |
@@ -0,0 +1,117 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "gm.h" |
+ |
+#if SK_SUPPORT_GPU |
+ |
+#include "GrContext.h" |
+#include "GrContextOptions.h" |
+#include "SkPath.h" |
+ |
+/** This tests the GPU backend's caching of path coverage masks */ |
+class PathMaskCache : public skiagm::GM { |
+public: |
+ PathMaskCache() {} |
+ |
+protected: |
+ SkString onShortName() override { return SkString("path_mask_cache"); } |
+ |
+ SkISize onISize() override { |
+ return SkISize::Make(650, 950); |
+ } |
+ |
+ void onDraw(SkCanvas* canvas) override { |
+ static constexpr SkScalar kPad = 5.f; |
+ |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ auto drawPathSet = [canvas] (const SkPath& path, const SkMatrix& m) { |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ SkRect bounds = path.getBounds(); |
+ m.mapRect(&bounds); |
+ bounds.roundOut(); |
+ canvas->save(); |
+ canvas->translate(-bounds.fLeft, -bounds.fTop); |
+ |
+ canvas->save(); |
+ canvas->concat(m); |
+ canvas->drawPath(path, paint); |
+ canvas->restore(); |
+ |
+ // translate by integer |
+ canvas->translate(bounds.width() + kPad, 0.f); |
+ canvas->save(); |
+ canvas->concat(m); |
+ canvas->drawPath(path, paint); |
+ canvas->restore(); |
+ |
+ // translate by non-integer |
+ canvas->translate(bounds.width() + kPad + 0.15f, 0.f); |
+ canvas->save(); |
+ canvas->concat(m); |
+ canvas->drawPath(path, paint); |
+ canvas->restore(); |
+ |
+ // translate again so total translate fraction is almost identical to previous. |
+ canvas->translate(bounds.width() + kPad + 0.002f, 0.f); |
+ canvas->save(); |
+ canvas->concat(m); |
+ canvas->drawPath(path, paint); |
+ canvas->restore(); |
+ canvas->restore(); |
+ return bounds.fBottom + kPad; |
+ }; |
+ |
+ |
+ SkTArray<SkPath> paths; |
+ paths.push_back(); |
+ paths.back().moveTo(0.f, 0.f); |
+ paths.back().lineTo(98.f, 100.f); |
+ paths.back().lineTo(100.f, 100.f); |
+ paths.back().conicTo(150.f, 50.f, 100.f, 0.f, 0.6f); |
+ paths.back().conicTo(148.f, 50.f, 100.f, 100.f, 0.6f); |
+ paths.back().conicTo(50.f, 30.f, 0.f, 100.f, 0.9f); |
+ |
+ paths.push_back(); |
+ paths.back().addCircle(30.f, 30.f, 30.f); |
+ paths.back().addRect(SkRect::MakeXYWH(45.f, 45.f, 50.f, 60.f)); |
+ paths.back().setFillType(SkPath::kEvenOdd_FillType); |
+ |
+ canvas->translate(kPad, kPad); |
+ |
+ for (const SkPath& path : paths) { |
+ SkScalar ty = drawPathSet(path, SkMatrix::I()); |
+ canvas->translate(0, ty); |
+ |
+ // Non-uniform scale. |
+ SkMatrix s; |
+ s.setScale(0.5f, 2.f); |
+ ty = drawPathSet(path, s); |
+ canvas->translate(0.f, ty); |
+ |
+ // Rotation |
+ SkMatrix r; |
+ r.setRotate(60.f, path.getBounds().centerX(), path.getBounds().centerY()); |
+ ty = drawPathSet(path, r); |
+ canvas->translate(0.f, ty); |
+ } |
+ } |
+ |
+ void modifyGrContextOptions(GrContextOptions* options) override { |
+ options->fForceSWPathMasks = true; |
+ options->fAllowPathMaskCaching = true; |
+ } |
+ |
+private: |
+ typedef GM INHERITED; |
+}; |
+ |
+DEF_GM( return new PathMaskCache(); ) |
+ |
+#endif |