blob: bf61924c9ccf282d0188a4c6a2236c830985272a [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "gm/gm.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040011#include "include/core/SkBlendMode.h"
12#include "include/core/SkCanvas.h"
13#include "include/core/SkMatrix.h"
14#include "include/core/SkPaint.h"
15#include "include/core/SkPath.h"
16#include "include/core/SkPoint.h"
17#include "include/core/SkRect.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040018#include "include/core/SkScalar.h"
19#include "include/core/SkSize.h"
20#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "include/gpu/GrContext.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040022#include "include/private/GrSharedEnums.h"
23#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/core/SkTLList.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040025#include "src/gpu/GrFragmentProcessor.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040026#include "src/gpu/GrPaint.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040027#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "src/gpu/GrRenderTargetContextPriv.h"
29#include "src/gpu/effects/GrConvexPolyEffect.h"
Brian Salomone21af502019-11-22 16:56:36 -050030#include "tools/gpu/TestOps.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040031
32#include <memory>
33#include <utility>
34
35class GrAppliedClip;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000036
bsalomon342bfc22016-04-01 06:06:20 -070037namespace skiagm {
joshualitt95964c62015-02-11 13:45:50 -080038
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000039/**
joshualittb0a8a372014-09-23 09:50:21 -070040 * This GM directly exercises a GrProcessor that draws convex polygons.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000041 */
Chris Dalton3a778372019-02-07 15:23:36 -070042class ConvexPolyEffect : public GpuGM {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000043public:
44 ConvexPolyEffect() {
45 this->setBGColor(0xFFFFFFFF);
46 }
47
48protected:
mtklein36352bf2015-03-25 18:17:31 -070049 SkString onShortName() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000050 return SkString("convex_poly_effect");
51 }
52
mtklein36352bf2015-03-25 18:17:31 -070053 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070054 return SkISize::Make(720, 800);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000055 }
56
mtklein36352bf2015-03-25 18:17:31 -070057 void onOnceBeforeDraw() override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000058 SkPath tri;
59 tri.moveTo(5.f, 5.f);
60 tri.lineTo(100.f, 20.f);
61 tri.lineTo(15.f, 100.f);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000062
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000063 fPaths.addToTail(tri);
64 fPaths.addToTail(SkPath())->reverseAddPath(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000065
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000066 tri.close();
67 fPaths.addToTail(tri);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000068
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000069 SkPath ngon;
mtkleindbfd7ab2016-09-01 11:24:54 -070070 constexpr SkScalar kRadius = 50.f;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000071 const SkPoint center = { kRadius, kRadius };
72 for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) {
73 SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges;
Brian Osman4428f2c2019-04-02 10:59:28 -040074 SkPoint point = { SkScalarCos(angle), SkScalarSin(angle) };
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000075 point.scale(kRadius);
76 point = center + point;
77 if (0 == i) {
78 ngon.moveTo(point);
79 } else {
80 ngon.lineTo(point);
81 }
82 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +000083
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000084 fPaths.addToTail(ngon);
85 SkMatrix scaleM;
86 scaleM.setScale(1.1f, 0.4f);
87 ngon.transform(scaleM);
88 fPaths.addToTail(ngon);
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +000089
bsalomon7888de02016-03-28 15:04:45 -070090 SkPath linePath;
91 linePath.moveTo(5.f, 5.f);
92 linePath.lineTo(6.f, 6.f);
93 fPaths.addToTail(linePath);
94
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +000095 // integer edges
96 fRects.addToTail(SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f));
97 // half-integer edges
98 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f));
99 // vertically/horizontally thin rects that cover pixel centers
100 fRects.addToTail(SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f));
101 fRects.addToTail(SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 0.75f));
102 // vertically/horizontally thin rects that don't cover pixel centers
103 fRects.addToTail(SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f));
104 fRects.addToTail(SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f));
105 // small in x and y
106 fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
107 // inverted in x and y
108 fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000109 }
110
Chris Dalton3a778372019-02-07 15:23:36 -0700111 void onDraw(GrContext* context, GrRenderTargetContext* renderTargetContext,
112 SkCanvas* canvas) override {
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000113 SkScalar y = 0;
Brian Salomone21af502019-11-22 16:56:36 -0500114 static constexpr SkScalar kDX = 12.f;
115 static constexpr SkScalar kOutset = 5.f;
116
bsalomonf045d602015-11-18 19:01:12 -0800117 for (PathList::Iter iter(fPaths, PathList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700118 iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000119 iter.next()) {
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000120 const SkPath* path = iter.get();
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000121 SkScalar x = 0;
122
Ethan Nicholas1706f842017-11-10 11:58:19 -0500123 for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
Mike Reed1f607332020-05-21 12:11:27 -0400124 const SkMatrix m = SkMatrix::Translate(x, y);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000125 SkPath p;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000126 path->transform(m, &p);
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000127
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500128 GrClipEdgeType edgeType = (GrClipEdgeType) et;
John Stilesec9269b2020-06-15 16:05:14 -0400129 std::unique_ptr<GrFragmentProcessor> fp =
130 GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, p);
joshualittb0a8a372014-09-23 09:50:21 -0700131 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000132 continue;
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000133 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000134
robertphillips28a838e2016-06-23 14:07:00 -0700135 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -0400136 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomona1633922017-01-09 11:46:10 -0500137 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700138 grPaint.addCoverageFragmentProcessor(std::move(fp));
joshualitt9853cce2014-11-17 14:22:48 -0800139
Brian Salomone21af502019-11-22 16:56:36 -0500140 auto rect = p.getBounds().makeOutset(kOutset, kOutset);
141 auto op = sk_gpu_test::test_ops::MakeRect(context, std::move(grPaint), rect);
Brian Salomon576eda12017-07-14 11:30:17 -0400142 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000143
bsalomon7888de02016-03-28 15:04:45 -0700144 x += SkScalarCeilToScalar(path->getBounds().width() + kDX);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000145 }
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000146
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000147 // Draw AA and non AA paths using normal API for reference.
148 canvas->save();
149 canvas->translate(x, y);
150 SkPaint paint;
151 canvas->drawPath(*path, paint);
152 canvas->translate(path->getBounds().width() + 10.f, 0);
153 paint.setAntiAlias(true);
154 canvas->drawPath(*path, paint);
155 canvas->restore();
skia.committer@gmail.com4c18e9f2014-01-31 03:01:59 +0000156
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000157 y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
158 }
159
bsalomonf045d602015-11-18 19:01:12 -0800160 for (RectList::Iter iter(fRects, RectList::Iter::kHead_IterStart);
bsalomon49f085d2014-09-05 13:34:00 -0700161 iter.get();
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000162 iter.next()) {
163
164 SkScalar x = 0;
165
Ethan Nicholas1706f842017-11-10 11:58:19 -0500166 for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
Brian Salomone21af502019-11-22 16:56:36 -0500167 SkRect rect = iter.get()->makeOffset(x, y);
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500168 GrClipEdgeType edgeType = (GrClipEdgeType) et;
John Stilesec9269b2020-06-15 16:05:14 -0400169 std::unique_ptr<GrFragmentProcessor> fp =
170 GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, rect);
joshualittb0a8a372014-09-23 09:50:21 -0700171 if (!fp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000172 continue;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000173 }
174
robertphillips28a838e2016-06-23 14:07:00 -0700175 GrPaint grPaint;
Brian Osmancb3d0872018-10-16 15:19:28 -0400176 grPaint.setColor4f({ 0, 0, 0, 1.f });
Brian Salomona1633922017-01-09 11:46:10 -0500177 grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips28a838e2016-06-23 14:07:00 -0700178 grPaint.addCoverageFragmentProcessor(std::move(fp));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000179
Brian Salomone21af502019-11-22 16:56:36 -0500180 auto drawRect = rect.makeOutset(kOutset, kOutset);
181 auto op = sk_gpu_test::test_ops::MakeRect(context, std::move(grPaint), drawRect);
182
Brian Salomon576eda12017-07-14 11:30:17 -0400183 renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000184
bsalomon7888de02016-03-28 15:04:45 -0700185 x += SkScalarCeilToScalar(rect.width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000186 }
187
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000188 // Draw rect without and with AA using normal API for reference
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000189 canvas->save();
190 canvas->translate(x, y);
191 SkPaint paint;
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000192 canvas->drawRect(*iter.get(), paint);
bsalomon7888de02016-03-28 15:04:45 -0700193 x += SkScalarCeilToScalar(iter.get()->width() + kDX);
commit-bot@chromium.orgf0539802014-02-08 19:31:05 +0000194 paint.setAntiAlias(true);
195 canvas->drawRect(*iter.get(), paint);
196 canvas->restore();
197
commit-bot@chromium.orgd85f32c2014-02-28 14:43:26 +0000198 y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000199 }
200 }
201
202private:
bsalomonf045d602015-11-18 19:01:12 -0800203 typedef SkTLList<SkPath, 1> PathList;
204 typedef SkTLList<SkRect, 1> RectList;
205 PathList fPaths;
206 RectList fRects;
skia.committer@gmail.comf0b0cda2014-02-09 03:02:01 +0000207
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000208 typedef GM INHERITED;
209};
210
halcanary385fe4d2015-08-26 13:07:48 -0700211DEF_GM(return new ConvexPolyEffect;)
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +0000212}