blob: 7c9e5f098379d8af1db1ca7b7c909ced06967817 [file] [log] [blame]
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrShaderCaps.h"
9#include "src/gpu/effects/GrBezierEffect.h"
10#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
11#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
12#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
13#include "src/gpu/glsl/GrGLSLUniformHandler.h"
14#include "src/gpu/glsl/GrGLSLUtil.h"
15#include "src/gpu/glsl/GrGLSLVarying.h"
16#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000017
egdaniele659a582015-11-13 09:55:43 -080018class GrGLConicEffect : public GrGLSLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000019public:
joshualitt465283c2015-09-11 08:19:35 -070020 GrGLConicEffect(const GrGeometryProcessor&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000021
mtklein36352bf2015-03-25 18:17:31 -070022 void onEmitCode(EmitArgs&, GrGPArgs*) override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000023
joshualitt87f48d92014-12-04 10:41:40 -080024 static inline void GenKey(const GrGeometryProcessor&,
Brian Salomon94efbf52016-11-29 13:43:05 -050025 const GrShaderCaps&,
joshualitt87f48d92014-12-04 10:41:40 -080026 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000027
bsalomona624bf32016-09-20 09:12:47 -070028 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
29 FPCoordTransformIter&& transformIter) override {
joshualitte578a952015-05-14 10:09:13 -070030 const GrConicEffect& ce = primProc.cast<GrConicEffect>();
joshualitt5559ca22015-05-21 15:50:36 -070031
32 if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
33 fViewMatrix = ce.viewMatrix();
egdaniel018fb622015-10-28 07:26:40 -070034 float viewMatrix[3 * 3];
egdaniel64c47282015-11-13 06:54:19 -080035 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
joshualitt5559ca22015-05-21 15:50:36 -070036 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
37 }
joshualittee2af952014-12-30 09:04:15 -080038
joshualittb8c241a2015-05-19 08:23:30 -070039 if (ce.color() != fColor) {
Brian Osmancf860852018-10-31 14:04:39 -040040 pdman.set4fv(fColorUniform, 1, ce.color().vec());
joshualittb8c241a2015-05-19 08:23:30 -070041 fColor = ce.color();
joshualitt9b989322014-12-15 14:16:27 -080042 }
joshualittb8c241a2015-05-19 08:23:30 -070043
44 if (ce.coverageScale() != 0xff && ce.coverageScale() != fCoverageScale) {
45 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
46 fCoverageScale = ce.coverageScale();
joshualitt9b989322014-12-15 14:16:27 -080047 }
bsalomona624bf32016-09-20 09:12:47 -070048 this->setTransformDataHelper(ce.localMatrix(), pdman, &transformIter);
joshualitte3ababe2015-05-15 07:56:07 -070049 }
50
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000051private:
joshualitt5559ca22015-05-21 15:50:36 -070052 SkMatrix fViewMatrix;
Brian Osmancf860852018-10-31 14:04:39 -040053 SkPMColor4f fColor;
joshualitt9b989322014-12-15 14:16:27 -080054 uint8_t fCoverageScale;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050055 GrClipEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -080056 UniformHandle fColorUniform;
57 UniformHandle fCoverageScaleUniform;
joshualitt5559ca22015-05-21 15:50:36 -070058 UniformHandle fViewMatrixUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000059
egdaniele659a582015-11-13 09:55:43 -080060 typedef GrGLSLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000061};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000062
joshualitt465283c2015-09-11 08:19:35 -070063GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
Brian Osmancf860852018-10-31 14:04:39 -040064 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(SK_PMColor4fILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -080065 const GrConicEffect& ce = processor.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000066 fEdgeType = ce.getEdgeType();
67}
68
robertphillips46d36f02015-01-18 08:14:14 -080069void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
egdaniel4ca2e602015-11-18 08:01:26 -080070 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
joshualitt2dd1ae02014-12-03 06:24:10 -080071 const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
egdaniel0eafe792015-11-20 14:01:22 -080072 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
egdaniel7ea439b2015-12-03 09:20:44 -080073 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
joshualitt2dd1ae02014-12-03 06:24:10 -080074
joshualittabb52a12015-01-13 15:02:10 -080075 // emit attributes
egdaniel0eafe792015-11-20 14:01:22 -080076 varyingHandler->emitAttributes(gp);
joshualittabb52a12015-01-13 15:02:10 -080077
Chris Dalton27372882017-12-08 13:34:21 -070078 GrGLSLVarying v(kFloat4_GrSLType);
Chris Daltonfdde34e2017-10-16 14:15:26 -060079 varyingHandler->addVarying("ConicCoeffs", &v);
Brian Salomon92be2f72018-06-19 14:33:47 -040080 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs().name());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000081
Chris Dalton60283612018-02-14 13:38:14 -070082 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
joshualitt9b989322014-12-15 14:16:27 -080083 // Setup pass through color
Brian Salomonbfd51832017-01-04 13:22:08 -050084 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
joshualitt9b989322014-12-15 14:16:27 -080085
joshualittabb52a12015-01-13 15:02:10 -080086 // Setup position
Brian Salomon7f235432017-08-16 09:41:48 -040087 this->writeOutputPosition(vertBuilder,
88 uniformHandler,
89 gpArgs,
Brian Salomon92be2f72018-06-19 14:33:47 -040090 gp.inPosition().name(),
Brian Salomon7f235432017-08-16 09:41:48 -040091 gp.viewMatrix(),
92 &fViewMatrixUniform);
joshualitt4973d9d2014-11-08 09:24:25 -080093
joshualittabb52a12015-01-13 15:02:10 -080094 // emit transforms with position
egdaniel7ea439b2015-12-03 09:20:44 -080095 this->emitTransforms(vertBuilder,
egdaniel0eafe792015-11-20 14:01:22 -080096 varyingHandler,
egdaniel7ea439b2015-12-03 09:20:44 -080097 uniformHandler,
Brian Salomon92be2f72018-06-19 14:33:47 -040098 gp.inPosition().asShaderVar(),
egdaniel4ca2e602015-11-18 08:01:26 -080099 gp.localMatrix(),
bsalomona624bf32016-09-20 09:12:47 -0700100 args.fFPCoordTransformHandler);
joshualittabb52a12015-01-13 15:02:10 -0800101
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400102 // TODO: we should check on the number of bits float and half provide and use the smallest one
103 // that suffices. Additionally we should assert that the upstream code only lets us get here if
104 // either float or half provides the required number of bits.
robertphillips2eb10092015-12-11 04:59:36 -0800105
Ethan Nicholase1f55022019-02-05 17:17:40 -0500106 GrShaderVar edgeAlpha("edgeAlpha", kHalf_GrSLType, 0);
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400107 GrShaderVar dklmdx("dklmdx", kFloat3_GrSLType, 0);
108 GrShaderVar dklmdy("dklmdy", kFloat3_GrSLType, 0);
109 GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0);
110 GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0);
111 GrShaderVar gF("gF", kFloat2_GrSLType, 0);
112 GrShaderVar gFM("gFM", kFloat_GrSLType, 0);
113 GrShaderVar func("func", kFloat_GrSLType, 0);
robertphillips96afa522015-12-09 07:54:24 -0800114
115 fragBuilder->declAppend(edgeAlpha);
116 fragBuilder->declAppend(dklmdx);
117 fragBuilder->declAppend(dklmdy);
118 fragBuilder->declAppend(dfdx);
119 fragBuilder->declAppend(dfdy);
120 fragBuilder->declAppend(gF);
121 fragBuilder->declAppend(gFM);
122 fragBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000123
124 switch (fEdgeType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500125 case GrClipEdgeType::kHairlineAA: {
robertphillips96afa522015-12-09 07:54:24 -0800126 fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
127 fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
128 fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
129 dfdx.c_str(),
130 v.fsIn(), dklmdx.c_str(),
131 v.fsIn(), dklmdx.c_str(),
132 v.fsIn(), dklmdx.c_str());
133 fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
134 dfdy.c_str(),
135 v.fsIn(), dklmdy.c_str(),
136 v.fsIn(), dklmdy.c_str(),
137 v.fsIn(), dklmdy.c_str());
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400138 fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400139 dfdy.c_str());
robertphillips96afa522015-12-09 07:54:24 -0800140 fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
141 gFM.c_str(), gF.c_str(), gF.c_str());
142 fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
143 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
144 fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
Ethan Nicholase1f55022019-02-05 17:17:40 -0500145 fragBuilder->codeAppendf("%s = half(%s / %s);",
robertphillips96afa522015-12-09 07:54:24 -0800146 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
147 fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
148 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000149 // Add line below for smooth cubic ramp
egdaniel4ca2e602015-11-18 08:01:26 -0800150 // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000151 break;
152 }
Ethan Nicholas1706f842017-11-10 11:58:19 -0500153 case GrClipEdgeType::kFillAA: {
robertphillips96afa522015-12-09 07:54:24 -0800154 fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
155 fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
156 fragBuilder->codeAppendf("%s ="
157 "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
158 dfdx.c_str(),
159 v.fsIn(), dklmdx.c_str(),
160 v.fsIn(), dklmdx.c_str(),
161 v.fsIn(), dklmdx.c_str());
162 fragBuilder->codeAppendf("%s ="
163 "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
164 dfdy.c_str(),
165 v.fsIn(), dklmdy.c_str(),
166 v.fsIn(), dklmdy.c_str(),
167 v.fsIn(), dklmdy.c_str());
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400168 fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(),
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400169 dfdy.c_str());
robertphillips96afa522015-12-09 07:54:24 -0800170 fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
171 gFM.c_str(), gF.c_str(), gF.c_str());
172 fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
173 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
Ethan Nicholase1f55022019-02-05 17:17:40 -0500174 fragBuilder->codeAppendf("%s = half(%s / %s);",
robertphillips96afa522015-12-09 07:54:24 -0800175 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
Ethan Nicholas12fb9cf2018-08-03 16:16:57 -0400176 fragBuilder->codeAppendf("%s = saturate(0.5 - %s);",
robertphillips96afa522015-12-09 07:54:24 -0800177 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000178 // Add line below for smooth cubic ramp
egdaniel4ca2e602015-11-18 08:01:26 -0800179 // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000180 break;
181 }
Ethan Nicholas1706f842017-11-10 11:58:19 -0500182 case GrClipEdgeType::kFillBW: {
Ethan Nicholase1f55022019-02-05 17:17:40 -0500183 fragBuilder->codeAppendf("%s = half(%s.x * %s.x - %s.y * %s.z);",
robertphillips96afa522015-12-09 07:54:24 -0800184 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
Ethan Nicholase1f55022019-02-05 17:17:40 -0500185 fragBuilder->codeAppendf("%s = half(%s < 0.0);",
robertphillips96afa522015-12-09 07:54:24 -0800186 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000187 break;
188 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000189 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400190 SK_ABORT("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000191 }
192
joshualittb8c241a2015-05-19 08:23:30 -0700193 // TODO should we really be doing this?
194 if (gp.coverageScale() != 0xff) {
joshualitt9b989322014-12-15 14:16:27 -0800195 const char* coverageScale;
cdalton5e58cee2016-02-11 12:49:47 -0800196 fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
Ethan Nicholas8aa45692017-09-20 11:24:15 -0400197 kFloat_GrSLType,
cdalton5e58cee2016-02-11 12:49:47 -0800198 "Coverage",
199 &coverageScale);
Ethan Nicholase1f55022019-02-05 17:17:40 -0500200 fragBuilder->codeAppendf("%s = half4(half(%s) * %s);",
robertphillips96afa522015-12-09 07:54:24 -0800201 args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
joshualitt9b989322014-12-15 14:16:27 -0800202 } else {
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400203 fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
joshualitt9b989322014-12-15 14:16:27 -0800204 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000205}
206
robertphillips46d36f02015-01-18 08:14:14 -0800207void GrGLConicEffect::GenKey(const GrGeometryProcessor& gp,
Brian Salomon94efbf52016-11-29 13:43:05 -0500208 const GrShaderCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700209 GrProcessorKeyBuilder* b) {
robertphillips46d36f02015-01-18 08:14:14 -0800210 const GrConicEffect& ce = gp.cast<GrConicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700211 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualittb8c241a2015-05-19 08:23:30 -0700212 key |= 0xff != ce.coverageScale() ? 0x8 : 0x0;
213 key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
joshualitte578a952015-05-14 10:09:13 -0700214 key |= ComputePosKey(ce.viewMatrix()) << 5;
bsalomon63e99f72014-07-21 08:03:14 -0700215 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000216}
217
218//////////////////////////////////////////////////////////////////////////////
219
Brian Salomon92be2f72018-06-19 14:33:47 -0400220constexpr GrPrimitiveProcessor::Attribute GrConicEffect::kAttributes[];
221
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000222GrConicEffect::~GrConicEffect() {}
223
Brian Salomon94efbf52016-11-29 13:43:05 -0500224void GrConicEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -0800225 GrProcessorKeyBuilder* b) const {
joshualitt465283c2015-09-11 08:19:35 -0700226 GrGLConicEffect::GenKey(*this, caps, b);
joshualitteb2a6762014-12-04 11:35:33 -0800227}
228
Brian Salomon94efbf52016-11-29 13:43:05 -0500229GrGLSLPrimitiveProcessor* GrConicEffect::createGLSLInstance(const GrShaderCaps&) const {
joshualitt465283c2015-09-11 08:19:35 -0700230 return new GrGLConicEffect(*this);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000231}
232
Brian Osmancf860852018-10-31 14:04:39 -0400233GrConicEffect::GrConicEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500234 GrClipEdgeType edgeType, const SkMatrix& localMatrix,
joshualittb8c241a2015-05-19 08:23:30 -0700235 bool usesLocalCoords)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400236 : INHERITED(kGrConicEffect_ClassID)
237 , fColor(color)
joshualitte578a952015-05-14 10:09:13 -0700238 , fViewMatrix(viewMatrix)
joshualitte3ababe2015-05-15 07:56:07 -0700239 , fLocalMatrix(viewMatrix)
joshualittb8c241a2015-05-19 08:23:30 -0700240 , fUsesLocalCoords(usesLocalCoords)
joshualitt8059eb92014-12-29 15:10:07 -0800241 , fCoverageScale(coverage)
242 , fEdgeType(edgeType) {
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500243 this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
joshualitt9b989322014-12-15 14:16:27 -0800244}
245
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000246//////////////////////////////////////////////////////////////////////////////
247
joshualittb0a8a372014-09-23 09:50:21 -0700248GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000249
Hal Canary6f6961e2017-01-31 13:50:44 -0500250#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -0700251sk_sp<GrGeometryProcessor> GrConicEffect::TestCreate(GrProcessorTestData* d) {
252 sk_sp<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000253 do {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500254 GrClipEdgeType edgeType =
255 static_cast<GrClipEdgeType>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500256 d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
Brian Osmancf860852018-10-31 14:04:39 -0400257 gp = GrConicEffect::Make(SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
Brian Osman1be2b7c2018-10-29 16:07:15 -0400258 GrTest::TestMatrix(d->fRandom), edgeType, *d->caps(),
259 GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
halcanary96fcdcc2015-08-27 07:41:13 -0700260 } while (nullptr == gp);
joshualittb0a8a372014-09-23 09:50:21 -0700261 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000262}
Hal Canary6f6961e2017-01-31 13:50:44 -0500263#endif
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000264
265//////////////////////////////////////////////////////////////////////////////
266// Quad
267//////////////////////////////////////////////////////////////////////////////
268
egdaniele659a582015-11-13 09:55:43 -0800269class GrGLQuadEffect : public GrGLSLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000270public:
joshualitt465283c2015-09-11 08:19:35 -0700271 GrGLQuadEffect(const GrGeometryProcessor&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000272
mtklein36352bf2015-03-25 18:17:31 -0700273 void onEmitCode(EmitArgs&, GrGPArgs*) override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000274
joshualitt87f48d92014-12-04 10:41:40 -0800275 static inline void GenKey(const GrGeometryProcessor&,
Brian Salomon94efbf52016-11-29 13:43:05 -0500276 const GrShaderCaps&,
joshualitt87f48d92014-12-04 10:41:40 -0800277 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000278
bsalomona624bf32016-09-20 09:12:47 -0700279 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
280 FPCoordTransformIter&& transformIter) override {
joshualitte578a952015-05-14 10:09:13 -0700281 const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
joshualitt5559ca22015-05-21 15:50:36 -0700282
283 if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) {
284 fViewMatrix = qe.viewMatrix();
egdaniel018fb622015-10-28 07:26:40 -0700285 float viewMatrix[3 * 3];
egdaniel64c47282015-11-13 06:54:19 -0800286 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
joshualitt5559ca22015-05-21 15:50:36 -0700287 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
288 }
joshualittee2af952014-12-30 09:04:15 -0800289
joshualittb8c241a2015-05-19 08:23:30 -0700290 if (qe.color() != fColor) {
Brian Osmancf860852018-10-31 14:04:39 -0400291 pdman.set4fv(fColorUniform, 1, qe.color().vec());
joshualittb8c241a2015-05-19 08:23:30 -0700292 fColor = qe.color();
joshualitt9b989322014-12-15 14:16:27 -0800293 }
joshualittb8c241a2015-05-19 08:23:30 -0700294
295 if (qe.coverageScale() != 0xff && qe.coverageScale() != fCoverageScale) {
296 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
297 fCoverageScale = qe.coverageScale();
joshualitt9b989322014-12-15 14:16:27 -0800298 }
bsalomona624bf32016-09-20 09:12:47 -0700299 this->setTransformDataHelper(qe.localMatrix(), pdman, &transformIter);
joshualitte3ababe2015-05-15 07:56:07 -0700300 }
301
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000302private:
joshualitt5559ca22015-05-21 15:50:36 -0700303 SkMatrix fViewMatrix;
Brian Osmancf860852018-10-31 14:04:39 -0400304 SkPMColor4f fColor;
joshualitt9b989322014-12-15 14:16:27 -0800305 uint8_t fCoverageScale;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500306 GrClipEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800307 UniformHandle fColorUniform;
308 UniformHandle fCoverageScaleUniform;
joshualitt5559ca22015-05-21 15:50:36 -0700309 UniformHandle fViewMatrixUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000310
egdaniele659a582015-11-13 09:55:43 -0800311 typedef GrGLSLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000312};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000313
joshualitt465283c2015-09-11 08:19:35 -0700314GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
Brian Osmancf860852018-10-31 14:04:39 -0400315 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(SK_PMColor4fILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -0800316 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000317 fEdgeType = ce.getEdgeType();
318}
319
robertphillips46d36f02015-01-18 08:14:14 -0800320void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
egdaniel4ca2e602015-11-18 08:01:26 -0800321 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
joshualitt2dd1ae02014-12-03 06:24:10 -0800322 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
egdaniel0eafe792015-11-20 14:01:22 -0800323 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
egdaniel7ea439b2015-12-03 09:20:44 -0800324 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
joshualitt2dd1ae02014-12-03 06:24:10 -0800325
joshualittabb52a12015-01-13 15:02:10 -0800326 // emit attributes
egdaniel0eafe792015-11-20 14:01:22 -0800327 varyingHandler->emitAttributes(gp);
joshualittabb52a12015-01-13 15:02:10 -0800328
Chris Dalton27372882017-12-08 13:34:21 -0700329 GrGLSLVarying v(kHalf4_GrSLType);
egdaniel0eafe792015-11-20 14:01:22 -0800330 varyingHandler->addVarying("HairQuadEdge", &v);
Brian Salomon92be2f72018-06-19 14:33:47 -0400331 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge().name());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000332
Chris Dalton60283612018-02-14 13:38:14 -0700333 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
joshualitt9b989322014-12-15 14:16:27 -0800334 // Setup pass through color
Brian Salomonbfd51832017-01-04 13:22:08 -0500335 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
joshualitt9b989322014-12-15 14:16:27 -0800336
joshualittabb52a12015-01-13 15:02:10 -0800337 // Setup position
Brian Salomon7f235432017-08-16 09:41:48 -0400338 this->writeOutputPosition(vertBuilder,
339 uniformHandler,
340 gpArgs,
Brian Salomon92be2f72018-06-19 14:33:47 -0400341 gp.inPosition().name(),
Brian Salomon7f235432017-08-16 09:41:48 -0400342 gp.viewMatrix(),
343 &fViewMatrixUniform);
joshualitt4973d9d2014-11-08 09:24:25 -0800344
joshualittabb52a12015-01-13 15:02:10 -0800345 // emit transforms with position
egdaniel7ea439b2015-12-03 09:20:44 -0800346 this->emitTransforms(vertBuilder,
egdaniel0eafe792015-11-20 14:01:22 -0800347 varyingHandler,
egdaniel7ea439b2015-12-03 09:20:44 -0800348 uniformHandler,
Brian Salomon92be2f72018-06-19 14:33:47 -0400349 gp.inPosition().asShaderVar(),
egdaniel4ca2e602015-11-18 08:01:26 -0800350 gp.localMatrix(),
bsalomona624bf32016-09-20 09:12:47 -0700351 args.fFPCoordTransformHandler);
joshualittabb52a12015-01-13 15:02:10 -0800352
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400353 fragBuilder->codeAppendf("half edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700354
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000355 switch (fEdgeType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500356 case GrClipEdgeType::kHairlineAA: {
Ethan Nicholase1f55022019-02-05 17:17:40 -0500357 fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
358 fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400359 fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
egdaniel4ca2e602015-11-18 08:01:26 -0800360 " 2.0 * %s.x * duvdy.x - duvdy.y);",
361 v.fsIn(), v.fsIn());
Ethan Nicholase1f55022019-02-05 17:17:40 -0500362 fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
egdaniel4ca2e602015-11-18 08:01:26 -0800363 v.fsIn(), v.fsIn(), v.fsIn());
364 fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
365 fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000366 // Add line below for smooth cubic ramp
egdaniel4ca2e602015-11-18 08:01:26 -0800367 // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000368 break;
369 }
Ethan Nicholas1706f842017-11-10 11:58:19 -0500370 case GrClipEdgeType::kFillAA: {
Ethan Nicholase1f55022019-02-05 17:17:40 -0500371 fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
372 fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400373 fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
egdaniel4ca2e602015-11-18 08:01:26 -0800374 " 2.0 * %s.x * duvdy.x - duvdy.y);",
375 v.fsIn(), v.fsIn());
Ethan Nicholase1f55022019-02-05 17:17:40 -0500376 fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
egdaniel4ca2e602015-11-18 08:01:26 -0800377 v.fsIn(), v.fsIn(), v.fsIn());
378 fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
Ethan Nicholas12fb9cf2018-08-03 16:16:57 -0400379 fragBuilder->codeAppend("edgeAlpha = saturate(0.5 - edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000380 // Add line below for smooth cubic ramp
egdaniel4ca2e602015-11-18 08:01:26 -0800381 // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000382 break;
383 }
Ethan Nicholas1706f842017-11-10 11:58:19 -0500384 case GrClipEdgeType::kFillBW: {
Ethan Nicholase1f55022019-02-05 17:17:40 -0500385 fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
egdaniel4ca2e602015-11-18 08:01:26 -0800386 v.fsIn(), v.fsIn(), v.fsIn());
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400387 fragBuilder->codeAppend("edgeAlpha = half(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000388 break;
389 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000390 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400391 SK_ABORT("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000392 }
393
joshualittb8c241a2015-05-19 08:23:30 -0700394 if (0xff != gp.coverageScale()) {
joshualitt9b989322014-12-15 14:16:27 -0800395 const char* coverageScale;
cdalton5e58cee2016-02-11 12:49:47 -0800396 fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400397 kHalf_GrSLType,
cdalton5e58cee2016-02-11 12:49:47 -0800398 "Coverage",
399 &coverageScale);
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400400 fragBuilder->codeAppendf("%s = half4(%s * edgeAlpha);", args.fOutputCoverage,
401 coverageScale);
joshualitt9b989322014-12-15 14:16:27 -0800402 } else {
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400403 fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
joshualitt9b989322014-12-15 14:16:27 -0800404 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000405}
406
robertphillips46d36f02015-01-18 08:14:14 -0800407void GrGLQuadEffect::GenKey(const GrGeometryProcessor& gp,
Brian Salomon94efbf52016-11-29 13:43:05 -0500408 const GrShaderCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700409 GrProcessorKeyBuilder* b) {
robertphillips46d36f02015-01-18 08:14:14 -0800410 const GrQuadEffect& ce = gp.cast<GrQuadEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700411 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualittb8c241a2015-05-19 08:23:30 -0700412 key |= ce.coverageScale() != 0xff ? 0x8 : 0x0;
413 key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
joshualitte578a952015-05-14 10:09:13 -0700414 key |= ComputePosKey(ce.viewMatrix()) << 5;
bsalomon63e99f72014-07-21 08:03:14 -0700415 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000416}
417
418//////////////////////////////////////////////////////////////////////////////
419
Brian Salomon92be2f72018-06-19 14:33:47 -0400420constexpr GrPrimitiveProcessor::Attribute GrQuadEffect::kAttributes[];
421
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000422GrQuadEffect::~GrQuadEffect() {}
423
Brian Salomon94efbf52016-11-29 13:43:05 -0500424void GrQuadEffect::getGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -0800425 GrProcessorKeyBuilder* b) const {
joshualitt465283c2015-09-11 08:19:35 -0700426 GrGLQuadEffect::GenKey(*this, caps, b);
joshualitteb2a6762014-12-04 11:35:33 -0800427}
428
Brian Salomon94efbf52016-11-29 13:43:05 -0500429GrGLSLPrimitiveProcessor* GrQuadEffect::createGLSLInstance(const GrShaderCaps&) const {
joshualitt465283c2015-09-11 08:19:35 -0700430 return new GrGLQuadEffect(*this);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000431}
432
Brian Osmancf860852018-10-31 14:04:39 -0400433GrQuadEffect::GrQuadEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, uint8_t coverage,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500434 GrClipEdgeType edgeType, const SkMatrix& localMatrix,
joshualittb8c241a2015-05-19 08:23:30 -0700435 bool usesLocalCoords)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400436 : INHERITED(kGrQuadEffect_ClassID)
437 , fColor(color)
joshualitte578a952015-05-14 10:09:13 -0700438 , fViewMatrix(viewMatrix)
joshualitte3ababe2015-05-15 07:56:07 -0700439 , fLocalMatrix(localMatrix)
joshualittb8c241a2015-05-19 08:23:30 -0700440 , fUsesLocalCoords(usesLocalCoords)
joshualitt8059eb92014-12-29 15:10:07 -0800441 , fCoverageScale(coverage)
442 , fEdgeType(edgeType) {
Brian Osmanf04fb3c2018-11-12 15:34:00 -0500443 this->setVertexAttributes(kAttributes, SK_ARRAY_COUNT(kAttributes));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000444}
445
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000446//////////////////////////////////////////////////////////////////////////////
447
joshualittb0a8a372014-09-23 09:50:21 -0700448GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000449
Hal Canary6f6961e2017-01-31 13:50:44 -0500450#if GR_TEST_UTILS
bungeman06ca8ec2016-06-09 08:01:03 -0700451sk_sp<GrGeometryProcessor> GrQuadEffect::TestCreate(GrProcessorTestData* d) {
452 sk_sp<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000453 do {
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500454 GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500455 d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
Brian Osmancf860852018-10-31 14:04:39 -0400456 gp = GrQuadEffect::Make(SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
Brian Osman1be2b7c2018-10-29 16:07:15 -0400457 GrTest::TestMatrix(d->fRandom), edgeType, *d->caps(),
458 GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
halcanary96fcdcc2015-08-27 07:41:13 -0700459 } while (nullptr == gp);
joshualittb0a8a372014-09-23 09:50:21 -0700460 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000461}
Hal Canary6f6961e2017-01-31 13:50:44 -0500462#endif