blob: 9f4c48b4eb741452a583bda24efd17d2fbd6f310 [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"
joshualitt5478d422014-11-14 16:00:38 -080016#include "GrDefaultGeoProcFactory.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000017#include "GrPathUtils.h"
18#include "GrTest.h"
19#include "SkColorPriv.h"
20#include "SkDevice.h"
21#include "SkGeometry.h"
22#include "SkTLList.h"
23
24#include "effects/GrConvexPolyEffect.h"
25
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000026namespace skiagm {
27/**
joshualittb0a8a372014-09-23 09:50:21 -070028 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000029 */
30class ConvexPolyEffect : public GM {
31public:
32 ConvexPolyEffect() {
33 this->setBGColor(0xFFFFFFFF);
34 }
35
36protected:
37 virtual SkString onShortName() SK_OVERRIDE {
38 return SkString("convex_poly_effect");
39 }
40
41 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -070042 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000043 }
44
45 virtual uint32_t onGetFlags() const SK_OVERRIDE {
46 // This is a GPU-specific GM.
47 return kGPUOnly_Flag;
48 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000049
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000050 virtual void onOnceBeforeDraw() SK_OVERRIDE {
51 SkPath tri;
52 tri.moveTo(5.f, 5.f);
53 tri.lineTo(100.f, 20.f);
54 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000055
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000056 fPaths.addToTail(tri);
57 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000058
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000059 tri.close();
60 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000061
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000062 SkPath ngon;
63 static const SkScalar kRadius = 50.f;
64 const SkPoint center = { kRadius, kRadius };
65 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
66 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
67 SkPoint point;
68 point.fY = SkScalarSinCos(angle, &point.fX);
69 point.scale(kRadius);
70 point = center + point;
71 if (0 == i) {
72 ngon.moveTo(point);
73 } else {
74 ngon.lineTo(point);
75 }
76 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000077
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000078 fPaths.addToTail(ngon);
79 SkMatrix scaleM;
80 scaleM.setScale(1.1f, 0.4f);
81 ngon.transform(scaleM);
82 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +000083
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000084 // integer edges
85 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
86 // half-integer edges
87 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
88 // vertically/horizontally thin rects that cover pixel centers
89 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
90 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
91 // vertically/horizontally thin rects that don't cover pixel centers
92 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
93 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
94 // small in x and y
95 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
96 // inverted in x and y
97 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000098 }
99
100 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000101 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000102 if (NULL == rt) {
103 return;
104 }
105 GrContext* context = rt->getContext();
106 if (NULL == context) {
107 return;
108 }
109
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000110 SkScalar y = 0;
111 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700112 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000113 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000114 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000115 SkScalar x = 0;
116
joshualittb0a8a372014-09-23 09:50:21 -0700117 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000118 GrTestTarget tt;
119 context->getTestTarget(&tt);
120 if (NULL == tt.target()) {
121 SkDEBUGFAIL("Couldn't get Gr test target.");
122 return;
123 }
124 GrDrawState* drawState = tt.target()->drawState();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000125
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000126 SkMatrix m;
127 SkPath p;
128 m.setTranslate(x, y);
129 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000130
joshualittb0a8a372014-09-23 09:50:21 -0700131 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
132 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
133 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000134 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000135 }
joshualitt5478d422014-11-14 16:00:38 -0800136 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
joshualittb0a8a372014-09-23 09:50:21 -0700137 drawState->addCoverageProcessor(fp);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000138 drawState->setIdentityViewMatrix();
139 drawState->setRenderTarget(rt);
140 drawState->setColor(0xff000000);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000141
joshualitt50408ad2014-11-03 12:31:14 -0800142 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
143 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
144
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000145 SkRect bounds = p.getBounds();
146 // Make sure any artifacts around the exterior of path are visible by using overly
147 // conservative bounding geometry.
148 bounds.outset(5.f, 5.f);
149 bounds.toQuad(verts);
150
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000151 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
152 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000153
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000154 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000155 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000156
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000157 // Draw AA and non AA paths using normal API for reference.
158 canvas->save();
159 canvas->translate(x, y);
160 SkPaint paint;
161 canvas->drawPath(*path, paint);
162 canvas->translate(path->getBounds().width() + 10.f, 0);
163 paint.setAntiAlias(true);
164 canvas->drawPath(*path, paint);
165 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000166
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000167 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
168 }
169
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000170 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700171 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000172 iter.next()) {
173
174 SkScalar x = 0;
175
joshualittb0a8a372014-09-23 09:50:21 -0700176 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000177 GrTestTarget tt;
178 context->getTestTarget(&tt);
179 if (NULL == tt.target()) {
180 SkDEBUGFAIL("Couldn't get Gr test target.");
181 return;
182 }
183 SkRect rect = *iter.get();
184 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700185 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
186 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
187 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000188 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000189 }
190
191 GrDrawState* drawState = tt.target()->drawState();
joshualitt5478d422014-11-14 16:00:38 -0800192 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
joshualittb0a8a372014-09-23 09:50:21 -0700193 drawState->addCoverageProcessor(fp);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000194 drawState->setIdentityViewMatrix();
195 drawState->setRenderTarget(rt);
196 drawState->setColor(0xff000000);
197
joshualitt50408ad2014-11-03 12:31:14 -0800198 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
199 SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
200
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000201 SkRect bounds = rect;
202 bounds.outset(5.f, 5.f);
203 bounds.toQuad(verts);
204
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000205 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
206 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
207
208 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000209 }
210
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000211 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000212 canvas->save();
213 canvas->translate(x, y);
214 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000215 canvas->drawRect(*iter.get(), paint);
216 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000217 paint.setAntiAlias(true);
218 canvas->drawRect(*iter.get(), paint);
219 canvas->restore();
220
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000221 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000222 }
223 }
224
225private:
226 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000227 SkTLList<SkRect> fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000228
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000229 typedef GM INHERITED;
230};
231
232DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000233}
234
235#endif