blob: 60b73c571d97a067d5b566d2ed0b88570dd65212 [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"
bsalomoned0bcad2015-05-04 10:36:42 -070020#include "GrResourceProvider.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000021#include "GrTest.h"
joshualitt95964c62015-02-11 13:45:50 -080022#include "GrTestBatch.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000023#include "SkColorPriv.h"
24#include "SkDevice.h"
25#include "SkGeometry.h"
26#include "SkTLList.h"
27
28#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:
34 struct Geometry : public GrTestBatch::Geometry {
35 SkRect fBounds;
36 };
37
mtklein36352bf2015-03-25 18:17:31 -070038 const char* name() const override { return "ConvexPolyTestBatch"; }
joshualitt95964c62015-02-11 13:45:50 -080039
40 static GrBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo) {
41 return SkNEW_ARGS(ConvexPolyTestBatch, (gp, geo));
42 }
43
44private:
45 ConvexPolyTestBatch(const GrGeometryProcessor* gp, const Geometry& geo)
joshualitt99c7c072015-05-01 13:43:30 -070046 : INHERITED(gp, geo.fBounds)
joshualitt95964c62015-02-11 13:45:50 -080047 , fGeometry(geo) {
48 }
49
mtklein36352bf2015-03-25 18:17:31 -070050 Geometry* geoData(int index) override {
joshualitt95964c62015-02-11 13:45:50 -080051 SkASSERT(0 == index);
52 return &fGeometry;
53 }
54
mtklein36352bf2015-03-25 18:17:31 -070055 void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
bsalomoned0bcad2015-05-04 10:36:42 -070056 SkAutoTUnref<const GrIndexBuffer> indexBuffer(
57 batchTarget->resourceProvider()->refQuadIndexBuffer());
bsalomond8ed1b62015-05-04 10:09:23 -070058
bsalomoned0bcad2015-05-04 10:36:42 -070059 size_t vertexStride = this->geometryProcessor()->getVertexStride();
joshualitt95964c62015-02-11 13:45:50 -080060 const GrVertexBuffer* vertexBuffer;
61 int firstVertex;
62
63 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
64 kVertsPerCubic,
65 &vertexBuffer,
66 &firstVertex);
67
bsalomoned0bcad2015-05-04 10:36:42 -070068 if (!vertices || !indexBuffer) {
joshualitt4b31de82015-03-05 14:33:41 -080069 SkDebugf("Could not allocate buffers\n");
70 return;
71 }
72
joshualitt95964c62015-02-11 13:45:50 -080073 SkASSERT(vertexStride == sizeof(SkPoint));
74 SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
75
76 // Make sure any artifacts around the exterior of path are visible by using overly
77 // conservative bounding geometry.
78 fGeometry.fBounds.outset(5.f, 5.f);
79 fGeometry.fBounds.toQuad(verts);
80
81 GrDrawTarget::DrawInfo drawInfo;
82 drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
83 drawInfo.setVertexBuffer(vertexBuffer);
84 drawInfo.setStartVertex(firstVertex);
85 drawInfo.setVertexCount(kVertsPerCubic);
86 drawInfo.setStartIndex(0);
87 drawInfo.setIndexCount(kIndicesPerCubic);
bsalomoned0bcad2015-05-04 10:36:42 -070088 drawInfo.setIndexBuffer(indexBuffer);
joshualitt95964c62015-02-11 13:45:50 -080089 batchTarget->draw(drawInfo);
90 }
91
92 Geometry fGeometry;
93
94 static const int kVertsPerCubic = 4;
95 static const int kIndicesPerCubic = 6;
96
97 typedef GrTestBatch INHERITED;
98};
99
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000100/**
joshualittb0a8a372014-09-23 09:50:21 -0700101 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000102 */
103class ConvexPolyEffect : public GM {
104public:
105 ConvexPolyEffect() {
106 this->setBGColor(0xFFFFFFFF);
107 }
108
109protected:
mtklein36352bf2015-03-25 18:17:31 -0700110 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000111 return SkString("convex_poly_effect");
112 }
113
mtklein36352bf2015-03-25 18:17:31 -0700114 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700115 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000116 }
117
mtklein36352bf2015-03-25 18:17:31 -0700118 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000119 SkPath tri;
120 tri.moveTo(5.f, 5.f);
121 tri.lineTo(100.f, 20.f);
122 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000123
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000124 fPaths.addToTail(tri);
125 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000126
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000127 tri.close();
128 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000129
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000130 SkPath ngon;
131 static const SkScalar kRadius = 50.f;
132 const SkPoint center = { kRadius, kRadius };
133 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
134 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
135 SkPoint point;
136 point.fY = SkScalarSinCos(angle, &point.fX);
137 point.scale(kRadius);
138 point = center + point;
139 if (0 == i) {
140 ngon.moveTo(point);
141 } else {
142 ngon.lineTo(point);
143 }
144 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000145
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000146 fPaths.addToTail(ngon);
147 SkMatrix scaleM;
148 scaleM.setScale(1.1f, 0.4f);
149 ngon.transform(scaleM);
150 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000151
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000152 // integer edges
153 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
154 // half-integer edges
155 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
156 // vertically/horizontally thin rects that cover pixel centers
157 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
158 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
159 // vertically/horizontally thin rects that don't cover pixel centers
160 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
161 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
162 // small in x and y
163 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
164 // inverted in x and y
165 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000166 }
167
mtklein36352bf2015-03-25 18:17:31 -0700168 void onDraw(SkCanvas* canvas) override {
reed@google.com9c135db2014-03-12 18:28:35 +0000169 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000170 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800171 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000172 return;
173 }
174 GrContext* context = rt->getContext();
175 if (NULL == context) {
176 return;
177 }
178
joshualitt95964c62015-02-11 13:45:50 -0800179 SkAutoTUnref<const GrGeometryProcessor> gp(
180 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
181 0xff000000));
182
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000183 SkScalar y = 0;
184 for (SkTLList<SkPath>::Iter iter(fPaths, SkTLList<SkPath>::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) {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000191 GrTestTarget tt;
192 context->getTestTarget(&tt);
193 if (NULL == tt.target()) {
194 SkDEBUGFAIL("Couldn't get Gr test target.");
195 return;
196 }
robertphillips1d24b8d2015-03-26 19:57:08 -0700197 const SkMatrix m = SkMatrix::MakeTrans(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000198 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000199 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000200
joshualittb0a8a372014-09-23 09:50:21 -0700201 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
202 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, p));
203 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000204 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000205 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000206
egdaniel8dd688b2015-01-22 10:16:09 -0800207 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800208 pipelineBuilder.addCoverageProcessor(fp);
209 pipelineBuilder.setRenderTarget(rt);
joshualitt9853cce2014-11-17 14:22:48 -0800210
joshualitt95964c62015-02-11 13:45:50 -0800211 ConvexPolyTestBatch::Geometry geometry;
212 geometry.fColor = gp->color();
213 geometry.fBounds = p.getBounds();
joshualitt50408ad2014-11-03 12:31:14 -0800214
joshualitt95964c62015-02-11 13:45:50 -0800215 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000216
joshualitt99c7c072015-05-01 13:43:30 -0700217 tt.target()->drawBatch(&pipelineBuilder, batch);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000218
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000219 x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000220 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000221
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000222 // Draw AA and non AA paths using normal API for reference.
223 canvas->save();
224 canvas->translate(x, y);
225 SkPaint paint;
226 canvas->drawPath(*path, paint);
227 canvas->translate(path->getBounds().width() + 10.f, 0);
228 paint.setAntiAlias(true);
229 canvas->drawPath(*path, paint);
230 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000231
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000232 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
233 }
234
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000235 for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700236 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000237 iter.next()) {
238
239 SkScalar x = 0;
240
joshualittb0a8a372014-09-23 09:50:21 -0700241 for (int et = 0; et < kGrProcessorEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000242 GrTestTarget tt;
243 context->getTestTarget(&tt);
244 if (NULL == tt.target()) {
245 SkDEBUGFAIL("Couldn't get Gr test target.");
246 return;
247 }
248 SkRect rect = *iter.get();
249 rect.offset(x, y);
joshualittb0a8a372014-09-23 09:50:21 -0700250 GrPrimitiveEdgeType edgeType = (GrPrimitiveEdgeType) et;
251 SkAutoTUnref<GrFragmentProcessor> fp(GrConvexPolyEffect::Create(edgeType, rect));
252 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000253 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000254 }
255
egdaniel8dd688b2015-01-22 10:16:09 -0800256 GrPipelineBuilder pipelineBuilder;
egdaniel8dd688b2015-01-22 10:16:09 -0800257 pipelineBuilder.addCoverageProcessor(fp);
258 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000259
joshualitt95964c62015-02-11 13:45:50 -0800260 ConvexPolyTestBatch::Geometry geometry;
261 geometry.fColor = gp->color();
262 geometry.fBounds = rect;
joshualitt50408ad2014-11-03 12:31:14 -0800263
joshualitt95964c62015-02-11 13:45:50 -0800264 SkAutoTUnref<GrBatch> batch(ConvexPolyTestBatch::Create(gp, geometry));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000265
joshualitt99c7c072015-05-01 13:43:30 -0700266 tt.target()->drawBatch(&pipelineBuilder, batch);
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000267
268 x += SkScalarCeilToScalar(rect.width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000269 }
270
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000271 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000272 canvas->save();
273 canvas->translate(x, y);
274 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000275 canvas->drawRect(*iter.get(), paint);
276 x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000277 paint.setAntiAlias(true);
278 canvas->drawRect(*iter.get(), paint);
279 canvas->restore();
280
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000281 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000282 }
283 }
284
285private:
286 SkTLList<SkPath> fPaths;
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000287 SkTLList<SkRect> fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000288
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000289 typedef GM INHERITED;
290};
291
292DEF_GM( return SkNEW(ConvexPolyEffect); )
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000293}
294
295#endif