blob: f3b7294f2c6778456afb62e13bd1d68c8b66015a [file] [log] [blame]
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +00001/*
2 * Copyright 2014 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// This test only works with the GPU backend.
9
10#include "gm.h"
11
12#if SK_SUPPORT_GPU
13
14#include "GrContext.h"
joshualitt5478d422014-11-14 16:00:38 -080015#include "GrDefaultGeoProcFactory.h"
Brian Osman11052242016-10-27 14:47:55 -040016#include "GrRenderTargetContextPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000017#include "GrPathUtils.h"
18#include "GrTest.h"
19#include "SkColorPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000020#include "SkGeometry.h"
21#include "SkTLList.h"
22
Brian Salomondad29232016-12-01 16:40:24 -050023#include "batches/GrMeshDrawOp.h"
Brian Salomon6b316e92016-12-16 09:35:49 -050024#include "batches/GrTestMeshDrawOp.h"
joshualitt2771b562015-08-07 12:46:26 -070025
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000026#include "effects/GrConvexPolyEffect.h"
27
bsalomon342bfc22016-04-01 06:06:20 -070028/** outset rendered rect to visualize anti-aliased poly edges */
29static SkRect outset(const SkRect& unsorted) {
30 SkRect r = unsorted;
31 r.outset(5.f, 5.f);
32 return r;
33}
joshualitt95964c62015-02-11 13:45:50 -080034
bsalomon342bfc22016-04-01 06:06:20 -070035/** sorts a rect */
36static SkRect sorted_rect(const SkRect& unsorted) {
37 SkRect r = unsorted;
38 r.sort();
39 return r;
40}
41
42namespace skiagm {
Brian Salomon6b316e92016-12-16 09:35:49 -050043class PolyBoundsOp : public GrTestMeshDrawOp {
joshualitt95964c62015-02-11 13:45:50 -080044public:
Brian Salomon25a88092016-12-01 09:36:50 -050045 DEFINE_OP_CLASS_ID
joshualitt95964c62015-02-11 13:45:50 -080046
Brian Salomon6b316e92016-12-16 09:35:49 -050047 const char* name() const override { return "PolyBoundsOp"; }
joshualitt95964c62015-02-11 13:45:50 -080048
Brian Salomon6b316e92016-12-16 09:35:49 -050049 static sk_sp<GrDrawOp> Make(const SkRect& rect, GrColor color) {
50 return sk_sp<GrDrawOp>(new PolyBoundsOp(rect, color));
joshualitt95964c62015-02-11 13:45:50 -080051 }
52
53private:
Brian Salomon6b316e92016-12-16 09:35:49 -050054 PolyBoundsOp(const SkRect& rect, GrColor color)
55 : INHERITED(ClassID(), outset(sorted_rect(rect)), color), fRect(outset(rect)) {}
56
bsalomon342bfc22016-04-01 06:06:20 -070057 void onPrepareDraws(Target* target) const override {
58 using namespace GrDefaultGeoProcFactory;
joshualitt95964c62015-02-11 13:45:50 -080059
bsalomon342bfc22016-04-01 06:06:20 -070060 Color color(this->color());
61 Coverage coverage(Coverage::kSolid_Type);
62 LocalCoords localCoords(LocalCoords::kUnused_Type);
bungeman06ca8ec2016-06-09 08:01:03 -070063 sk_sp<GrGeometryProcessor> gp(
64 GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix::I()));
joshualitt95964c62015-02-11 13:45:50 -080065
bsalomon342bfc22016-04-01 06:06:20 -070066 size_t vertexStride = gp->getVertexStride();
bsalomonb5238a72015-05-05 07:49:49 -070067 SkASSERT(vertexStride == sizeof(SkPoint));
68 QuadHelper helper;
bsalomon75398562015-08-17 12:55:38 -070069 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
bsalomonb5238a72015-05-05 07:49:49 -070070 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -080071 return;
72 }
73
bsalomon342bfc22016-04-01 06:06:20 -070074 fRect.toQuad(verts);
joshualitt95964c62015-02-11 13:45:50 -080075
bungeman06ca8ec2016-06-09 08:01:03 -070076 helper.recordDraw(target, gp.get());
joshualitt95964c62015-02-11 13:45:50 -080077 }
78
bsalomon342bfc22016-04-01 06:06:20 -070079 SkRect fRect;
joshualitt95964c62015-02-11 13:45:50 -080080
Brian Salomon6b316e92016-12-16 09:35:49 -050081 typedef GrTestMeshDrawOp INHERITED;
joshualitt95964c62015-02-11 13:45:50 -080082};
83
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000084/**
joshualittb0a8a372014-09-23 09:50:21 -070085 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000086 */
87class ConvexPolyEffect : public GM {
88public:
89 ConvexPolyEffect() {
90 this->setBGColor(0xFFFFFFFF);
91 }
92
93protected:
mtklein36352bf2015-03-25 18:17:31 -070094 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000095 return SkString("convex_poly_effect");
96 }
97
mtklein36352bf2015-03-25 18:17:31 -070098 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070099 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000100 }
101
mtklein36352bf2015-03-25 18:17:31 -0700102 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000103 SkPath tri;
104 tri.moveTo(5.f, 5.f);
105 tri.lineTo(100.f, 20.f);
106 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000107
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000108 fPaths.addToTail(tri);
109 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000110
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000111 tri.close();
112 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000113
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000114 SkPath ngon;
mtkleindbfd7ab2016-09-01 11:24:54 -0700115 constexpr SkScalar kRadius = 50.f;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000116 const SkPoint center = { kRadius, kRadius };
117 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
118 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
119 SkPoint point;
120 point.fY = SkScalarSinCos(angle, &point.fX);
121 point.scale(kRadius);
122 point = center + point;
123 if (0 == i) {
124 ngon.moveTo(point);
125 } else {
126 ngon.lineTo(point);
127 }
128 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000129
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000130 fPaths.addToTail(ngon);
131 SkMatrix scaleM;
132 scaleM.setScale(1.1f, 0.4f);
133 ngon.transform(scaleM);
134 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000135
bsalomon7888de02016-03-28 15:04:45 -0700136 SkPath linePath;
137 linePath.moveTo(5.f, 5.f);
138 linePath.lineTo(6.f, 6.f);
139 fPaths.addToTail(linePath);
140
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000141 // integer edges
142 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
143 // half-integer edges
144 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
145 // vertically/horizontally thin rects that cover pixel centers
146 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
147 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
148 // vertically/horizontally thin rects that don't cover pixel centers
149 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
150 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
151 // small in x and y
152 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
153 // inverted in x and y
154 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000155 }
156
mtklein36352bf2015-03-25 18:17:31 -0700157 void onDraw(SkCanvas* canvas) override {
Brian Osman11052242016-10-27 14:47:55 -0400158 GrRenderTargetContext* renderTargetContext =
159 canvas->internal_private_accessTopLayerRenderTargetContext();
160 if (!renderTargetContext) {
robertphillips175dd9b2016-04-28 14:32:04 -0700161 skiagm::GM::DrawGpuOnlyMessage(canvas);
joshualittf5883a62016-01-13 07:47:38 -0800162 return;
163 }
164
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000165 SkScalar y = 0;
mtkleindbfd7ab2016-09-01 11:24:54 -0700166 constexpr SkScalar kDX = 12.f;
bsalomonf045d602015-11-18 19:01:12 -0800167 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700168 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000169 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000170 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000171 SkScalar x = 0;
172
joshualittb0a8a372014-09-23 09:50:21 -0700173 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
robertphillips1d24b8d2015-03-26 19:57:08 -0700174 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000175 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000176 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000177
joshualittb0a8a372014-09-23 09:50:21 -0700178 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
bungeman06ca8ec2016-06-09 08:01:03 -0700179 sk_sp<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, p));
joshualittb0a8a372014-09-23 09:50:21 -0700180 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000181 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000182 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000183
robertphillips28a838e2016-06-23 14:07:00 -0700184 GrPaint grPaint;
Mike Reed7d954ad2016-10-28 15:42:34 -0400185 grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700186 grPaint.addCoverageFragmentProcessor(std::move(fp));
joshualitt9853cce2014-11-17 14:22:48 -0800187
Brian Salomon6b316e92016-12-16 09:35:49 -0500188 sk_sp<GrDrawOp> op = PolyBoundsOp::Make(p.getBounds(), 0xff000000);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000189
Brian Salomon1951f3d2016-12-09 16:07:12 -0500190 renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
191 std::move(op));
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000192
bsalomon7888de02016-03-28 15:04:45 -0700193 x += SkScalarCeilToScalar(path->getBounds().width() + kDX);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000194 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000195
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000196 // Draw AA and non AA paths using normal API for reference.
197 canvas->save();
198 canvas->translate(x, y);
199 SkPaint paint;
200 canvas->drawPath(*path, paint);
201 canvas->translate(path->getBounds().width() + 10.f, 0);
202 paint.setAntiAlias(true);
203 canvas->drawPath(*path, paint);
204 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000205
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000206 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
207 }
208
bsalomonf045d602015-11-18 19:01:12 -0800209 for (RectList::Iter iter(fRects, RectList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700210 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000211 iter.next()) {
212
213 SkScalar x = 0;
214
joshualittb0a8a372014-09-23 09:50:21 -0700215 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000216 SkRect rect = *iter.get();
217 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700218 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
bungeman06ca8ec2016-06-09 08:01:03 -0700219 sk_sp<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, rect));
joshualittb0a8a372014-09-23 09:50:21 -0700220 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000221 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000222 }
223
robertphillips28a838e2016-06-23 14:07:00 -0700224 GrPaint grPaint;
Mike Reed7d954ad2016-10-28 15:42:34 -0400225 grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700226 grPaint.addCoverageFragmentProcessor(std::move(fp));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000227
Brian Salomon6b316e92016-12-16 09:35:49 -0500228 sk_sp<GrDrawOp> op = PolyBoundsOp::Make(rect, 0xff000000);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000229
Brian Salomon1951f3d2016-12-09 16:07:12 -0500230 renderTargetContext->priv().testingOnly_addDrawOp(grPaint, GrAAType::kNone,
231 std::move(op));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000232
bsalomon7888de02016-03-28 15:04:45 -0700233 x += SkScalarCeilToScalar(rect.width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000234 }
235
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000236 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000237 canvas->save();
238 canvas->translate(x, y);
239 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000240 canvas->drawRect(*iter.get(), paint);
bsalomon7888de02016-03-28 15:04:45 -0700241 x += SkScalarCeilToScalar(iter.get()->width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000242 paint.setAntiAlias(true);
243 canvas->drawRect(*iter.get(), paint);
244 canvas->restore();
245
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000246 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000247 }
248 }
249
250private:
bsalomonf045d602015-11-18 19:01:12 -0800251 typedef SkTLList<SkPath, 1> PathList;
252 typedef SkTLList<SkRect, 1> RectList;
253 PathList fPaths;
254 RectList fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000255
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000256 typedef GM INHERITED;
257};
258
halcanary385fe4d2015-08-26 13:07:48 -0700259DEF_GM(return new ConvexPolyEffect;)
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000260}
261
262#endif