blob: cd9b3d10e55b2efbc56efa0a49b6bf5aa2aaae67 [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"
16#include "GrBufferAllocPool.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000017#include "GrContext.h"
joshualitt5478d422014-11-14 16:00:38 -080018#include "GrDefaultGeoProcFactory.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000019#include "GrPathUtils.h"
20#include "GrTest.h"
joshualitt95964c62015-02-11 13:45:50 -080021#include "GrTestBatch.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000022#include "SkColorPriv.h"
23#include "SkDevice.h"
24#include "SkGeometry.h"
25#include "SkTLList.h"
26
27#include "effects/GrConvexPolyEffect.h"
28
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000029namespace skiagm {
joshualitt95964c62015-02-11 13:45:50 -080030
31class ConvexPolyTestBatch : public GrTestBatch {
32public:
33 struct Geometry : public GrTestBatch::Geometry {
34 SkRect fBounds;
35 };
36
mtklein36352bf2015-03-25 18:17:31 -070037 const char* name() const override { return "ConvexPolyTestBatch"; }
joshualitt95964c62015-02-11 13:45:50 -080038
39 static GrBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo) {
40 return SkNEW_ARGS(ConvexPolyTestBatch, (gp, geo));
41 }
42
43private:
44 ConvexPolyTestBatch(const GrGeometryProcessor* gp, const Geometry& geo)
joshualitt99c7c072015-05-01 13:43:30 -070045 : INHERITED(gp, geo.fBounds)
joshualitt95964c62015-02-11 13:45:50 -080046 , fGeometry(geo) {
47 }
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
mtklein36352bf2015-03-25 18:17:31 -070054 void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
bsalomoned0bcad2015-05-04 10:36:42 -070055 size_t vertexStride = this->geometryProcessor()->getVertexStride();
bsalomonb5238a72015-05-05 07:49:49 -070056 SkASSERT(vertexStride == sizeof(SkPoint));
57 QuadHelper helper;
58 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(batchTarget, vertexStride, 1));
59 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -080060 return;
61 }
62
joshualitt95964c62015-02-11 13:45:50 -080063 // Make sure any artifacts around the exterior of path are visible by using overly
64 // conservative bounding geometry.
65 fGeometry.fBounds.outset(5.f, 5.f);
66 fGeometry.fBounds.toQuad(verts);
67
bsalomonb5238a72015-05-05 07:49:49 -070068 helper.issueDraws(batchTarget);
joshualitt95964c62015-02-11 13:45:50 -080069 }
70
71 Geometry fGeometry;
72
joshualitt95964c62015-02-11 13:45:50 -080073 typedef GrTestBatch INHERITED;
74};
75
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000076/**
joshualittb0a8a372014-09-23 09:50:21 -070077 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000078 */
79class ConvexPolyEffect : public GM {
80public:
81 ConvexPolyEffect() {
82 this->setBGColor(0xFFFFFFFF);
83 }
84
85protected:
mtklein36352bf2015-03-25 18:17:31 -070086 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000087 return SkString("convex_poly_effect");
88 }
89
mtklein36352bf2015-03-25 18:17:31 -070090 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070091 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000092 }
93
mtklein36352bf2015-03-25 18:17:31 -070094 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000095 SkPath tri;
96 tri.moveTo(5.f, 5.f);
97 tri.lineTo(100.f, 20.f);
98 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000099
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000100 fPaths.addToTail(tri);
101 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000102
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000103 tri.close();
104 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000105
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000106 SkPath ngon;
107 static const SkScalar kRadius = 50.f;
108 const SkPoint center = { kRadius, kRadius };
109 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
110 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
111 SkPoint point;
112 point.fY = SkScalarSinCos(angle, &point.fX);
113 point.scale(kRadius);
114 point = center + point;
115 if (0 == i) {
116 ngon.moveTo(point);
117 } else {
118 ngon.lineTo(point);
119 }
120 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000121
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000122 fPaths.addToTail(ngon);
123 SkMatrix scaleM;
124 scaleM.setScale(1.1f, 0.4f);
125 ngon.transform(scaleM);
126 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000127
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000128 // integer edges
129 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
130 // half-integer edges
131 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
132 // vertically/horizontally thin rects that cover pixel centers
133 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
134 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
135 // vertically/horizontally thin rects that don't cover pixel centers
136 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
137 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
138 // small in x and y
139 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
140 // inverted in x and y
141 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000142 }
143
mtklein36352bf2015-03-25 18:17:31 -0700144 void onDraw(SkCanvas* canvas) override {
reed@google.com9c135db2014-03-12 18:28:35 +0000145 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000146 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800147 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000148 return;
149 }
150 GrContext* context = rt->getContext();
151 if (NULL == context) {
152 return;
153 }
154
joshualitt95964c62015-02-11 13:45:50 -0800155 SkAutoTUnref<const GrGeometryProcessor> gp(
156 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
157 0xff000000));
158
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000159 SkScalar y = 0;
160 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700161 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000162 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000163 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000164 SkScalar x = 0;
165
joshualittb0a8a372014-09-23 09:50:21 -0700166 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000167 GrTestTarget tt;
168 context->getTestTarget(&tt);
169 if (NULL == tt.target()) {
170 SkDEBUGFAIL("Couldn't get Gr test target.");
171 return;
172 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700173 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000174 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000175 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000176
joshualittb0a8a372014-09-23 09:50:21 -0700177 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
178 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
179 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000180 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000181 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000182
egdaniel8dd688b2015-01-22 10:16:09 -0800183 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800184 pipelineBuilder.addCoverageProcessor(fp);
185 pipelineBuilder.setRenderTarget(rt);
joshualitt9853cce2014-11-17 14:22:48 -0800186
joshualitt95964c62015-02-11 13:45:50 -0800187 ConvexPolyTestBatch::Geometry geometry;
188 geometry.fColor = gp->color();
189 geometry.fBounds = p.getBounds();
joshualitt50408ad2014-11-03 12:31:14 -0800190
joshualitt95964c62015-02-11 13:45:50 -0800191 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000192
joshualitt99c7c072015-05-01 13:43:30 -0700193 tt.target()->drawBatch(&pipelineBuilder, batch);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000194
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000195 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000196 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000197
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000198 // Draw AA and non AA paths using normal API for reference.
199 canvas->save();
200 canvas->translate(x, y);
201 SkPaint paint;
202 canvas->drawPath(*path, paint);
203 canvas->translate(path->getBounds().width() + 10.f, 0);
204 paint.setAntiAlias(true);
205 canvas->drawPath(*path, paint);
206 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000207
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000208 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
209 }
210
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000211 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700212 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000213 iter.next()) {
214
215 SkScalar x = 0;
216
joshualittb0a8a372014-09-23 09:50:21 -0700217 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000218 GrTestTarget tt;
219 context->getTestTarget(&tt);
220 if (NULL == tt.target()) {
221 SkDEBUGFAIL("Couldn't get Gr test target.");
222 return;
223 }
224 SkRect rect = *iter.get();
225 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700226 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
227 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
228 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000229 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000230 }
231
egdaniel8dd688b2015-01-22 10:16:09 -0800232 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800233 pipelineBuilder.addCoverageProcessor(fp);
234 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000235
joshualitt95964c62015-02-11 13:45:50 -0800236 ConvexPolyTestBatch::Geometry geometry;
237 geometry.fColor = gp->color();
238 geometry.fBounds = rect;
joshualitt50408ad2014-11-03 12:31:14 -0800239
joshualitt95964c62015-02-11 13:45:50 -0800240 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000241
joshualitt99c7c072015-05-01 13:43:30 -0700242 tt.target()->drawBatch(&pipelineBuilder, batch);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000243
244 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000245 }
246
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000247 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000248 canvas->save();
249 canvas->translate(x, y);
250 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000251 canvas->drawRect(*iter.get(), paint);
252 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000253 paint.setAntiAlias(true);
254 canvas->drawRect(*iter.get(), paint);
255 canvas->restore();
256
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000257 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000258 }
259 }
260
261private:
262 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000263 SkTLList<SkRect> fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000264
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000265 typedef GM INHERITED;
266};
267
268DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000269}
270
271#endif