blob: e567208c1e9e7e674ba24e3d4fa9f8ae6b7331f9 [file] [log] [blame]
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +00001
2/*
3 * Copyright 2014 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9// This test only works with the GPU backend.
10
11#include "gm.h"
12
13#if SK_SUPPORT_GPU
14
15#include "GrContext.h"
16#include "GrPathUtils.h"
17#include "GrTest.h"
18#include "SkColorPriv.h"
19#include "SkDevice.h"
20#include "SkGeometry.h"
21#include "SkTLList.h"
22
23#include "effects/GrConvexPolyEffect.h"
24
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000025namespace skiagm {
26/**
joshualittb0a8a372014-09-23 09:50:21 -070027 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000028 */
29class ConvexPolyEffect : public GM {
30public:
31 ConvexPolyEffect() {
32 this->setBGColor(0xFFFFFFFF);
33 }
34
35protected:
36 virtual SkString onShortName() SK_OVERRIDE {
37 return SkString("convex_poly_effect");
38 }
39
40 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -070041 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000042 }
43
44 virtual uint32_t onGetFlags() const SK_OVERRIDE {
45 // This is a GPU-specific GM.
46 return kGPUOnly_Flag;
47 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000048
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000049 virtual void onOnceBeforeDraw() SK_OVERRIDE {
50 SkPath tri;
51 tri.moveTo(5.f, 5.f);
52 tri.lineTo(100.f, 20.f);
53 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000054
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000055 fPaths.addToTail(tri);
56 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000057
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000058 tri.close();
59 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000060
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000061 SkPath ngon;
62 static const SkScalar kRadius = 50.f;
63 const SkPoint center = { kRadius, kRadius };
64 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
65 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
66 SkPoint point;
67 point.fY = SkScalarSinCos(angle, &point.fX);
68 point.scale(kRadius);
69 point = center + point;
70 if (0 == i) {
71 ngon.moveTo(point);
72 } else {
73 ngon.lineTo(point);
74 }
75 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000076
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000077 fPaths.addToTail(ngon);
78 SkMatrix scaleM;
79 scaleM.setScale(1.1f, 0.4f);
80 ngon.transform(scaleM);
81 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +000082
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000083 // integer edges
84 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
85 // half-integer edges
86 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
87 // vertically/horizontally thin rects that cover pixel centers
88 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
89 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
90 // vertically/horizontally thin rects that don't cover pixel centers
91 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
92 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
93 // small in x and y
94 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
95 // inverted in x and y
96 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000097 }
98
99 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000100 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000101 if (NULL == rt) {
102 return;
103 }
104 GrContext* context = rt->getContext();
105 if (NULL == context) {
106 return;
107 }
108
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000109 SkScalar y = 0;
110 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700111 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000112 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000113 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000114 SkScalar x = 0;
115
joshualittb0a8a372014-09-23 09:50:21 -0700116 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000117 GrTestTarget tt;
118 context->getTestTarget(&tt);
119 if (NULL == tt.target()) {
120 SkDEBUGFAIL("Couldn't get Gr test target.");
121 return;
122 }
123 GrDrawState* drawState = tt.target()->drawState();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000124
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000125 SkMatrix m;
126 SkPath p;
127 m.setTranslate(x, y);
128 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000129
joshualittb0a8a372014-09-23 09:50:21 -0700130 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
131 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
132 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000133 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000134 }
joshualittb0a8a372014-09-23 09:50:21 -0700135 drawState->addCoverageProcessor(fp);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000136 drawState->setIdentityViewMatrix();
137 drawState->setRenderTarget(rt);
138 drawState->setColor(0xff000000);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000139
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000140 SkPoint verts[4];
141 SkRect bounds = p.getBounds();
142 // Make sure any artifacts around the exterior of path are visible by using overly
143 // conservative bounding geometry.
144 bounds.outset(5.f, 5.f);
145 bounds.toQuad(verts);
146
147 tt.target()->setVertexSourceToArray(verts, 4);
148 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
149 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000150
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000151 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000152 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000153
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000154 // Draw AA and non AA paths using normal API for reference.
155 canvas->save();
156 canvas->translate(x, y);
157 SkPaint paint;
158 canvas->drawPath(*path, paint);
159 canvas->translate(path->getBounds().width() + 10.f, 0);
160 paint.setAntiAlias(true);
161 canvas->drawPath(*path, paint);
162 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000163
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000164 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
165 }
166
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000167 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700168 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000169 iter.next()) {
170
171 SkScalar x = 0;
172
joshualittb0a8a372014-09-23 09:50:21 -0700173 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000174 GrTestTarget tt;
175 context->getTestTarget(&tt);
176 if (NULL == tt.target()) {
177 SkDEBUGFAIL("Couldn't get Gr test target.");
178 return;
179 }
180 SkRect rect = *iter.get();
181 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700182 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
183 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
184 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000185 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000186 }
187
188 GrDrawState* drawState = tt.target()->drawState();
joshualittb0a8a372014-09-23 09:50:21 -0700189 drawState->addCoverageProcessor(fp);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000190 drawState->setIdentityViewMatrix();
191 drawState->setRenderTarget(rt);
192 drawState->setColor(0xff000000);
193
194 SkPoint verts[4];
195 SkRect bounds = rect;
196 bounds.outset(5.f, 5.f);
197 bounds.toQuad(verts);
198
199 tt.target()->setVertexSourceToArray(verts, 4);
200 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
201 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
202
203 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000204 }
205
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000206 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000207 canvas->save();
208 canvas->translate(x, y);
209 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000210 canvas->drawRect(*iter.get(), paint);
211 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000212 paint.setAntiAlias(true);
213 canvas->drawRect(*iter.get(), paint);
214 canvas->restore();
215
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000216 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000217 }
218 }
219
220private:
221 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000222 SkTLList<SkRect> fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000223
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000224 typedef GM INHERITED;
225};
226
227DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000228}
229
230#endif