blob: 294de5537ff64618bee8ea822f63f708533d7cd3 [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)
45 : INHERITED(gp)
46 , 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 {
joshualitt95964c62015-02-11 13:45:50 -080055 size_t vertexStride = this->geometryProcessor()->getVertexStride();
56
57 const GrVertexBuffer* vertexBuffer;
58 int firstVertex;
59
60 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
61 kVertsPerCubic,
62 &vertexBuffer,
63 &firstVertex);
64
joshualitt4b31de82015-03-05 14:33:41 -080065 if (!vertices || !batchTarget->quadIndexBuffer()) {
66 SkDebugf("Could not allocate buffers\n");
67 return;
68 }
69
joshualitt95964c62015-02-11 13:45:50 -080070 SkASSERT(vertexStride == sizeof(SkPoint));
71 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
72
73 // Make sure any artifacts around the exterior of path are visible by using overly
74 // conservative bounding geometry.
75 fGeometry.fBounds.outset(5.f, 5.f);
76 fGeometry.fBounds.toQuad(verts);
77
78 GrDrawTarget::DrawInfo drawInfo;
79 drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
80 drawInfo.setVertexBuffer(vertexBuffer);
81 drawInfo.setStartVertex(firstVertex);
82 drawInfo.setVertexCount(kVertsPerCubic);
83 drawInfo.setStartIndex(0);
84 drawInfo.setIndexCount(kIndicesPerCubic);
85 drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer());
86 batchTarget->draw(drawInfo);
87 }
88
89 Geometry fGeometry;
90
91 static const int kVertsPerCubic = 4;
92 static const int kIndicesPerCubic = 6;
93
94 typedef GrTestBatch INHERITED;
95};
96
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000097/**
joshualittb0a8a372014-09-23 09:50:21 -070098 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000099 */
100class ConvexPolyEffect : public GM {
101public:
102 ConvexPolyEffect() {
103 this->setBGColor(0xFFFFFFFF);
104 }
105
106protected:
mtklein36352bf2015-03-25 18:17:31 -0700107 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000108 return SkString("convex_poly_effect");
109 }
110
mtklein36352bf2015-03-25 18:17:31 -0700111 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700112 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000113 }
114
mtklein36352bf2015-03-25 18:17:31 -0700115 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000116 SkPath tri;
117 tri.moveTo(5.f, 5.f);
118 tri.lineTo(100.f, 20.f);
119 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000120
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000121 fPaths.addToTail(tri);
122 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000123
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000124 tri.close();
125 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000126
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000127 SkPath ngon;
128 static const SkScalar kRadius = 50.f;
129 const SkPoint center = { kRadius, kRadius };
130 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
131 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
132 SkPoint point;
133 point.fY = SkScalarSinCos(angle, &point.fX);
134 point.scale(kRadius);
135 point = center + point;
136 if (0 == i) {
137 ngon.moveTo(point);
138 } else {
139 ngon.lineTo(point);
140 }
141 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000142
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000143 fPaths.addToTail(ngon);
144 SkMatrix scaleM;
145 scaleM.setScale(1.1f, 0.4f);
146 ngon.transform(scaleM);
147 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000148
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000149 // integer edges
150 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
151 // half-integer edges
152 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
153 // vertically/horizontally thin rects that cover pixel centers
154 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
155 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
156 // vertically/horizontally thin rects that don't cover pixel centers
157 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
158 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
159 // small in x and y
160 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
161 // inverted in x and y
162 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000163 }
164
mtklein36352bf2015-03-25 18:17:31 -0700165 void onDraw(SkCanvas* canvas) override {
reed@google.com9c135db2014-03-12 18:28:35 +0000166 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000167 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800168 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000169 return;
170 }
171 GrContext* context = rt->getContext();
172 if (NULL == context) {
173 return;
174 }
175
joshualitt95964c62015-02-11 13:45:50 -0800176 SkAutoTUnref<const GrGeometryProcessor> gp(
177 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
178 0xff000000));
179
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000180 SkScalar y = 0;
181 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700182 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000183 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000184 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000185 SkScalar x = 0;
186
joshualittb0a8a372014-09-23 09:50:21 -0700187 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000188 GrTestTarget tt;
189 context->getTestTarget(&tt);
190 if (NULL == tt.target()) {
191 SkDEBUGFAIL("Couldn't get Gr test target.");
192 return;
193 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700194 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000195 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000196 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000197
joshualittb0a8a372014-09-23 09:50:21 -0700198 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
199 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
200 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000201 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000202 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000203
egdaniel8dd688b2015-01-22 10:16:09 -0800204 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800205 pipelineBuilder.addCoverageProcessor(fp);
206 pipelineBuilder.setRenderTarget(rt);
joshualitt9853cce2014-11-17 14:22:48 -0800207
joshualitt95964c62015-02-11 13:45:50 -0800208 ConvexPolyTestBatch::Geometry geometry;
209 geometry.fColor = gp->color();
210 geometry.fBounds = p.getBounds();
joshualitt50408ad2014-11-03 12:31:14 -0800211
joshualitt95964c62015-02-11 13:45:50 -0800212 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000213
joshualitt95964c62015-02-11 13:45:50 -0800214 tt.target()->drawBatch(&pipelineBuilder, batch, NULL);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000215
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000216 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
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
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000232 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::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 GrTestTarget tt;
240 context->getTestTarget(&tt);
241 if (NULL == tt.target()) {
242 SkDEBUGFAIL("Couldn't get Gr test target.");
243 return;
244 }
245 SkRect rect = *iter.get();
246 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700247 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
248 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
249 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000250 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000251 }
252
egdaniel8dd688b2015-01-22 10:16:09 -0800253 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800254 pipelineBuilder.addCoverageProcessor(fp);
255 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000256
joshualitt95964c62015-02-11 13:45:50 -0800257 ConvexPolyTestBatch::Geometry geometry;
258 geometry.fColor = gp->color();
259 geometry.fBounds = rect;
joshualitt50408ad2014-11-03 12:31:14 -0800260
joshualitt95964c62015-02-11 13:45:50 -0800261 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000262
joshualitt95964c62015-02-11 13:45:50 -0800263 tt.target()->drawBatch(&pipelineBuilder, batch, NULL);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000264
265 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000266 }
267
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000268 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000269 canvas->save();
270 canvas->translate(x, y);
271 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000272 canvas->drawRect(*iter.get(), paint);
273 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000274 paint.setAntiAlias(true);
275 canvas->drawRect(*iter.get(), paint);
276 canvas->restore();
277
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000278 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000279 }
280 }
281
282private:
283 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000284 SkTLList<SkRect> 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
289DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000290}
291
292#endif