blob: 1599e7a65d36153f8aaacafd204cd6fd82e035ac [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
joshualitt95964c62015-02-11 13:45:50 -080015#include "GrBatchTarget.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000016#include "GrContext.h"
joshualitt5478d422014-11-14 16:00:38 -080017#include "GrDefaultGeoProcFactory.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000018#include "GrPathUtils.h"
19#include "GrTest.h"
joshualitt95964c62015-02-11 13:45:50 -080020#include "GrTestBatch.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000021#include "SkColorPriv.h"
22#include "SkDevice.h"
23#include "SkGeometry.h"
24#include "SkTLList.h"
25
26#include "effects/GrConvexPolyEffect.h"
27
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000028namespace skiagm {
joshualitt95964c62015-02-11 13:45:50 -080029
30class ConvexPolyTestBatch : public GrTestBatch {
31public:
32 struct Geometry : public GrTestBatch::Geometry {
33 SkRect fBounds;
34 };
35
mtklein36352bf2015-03-25 18:17:31 -070036 const char* name() const override { return "ConvexPolyTestBatch"; }
joshualitt95964c62015-02-11 13:45:50 -080037
38 static GrBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo) {
39 return SkNEW_ARGS(ConvexPolyTestBatch, (gp, geo));
40 }
41
42private:
43 ConvexPolyTestBatch(const GrGeometryProcessor* gp, const Geometry& geo)
joshualitt99c7c072015-05-01 13:43:30 -070044 : INHERITED(gp, geo.fBounds)
joshualitt95964c62015-02-11 13:45:50 -080045 , fGeometry(geo) {
joshualittdbe1e6f2015-07-16 08:12:45 -070046 this->initClassID<ConvexPolyTestBatch>();
joshualitt95964c62015-02-11 13:45:50 -080047 }
48
mtklein36352bf2015-03-25 18:17:31 -070049 Geometry* geoData(int index) override {
joshualitt95964c62015-02-11 13:45:50 -080050 SkASSERT(0 == index);
51 return &fGeometry;
52 }
53
joshualitt88c23fc2015-05-13 14:18:07 -070054 const Geometry* geoData(int index) const override {
55 SkASSERT(0 == index);
56 return &fGeometry;
57 }
58
mtklein36352bf2015-03-25 18:17:31 -070059 void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
bsalomoned0bcad2015-05-04 10:36:42 -070060 size_t vertexStride = this->geometryProcessor()->getVertexStride();
bsalomonb5238a72015-05-05 07:49:49 -070061 SkASSERT(vertexStride == sizeof(SkPoint));
62 QuadHelper helper;
63 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(batchTarget, vertexStride, 1));
64 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -080065 return;
66 }
67
joshualitt95964c62015-02-11 13:45:50 -080068 // Make sure any artifacts around the exterior of path are visible by using overly
69 // conservative bounding geometry.
70 fGeometry.fBounds.outset(5.f, 5.f);
71 fGeometry.fBounds.toQuad(verts);
72
bsalomone64eb572015-05-07 11:35:55 -070073 helper.issueDraw(batchTarget);
joshualitt95964c62015-02-11 13:45:50 -080074 }
75
76 Geometry fGeometry;
77
joshualitt95964c62015-02-11 13:45:50 -080078 typedef GrTestBatch INHERITED;
79};
80
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000081/**
joshualittb0a8a372014-09-23 09:50:21 -070082 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000083 */
84class ConvexPolyEffect : public GM {
85public:
86 ConvexPolyEffect() {
87 this->setBGColor(0xFFFFFFFF);
88 }
89
90protected:
mtklein36352bf2015-03-25 18:17:31 -070091 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000092 return SkString("convex_poly_effect");
93 }
94
mtklein36352bf2015-03-25 18:17:31 -070095 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070096 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000097 }
98
mtklein36352bf2015-03-25 18:17:31 -070099 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000100 SkPath tri;
101 tri.moveTo(5.f, 5.f);
102 tri.lineTo(100.f, 20.f);
103 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000104
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000105 fPaths.addToTail(tri);
106 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000107
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000108 tri.close();
109 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000110
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000111 SkPath ngon;
112 static const SkScalar kRadius = 50.f;
113 const SkPoint center = { kRadius, kRadius };
114 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
115 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
116 SkPoint point;
117 point.fY = SkScalarSinCos(angle, &point.fX);
118 point.scale(kRadius);
119 point = center + point;
120 if (0 == i) {
121 ngon.moveTo(point);
122 } else {
123 ngon.lineTo(point);
124 }
125 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000126
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000127 fPaths.addToTail(ngon);
128 SkMatrix scaleM;
129 scaleM.setScale(1.1f, 0.4f);
130 ngon.transform(scaleM);
131 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000132
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000133 // integer edges
134 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
135 // half-integer edges
136 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
137 // vertically/horizontally thin rects that cover pixel centers
138 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
139 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
140 // vertically/horizontally thin rects that don't cover pixel centers
141 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
142 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
143 // small in x and y
144 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
145 // inverted in x and y
146 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000147 }
148
mtklein36352bf2015-03-25 18:17:31 -0700149 void onDraw(SkCanvas* canvas) override {
joshualittdf0c5572015-08-03 11:35:28 -0700150 using namespace GrDefaultGeoProcFactory;
reed@google.com9c135db2014-03-12 18:28:35 +0000151 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000152 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800153 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000154 return;
155 }
156 GrContext* context = rt->getContext();
157 if (NULL == context) {
158 return;
159 }
160
joshualittdf0c5572015-08-03 11:35:28 -0700161 Color color(0xff000000);
162 Coverage coverage(Coverage::kSolid_Type);
163 LocalCoords localCoords(LocalCoords::kUnused_Type);
joshualitt95964c62015-02-11 13:45:50 -0800164 SkAutoTUnref<const GrGeometryProcessor> gp(
joshualittdf0c5572015-08-03 11:35:28 -0700165 GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I()));
joshualitt95964c62015-02-11 13:45:50 -0800166
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000167 SkScalar y = 0;
168 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700169 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000170 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000171 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000172 SkScalar x = 0;
173
joshualittb0a8a372014-09-23 09:50:21 -0700174 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000175 GrTestTarget tt;
176 context->getTestTarget(&tt);
177 if (NULL == tt.target()) {
178 SkDEBUGFAIL("Couldn't get Gr test target.");
179 return;
180 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700181 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000182 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000183 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000184
joshualittb0a8a372014-09-23 09:50:21 -0700185 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
186 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
187 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000188 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000189 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000190
egdaniel8dd688b2015-01-22 10:16:09 -0800191 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800192 pipelineBuilder.addCoverageProcessor(fp);
193 pipelineBuilder.setRenderTarget(rt);
joshualitt9853cce2014-11-17 14:22:48 -0800194
joshualitt95964c62015-02-11 13:45:50 -0800195 ConvexPolyTestBatch::Geometry geometry;
joshualittdf0c5572015-08-03 11:35:28 -0700196 geometry.fColor = color.fColor;
joshualitt95964c62015-02-11 13:45:50 -0800197 geometry.fBounds = p.getBounds();
joshualitt50408ad2014-11-03 12:31:14 -0800198
joshualitt95964c62015-02-11 13:45:50 -0800199 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000200
joshualitt1c735482015-07-13 08:08:25 -0700201 tt.target()->drawBatch(pipelineBuilder, batch);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000202
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000203 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000204 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000205
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000206 // Draw AA and non AA paths using normal API for reference.
207 canvas->save();
208 canvas->translate(x, y);
209 SkPaint paint;
210 canvas->drawPath(*path, paint);
211 canvas->translate(path->getBounds().width() + 10.f, 0);
212 paint.setAntiAlias(true);
213 canvas->drawPath(*path, paint);
214 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000215
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000216 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
217 }
218
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000219 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700220 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000221 iter.next()) {
222
223 SkScalar x = 0;
224
joshualittb0a8a372014-09-23 09:50:21 -0700225 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000226 GrTestTarget tt;
227 context->getTestTarget(&tt);
228 if (NULL == tt.target()) {
229 SkDEBUGFAIL("Couldn't get Gr test target.");
230 return;
231 }
232 SkRect rect = *iter.get();
233 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700234 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
235 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
236 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000237 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000238 }
239
egdaniel8dd688b2015-01-22 10:16:09 -0800240 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800241 pipelineBuilder.addCoverageProcessor(fp);
242 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000243
joshualitt95964c62015-02-11 13:45:50 -0800244 ConvexPolyTestBatch::Geometry geometry;
joshualittdf0c5572015-08-03 11:35:28 -0700245 geometry.fColor = color.fColor;
joshualitt95964c62015-02-11 13:45:50 -0800246 geometry.fBounds = rect;
joshualitt50408ad2014-11-03 12:31:14 -0800247
joshualitt95964c62015-02-11 13:45:50 -0800248 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000249
joshualitt1c735482015-07-13 08:08:25 -0700250 tt.target()->drawBatch(pipelineBuilder, batch);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000251
252 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000253 }
254
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000255 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000256 canvas->save();
257 canvas->translate(x, y);
258 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000259 canvas->drawRect(*iter.get(), paint);
260 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000261 paint.setAntiAlias(true);
262 canvas->drawRect(*iter.get(), paint);
263 canvas->restore();
264
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000265 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000266 }
267 }
268
269private:
270 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000271 SkTLList<SkRect> fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000272
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000273 typedef GM INHERITED;
274};
275
276DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000277}
278
279#endif