blob: 0ea5a5fa5eb706e45e97c1b886a23d92fc83e121 [file] [log] [blame]
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +00001/*
2 * Copyright 2014 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"
11
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000012#include "GrContext.h"
joshualitt5478d422014-11-14 16:00:38 -080013#include "GrDefaultGeoProcFactory.h"
Robert Phillips7c525e62018-06-12 10:11:12 -040014#include "GrMemoryPool.h"
Brian Salomon576eda12017-07-14 11:30:17 -040015#include "GrOpFlushState.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000016#include "GrPathUtils.h"
Robert Phillipsbe9aff22019-02-15 11:33:22 -050017#include "GrRecordingContext.h"
18#include "GrRecordingContextPriv.h"
Brian Salomon576eda12017-07-14 11:30:17 -040019#include "GrRenderTargetContextPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000020#include "SkColorPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000021#include "SkGeometry.h"
Cary Clark74f623d2017-11-06 20:02:02 -050022#include "SkPointPriv.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000023#include "SkTLList.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000024#include "effects/GrConvexPolyEffect.h"
Brian Salomon576eda12017-07-14 11:30:17 -040025#include "ops/GrMeshDrawOp.h"
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000026
bsalomon342bfc22016-04-01 06:06:20 -070027/** outset rendered rect to visualize anti-aliased poly edges */
28static SkRect outset(const SkRect& unsorted) {
29 SkRect r = unsorted;
30 r.outset(5.f, 5.f);
31 return r;
32}
joshualitt95964c62015-02-11 13:45:50 -080033
bsalomon342bfc22016-04-01 06:06:20 -070034/** sorts a rect */
35static SkRect sorted_rect(const SkRect& unsorted) {
36 SkRect r = unsorted;
37 r.sort();
38 return r;
39}
40
41namespace skiagm {
Brian Salomon576eda12017-07-14 11:30:17 -040042class PolyBoundsOp : public GrMeshDrawOp {
joshualitt95964c62015-02-11 13:45:50 -080043public:
Brian Salomon25a88092016-12-01 09:36:50 -050044 DEFINE_OP_CLASS_ID
joshualitt95964c62015-02-11 13:45:50 -080045
Robert Phillipsbe9aff22019-02-15 11:33:22 -050046 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips7c525e62018-06-12 10:11:12 -040047 GrPaint&& paint,
48 const SkRect& rect) {
Robert Phillips9da87e02019-02-04 13:26:26 -050049 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040050
51 return pool->allocate<PolyBoundsOp>(std::move(paint), rect);
Brian Salomon576eda12017-07-14 11:30:17 -040052 }
53
Robert Phillipsb493eeb2017-09-13 13:10:52 -040054 const char* name() const override { return "PolyBoundsOp"; }
55
Brian Salomon7d94bb52018-10-12 14:37:19 -040056 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillipsb493eeb2017-09-13 13:10:52 -040057 fProcessors.visitProxies(func);
58 }
59
Brian Salomon576eda12017-07-14 11:30:17 -040060 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
61
Brian Osman5ced0bf2019-03-15 10:15:29 -040062 GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
63 GrFSAAType fsaaType, GrClampType clampType) override {
Chris Daltonb8fff0d2019-03-05 10:11:58 -070064 return fProcessors.finalize(
65 fColor, GrProcessorAnalysisCoverage::kNone, clip, &GrUserStencilSettings::kUnused,
Brian Osman5ced0bf2019-03-15 10:15:29 -040066 fsaaType, caps, clampType, &fColor);
joshualitt95964c62015-02-11 13:45:50 -080067 }
68
69private:
Robert Phillips7c525e62018-06-12 10:11:12 -040070 friend class ::GrOpMemoryPool; // for ctor
71
Brian Salomon576eda12017-07-14 11:30:17 -040072 PolyBoundsOp(GrPaint&& paint, const SkRect& rect)
73 : INHERITED(ClassID())
Brian Osmancf860852018-10-31 14:04:39 -040074 , fColor(paint.getColor4f())
Brian Salomon576eda12017-07-14 11:30:17 -040075 , fProcessors(std::move(paint))
76 , fRect(outset(rect)) {
77 this->setBounds(sorted_rect(fRect), HasAABloat::kNo, IsZeroArea::kNo);
78 }
Brian Salomon6b316e92016-12-16 09:35:49 -050079
Brian Salomon91326c32017-08-09 16:02:19 -040080 void onPrepareDraws(Target* target) override {
bsalomon342bfc22016-04-01 06:06:20 -070081 using namespace GrDefaultGeoProcFactory;
joshualitt95964c62015-02-11 13:45:50 -080082
Brian Salomon576eda12017-07-14 11:30:17 -040083 Color color(fColor);
Brian Salomon8c852be2017-01-04 10:44:42 -050084 sk_sp<GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Make(
Ruiqi Maob609e6d2018-07-17 10:19:38 -040085 target->caps().shaderCaps(),
86 color,
87 Coverage::kSolid_Type,
88 LocalCoords::kUnused_Type,
89 SkMatrix::I()));
joshualitt95964c62015-02-11 13:45:50 -080090
Brian Osmanf04fb3c2018-11-12 15:34:00 -050091 SkASSERT(gp->vertexStride() == sizeof(SkPoint));
Brian Salomon7eae3e02018-08-07 14:02:38 +000092 QuadHelper helper(target, sizeof(SkPoint), 1);
93 SkPoint* verts = reinterpret_cast<SkPoint*>(helper.vertices());
bsalomonb5238a72015-05-05 07:49:49 -070094 if (!verts) {
joshualitt4b31de82015-03-05 14:33:41 -080095 return;
96 }
97
Brian Salomonec42e152018-05-18 12:52:22 -040098 SkPointPriv::SetRectTriStrip(verts, fRect, sizeof(SkPoint));
Chris Dalton07cdcfc92019-02-26 11:13:22 -070099 helper.recordDraw(target, std::move(gp));
100 }
joshualitt95964c62015-02-11 13:45:50 -0800101
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700102 void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
103 flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, std::move(fProcessors));
joshualitt95964c62015-02-11 13:45:50 -0800104 }
105
Brian Osmancf860852018-10-31 14:04:39 -0400106 SkPMColor4f fColor;
Brian Salomon576eda12017-07-14 11:30:17 -0400107 GrProcessorSet fProcessors;
bsalomon342bfc22016-04-01 06:06:20 -0700108 SkRect fRect;
joshualitt95964c62015-02-11 13:45:50 -0800109
Brian Salomon576eda12017-07-14 11:30:17 -0400110 typedef GrMeshDrawOp INHERITED;
joshualitt95964c62015-02-11 13:45:50 -0800111};
112
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000113/**
joshualittb0a8a372014-09-23 09:50:21 -0700114 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000115 */
Chris Dalton3a778372019-02-07 15:23:36 -0700116class ConvexPolyEffect : public GpuGM {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000117public:
118 ConvexPolyEffect() {
119 this->setBGColor(0xFFFFFFFF);
120 }
121
122protected:
mtklein36352bf2015-03-25 18:17:31 -0700123 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000124 return SkString("convex_poly_effect");
125 }
126
mtklein36352bf2015-03-25 18:17:31 -0700127 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -0700128 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000129 }
130
mtklein36352bf2015-03-25 18:17:31 -0700131 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000132 SkPath tri;
133 tri.moveTo(5.f, 5.f);
134 tri.lineTo(100.f, 20.f);
135 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000136
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000137 fPaths.addToTail(tri);
138 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000139
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000140 tri.close();
141 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000142
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000143 SkPath ngon;
mtkleindbfd7ab2016-09-01 11:24:54 -0700144 constexpr SkScalar kRadius = 50.f;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000145 const SkPoint center = { kRadius, kRadius };
146 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
147 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
148 SkPoint point;
149 point.fY = SkScalarSinCos(angle, &point.fX);
150 point.scale(kRadius);
151 point = center + point;
152 if (0 == i) {
153 ngon.moveTo(point);
154 } else {
155 ngon.lineTo(point);
156 }
157 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000158
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000159 fPaths.addToTail(ngon);
160 SkMatrix scaleM;
161 scaleM.setScale(1.1f, 0.4f);
162 ngon.transform(scaleM);
163 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000164
bsalomon7888de02016-03-28 15:04:45 -0700165 SkPath linePath;
166 linePath.moveTo(5.f, 5.f);
167 linePath.lineTo(6.f, 6.f);
168 fPaths.addToTail(linePath);
169
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000170 // integer edges
171 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
172 // half-integer edges
173 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
174 // vertically/horizontally thin rects that cover pixel centers
175 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
176 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
177 // vertically/horizontally thin rects that don't cover pixel centers
178 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
179 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
180 // small in x and y
181 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
182 // inverted in x and y
183 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000184 }
185
Chris Dalton3a778372019-02-07 15:23:36 -0700186 void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
187 SkCanvas* canvas) override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000188 SkScalar y = 0;
mtkleindbfd7ab2016-09-01 11:24:54 -0700189 constexpr SkScalar kDX = 12.f;
bsalomonf045d602015-11-18 19:01:12 -0800190 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700191 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000192 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000193 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000194 SkScalar x = 0;
195
Ethan Nicholas1706f842017-11-10 11:58:19 -0500196 for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
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
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500201 GrClipEdgeType edgeType = (GrClipEdgeType) et;
Ethan Nicholaseace9352018-10-15 20:09:54 +0000202 std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, p));
joshualittb0a8a372014-09-23 09:50:21 -0700203 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
robertphillips28a838e2016-06-23 14:07:00 -0700207 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -0400208 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomona1633922017-01-09 11:46:10 -0500209 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700210 grPaint.addCoverageFragmentProcessor(std::move(fp));
joshualitt9853cce2014-11-17 14:22:48 -0800211
Brian Salomon576eda12017-07-14 11:30:17 -0400212 std::unique_ptr<GrDrawOp> op =
Robert Phillips7c525e62018-06-12 10:11:12 -0400213 PolyBoundsOp::Make(context, std::move(grPaint), p.getBounds());
Brian Salomon576eda12017-07-14 11:30:17 -0400214 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
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
Ethan Nicholas1706f842017-11-10 11:58:19 -0500238 for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000239 SkRect rect = *iter.get();
240 rect.offset(x, y);
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500241 GrClipEdgeType edgeType = (GrClipEdgeType) et;
Ethan Nicholaseace9352018-10-15 20:09:54 +0000242 std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, rect));
joshualittb0a8a372014-09-23 09:50:21 -0700243 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000244 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000245 }
246
robertphillips28a838e2016-06-23 14:07:00 -0700247 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -0400248 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomona1633922017-01-09 11:46:10 -0500249 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700250 grPaint.addCoverageFragmentProcessor(std::move(fp));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000251
Robert Phillips7c525e62018-06-12 10:11:12 -0400252 std::unique_ptr<GrDrawOp> op = PolyBoundsOp::Make(context, std::move(grPaint),
253 rect);
Brian Salomon576eda12017-07-14 11:30:17 -0400254 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000255
bsalomon7888de02016-03-28 15:04:45 -0700256 x += SkScalarCeilToScalar(rect.width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000257 }
258
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000259 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000260 canvas->save();
261 canvas->translate(x, y);
262 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000263 canvas->drawRect(*iter.get(), paint);
bsalomon7888de02016-03-28 15:04:45 -0700264 x += SkScalarCeilToScalar(iter.get()->width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000265 paint.setAntiAlias(true);
266 canvas->drawRect(*iter.get(), paint);
267 canvas->restore();
268
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000269 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000270 }
271 }
272
273private:
bsalomonf045d602015-11-18 19:01:12 -0800274 typedef SkTLList<SkPath, 1> PathList;
275 typedef SkTLList<SkRect, 1> RectList;
276 PathList fPaths;
277 RectList fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000278
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000279 typedef GM INHERITED;
280};
281
halcanary385fe4d2015-08-26 13:07:48 -0700282DEF_GM(return new ConvexPolyEffect;)
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000283}