blob: 412e47893d15c2c8c871b3deaada51232f5ad993 [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"
robertphillips391395d2016-03-02 09:26:36 -080017#include "GrDrawContextPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000018#include "GrPathUtils.h"
19#include "GrTest.h"
20#include "SkColorPriv.h"
21#include "SkDevice.h"
22#include "SkGeometry.h"
23#include "SkTLList.h"
24
joshualitt2771b562015-08-07 12:46:26 -070025#include "batches/GrTestBatch.h"
bsalomon16b99132015-08-13 14:55:50 -070026#include "batches/GrVertexBatch.h"
joshualitt2771b562015-08-07 12:46:26 -070027
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000028#include "effects/GrConvexPolyEffect.h"
29
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000030namespace skiagm {
joshualitt95964c62015-02-11 13:45:50 -080031
32class ConvexPolyTestBatch : public GrTestBatch {
33public:
reed1b55a962015-09-17 20:16:13 -070034 DEFINE_BATCH_CLASS_ID
joshualitt95964c62015-02-11 13:45:50 -080035 struct Geometry : public GrTestBatch::Geometry {
joshualittf5883a62016-01-13 07:47:38 -080036 SkRect fRect;
37 SkRect fBounds; // This will be == fRect, except fBounds must be sorted, whereas fRect can
38 // be inverted
joshualitt95964c62015-02-11 13:45:50 -080039 };
40
mtklein36352bf2015-03-25 18:17:31 -070041 const char* name() const override { return "ConvexPolyTestBatch"; }
joshualitt95964c62015-02-11 13:45:50 -080042
bsalomonabd30f52015-08-13 13:34:48 -070043 static GrDrawBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo) {
halcanary385fe4d2015-08-26 13:07:48 -070044 return new ConvexPolyTestBatch(gp, geo);
joshualitt95964c62015-02-11 13:45:50 -080045 }
46
47private:
48 ConvexPolyTestBatch(const GrGeometryProcessor* gp, const Geometry& geo)
reed1b55a962015-09-17 20:16:13 -070049 : INHERITED(ClassID(), gp, geo.fBounds)
joshualitt95964c62015-02-11 13:45:50 -080050 , fGeometry(geo) {
joshualitt144c3c82015-11-30 12:30:13 -080051 // Make sure any artifacts around the exterior of path are visible by using overly
52 // conservative bounding geometry.
53 fGeometry.fBounds.outset(5.f, 5.f);
joshualittf5883a62016-01-13 07:47:38 -080054 fGeometry.fRect.outset(5.f, 5.f);
joshualitt95964c62015-02-11 13:45:50 -080055 }
56
mtklein36352bf2015-03-25 18:17:31 -070057 Geometry* geoData(int index) override {
joshualitt95964c62015-02-11 13:45:50 -080058 SkASSERT(0 == index);
59 return &fGeometry;
60 }
61
joshualitt88c23fc2015-05-13 14:18:07 -070062 const Geometry* geoData(int index) const override {
63 SkASSERT(0 == index);
64 return &fGeometry;
65 }
66
joshualitt144c3c82015-11-30 12:30:13 -080067 void generateGeometry(Target* target) const override {
bsalomoned0bcad2015-05-04 10:36:42 -070068 size_t vertexStride = this->geometryProcessor()->getVertexStride();
bsalomonb5238a72015-05-05 07:49:49 -070069 SkASSERT(vertexStride == sizeof(SkPoint));
70 QuadHelper helper;
bsalomon75398562015-08-17 12:55:38 -070071 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1));
bsalomonb5238a72015-05-05 07:49:49 -070072 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -080073 return;
74 }
75
joshualittf5883a62016-01-13 07:47:38 -080076 fGeometry.fRect.toQuad(verts);
joshualitt95964c62015-02-11 13:45:50 -080077
bsalomon75398562015-08-17 12:55:38 -070078 helper.recordDraw(target);
joshualitt95964c62015-02-11 13:45:50 -080079 }
80
81 Geometry fGeometry;
82
joshualitt95964c62015-02-11 13:45:50 -080083 typedef GrTestBatch INHERITED;
84};
85
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000086/**
joshualittb0a8a372014-09-23 09:50:21 -070087 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000088 */
89class ConvexPolyEffect : public GM {
90public:
91 ConvexPolyEffect() {
92 this->setBGColor(0xFFFFFFFF);
93 }
94
95protected:
mtklein36352bf2015-03-25 18:17:31 -070096 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000097 return SkString("convex_poly_effect");
98 }
99
mtklein36352bf2015-03-25 18:17:31 -0700100 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700101 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000102 }
103
mtklein36352bf2015-03-25 18:17:31 -0700104 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000105 SkPath tri;
106 tri.moveTo(5.f, 5.f);
107 tri.lineTo(100.f, 20.f);
108 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000109
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000110 fPaths.addToTail(tri);
111 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000112
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000113 tri.close();
114 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000115
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000116 SkPath ngon;
117 static const SkScalar kRadius = 50.f;
118 const SkPoint center = { kRadius, kRadius };
119 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
120 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
121 SkPoint point;
122 point.fY = SkScalarSinCos(angle, &point.fX);
123 point.scale(kRadius);
124 point = center + point;
125 if (0 == i) {
126 ngon.moveTo(point);
127 } else {
128 ngon.lineTo(point);
129 }
130 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000131
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000132 fPaths.addToTail(ngon);
133 SkMatrix scaleM;
134 scaleM.setScale(1.1f, 0.4f);
135 ngon.transform(scaleM);
136 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000137
bsalomon7888de02016-03-28 15:04:45 -0700138 SkPath linePath;
139 linePath.moveTo(5.f, 5.f);
140 linePath.lineTo(6.f, 6.f);
141 fPaths.addToTail(linePath);
142
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000143 // integer edges
144 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
145 // half-integer edges
146 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
147 // vertically/horizontally thin rects that cover pixel centers
148 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
149 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
150 // vertically/horizontally thin rects that don't cover pixel centers
151 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
152 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
153 // small in x and y
154 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
155 // inverted in x and y
156 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000157 }
158
mtklein36352bf2015-03-25 18:17:31 -0700159 void onDraw(SkCanvas* canvas) override {
joshualittdf0c5572015-08-03 11:35:28 -0700160 using namespace GrDefaultGeoProcFactory;
reed@google.com9c135db2014-03-12 18:28:35 +0000161 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
halcanary96fcdcc2015-08-27 07:41:13 -0700162 if (nullptr == rt) {
halcanary2a243382015-09-09 08:16:41 -0700163 skiagm::GM::DrawGpuOnlyMessage(canvas);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000164 return;
165 }
166 GrContext* context = rt->getContext();
halcanary96fcdcc2015-08-27 07:41:13 -0700167 if (nullptr == context) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000168 return;
169 }
170
joshualittf5883a62016-01-13 07:47:38 -0800171 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(rt));
172 if (!drawContext) {
173 return;
174 }
175
joshualittdf0c5572015-08-03 11:35:28 -0700176 Color color(0xff000000);
177 Coverage coverage(Coverage::kSolid_Type);
178 LocalCoords localCoords(LocalCoords::kUnused_Type);
joshualitt95964c62015-02-11 13:45:50 -0800179 SkAutoTUnref<const GrGeometryProcessor> gp(
joshualittdf0c5572015-08-03 11:35:28 -0700180 GrDefaultGeoProcFactory::Create(color, coverage, localCoords, SkMatrix::I()));
joshualitt95964c62015-02-11 13:45:50 -0800181
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000182 SkScalar y = 0;
bsalomon7888de02016-03-28 15:04:45 -0700183 static const SkScalar kDX = 12.f;
bsalomonf045d602015-11-18 19:01:12 -0800184 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700185 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000186 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000187 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000188 SkScalar x = 0;
189
joshualittb0a8a372014-09-23 09:50:21 -0700190 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
robertphillips1d24b8d2015-03-26 19:57:08 -0700191 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000192 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000193 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000194
joshualittb0a8a372014-09-23 09:50:21 -0700195 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
196 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
197 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000198 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000199 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000200
egdaniel8dd688b2015-01-22 10:16:09 -0800201 GrPipelineBuilder pipelineBuilder;
egdanielc4b72722015-11-23 13:20:41 -0800202 pipelineBuilder.setXPFactory(
203 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
bsalomonac856c92015-08-27 06:30:17 -0700204 pipelineBuilder.addCoverageFragmentProcessor(fp);
egdaniel8dd688b2015-01-22 10:16:09 -0800205 pipelineBuilder.setRenderTarget(rt);
joshualitt9853cce2014-11-17 14:22:48 -0800206
joshualitt95964c62015-02-11 13:45:50 -0800207 ConvexPolyTestBatch::Geometry geometry;
joshualittdf0c5572015-08-03 11:35:28 -0700208 geometry.fColor = color.fColor;
joshualittf5883a62016-01-13 07:47:38 -0800209 geometry.fRect = p.getBounds();
joshualitt95964c62015-02-11 13:45:50 -0800210 geometry.fBounds = p.getBounds();
joshualitt50408ad2014-11-03 12:31:14 -0800211
bsalomonabd30f52015-08-13 13:34:48 -0700212 SkAutoTUnref<GrDrawBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000213
robertphillips391395d2016-03-02 09:26:36 -0800214 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBuilder, batch);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000215
bsalomon7888de02016-03-28 15:04:45 -0700216 x += SkScalarCeilToScalar(path->getBounds().width() + kDX);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000217 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000218
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000219 // Draw AA and non AA paths using normal API for reference.
220 canvas->save();
221 canvas->translate(x, y);
222 SkPaint paint;
223 canvas->drawPath(*path, paint);
224 canvas->translate(path->getBounds().width() + 10.f, 0);
225 paint.setAntiAlias(true);
226 canvas->drawPath(*path, paint);
227 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000228
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000229 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
230 }
231
bsalomonf045d602015-11-18 19:01:12 -0800232 for (RectList::Iter iter(fRects, RectList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700233 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000234 iter.next()) {
235
236 SkScalar x = 0;
237
joshualittb0a8a372014-09-23 09:50:21 -0700238 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000239 SkRect rect = *iter.get();
240 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700241 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
242 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
243 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000244 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000245 }
246
egdaniel8dd688b2015-01-22 10:16:09 -0800247 GrPipelineBuilder pipelineBuilder;
egdanielc4b72722015-11-23 13:20:41 -0800248 pipelineBuilder.setXPFactory(
249 GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
bsalomonac856c92015-08-27 06:30:17 -0700250 pipelineBuilder.addCoverageFragmentProcessor(fp);
egdaniel8dd688b2015-01-22 10:16:09 -0800251 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000252
joshualitt95964c62015-02-11 13:45:50 -0800253 ConvexPolyTestBatch::Geometry geometry;
joshualittdf0c5572015-08-03 11:35:28 -0700254 geometry.fColor = color.fColor;
joshualittf5883a62016-01-13 07:47:38 -0800255 geometry.fRect = rect;
joshualitt95964c62015-02-11 13:45:50 -0800256 geometry.fBounds = rect;
joshualittf5883a62016-01-13 07:47:38 -0800257 geometry.fBounds.sort();
joshualitt50408ad2014-11-03 12:31:14 -0800258
bsalomonabd30f52015-08-13 13:34:48 -0700259 SkAutoTUnref<GrDrawBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000260
robertphillips391395d2016-03-02 09:26:36 -0800261 drawContext->drawContextPriv().testingOnly_drawBatch(pipelineBuilder, batch);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000262
bsalomon7888de02016-03-28 15:04:45 -0700263 x += SkScalarCeilToScalar(rect.width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000264 }
265
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000266 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000267 canvas->save();
268 canvas->translate(x, y);
269 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000270 canvas->drawRect(*iter.get(), paint);
bsalomon7888de02016-03-28 15:04:45 -0700271 x += SkScalarCeilToScalar(iter.get()->width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000272 paint.setAntiAlias(true);
273 canvas->drawRect(*iter.get(), paint);
274 canvas->restore();
275
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000276 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000277 }
278 }
279
280private:
bsalomonf045d602015-11-18 19:01:12 -0800281 typedef SkTLList<SkPath, 1> PathList;
282 typedef SkTLList<SkRect, 1> RectList;
283 PathList fPaths;
284 RectList fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000285
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000286 typedef GM INHERITED;
287};
288
halcanary385fe4d2015-08-26 13:07:48 -0700289DEF_GM(return new ConvexPolyEffect;)
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000290}
291
292#endif