blob: eaa9a7d70733c5ae73d0c4615efd2dbe4d71ed41 [file] [log] [blame]
commit-bot@chromium.org78a10782013-08-21 19:27:48 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8// This test only works with the GPU backend.
9
10#include "gm.h"
Chris Dalton1d4af542018-04-16 14:23:00 -060011#include "sk_tool_utils.h"
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000012
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000013#include "GrContext.h"
Robert Phillips7c525e62018-06-12 10:11:12 -040014#include "GrMemoryPool.h"
Brian Salomon477d0ef2017-07-14 10:12:26 -040015#include "GrOpFlushState.h"
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000016#include "GrPathUtils.h"
Brian Salomon477d0ef2017-07-14 10:12:26 -040017#include "GrRenderTargetContextPriv.h"
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000018#include "SkColorPriv.h"
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000019#include "SkGeometry.h"
Cary Clarke4442cb2017-10-18 11:46:18 -040020#include "SkPoint3.h"
Cary Clark74f623d2017-11-06 20:02:02 -050021#include "SkPointPriv.h"
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000022#include "effects/GrBezierEffect.h"
Brian Salomon477d0ef2017-07-14 10:12:26 -040023#include "ops/GrMeshDrawOp.h"
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000024
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000025namespace skiagm {
joshualitt95964c62015-02-11 13:45:50 -080026
Brian Salomon477d0ef2017-07-14 10:12:26 -040027class BezierTestOp : public GrMeshDrawOp {
28public:
29 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
30
Chris Dalton4b62aed2019-01-15 11:53:00 -070031 GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
32 return fProcessorSet.finalize(fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip,
33 false, caps, &fColor);
Brian Salomon477d0ef2017-07-14 10:12:26 -040034 }
35
Brian Salomon7d94bb52018-10-12 14:37:19 -040036 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -040037 fProcessorSet.visitProxies(func);
38 }
39
Brian Salomon477d0ef2017-07-14 10:12:26 -040040protected:
Brian Osmancf860852018-10-31 14:04:39 -040041 BezierTestOp(sk_sp<const GrGeometryProcessor> gp, const SkRect& rect, const SkPMColor4f& color,
Brian Salomon7eae3e02018-08-07 14:02:38 +000042 int32_t classID)
Brian Salomon477d0ef2017-07-14 10:12:26 -040043 : INHERITED(classID)
44 , fRect(rect)
45 , fColor(color)
46 , fGeometryProcessor(std::move(gp))
47 , fProcessorSet(SkBlendMode::kSrc) {
48 this->setBounds(rect, HasAABloat::kYes, IsZeroArea::kNo);
49 }
50
Brian Salomon49348902018-06-26 09:12:38 -040051 Target::PipelineAndFixedDynamicState makePipeline(Target* target) {
Brian Salomonbfd18cd2017-08-09 16:27:09 -040052 return target->makePipeline(0, std::move(fProcessorSet), target->detachAppliedClip());
Brian Salomon477d0ef2017-07-14 10:12:26 -040053 }
54
Brian Salomon7eae3e02018-08-07 14:02:38 +000055 sk_sp<const GrGeometryProcessor> gp() const { return fGeometryProcessor; }
Brian Salomon477d0ef2017-07-14 10:12:26 -040056
57 const SkRect& rect() const { return fRect; }
Brian Osmancf860852018-10-31 14:04:39 -040058 const SkPMColor4f& color() const { return fColor; }
Brian Salomon477d0ef2017-07-14 10:12:26 -040059
60private:
Brian Salomon477d0ef2017-07-14 10:12:26 -040061 SkRect fRect;
Brian Osmancf860852018-10-31 14:04:39 -040062 SkPMColor4f fColor;
Brian Salomon7eae3e02018-08-07 14:02:38 +000063 sk_sp<const GrGeometryProcessor> fGeometryProcessor;
Brian Salomon477d0ef2017-07-14 10:12:26 -040064 GrProcessorSet fProcessorSet;
65
66 typedef GrMeshDrawOp INHERITED;
67};
68
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000069/**
70 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
71 */
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000072
Brian Salomon477d0ef2017-07-14 10:12:26 -040073class BezierConicTestOp : public BezierTestOp {
Chris Daltonfebbffa2017-06-08 13:12:02 -060074public:
75 DEFINE_OP_CLASS_ID
76
77 const char* name() const override { return "BezierConicTestOp"; }
78
Robert Phillips7c525e62018-06-12 10:11:12 -040079 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
Brian Salomon7eae3e02018-08-07 14:02:38 +000080 sk_sp<const GrGeometryProcessor> gp,
Robert Phillips7c525e62018-06-12 10:11:12 -040081 const SkRect& rect,
Brian Osmancf860852018-10-31 14:04:39 -040082 const SkPMColor4f& color,
Robert Phillips7c525e62018-06-12 10:11:12 -040083 const SkMatrix& klm) {
Robert Phillips9da87e02019-02-04 13:26:26 -050084 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040085
86 return pool->allocate<BezierConicTestOp>(std::move(gp), rect, color, klm);
Chris Daltonfebbffa2017-06-08 13:12:02 -060087 }
88
89private:
Robert Phillips7c525e62018-06-12 10:11:12 -040090 friend class ::GrOpMemoryPool; // for ctor
91
Brian Osman936fe7d2018-10-30 15:30:35 -040092 BezierConicTestOp(sk_sp<const GrGeometryProcessor> gp, const SkRect& rect,
Brian Osmancf860852018-10-31 14:04:39 -040093 const SkPMColor4f& color, const SkMatrix& klm)
Brian Salomon477d0ef2017-07-14 10:12:26 -040094 : INHERITED(std::move(gp), rect, color, ClassID()), fKLM(klm) {}
95
Chris Daltonfebbffa2017-06-08 13:12:02 -060096 struct Vertex {
97 SkPoint fPosition;
98 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
99 };
100
Brian Salomon91326c32017-08-09 16:02:19 -0400101 void onPrepareDraws(Target* target) override {
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500102 SkASSERT(this->gp()->vertexStride() == sizeof(Vertex));
Brian Salomon7eae3e02018-08-07 14:02:38 +0000103 QuadHelper helper(target, sizeof(Vertex), 1);
104 Vertex* verts = reinterpret_cast<Vertex*>(helper.vertices());
Chris Daltonfebbffa2017-06-08 13:12:02 -0600105 if (!verts) {
106 return;
107 }
Brian Salomon477d0ef2017-07-14 10:12:26 -0400108 SkRect rect = this->rect();
Cary Clark74f623d2017-11-06 20:02:02 -0500109 SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect.fLeft, rect.fTop, rect.fRight,
110 rect.fBottom, sizeof(Vertex));
Chris Daltonfebbffa2017-06-08 13:12:02 -0600111 for (int v = 0; v < 4; ++v) {
Cary Clarke4442cb2017-10-18 11:46:18 -0400112 SkPoint3 pt3 = {verts[v].fPosition.x(), verts[v].fPosition.y(), 1.f};
113 fKLM.mapHomogeneousPoints((SkPoint3* ) verts[v].fKLM, &pt3, 1);
Chris Daltonfebbffa2017-06-08 13:12:02 -0600114 }
Brian Salomon49348902018-06-26 09:12:38 -0400115 auto pipe = this->makePipeline(target);
116 helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState);
Chris Daltonfebbffa2017-06-08 13:12:02 -0600117 }
118
119 SkMatrix fKLM;
Chris Daltonfebbffa2017-06-08 13:12:02 -0600120
121 static constexpr int kVertsPerCubic = 4;
122 static constexpr int kIndicesPerCubic = 6;
123
Brian Salomon477d0ef2017-07-14 10:12:26 -0400124 typedef BezierTestOp INHERITED;
Chris Daltonfebbffa2017-06-08 13:12:02 -0600125};
126
127
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000128/**
129 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
130 */
Chris Dalton382b1222019-02-07 10:05:55 +0000131class BezierConicEffects : public GM {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000132public:
133 BezierConicEffects() {
134 this->setBGColor(0xFFFFFFFF);
135 }
136
137protected:
mtklein36352bf2015-03-25 18:17:31 -0700138 SkString onShortName() override {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000139 return SkString("bezier_conic_effects");
140 }
141
mtklein36352bf2015-03-25 18:17:31 -0700142 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700143 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000144 }
145
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000146
Chris Dalton382b1222019-02-07 10:05:55 +0000147 void onDraw(SkCanvas* canvas) override {
148 GrRenderTargetContext* renderTargetContext =
149 canvas->internal_private_accessTopLayerRenderTargetContext();
150 if (!renderTargetContext) {
151 skiagm::GM::DrawGpuOnlyMessage(canvas);
152 return;
153 }
154
155 GrContext* context = canvas->getGrContext();
156 if (!context) {
157 return;
158 }
159
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000160 struct Vertex {
161 SkPoint fPosition;
162 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
163 };
164
mtkleindbfd7ab2016-09-01 11:24:54 -0700165 constexpr int kNumConics = 10;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000166 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000167
168 // Mult by 3 for each edge effect type
169 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3)));
170 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
Brian Osman11052242016-10-27 14:47:55 -0400171 SkScalar w = SkIntToScalar(renderTargetContext->width()) / numCols;
172 SkScalar h = SkIntToScalar(renderTargetContext->height()) / numRows;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000173 int row = 0;
174 int col = 0;
Brian Osmancf860852018-10-31 14:04:39 -0400175 SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(0xff000000);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000176
177 for (int i = 0; i < kNumConics; ++i) {
178 SkPoint baseControlPts[] = {
179 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
180 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
181 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
182 };
183 SkScalar weight = rand.nextRangeF(0.f, 2.f);
Ethan Nicholas1706f842017-11-10 11:58:19 -0500184 for(int edgeType = 0; edgeType < kGrClipEdgeTypeCnt; ++edgeType) {
bungeman06ca8ec2016-06-09 08:01:03 -0700185 sk_sp<GrGeometryProcessor> gp;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500186 GrClipEdgeType et = (GrClipEdgeType)edgeType;
Robert Phillips9da87e02019-02-04 13:26:26 -0500187 gp = GrConicEffect::Make(color, SkMatrix::I(), et, *context->priv().caps(),
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400188 SkMatrix::I(), false);
joshualittf5883a62016-01-13 07:47:38 -0800189 if (!gp) {
190 continue;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000191 }
192
Mike Reeddf85c382017-02-14 10:59:19 -0500193 SkScalar x = col * w;
194 SkScalar y = row * h;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000195 SkPoint controlPts[] = {
196 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
197 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
198 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
199 };
200 SkConic dst[4];
csmartdaltoncc261272017-03-23 13:38:45 -0600201 SkMatrix klm;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000202 int cnt = chop_conic(controlPts, dst, weight);
csmartdaltoncc261272017-03-23 13:38:45 -0600203 GrPathUtils::getConicKLM(controlPts, weight, &klm);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000204
205 SkPaint ctrlPtPaint;
206 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
207 for (int i = 0; i < 3; ++i) {
Hal Canary23e474c2017-05-15 13:35:35 -0400208 canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000209 }
210
211 SkPaint polyPaint;
212 polyPaint.setColor(0xffA0A0A0);
213 polyPaint.setStrokeWidth(0);
214 polyPaint.setStyle(SkPaint::kStroke_Style);
215 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
216
217 SkPaint choppedPtPaint;
218 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
219
220 for (int c = 0; c < cnt; ++c) {
221 SkPoint* pts = dst[c].fPts;
222 for (int i = 0; i < 3; ++i) {
Hal Canary23e474c2017-05-15 13:35:35 -0400223 canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000224 }
225
226 SkRect bounds;
227 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
228 //bounds.set(bPts, 2);
229 bounds.set(pts, 3);
230
231 SkPaint boundsPaint;
232 boundsPaint.setColor(0xff808080);
233 boundsPaint.setStrokeWidth(0);
234 boundsPaint.setStyle(SkPaint::kStroke_Style);
235 canvas->drawRect(bounds, boundsPaint);
236
Robert Phillips7c525e62018-06-12 10:11:12 -0400237 std::unique_ptr<GrDrawOp> op = BezierConicTestOp::Make(context, gp, bounds,
238 color, klm);
Brian Salomon477d0ef2017-07-14 10:12:26 -0400239 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000240 }
241 ++col;
242 if (numCols == col) {
243 col = 0;
244 ++row;
245 }
246 }
247 }
248 }
249
250private:
251 // Uses the max curvature function for quads to estimate
252 // where to chop the conic. If the max curvature is not
253 // found along the curve segment it will return 1 and
254 // dst[0] is the original conic. If it returns 2 the dst[0]
255 // and dst[1] are the two new conics.
256 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
257 SkScalar t = SkFindQuadMaxCurvature(src);
Chris Dalton1d474dd2018-07-24 01:08:31 -0600258 if (t == 0 || t == 1) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000259 if (dst) {
260 dst[0].set(src, weight);
261 }
262 return 1;
263 } else {
264 if (dst) {
265 SkConic conic;
266 conic.set(src, weight);
caryclark414c4292016-09-26 11:03:54 -0700267 if (!conic.chopAt(t, dst)) {
268 dst[0].set(src, weight);
269 return 1;
270 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000271 }
272 return 2;
273 }
274 }
275
276 // Calls split_conic on the entire conic and then once more on each subsection.
277 // Most cases will result in either 1 conic (chop point is not within t range)
278 // or 3 points (split once and then one subsection is split again).
279 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
280 SkConic dstTemp[2];
281 int conicCnt = split_conic(src, dstTemp, weight);
282 if (2 == conicCnt) {
283 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
284 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
285 } else {
286 dst[0] = dstTemp[0];
287 }
288 return conicCnt;
289 }
290
291 typedef GM INHERITED;
292};
293
294//////////////////////////////////////////////////////////////////////////////
joshualitt95964c62015-02-11 13:45:50 -0800295
Brian Salomon477d0ef2017-07-14 10:12:26 -0400296class BezierQuadTestOp : public BezierTestOp {
joshualitt95964c62015-02-11 13:45:50 -0800297public:
Brian Salomon25a88092016-12-01 09:36:50 -0500298 DEFINE_OP_CLASS_ID
Brian Salomon6b316e92016-12-16 09:35:49 -0500299 const char* name() const override { return "BezierQuadTestOp"; }
joshualitt95964c62015-02-11 13:45:50 -0800300
Robert Phillips7c525e62018-06-12 10:11:12 -0400301 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
Brian Salomon7eae3e02018-08-07 14:02:38 +0000302 sk_sp<const GrGeometryProcessor> gp,
Robert Phillips7c525e62018-06-12 10:11:12 -0400303 const SkRect& rect,
Brian Osmancf860852018-10-31 14:04:39 -0400304 const SkPMColor4f& color,
Robert Phillips7c525e62018-06-12 10:11:12 -0400305 const GrPathUtils::QuadUVMatrix& devToUV) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500306 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400307
308 return pool->allocate<BezierQuadTestOp>(std::move(gp), rect, color, devToUV);
joshualitt95964c62015-02-11 13:45:50 -0800309 }
310
311private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400312 friend class ::GrOpMemoryPool; // for ctor
313
Brian Osman936fe7d2018-10-30 15:30:35 -0400314 BezierQuadTestOp(sk_sp<const GrGeometryProcessor> gp, const SkRect& rect,
Brian Osmancf860852018-10-31 14:04:39 -0400315 const SkPMColor4f& color, const GrPathUtils::QuadUVMatrix& devToUV)
Brian Salomon477d0ef2017-07-14 10:12:26 -0400316 : INHERITED(std::move(gp), rect, color, ClassID()), fDevToUV(devToUV) {}
joshualitt95964c62015-02-11 13:45:50 -0800317
318 struct Vertex {
319 SkPoint fPosition;
320 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
321 };
322
Brian Salomon91326c32017-08-09 16:02:19 -0400323 void onPrepareDraws(Target* target) override {
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500324 SkASSERT(this->gp()->vertexStride() == sizeof(Vertex));
Brian Salomon7eae3e02018-08-07 14:02:38 +0000325 QuadHelper helper(target, sizeof(Vertex), 1);
326 Vertex* verts = reinterpret_cast<Vertex*>(helper.vertices());
bsalomonb5238a72015-05-05 07:49:49 -0700327 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -0800328 return;
329 }
Brian Salomon477d0ef2017-07-14 10:12:26 -0400330 SkRect rect = this->rect();
Brian Salomonec42e152018-05-18 12:52:22 -0400331 SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect, sizeof(Vertex));
Brian Osman568bec72018-12-26 16:48:25 -0500332 fDevToUV.apply(verts, 4, sizeof(Vertex), sizeof(SkPoint));
Brian Salomon49348902018-06-26 09:12:38 -0400333 auto pipe = this->makePipeline(target);
334 helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState);
joshualitt95964c62015-02-11 13:45:50 -0800335 }
336
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500337 GrPathUtils::QuadUVMatrix fDevToUV;
joshualitt95964c62015-02-11 13:45:50 -0800338
mtkleindbfd7ab2016-09-01 11:24:54 -0700339 static constexpr int kVertsPerCubic = 4;
340 static constexpr int kIndicesPerCubic = 6;
joshualitt95964c62015-02-11 13:45:50 -0800341
Brian Salomon477d0ef2017-07-14 10:12:26 -0400342 typedef BezierTestOp INHERITED;
joshualitt95964c62015-02-11 13:45:50 -0800343};
344
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000345/**
346 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
347 */
Chris Dalton382b1222019-02-07 10:05:55 +0000348class BezierQuadEffects : public GM {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000349public:
350 BezierQuadEffects() {
351 this->setBGColor(0xFFFFFFFF);
352 }
353
354protected:
mtklein36352bf2015-03-25 18:17:31 -0700355 SkString onShortName() override {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000356 return SkString("bezier_quad_effects");
357 }
358
mtklein36352bf2015-03-25 18:17:31 -0700359 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700360 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000361 }
362
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000363
Chris Dalton382b1222019-02-07 10:05:55 +0000364 void onDraw(SkCanvas* canvas) override {
365 GrRenderTargetContext* renderTargetContext =
366 canvas->internal_private_accessTopLayerRenderTargetContext();
367 if (!renderTargetContext) {
368 skiagm::GM::DrawGpuOnlyMessage(canvas);
369 return;
370 }
371
372 GrContext* context = canvas->getGrContext();
373 if (!context) {
374 return;
375 }
376
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000377 struct Vertex {
378 SkPoint fPosition;
379 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
380 };
381
mtkleindbfd7ab2016-09-01 11:24:54 -0700382 constexpr int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000383 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000384
385 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
386 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
Brian Osman11052242016-10-27 14:47:55 -0400387 SkScalar w = SkIntToScalar(renderTargetContext->width()) / numCols;
388 SkScalar h = SkIntToScalar(renderTargetContext->height()) / numRows;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000389 int row = 0;
390 int col = 0;
Brian Osmancf860852018-10-31 14:04:39 -0400391 SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(0xff000000);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000392
393 for (int i = 0; i < kNumQuads; ++i) {
394 SkPoint baseControlPts[] = {
395 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
396 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
397 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
398 };
Ethan Nicholas1706f842017-11-10 11:58:19 -0500399 for(int edgeType = 0; edgeType < kGrClipEdgeTypeCnt; ++edgeType) {
bungeman06ca8ec2016-06-09 08:01:03 -0700400 sk_sp<GrGeometryProcessor> gp;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500401 GrClipEdgeType et = (GrClipEdgeType)edgeType;
Robert Phillips9da87e02019-02-04 13:26:26 -0500402 gp = GrQuadEffect::Make(color, SkMatrix::I(), et, *context->priv().caps(),
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400403 SkMatrix::I(), false);
joshualittf5883a62016-01-13 07:47:38 -0800404 if (!gp) {
405 continue;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000406 }
407
Mike Reeddf85c382017-02-14 10:59:19 -0500408 SkScalar x = col * w;
409 SkScalar y = row * h;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000410 SkPoint controlPts[] = {
411 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
412 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
413 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
414 };
415 SkPoint chopped[5];
416 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
417
418 SkPaint ctrlPtPaint;
419 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
420 for (int i = 0; i < 3; ++i) {
Hal Canary23e474c2017-05-15 13:35:35 -0400421 canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000422 }
423
424 SkPaint polyPaint;
425 polyPaint.setColor(0xffA0A0A0);
426 polyPaint.setStrokeWidth(0);
427 polyPaint.setStyle(SkPaint::kStroke_Style);
428 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
429
430 SkPaint choppedPtPaint;
431 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
432
433 for (int c = 0; c < cnt; ++c) {
434 SkPoint* pts = chopped + 2 * c;
435
436 for (int i = 0; i < 3; ++i) {
Hal Canary23e474c2017-05-15 13:35:35 -0400437 canvas->drawCircle(pts[i], 3.f, choppedPtPaint);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000438 }
439
440 SkRect bounds;
441 bounds.set(pts, 3);
442
443 SkPaint boundsPaint;
444 boundsPaint.setColor(0xff808080);
445 boundsPaint.setStrokeWidth(0);
446 boundsPaint.setStyle(SkPaint::kStroke_Style);
447 canvas->drawRect(bounds, boundsPaint);
448
robertphillips28a838e2016-06-23 14:07:00 -0700449 GrPaint grPaint;
Brian Salomona1633922017-01-09 11:46:10 -0500450 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
joshualitt3f284d72015-02-11 11:34:58 -0800451
joshualitt95964c62015-02-11 13:45:50 -0800452 GrPathUtils::QuadUVMatrix DevToUV(pts);
453
Robert Phillips7c525e62018-06-12 10:11:12 -0400454 std::unique_ptr<GrDrawOp> op = BezierQuadTestOp::Make(context, gp,
455 bounds, color, DevToUV);
Brian Salomon477d0ef2017-07-14 10:12:26 -0400456 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000457 }
458 ++col;
459 if (numCols == col) {
460 col = 0;
461 ++row;
462 }
463 }
464 }
465 }
466
467private:
468 typedef GM INHERITED;
469};
470
halcanary385fe4d2015-08-26 13:07:48 -0700471DEF_GM(return new BezierConicEffects;)
472DEF_GM(return new BezierQuadEffects;)
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000473}