blob: 41bd42fab8d2cb9a2a0f1653116d1097dca0c730 [file] [log] [blame]
jvanverth@google.comd830d132013-11-11 20:54:09 +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#include "GrDistanceFieldTextureEffect.h"
egdaniel605dd0f2014-11-12 08:35:25 -08009#include "GrInvariantOutput.h"
joshualitteb2a6762014-12-04 11:35:33 -080010#include "GrTexture.h"
11#include "SkDistanceFieldGen.h"
joshualittb0a8a372014-09-23 09:50:21 -070012#include "gl/GrGLProcessor.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000013#include "gl/GrGLSL.h"
14#include "gl/GrGLTexture.h"
joshualitt249af152014-09-15 11:41:13 -070015#include "gl/GrGLGeometryProcessor.h"
joshualitteb2a6762014-12-04 11:35:33 -080016#include "gl/builders/GrGLProgramBuilder.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000017
jvanverth2d2a68c2014-06-10 06:42:56 -070018// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2
19#define SK_DistanceFieldAAFactor "0.7071"
20
joshualitt9b989322014-12-15 14:16:27 -080021struct DistanceFieldBatchTracker {
22 GrGPInput fInputColorType;
23 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -080024 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -080025};
26
joshualitt249af152014-09-15 11:41:13 -070027class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor {
jvanverth@google.comd830d132013-11-11 20:54:09 +000028public:
joshualitteb2a6762014-12-04 11:35:33 -080029 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -080030 const GrBatchTracker&)
joshualitt9b989322014-12-15 14:16:27 -080031 : fColor(GrColor_ILLEGAL)
32 , fTextureSize(SkISize::Make(-1,-1))
jvanverth9564ce62014-09-16 05:45:19 -070033#ifdef SK_GAMMA_APPLY_TO_A8
34 , fLuminance(-1.0f)
35#endif
36 {}
jvanverth@google.comd830d132013-11-11 20:54:09 +000037
robertphillips46d36f02015-01-18 08:14:14 -080038 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
joshualitt249af152014-09-15 11:41:13 -070039 const GrDistanceFieldTextureEffect& dfTexEffect =
joshualittc369e7c2014-10-22 10:56:26 -070040 args.fGP.cast<GrDistanceFieldTextureEffect>();
joshualitt9b989322014-12-15 14:16:27 -080041 const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>();
42 GrGLGPBuilder* pb = args.fPB;
joshualittc369e7c2014-10-22 10:56:26 -070043 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -070044 SkAssertResult(fsBuilder->enableFeature(
45 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
jvanverth@google.comd830d132013-11-11 20:54:09 +000046
joshualitt2dd1ae02014-12-03 06:24:10 -080047 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualittabb52a12015-01-13 15:02:10 -080048
49 // emit attributes
50 vsBuilder->emitAttributes(dfTexEffect);
51
joshualitt74077b92014-10-24 11:26:03 -070052 GrGLVertToFrag v(kVec2f_GrSLType);
53 args.fPB->addVarying("TextureCoords", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -080054 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000055
joshualitt9b989322014-12-15 14:16:27 -080056 // Setup pass through color
57 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
58 dfTexEffect.inColor(), &fColorUniform);
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000059
joshualittee2af952014-12-30 09:04:15 -080060 // setup uniform viewMatrix
61 this->addUniformViewMatrix(pb);
62
joshualittabb52a12015-01-13 15:02:10 -080063 // Setup position
robertphillips46d36f02015-01-18 08:14:14 -080064 SetupPosition(vsBuilder, gpArgs, dfTexEffect.inPosition()->fName,
65 dfTexEffect.viewMatrix(), this->uViewM());
joshualitt2dd1ae02014-12-03 06:24:10 -080066
joshualittabb52a12015-01-13 15:02:10 -080067 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -080068 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -080069 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
joshualitt4973d9d2014-11-08 09:24:25 -080070
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000071 const char* textureSizeUniName = NULL;
joshualittc369e7c2014-10-22 10:56:26 -070072 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -080073 kVec2f_GrSLType, kDefault_GrSLPrecision,
74 "TextureSize", &textureSizeUniName);
jvanverth@google.comd830d132013-11-11 20:54:09 +000075
jvanverthfdf7ccc2015-01-27 08:19:33 -080076 // Use highp to work around aliasing issues
77 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
78 pb->ctxInfo().standard()));
79 fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn());
80
81 fsBuilder->codeAppend("\tfloat texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -070082 fsBuilder->appendTextureLookup(args.fSamplers[0],
jvanverthfdf7ccc2015-01-27 08:19:33 -080083 "uv",
jvanverth@google.comd830d132013-11-11 20:54:09 +000084 kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -080085 fsBuilder->codeAppend(".r;\n");
joshualitt30ba4362014-08-21 20:18:45 -070086 fsBuilder->codeAppend("\tfloat distance = "
jvanverthfdf7ccc2015-01-27 08:19:33 -080087 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000088
89 // we adjust for the effect of the transformation on the distance by using
90 // the length of the gradient of the texture coordinates. We use st coordinates
91 // to ensure we're mapping 1:1 from texel space to pixel space.
jvanverthfdf7ccc2015-01-27 08:19:33 -080092 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
93 pb->ctxInfo().standard()));
94 fsBuilder->codeAppendf("vec2 st = uv*%s;\n", textureSizeUniName);
joshualitt30ba4362014-08-21 20:18:45 -070095 fsBuilder->codeAppend("\tfloat afwidth;\n");
jvanverth78f07182014-07-30 06:17:59 -070096 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000097 // this gives us a smooth step across approximately one fragment
jvanverthfa38a302014-10-06 05:59:05 -070098 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000099 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700100 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
101 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000102
joshualitt30ba4362014-08-21 20:18:45 -0700103 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
joshualittc369e7c2014-10-22 10:56:26 -0700104 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000105 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
joshualitt30ba4362014-08-21 20:18:45 -0700106 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
107 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
108 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
109 fsBuilder->codeAppend("\t} else {\n");
110 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
111 fsBuilder->codeAppend("\t}\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000112 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700113 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000114 }
joshualitt30ba4362014-08-21 20:18:45 -0700115 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
116 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000117
118 // this gives us a smooth step across approximately one fragment
joshualitt30ba4362014-08-21 20:18:45 -0700119 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000120 }
joshualitt30ba4362014-08-21 20:18:45 -0700121 fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
jvanverth@google.comd830d132013-11-11 20:54:09 +0000122
jvanverth2d2a68c2014-06-10 06:42:56 -0700123#ifdef SK_GAMMA_APPLY_TO_A8
124 // adjust based on gamma
125 const char* luminanceUniName = NULL;
126 // width, height, 1/(3*width)
joshualittc369e7c2014-10-22 10:56:26 -0700127 fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800128 kFloat_GrSLType, kDefault_GrSLPrecision,
129 "Luminance", &luminanceUniName);
jvanverth2d2a68c2014-06-10 06:42:56 -0700130
joshualitt30ba4362014-08-21 20:18:45 -0700131 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
132 fsBuilder->codeAppend("\tvec4 gammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700133 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700134 fsBuilder->codeAppend(";\n");
135 fsBuilder->codeAppend("\tval = gammaColor.r;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700136#endif
137
joshualitt2dd1ae02014-12-03 06:24:10 -0800138 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000139 }
140
kkinnunen7510b222014-07-30 00:04:16 -0700141 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800142 const GrPrimitiveProcessor& proc,
143 const GrBatchTracker& bt) SK_OVERRIDE {
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000144 SkASSERT(fTextureSizeUni.isValid());
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000145
joshualitt87f48d92014-12-04 10:41:40 -0800146 GrTexture* texture = proc.texture(0);
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000147 if (texture->width() != fTextureSize.width() ||
148 texture->height() != fTextureSize.height()) {
149 fTextureSize = SkISize::Make(texture->width(), texture->height());
kkinnunen7510b222014-07-30 00:04:16 -0700150 pdman.set2f(fTextureSizeUni,
151 SkIntToScalar(fTextureSize.width()),
152 SkIntToScalar(fTextureSize.height()));
commit-bot@chromium.org66beaf02014-03-26 18:21:55 +0000153 }
jvanverth2d2a68c2014-06-10 06:42:56 -0700154#ifdef SK_GAMMA_APPLY_TO_A8
155 const GrDistanceFieldTextureEffect& dfTexEffect =
joshualitt87f48d92014-12-04 10:41:40 -0800156 proc.cast<GrDistanceFieldTextureEffect>();
jvanverth2d2a68c2014-06-10 06:42:56 -0700157 float luminance = dfTexEffect.getLuminance();
158 if (luminance != fLuminance) {
kkinnunen7510b222014-07-30 00:04:16 -0700159 pdman.set1f(fLuminanceUni, luminance);
jvanverth2d2a68c2014-06-10 06:42:56 -0700160 fLuminance = luminance;
161 }
162#endif
joshualitt9b989322014-12-15 14:16:27 -0800163
joshualittee2af952014-12-30 09:04:15 -0800164 this->setUniformViewMatrix(pdman, proc.viewMatrix());
165
joshualitt9b989322014-12-15 14:16:27 -0800166 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
167 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
168 GrGLfloat c[4];
169 GrColorToRGBAFloat(local.fColor, c);
170 pdman.set4fv(fColorUniform, 1, c);
171 fColor = local.fColor;
172 }
commit-bot@chromium.org8fe2ee12014-03-26 18:03:05 +0000173 }
174
robertphillips46d36f02015-01-18 08:14:14 -0800175 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800176 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800177 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700178 GrProcessorKeyBuilder* b) {
robertphillips46d36f02015-01-18 08:14:14 -0800179 const GrDistanceFieldTextureEffect& dfTexEffect = gp.cast<GrDistanceFieldTextureEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800180 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800181 uint32_t key = dfTexEffect.getFlags();
182 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800183 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
184 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800185 b->add32(key);
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000186 }
187
jvanverth@google.comd830d132013-11-11 20:54:09 +0000188private:
joshualitt9b989322014-12-15 14:16:27 -0800189 GrColor fColor;
190 UniformHandle fColorUniform;
191 UniformHandle fTextureSizeUni;
192 SkISize fTextureSize;
193 UniformHandle fLuminanceUni;
mtklein50282b42015-01-22 07:59:52 -0800194#ifdef SK_GAMMA_APPLY_TO_A8
joshualitt9b989322014-12-15 14:16:27 -0800195 float fLuminance;
mtklein50282b42015-01-22 07:59:52 -0800196#endif
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000197
joshualitt249af152014-09-15 11:41:13 -0700198 typedef GrGLGeometryProcessor INHERITED;
jvanverth@google.comd830d132013-11-11 20:54:09 +0000199};
200
201///////////////////////////////////////////////////////////////////////////////
202
joshualitt2e3b3e32014-12-09 13:31:14 -0800203GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800204 const SkMatrix& viewMatrix,
joshualitt2e3b3e32014-12-09 13:31:14 -0800205 GrTexture* texture,
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000206 const GrTextureParams& params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700207#ifdef SK_GAMMA_APPLY_TO_A8
208 GrTexture* gamma,
209 const GrTextureParams& gammaParams,
210 float luminance,
211#endif
joshualitt56995b52014-12-11 15:44:02 -0800212 uint32_t flags, bool opaqueVertexColors)
joshualitt8059eb92014-12-29 15:10:07 -0800213 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
joshualitt2e3b3e32014-12-09 13:31:14 -0800214 , fTextureAccess(texture, params)
jvanverth2d2a68c2014-06-10 06:42:56 -0700215#ifdef SK_GAMMA_APPLY_TO_A8
216 , fGammaTextureAccess(gamma, gammaParams)
217 , fLuminance(luminance)
218#endif
joshualitt249af152014-09-15 11:41:13 -0700219 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
joshualitt2dd1ae02014-12-03 06:24:10 -0800220 , fInColor(NULL) {
jvanverth78f07182014-07-30 06:17:59 -0700221 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
joshualitteb2a6762014-12-04 11:35:33 -0800222 this->initClassID<GrDistanceFieldTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800223 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800224 if (flags & kColorAttr_DistanceFieldEffectFlag) {
joshualitt71c92602015-01-14 08:12:47 -0800225 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800226 this->setHasVertexColor();
227 }
joshualitt71c92602015-01-14 08:12:47 -0800228 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
joshualitt2dd1ae02014-12-03 06:24:10 -0800229 kVec2f_GrVertexAttribType));
jvanverth@google.comd830d132013-11-11 20:54:09 +0000230 this->addTextureAccess(&fTextureAccess);
jvanverth2d2a68c2014-06-10 06:42:56 -0700231#ifdef SK_GAMMA_APPLY_TO_A8
232 this->addTextureAccess(&fGammaTextureAccess);
233#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000234}
235
bsalomon0e08fc12014-10-15 08:19:04 -0700236bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700237 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700238 return
jvanverth78f07182014-07-30 06:17:59 -0700239#ifdef SK_GAMMA_APPLY_TO_A8
jvanverth78f07182014-07-30 06:17:59 -0700240 fLuminance == cte.fLuminance &&
241#endif
242 fFlags == cte.fFlags;
jvanverth@google.comd830d132013-11-11 20:54:09 +0000243}
244
joshualitt56995b52014-12-11 15:44:02 -0800245void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
246 out->setUnknownSingleComponent();
jvanverth@google.comd830d132013-11-11 20:54:09 +0000247}
248
joshualitteb2a6762014-12-04 11:35:33 -0800249void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
250 const GrGLCaps& caps,
251 GrProcessorKeyBuilder* b) const {
252 GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b);
253}
254
joshualittabb52a12015-01-13 15:02:10 -0800255GrGLPrimitiveProcessor*
256GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt,
257 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800258 return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt));
jvanverth@google.comd830d132013-11-11 20:54:09 +0000259}
260
joshualittca0a1792015-01-27 06:41:33 -0800261void GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800262 DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
263 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
264 SkToBool(fInColor));
joshualitt290c09b2014-12-19 13:45:20 -0800265 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800266}
267
268bool GrDistanceFieldTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800269 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800270 const GrBatchTracker& t) const {
271 const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>();
272 const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800273 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
274 that, theirs.fUsesLocalCoords) &&
275 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800276 theirs.fInputColorType, theirs.fColor);
277}
278
jvanverth@google.comd830d132013-11-11 20:54:09 +0000279///////////////////////////////////////////////////////////////////////////////
280
joshualittb0a8a372014-09-23 09:50:21 -0700281GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000282
joshualittb0a8a372014-09-23 09:50:21 -0700283GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
284 GrContext*,
285 const GrDrawTargetCaps&,
286 GrTexture* textures[]) {
287 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
288 GrProcessorUnitTest::kAlphaTextureIdx;
jvanverth2d2a68c2014-06-10 06:42:56 -0700289#ifdef SK_GAMMA_APPLY_TO_A8
joshualittb0a8a372014-09-23 09:50:21 -0700290 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
291 GrProcessorUnitTest::kAlphaTextureIdx;
jvanverth2d2a68c2014-06-10 06:42:56 -0700292#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000293 static const SkShader::TileMode kTileModes[] = {
294 SkShader::kClamp_TileMode,
295 SkShader::kRepeat_TileMode,
296 SkShader::kMirror_TileMode,
297 };
298 SkShader::TileMode tileModes[] = {
299 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
300 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
301 };
302 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
303 GrTextureParams::kNone_FilterMode);
jvanverth2d2a68c2014-06-10 06:42:56 -0700304#ifdef SK_GAMMA_APPLY_TO_A8
305 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
306 GrTextureParams::kNone_FilterMode);
307#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000308
joshualitt8059eb92014-12-29 15:10:07 -0800309 return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
310 GrProcessorUnitTest::TestMatrix(random),
311 textures[texIdx], params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700312#ifdef SK_GAMMA_APPLY_TO_A8
313 textures[texIdx2], params2,
314 random->nextF(),
315#endif
jvanverth78f07182014-07-30 06:17:59 -0700316 random->nextBool() ?
joshualitt56995b52014-12-11 15:44:02 -0800317 kSimilarity_DistanceFieldEffectFlag : 0,
318 random->nextBool());
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000319}
320
321///////////////////////////////////////////////////////////////////////////////
322
joshualitt9b989322014-12-15 14:16:27 -0800323struct DistanceFieldNoGammaBatchTracker {
324 GrGPInput fInputColorType;
325 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800326 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800327};
328
jvanverthfa38a302014-10-06 05:59:05 -0700329class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
330public:
joshualitteb2a6762014-12-04 11:35:33 -0800331 GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800332 const GrBatchTracker&)
joshualitt9b989322014-12-15 14:16:27 -0800333 : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {}
jvanverthfa38a302014-10-06 05:59:05 -0700334
robertphillips46d36f02015-01-18 08:14:14 -0800335 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
jvanverthfa38a302014-10-06 05:59:05 -0700336 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
joshualittc369e7c2014-10-22 10:56:26 -0700337 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>();
jvanverthfa38a302014-10-06 05:59:05 -0700338
joshualitt9b989322014-12-15 14:16:27 -0800339 const DistanceFieldNoGammaBatchTracker& local =
340 args.fBT.cast<DistanceFieldNoGammaBatchTracker>();
341 GrGLGPBuilder* pb = args.fPB;
joshualittc369e7c2014-10-22 10:56:26 -0700342 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
jvanverthfa38a302014-10-06 05:59:05 -0700343 SkAssertResult(fsBuilder->enableFeature(
344 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
345
joshualitt2dd1ae02014-12-03 06:24:10 -0800346 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualittabb52a12015-01-13 15:02:10 -0800347
348 // emit attributes
349 vsBuilder->emitAttributes(dfTexEffect);
350
joshualitt74077b92014-10-24 11:26:03 -0700351 GrGLVertToFrag v(kVec2f_GrSLType);
352 args.fPB->addVarying("TextureCoords", &v);
jvanverthfa38a302014-10-06 05:59:05 -0700353
joshualitt9b989322014-12-15 14:16:27 -0800354 // setup pass through color
355 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
356 dfTexEffect.inColor(), &fColorUniform);
joshualitt2dd1ae02014-12-03 06:24:10 -0800357
358 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
359
joshualittee2af952014-12-30 09:04:15 -0800360 // setup uniform viewMatrix
361 this->addUniformViewMatrix(pb);
362
joshualittabb52a12015-01-13 15:02:10 -0800363 // Setup position
robertphillips46d36f02015-01-18 08:14:14 -0800364 SetupPosition(vsBuilder, gpArgs, dfTexEffect.inPosition()->fName,
365 dfTexEffect.viewMatrix(), this->uViewM());
joshualittabb52a12015-01-13 15:02:10 -0800366
367 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -0800368 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -0800369 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
joshualitt4973d9d2014-11-08 09:24:25 -0800370
jvanverthfa38a302014-10-06 05:59:05 -0700371 const char* textureSizeUniName = NULL;
joshualittc369e7c2014-10-22 10:56:26 -0700372 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800373 kVec2f_GrSLType, kDefault_GrSLPrecision,
374 "TextureSize", &textureSizeUniName);
jvanverthfa38a302014-10-06 05:59:05 -0700375
jvanverthfdf7ccc2015-01-27 08:19:33 -0800376 // Use highp to work around aliasing issues
377 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
378 pb->ctxInfo().standard()));
379 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
380
381 fsBuilder->codeAppend("float texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700382 fsBuilder->appendTextureLookup(args.fSamplers[0],
jvanverthfdf7ccc2015-01-27 08:19:33 -0800383 "uv",
jvanverthfa38a302014-10-06 05:59:05 -0700384 kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800385 fsBuilder->codeAppend(".r;");
jvanverthfa38a302014-10-06 05:59:05 -0700386 fsBuilder->codeAppend("float distance = "
jvanverthfdf7ccc2015-01-27 08:19:33 -0800387 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
jvanverthfa38a302014-10-06 05:59:05 -0700388
389 // we adjust for the effect of the transformation on the distance by using
390 // the length of the gradient of the texture coordinates. We use st coordinates
391 // to ensure we're mapping 1:1 from texel space to pixel space.
jvanverthfdf7ccc2015-01-27 08:19:33 -0800392 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
393 pb->ctxInfo().standard()));
jvanverthfa38a302014-10-06 05:59:05 -0700394 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
395 fsBuilder->codeAppend("float afwidth;");
396 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
397 // this gives us a smooth step across approximately one fragment
398 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
399 } else {
400 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
401 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
402
403 fsBuilder->codeAppend("vec2 uv_grad;");
joshualittc369e7c2014-10-22 10:56:26 -0700404 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
jvanverthfa38a302014-10-06 05:59:05 -0700405 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
406 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
407 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
408 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
409 fsBuilder->codeAppend("} else {");
410 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
411 fsBuilder->codeAppend("}");
412 } else {
413 fsBuilder->codeAppend("uv_grad = normalize(uv);");
414 }
415 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,");
416 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);");
417
418 // this gives us a smooth step across approximately one fragment
419 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
420 }
421 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
422
joshualitt2dd1ae02014-12-03 06:24:10 -0800423 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
jvanverthfa38a302014-10-06 05:59:05 -0700424 }
425
426 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800427 const GrPrimitiveProcessor& proc,
428 const GrBatchTracker& bt) SK_OVERRIDE {
jvanverthfa38a302014-10-06 05:59:05 -0700429 SkASSERT(fTextureSizeUni.isValid());
430
joshualitt87f48d92014-12-04 10:41:40 -0800431 GrTexture* texture = proc.texture(0);
jvanverthfa38a302014-10-06 05:59:05 -0700432 if (texture->width() != fTextureSize.width() ||
433 texture->height() != fTextureSize.height()) {
434 fTextureSize = SkISize::Make(texture->width(), texture->height());
435 pdman.set2f(fTextureSizeUni,
436 SkIntToScalar(fTextureSize.width()),
437 SkIntToScalar(fTextureSize.height()));
438 }
joshualitt9b989322014-12-15 14:16:27 -0800439
joshualittee2af952014-12-30 09:04:15 -0800440 this->setUniformViewMatrix(pdman, proc.viewMatrix());
441
joshualitt9b989322014-12-15 14:16:27 -0800442 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
443 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
444 GrGLfloat c[4];
445 GrColorToRGBAFloat(local.fColor, c);
446 pdman.set4fv(fColorUniform, 1, c);
447 fColor = local.fColor;
448 }
jvanverthfa38a302014-10-06 05:59:05 -0700449 }
450
robertphillips46d36f02015-01-18 08:14:14 -0800451 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800452 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800453 const GrGLCaps&,
jvanverthfa38a302014-10-06 05:59:05 -0700454 GrProcessorKeyBuilder* b) {
455 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
robertphillips46d36f02015-01-18 08:14:14 -0800456 gp.cast<GrDistanceFieldNoGammaTextureEffect>();
jvanverthfa38a302014-10-06 05:59:05 -0700457
joshualitt9b989322014-12-15 14:16:27 -0800458 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800459 uint32_t key = dfTexEffect.getFlags();
460 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800461 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
462 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800463 b->add32(key);
jvanverthfa38a302014-10-06 05:59:05 -0700464 }
465
466private:
joshualitt9b989322014-12-15 14:16:27 -0800467 UniformHandle fColorUniform;
468 UniformHandle fTextureSizeUni;
469 GrColor fColor;
470 SkISize fTextureSize;
jvanverthfa38a302014-10-06 05:59:05 -0700471
472 typedef GrGLGeometryProcessor INHERITED;
473};
474
475///////////////////////////////////////////////////////////////////////////////
476
joshualitt2e3b3e32014-12-09 13:31:14 -0800477GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
478 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800479 const SkMatrix& viewMatrix,
joshualitt2e3b3e32014-12-09 13:31:14 -0800480 GrTexture* texture,
481 const GrTextureParams& params,
joshualitt56995b52014-12-11 15:44:02 -0800482 uint32_t flags,
483 bool opaqueVertexColors)
joshualitt8059eb92014-12-29 15:10:07 -0800484 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
joshualitt2e3b3e32014-12-09 13:31:14 -0800485 , fTextureAccess(texture, params)
jvanverthfa38a302014-10-06 05:59:05 -0700486 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
joshualitt2dd1ae02014-12-03 06:24:10 -0800487 , fInColor(NULL) {
jvanverthfa38a302014-10-06 05:59:05 -0700488 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
joshualitteb2a6762014-12-04 11:35:33 -0800489 this->initClassID<GrDistanceFieldNoGammaTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800490 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800491 if (flags & kColorAttr_DistanceFieldEffectFlag) {
joshualitt71c92602015-01-14 08:12:47 -0800492 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800493 this->setHasVertexColor();
494 }
joshualitt71c92602015-01-14 08:12:47 -0800495 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
joshualitt2dd1ae02014-12-03 06:24:10 -0800496 kVec2f_GrVertexAttribType));
jvanverthfa38a302014-10-06 05:59:05 -0700497 this->addTextureAccess(&fTextureAccess);
498}
499
bsalomon0e08fc12014-10-15 08:19:04 -0700500bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
jvanverthfa38a302014-10-06 05:59:05 -0700501 const GrDistanceFieldNoGammaTextureEffect& cte =
502 other.cast<GrDistanceFieldNoGammaTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700503 return fFlags == cte.fFlags;
jvanverthfa38a302014-10-06 05:59:05 -0700504}
505
joshualitt56995b52014-12-11 15:44:02 -0800506void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
507 out->setUnknownSingleComponent();
jvanverthfa38a302014-10-06 05:59:05 -0700508}
509
joshualitteb2a6762014-12-04 11:35:33 -0800510void GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
511 const GrGLCaps& caps,
512 GrProcessorKeyBuilder* b) const {
513 GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b);
514}
515
joshualittabb52a12015-01-13 15:02:10 -0800516GrGLPrimitiveProcessor*
517GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt,
518 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800519 return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt));
jvanverthfa38a302014-10-06 05:59:05 -0700520}
521
joshualitt9b989322014-12-15 14:16:27 -0800522void GrDistanceFieldNoGammaTextureEffect::initBatchTracker(GrBatchTracker* bt,
joshualittca0a1792015-01-27 06:41:33 -0800523 const InitBT& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800524 DistanceFieldNoGammaBatchTracker* local = bt->cast<DistanceFieldNoGammaBatchTracker>();
525 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
526 SkToBool(fInColor));
joshualitt290c09b2014-12-19 13:45:20 -0800527 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800528}
529
530bool GrDistanceFieldNoGammaTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800531 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800532 const GrBatchTracker& t) const {
533 const DistanceFieldNoGammaBatchTracker& mine = m.cast<DistanceFieldNoGammaBatchTracker>();
534 const DistanceFieldNoGammaBatchTracker& theirs = t.cast<DistanceFieldNoGammaBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800535 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
536 that, theirs.fUsesLocalCoords) &&
537 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800538 theirs.fInputColorType, theirs.fColor);
539}
540
jvanverthfa38a302014-10-06 05:59:05 -0700541///////////////////////////////////////////////////////////////////////////////
542
543GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect);
544
545GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* random,
546 GrContext*,
547 const GrDrawTargetCaps&,
548 GrTexture* textures[]) {
549 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
550 : GrProcessorUnitTest::kAlphaTextureIdx;
551 static const SkShader::TileMode kTileModes[] = {
552 SkShader::kClamp_TileMode,
553 SkShader::kRepeat_TileMode,
554 SkShader::kMirror_TileMode,
555 };
556 SkShader::TileMode tileModes[] = {
557 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
558 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
559 };
560 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode
561 : GrTextureParams::kNone_FilterMode);
562
joshualitt8059eb92014-12-29 15:10:07 -0800563 return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random),
564 GrProcessorUnitTest::TestMatrix(random),
565 textures[texIdx],
joshualitt2e3b3e32014-12-09 13:31:14 -0800566 params,
joshualitt56995b52014-12-11 15:44:02 -0800567 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
jvanverthfa38a302014-10-06 05:59:05 -0700568}
569
570///////////////////////////////////////////////////////////////////////////////
571
joshualitt9b989322014-12-15 14:16:27 -0800572struct DistanceFieldLCDBatchTracker {
573 GrGPInput fInputColorType;
574 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800575 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800576};
577
joshualitt249af152014-09-15 11:41:13 -0700578class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000579public:
joshualitteb2a6762014-12-04 11:35:33 -0800580 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800581 const GrBatchTracker&)
joshualitt9b989322014-12-15 14:16:27 -0800582 : fColor(GrColor_ILLEGAL)
583 , fTextureSize(SkISize::Make(-1,-1))
jvanverth9564ce62014-09-16 05:45:19 -0700584 , fTextColor(GrColor_ILLEGAL) {}
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000585
robertphillips46d36f02015-01-18 08:14:14 -0800586 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000587 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
joshualittc369e7c2014-10-22 10:56:26 -0700588 args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800589 const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>();
590 GrGLGPBuilder* pb = args.fPB;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000591
joshualittc369e7c2014-10-22 10:56:26 -0700592 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualittabb52a12015-01-13 15:02:10 -0800593
594 // emit attributes
595 vsBuilder->emitAttributes(dfTexEffect);
596
joshualitt2dd1ae02014-12-03 06:24:10 -0800597 GrGLVertToFrag v(kVec2f_GrSLType);
598 args.fPB->addVarying("TextureCoords", &v);
599 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
600
joshualitt9b989322014-12-15 14:16:27 -0800601 // setup pass through color
602 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
603 &fColorUniform);
604
joshualittee2af952014-12-30 09:04:15 -0800605 // setup uniform viewMatrix
606 this->addUniformViewMatrix(pb);
607
joshualittabb52a12015-01-13 15:02:10 -0800608 // Setup position
robertphillips46d36f02015-01-18 08:14:14 -0800609 SetupPosition(vsBuilder, gpArgs, dfTexEffect.inPosition()->fName,
610 dfTexEffect.viewMatrix(), this->uViewM());
joshualitt4973d9d2014-11-08 09:24:25 -0800611
joshualittabb52a12015-01-13 15:02:10 -0800612 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -0800613 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -0800614 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
615
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000616 const char* textureSizeUniName = NULL;
617 // width, height, 1/(3*width)
joshualittc369e7c2014-10-22 10:56:26 -0700618 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800619 kVec3f_GrSLType, kDefault_GrSLPrecision,
620 "TextureSize", &textureSizeUniName);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000621
joshualittc369e7c2014-10-22 10:56:26 -0700622 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700623
624 SkAssertResult(fsBuilder->enableFeature(
625 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
626
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000627 // create LCD offset adjusted by inverse of transform
jvanverthfdf7ccc2015-01-27 08:19:33 -0800628 // Use highp to work around aliasing issues
629 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
630 pb->ctxInfo().standard()));
631 fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn());
632 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
633 pb->ctxInfo().standard()));
634 fsBuilder->codeAppendf("vec2 st = uv*%s.xy;\n", textureSizeUniName);
jvanverth78f07182014-07-30 06:17:59 -0700635 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
636 if (isUniformScale) {
joshualitt30ba4362014-08-21 20:18:45 -0700637 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
638 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000639 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700640 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
641 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
642 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000643 }
644
645 // green is distance to uv center
joshualitt30ba4362014-08-21 20:18:45 -0700646 fsBuilder->codeAppend("\tvec4 texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700647 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700648 fsBuilder->codeAppend(";\n");
649 fsBuilder->codeAppend("\tvec3 distance;\n");
650 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000651 // red is distance to left offset
joshualitt30ba4362014-08-21 20:18:45 -0700652 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
653 fsBuilder->codeAppend("\ttexColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700654 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700655 fsBuilder->codeAppend(";\n");
656 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000657 // blue is distance to right offset
joshualitt30ba4362014-08-21 20:18:45 -0700658 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
659 fsBuilder->codeAppend("\ttexColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700660 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700661 fsBuilder->codeAppend(";\n");
662 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700663
joshualitt30ba4362014-08-21 20:18:45 -0700664 fsBuilder->codeAppend("\tdistance = "
jvanverthada68ef2014-11-03 14:00:24 -0800665 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
jvanverth2d2a68c2014-06-10 06:42:56 -0700666
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000667 // we adjust for the effect of the transformation on the distance by using
668 // the length of the gradient of the texture coordinates. We use st coordinates
669 // to ensure we're mapping 1:1 from texel space to pixel space.
670
671 // To be strictly correct, we should compute the anti-aliasing factor separately
672 // for each color component. However, this is only important when using perspective
673 // transformations, and even then using a single factor seems like a reasonable
674 // trade-off between quality and speed.
joshualitt30ba4362014-08-21 20:18:45 -0700675 fsBuilder->codeAppend("\tfloat afwidth;\n");
jvanverth78f07182014-07-30 06:17:59 -0700676 if (isUniformScale) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000677 // this gives us a smooth step across approximately one fragment
jvanverthfa38a302014-10-06 05:59:05 -0700678 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dx);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000679 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700680 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
joshualittc369e7c2014-10-22 10:56:26 -0700681 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000682 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
joshualitt30ba4362014-08-21 20:18:45 -0700683 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
684 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
685 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
686 fsBuilder->codeAppend("\t} else {\n");
687 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
688 fsBuilder->codeAppend("\t}\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000689 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700690 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000691 }
joshualitt30ba4362014-08-21 20:18:45 -0700692 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
693 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000694
695 // this gives us a smooth step across approximately one fragment
joshualitt30ba4362014-08-21 20:18:45 -0700696 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000697 }
698
joshualitt30ba4362014-08-21 20:18:45 -0700699 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000700
jvanverth2d2a68c2014-06-10 06:42:56 -0700701 // adjust based on gamma
702 const char* textColorUniName = NULL;
703 // width, height, 1/(3*width)
joshualittc369e7c2014-10-22 10:56:26 -0700704 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800705 kVec3f_GrSLType, kDefault_GrSLPrecision,
706 "TextColor", &textColorUniName);
jvanverth2d2a68c2014-06-10 06:42:56 -0700707
joshualitt30ba4362014-08-21 20:18:45 -0700708 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800709 fsBuilder->codeAppend("float gammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700710 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800711 fsBuilder->codeAppend(".r;\n");
712 fsBuilder->codeAppend("\tval.x = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700713
joshualitt30ba4362014-08-21 20:18:45 -0700714 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
715 fsBuilder->codeAppend("\tgammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700716 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800717 fsBuilder->codeAppend(".r;\n");
718 fsBuilder->codeAppend("\tval.y = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700719
joshualitt30ba4362014-08-21 20:18:45 -0700720 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
721 fsBuilder->codeAppend("\tgammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700722 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800723 fsBuilder->codeAppend(".r;\n");
724 fsBuilder->codeAppend("\tval.z = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700725
joshualitt2dd1ae02014-12-03 06:24:10 -0800726 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000727 }
728
kkinnunen7510b222014-07-30 00:04:16 -0700729 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800730 const GrPrimitiveProcessor& processor,
731 const GrBatchTracker& bt) SK_OVERRIDE {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000732 SkASSERT(fTextureSizeUni.isValid());
jvanverth2d2a68c2014-06-10 06:42:56 -0700733 SkASSERT(fTextColorUni.isValid());
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000734
jvanverth2d2a68c2014-06-10 06:42:56 -0700735 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
joshualittb0a8a372014-09-23 09:50:21 -0700736 processor.cast<GrDistanceFieldLCDTextureEffect>();
737 GrTexture* texture = processor.texture(0);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000738 if (texture->width() != fTextureSize.width() ||
739 texture->height() != fTextureSize.height()) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000740 fTextureSize = SkISize::Make(texture->width(), texture->height());
741 float delta = 1.0f/(3.0f*texture->width());
jvanverth78f07182014-07-30 06:17:59 -0700742 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000743 delta = -delta;
744 }
kkinnunen7510b222014-07-30 00:04:16 -0700745 pdman.set3f(fTextureSizeUni,
746 SkIntToScalar(fTextureSize.width()),
747 SkIntToScalar(fTextureSize.height()),
748 delta);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000749 }
jvanverth2d2a68c2014-06-10 06:42:56 -0700750
751 GrColor textColor = dfTexEffect.getTextColor();
752 if (textColor != fTextColor) {
753 static const float ONE_OVER_255 = 1.f / 255.f;
kkinnunen7510b222014-07-30 00:04:16 -0700754 pdman.set3f(fTextColorUni,
755 GrColorUnpackR(textColor) * ONE_OVER_255,
756 GrColorUnpackG(textColor) * ONE_OVER_255,
757 GrColorUnpackB(textColor) * ONE_OVER_255);
jvanverth2d2a68c2014-06-10 06:42:56 -0700758 fTextColor = textColor;
759 }
joshualitt9b989322014-12-15 14:16:27 -0800760
joshualittee2af952014-12-30 09:04:15 -0800761 this->setUniformViewMatrix(pdman, processor.viewMatrix());
762
joshualitt9b989322014-12-15 14:16:27 -0800763 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
764 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
765 GrGLfloat c[4];
766 GrColorToRGBAFloat(local.fColor, c);
767 pdman.set4fv(fColorUniform, 1, c);
768 fColor = local.fColor;
769 }
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000770 }
771
robertphillips46d36f02015-01-18 08:14:14 -0800772 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800773 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800774 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700775 GrProcessorKeyBuilder* b) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000776 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
robertphillips46d36f02015-01-18 08:14:14 -0800777 gp.cast<GrDistanceFieldLCDTextureEffect>();
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000778
joshualitt9b989322014-12-15 14:16:27 -0800779 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800780 uint32_t key = dfTexEffect.getFlags();
781 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800782 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
783 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800784 b->add32(key);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000785 }
786
787private:
joshualitt9b989322014-12-15 14:16:27 -0800788 GrColor fColor;
789 UniformHandle fColorUniform;
790 UniformHandle fTextureSizeUni;
791 SkISize fTextureSize;
792 UniformHandle fTextColorUni;
793 SkColor fTextColor;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000794
joshualitt249af152014-09-15 11:41:13 -0700795 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000796};
797
798///////////////////////////////////////////////////////////////////////////////
799
jvanverth2d2a68c2014-06-10 06:42:56 -0700800GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
joshualitt8059eb92014-12-29 15:10:07 -0800801 GrColor color, const SkMatrix& viewMatrix,
jvanverth2d2a68c2014-06-10 06:42:56 -0700802 GrTexture* texture, const GrTextureParams& params,
803 GrTexture* gamma, const GrTextureParams& gParams,
804 SkColor textColor,
jvanverth78f07182014-07-30 06:17:59 -0700805 uint32_t flags)
joshualitt8059eb92014-12-29 15:10:07 -0800806 : INHERITED(color, viewMatrix, SkMatrix::I())
joshualitt2e3b3e32014-12-09 13:31:14 -0800807 , fTextureAccess(texture, params)
jvanverth2d2a68c2014-06-10 06:42:56 -0700808 , fGammaTextureAccess(gamma, gParams)
809 , fTextColor(textColor)
joshualitt2dd1ae02014-12-03 06:24:10 -0800810 , fFlags(flags & kLCD_DistanceFieldEffectMask){
jvanverth78f07182014-07-30 06:17:59 -0700811 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
joshualitteb2a6762014-12-04 11:35:33 -0800812 this->initClassID<GrDistanceFieldLCDTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800813 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
814 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
joshualitt2dd1ae02014-12-03 06:24:10 -0800815 kVec2f_GrVertexAttribType));
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000816 this->addTextureAccess(&fTextureAccess);
jvanverth2d2a68c2014-06-10 06:42:56 -0700817 this->addTextureAccess(&fGammaTextureAccess);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000818}
819
bsalomon0e08fc12014-10-15 08:19:04 -0700820bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700821 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700822 return (fTextColor == cte.fTextColor &&
jvanverth78f07182014-07-30 06:17:59 -0700823 fFlags == cte.fFlags);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000824}
825
joshualitt56995b52014-12-11 15:44:02 -0800826void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
827 out->setUnknownFourComponents();
828 out->setUsingLCDCoverage();
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000829}
830
joshualitteb2a6762014-12-04 11:35:33 -0800831void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
832 const GrGLCaps& caps,
833 GrProcessorKeyBuilder* b) const {
834 GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b);
835}
836
joshualittabb52a12015-01-13 15:02:10 -0800837GrGLPrimitiveProcessor*
838GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt,
839 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800840 return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt));
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000841}
842
joshualitt9b989322014-12-15 14:16:27 -0800843void GrDistanceFieldLCDTextureEffect::initBatchTracker(GrBatchTracker* bt,
joshualittca0a1792015-01-27 06:41:33 -0800844 const InitBT& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800845 DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>();
846 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800847 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800848}
849
850bool GrDistanceFieldLCDTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800851 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800852 const GrBatchTracker& t) const {
853 const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>();
854 const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800855 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
856 that, theirs.fUsesLocalCoords) &&
857 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800858 theirs.fInputColorType, theirs.fColor);
859}
860
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000861///////////////////////////////////////////////////////////////////////////////
862
joshualittb0a8a372014-09-23 09:50:21 -0700863GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000864
joshualittb0a8a372014-09-23 09:50:21 -0700865GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
866 GrContext*,
867 const GrDrawTargetCaps&,
868 GrTexture* textures[]) {
869 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
870 GrProcessorUnitTest::kAlphaTextureIdx;
871 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
872 GrProcessorUnitTest::kAlphaTextureIdx;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000873 static const SkShader::TileMode kTileModes[] = {
874 SkShader::kClamp_TileMode,
875 SkShader::kRepeat_TileMode,
876 SkShader::kMirror_TileMode,
877 };
878 SkShader::TileMode tileModes[] = {
879 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
880 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
881 };
882 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
883 GrTextureParams::kNone_FilterMode);
jvanverth2d2a68c2014-06-10 06:42:56 -0700884 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
885 GrTextureParams::kNone_FilterMode);
886 GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
887 random->nextULessThan(256),
888 random->nextULessThan(256),
889 random->nextULessThan(256));
jvanverth78f07182014-07-30 06:17:59 -0700890 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
891 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
892 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
joshualitt8059eb92014-12-29 15:10:07 -0800893 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
894 GrProcessorUnitTest::TestMatrix(random),
895 textures[texIdx], params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700896 textures[texIdx2], params2,
897 textColor,
jvanverth78f07182014-07-30 06:17:59 -0700898 flags);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000899}