blob: 3b9bc9b6f0dcb7e111779f7bd136a3bb52747e8a [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"
jvanverth5a105ff2015-02-18 11:36:35 -08009#include "GrFontAtlasSizes.h"
egdaniel605dd0f2014-11-12 08:35:25 -080010#include "GrInvariantOutput.h"
joshualitteb2a6762014-12-04 11:35:33 -080011#include "GrTexture.h"
12#include "SkDistanceFieldGen.h"
joshualittb0a8a372014-09-23 09:50:21 -070013#include "gl/GrGLProcessor.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000014#include "gl/GrGLSL.h"
15#include "gl/GrGLTexture.h"
joshualitt249af152014-09-15 11:41:13 -070016#include "gl/GrGLGeometryProcessor.h"
joshualitteb2a6762014-12-04 11:35:33 -080017#include "gl/builders/GrGLProgramBuilder.h"
jvanverth@google.comd830d132013-11-11 20:54:09 +000018
jvanverth2d2a68c2014-06-10 06:42:56 -070019// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2
20#define SK_DistanceFieldAAFactor "0.7071"
21
joshualitt9b989322014-12-15 14:16:27 -080022struct DistanceFieldBatchTracker {
23 GrGPInput fInputColorType;
24 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -080025 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -080026};
27
joshualitt249af152014-09-15 11:41:13 -070028class GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor {
jvanverth@google.comd830d132013-11-11 20:54:09 +000029public:
joshualitteb2a6762014-12-04 11:35:33 -080030 GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -080031 const GrBatchTracker&)
joshualitt9b989322014-12-15 14:16:27 -080032 : fColor(GrColor_ILLEGAL)
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
jvanverth5a105ff2015-02-18 11:36:35 -080052 GrGLVertToFrag st(kVec2f_GrSLType);
jvanverth9671ecd2015-02-23 13:08:39 -080053 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
jvanverth5a105ff2015-02-18 11:36:35 -080054 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
55
56 GrGLVertToFrag uv(kVec2f_GrSLType);
jvanverth9671ecd2015-02-23 13:08:39 -080057 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
jvanverth5a105ff2015-02-18 11:36:35 -080058 // this is only used with text, so our texture bounds always match the glyph atlas
59 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
60 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
61 dfTexEffect.inTextureCoords()->fName);
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000062
joshualitt9b989322014-12-15 14:16:27 -080063 // Setup pass through color
64 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
65 dfTexEffect.inColor(), &fColorUniform);
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000066
joshualittabb52a12015-01-13 15:02:10 -080067 // Setup position
joshualittdd219872015-02-12 14:48:42 -080068 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
joshualitt2dd1ae02014-12-03 06:24:10 -080069
joshualittabb52a12015-01-13 15:02:10 -080070 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -080071 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -080072 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
joshualitt4973d9d2014-11-08 09:24:25 -080073
jvanverthfdf7ccc2015-01-27 08:19:33 -080074 // Use highp to work around aliasing issues
75 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
76 pb->ctxInfo().standard()));
jvanverth5a105ff2015-02-18 11:36:35 -080077 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
jvanverthfdf7ccc2015-01-27 08:19:33 -080078
79 fsBuilder->codeAppend("\tfloat texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -070080 fsBuilder->appendTextureLookup(args.fSamplers[0],
jvanverthfdf7ccc2015-01-27 08:19:33 -080081 "uv",
jvanverth@google.comd830d132013-11-11 20:54:09 +000082 kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -080083 fsBuilder->codeAppend(".r;\n");
joshualitt30ba4362014-08-21 20:18:45 -070084 fsBuilder->codeAppend("\tfloat distance = "
jvanverthfdf7ccc2015-01-27 08:19:33 -080085 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +000086
87 // we adjust for the effect of the transformation on the distance by using
88 // the length of the gradient of the texture coordinates. We use st coordinates
89 // to ensure we're mapping 1:1 from texel space to pixel space.
jvanverthfdf7ccc2015-01-27 08:19:33 -080090 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
91 pb->ctxInfo().standard()));
jvanverth5a105ff2015-02-18 11:36:35 -080092 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
joshualitt30ba4362014-08-21 20:18:45 -070093 fsBuilder->codeAppend("\tfloat afwidth;\n");
jvanverth78f07182014-07-30 06:17:59 -070094 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000095 // this gives us a smooth step across approximately one fragment
jvanverthfa38a302014-10-06 05:59:05 -070096 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +000097 } else {
joshualitt30ba4362014-08-21 20:18:45 -070098 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
99 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000100
joshualitt30ba4362014-08-21 20:18:45 -0700101 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
joshualittc369e7c2014-10-22 10:56:26 -0700102 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000103 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
joshualitt30ba4362014-08-21 20:18:45 -0700104 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
105 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
106 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
107 fsBuilder->codeAppend("\t} else {\n");
108 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
109 fsBuilder->codeAppend("\t}\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000110 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700111 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000112 }
joshualitt30ba4362014-08-21 20:18:45 -0700113 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
114 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000115
116 // this gives us a smooth step across approximately one fragment
joshualitt30ba4362014-08-21 20:18:45 -0700117 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000118 }
joshualitt30ba4362014-08-21 20:18:45 -0700119 fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
jvanverth@google.comd830d132013-11-11 20:54:09 +0000120
jvanverth2d2a68c2014-06-10 06:42:56 -0700121#ifdef SK_GAMMA_APPLY_TO_A8
122 // adjust based on gamma
123 const char* luminanceUniName = NULL;
124 // width, height, 1/(3*width)
joshualittc369e7c2014-10-22 10:56:26 -0700125 fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800126 kFloat_GrSLType, kDefault_GrSLPrecision,
127 "Luminance", &luminanceUniName);
jvanverth2d2a68c2014-06-10 06:42:56 -0700128
joshualitt30ba4362014-08-21 20:18:45 -0700129 fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
130 fsBuilder->codeAppend("\tvec4 gammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700131 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700132 fsBuilder->codeAppend(";\n");
133 fsBuilder->codeAppend("\tval = gammaColor.r;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700134#endif
135
joshualitt2dd1ae02014-12-03 06:24:10 -0800136 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000137 }
138
kkinnunen7510b222014-07-30 00:04:16 -0700139 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800140 const GrPrimitiveProcessor& proc,
141 const GrBatchTracker& bt) SK_OVERRIDE {
jvanverth2d2a68c2014-06-10 06:42:56 -0700142#ifdef SK_GAMMA_APPLY_TO_A8
143 const GrDistanceFieldTextureEffect& dfTexEffect =
joshualitt87f48d92014-12-04 10:41:40 -0800144 proc.cast<GrDistanceFieldTextureEffect>();
jvanverth2d2a68c2014-06-10 06:42:56 -0700145 float luminance = dfTexEffect.getLuminance();
146 if (luminance != fLuminance) {
kkinnunen7510b222014-07-30 00:04:16 -0700147 pdman.set1f(fLuminanceUni, luminance);
jvanverth2d2a68c2014-06-10 06:42:56 -0700148 fLuminance = luminance;
149 }
150#endif
joshualitt9b989322014-12-15 14:16:27 -0800151
joshualittee2af952014-12-30 09:04:15 -0800152 this->setUniformViewMatrix(pdman, proc.viewMatrix());
153
joshualitt9b989322014-12-15 14:16:27 -0800154 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
155 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
156 GrGLfloat c[4];
157 GrColorToRGBAFloat(local.fColor, c);
158 pdman.set4fv(fColorUniform, 1, c);
159 fColor = local.fColor;
160 }
commit-bot@chromium.org8fe2ee12014-03-26 18:03:05 +0000161 }
162
robertphillips46d36f02015-01-18 08:14:14 -0800163 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800164 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800165 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700166 GrProcessorKeyBuilder* b) {
robertphillips46d36f02015-01-18 08:14:14 -0800167 const GrDistanceFieldTextureEffect& dfTexEffect = gp.cast<GrDistanceFieldTextureEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800168 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800169 uint32_t key = dfTexEffect.getFlags();
170 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800171 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
172 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800173 b->add32(key);
commit-bot@chromium.org4362a382014-03-26 19:49:03 +0000174 }
175
jvanverth@google.comd830d132013-11-11 20:54:09 +0000176private:
joshualitt9b989322014-12-15 14:16:27 -0800177 GrColor fColor;
178 UniformHandle fColorUniform;
mtklein50282b42015-01-22 07:59:52 -0800179#ifdef SK_GAMMA_APPLY_TO_A8
jvanverth5a105ff2015-02-18 11:36:35 -0800180 UniformHandle fLuminanceUni;
joshualitt9b989322014-12-15 14:16:27 -0800181 float fLuminance;
mtklein50282b42015-01-22 07:59:52 -0800182#endif
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000183
joshualitt249af152014-09-15 11:41:13 -0700184 typedef GrGLGeometryProcessor INHERITED;
jvanverth@google.comd830d132013-11-11 20:54:09 +0000185};
186
187///////////////////////////////////////////////////////////////////////////////
188
joshualitt2e3b3e32014-12-09 13:31:14 -0800189GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800190 const SkMatrix& viewMatrix,
joshualitt2e3b3e32014-12-09 13:31:14 -0800191 GrTexture* texture,
commit-bot@chromium.org6c89c342014-02-14 21:48:29 +0000192 const GrTextureParams& params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700193#ifdef SK_GAMMA_APPLY_TO_A8
194 GrTexture* gamma,
195 const GrTextureParams& gammaParams,
196 float luminance,
197#endif
joshualitt56995b52014-12-11 15:44:02 -0800198 uint32_t flags, bool opaqueVertexColors)
joshualitt8059eb92014-12-29 15:10:07 -0800199 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
joshualitt2e3b3e32014-12-09 13:31:14 -0800200 , fTextureAccess(texture, params)
jvanverth2d2a68c2014-06-10 06:42:56 -0700201#ifdef SK_GAMMA_APPLY_TO_A8
202 , fGammaTextureAccess(gamma, gammaParams)
203 , fLuminance(luminance)
204#endif
joshualitt249af152014-09-15 11:41:13 -0700205 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
joshualitt2dd1ae02014-12-03 06:24:10 -0800206 , fInColor(NULL) {
jvanverth78f07182014-07-30 06:17:59 -0700207 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
joshualitteb2a6762014-12-04 11:35:33 -0800208 this->initClassID<GrDistanceFieldTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800209 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800210 if (flags & kColorAttr_DistanceFieldEffectFlag) {
joshualitt71c92602015-01-14 08:12:47 -0800211 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800212 this->setHasVertexColor();
213 }
joshualitt71c92602015-01-14 08:12:47 -0800214 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
jvanverth5a105ff2015-02-18 11:36:35 -0800215 kVec2s_GrVertexAttribType));
jvanverth@google.comd830d132013-11-11 20:54:09 +0000216 this->addTextureAccess(&fTextureAccess);
jvanverth2d2a68c2014-06-10 06:42:56 -0700217#ifdef SK_GAMMA_APPLY_TO_A8
218 this->addTextureAccess(&fGammaTextureAccess);
219#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000220}
221
bsalomon0e08fc12014-10-15 08:19:04 -0700222bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700223 const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700224 return
jvanverth78f07182014-07-30 06:17:59 -0700225#ifdef SK_GAMMA_APPLY_TO_A8
jvanverth78f07182014-07-30 06:17:59 -0700226 fLuminance == cte.fLuminance &&
227#endif
228 fFlags == cte.fFlags;
jvanverth@google.comd830d132013-11-11 20:54:09 +0000229}
230
joshualitt56995b52014-12-11 15:44:02 -0800231void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
232 out->setUnknownSingleComponent();
jvanverth@google.comd830d132013-11-11 20:54:09 +0000233}
234
joshualitteb2a6762014-12-04 11:35:33 -0800235void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
236 const GrGLCaps& caps,
237 GrProcessorKeyBuilder* b) const {
238 GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b);
239}
240
joshualittabb52a12015-01-13 15:02:10 -0800241GrGLPrimitiveProcessor*
242GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt,
243 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800244 return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt));
jvanverth@google.comd830d132013-11-11 20:54:09 +0000245}
246
joshualitt4d8da812015-01-28 12:53:54 -0800247void GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800248 DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
249 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
250 SkToBool(fInColor));
joshualitt290c09b2014-12-19 13:45:20 -0800251 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800252}
253
254bool GrDistanceFieldTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800255 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800256 const GrBatchTracker& t) const {
257 const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>();
258 const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800259 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
260 that, theirs.fUsesLocalCoords) &&
261 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800262 theirs.fInputColorType, theirs.fColor);
263}
264
jvanverth@google.comd830d132013-11-11 20:54:09 +0000265///////////////////////////////////////////////////////////////////////////////
266
joshualittb0a8a372014-09-23 09:50:21 -0700267GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000268
joshualittb0a8a372014-09-23 09:50:21 -0700269GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
270 GrContext*,
271 const GrDrawTargetCaps&,
272 GrTexture* textures[]) {
273 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
274 GrProcessorUnitTest::kAlphaTextureIdx;
jvanverth2d2a68c2014-06-10 06:42:56 -0700275#ifdef SK_GAMMA_APPLY_TO_A8
joshualittb0a8a372014-09-23 09:50:21 -0700276 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
277 GrProcessorUnitTest::kAlphaTextureIdx;
jvanverth2d2a68c2014-06-10 06:42:56 -0700278#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000279 static const SkShader::TileMode kTileModes[] = {
280 SkShader::kClamp_TileMode,
281 SkShader::kRepeat_TileMode,
282 SkShader::kMirror_TileMode,
283 };
284 SkShader::TileMode tileModes[] = {
285 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
286 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
287 };
288 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
289 GrTextureParams::kNone_FilterMode);
jvanverth2d2a68c2014-06-10 06:42:56 -0700290#ifdef SK_GAMMA_APPLY_TO_A8
291 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
292 GrTextureParams::kNone_FilterMode);
293#endif
jvanverth@google.comd830d132013-11-11 20:54:09 +0000294
joshualitt8059eb92014-12-29 15:10:07 -0800295 return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
296 GrProcessorUnitTest::TestMatrix(random),
297 textures[texIdx], params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700298#ifdef SK_GAMMA_APPLY_TO_A8
299 textures[texIdx2], params2,
300 random->nextF(),
301#endif
jvanverth78f07182014-07-30 06:17:59 -0700302 random->nextBool() ?
joshualitt56995b52014-12-11 15:44:02 -0800303 kSimilarity_DistanceFieldEffectFlag : 0,
304 random->nextBool());
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000305}
306
307///////////////////////////////////////////////////////////////////////////////
308
joshualitt9b989322014-12-15 14:16:27 -0800309struct DistanceFieldNoGammaBatchTracker {
310 GrGPInput fInputColorType;
311 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800312 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800313};
314
jvanverthfa38a302014-10-06 05:59:05 -0700315class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
316public:
joshualitteb2a6762014-12-04 11:35:33 -0800317 GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800318 const GrBatchTracker&)
reede4ef1ca2015-02-17 18:38:38 -0800319 : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {}
jvanverthfa38a302014-10-06 05:59:05 -0700320
robertphillips46d36f02015-01-18 08:14:14 -0800321 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
jvanverthfa38a302014-10-06 05:59:05 -0700322 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
joshualittc369e7c2014-10-22 10:56:26 -0700323 args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>();
jvanverthfa38a302014-10-06 05:59:05 -0700324
joshualitt9b989322014-12-15 14:16:27 -0800325 const DistanceFieldNoGammaBatchTracker& local =
326 args.fBT.cast<DistanceFieldNoGammaBatchTracker>();
327 GrGLGPBuilder* pb = args.fPB;
joshualittc369e7c2014-10-22 10:56:26 -0700328 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
jvanverthfa38a302014-10-06 05:59:05 -0700329 SkAssertResult(fsBuilder->enableFeature(
330 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
331
joshualitt2dd1ae02014-12-03 06:24:10 -0800332 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualittabb52a12015-01-13 15:02:10 -0800333
334 // emit attributes
335 vsBuilder->emitAttributes(dfTexEffect);
336
reede4ef1ca2015-02-17 18:38:38 -0800337 GrGLVertToFrag v(kVec2f_GrSLType);
jvanverth9671ecd2015-02-23 13:08:39 -0800338 args.fPB->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
jvanverthfa38a302014-10-06 05:59:05 -0700339
joshualitt9b989322014-12-15 14:16:27 -0800340 // setup pass through color
341 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
342 dfTexEffect.inColor(), &fColorUniform);
joshualitt2dd1ae02014-12-03 06:24:10 -0800343
reede4ef1ca2015-02-17 18:38:38 -0800344 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
345
joshualittabb52a12015-01-13 15:02:10 -0800346 // Setup position
joshualittdd219872015-02-12 14:48:42 -0800347 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
joshualittabb52a12015-01-13 15:02:10 -0800348
349 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -0800350 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -0800351 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
joshualitt4973d9d2014-11-08 09:24:25 -0800352
reede4ef1ca2015-02-17 18:38:38 -0800353 const char* textureSizeUniName = NULL;
354 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
355 kVec2f_GrSLType, kDefault_GrSLPrecision,
356 "TextureSize", &textureSizeUniName);
357
jvanverthfdf7ccc2015-01-27 08:19:33 -0800358 // Use highp to work around aliasing issues
359 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
360 pb->ctxInfo().standard()));
reede4ef1ca2015-02-17 18:38:38 -0800361 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
jvanverthfdf7ccc2015-01-27 08:19:33 -0800362
363 fsBuilder->codeAppend("float texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700364 fsBuilder->appendTextureLookup(args.fSamplers[0],
jvanverthfdf7ccc2015-01-27 08:19:33 -0800365 "uv",
jvanverthfa38a302014-10-06 05:59:05 -0700366 kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800367 fsBuilder->codeAppend(".r;");
jvanverthfa38a302014-10-06 05:59:05 -0700368 fsBuilder->codeAppend("float distance = "
jvanverthfdf7ccc2015-01-27 08:19:33 -0800369 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
jvanverthfa38a302014-10-06 05:59:05 -0700370
371 // we adjust for the effect of the transformation on the distance by using
372 // the length of the gradient of the texture coordinates. We use st coordinates
373 // to ensure we're mapping 1:1 from texel space to pixel space.
jvanverthfdf7ccc2015-01-27 08:19:33 -0800374 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
375 pb->ctxInfo().standard()));
reede4ef1ca2015-02-17 18:38:38 -0800376 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
jvanverthfa38a302014-10-06 05:59:05 -0700377 fsBuilder->codeAppend("float afwidth;");
378 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
379 // this gives us a smooth step across approximately one fragment
380 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
381 } else {
382 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
383 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
384
385 fsBuilder->codeAppend("vec2 uv_grad;");
joshualittc369e7c2014-10-22 10:56:26 -0700386 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
jvanverthfa38a302014-10-06 05:59:05 -0700387 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
388 fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
389 fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
390 fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
391 fsBuilder->codeAppend("} else {");
392 fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
393 fsBuilder->codeAppend("}");
394 } else {
395 fsBuilder->codeAppend("uv_grad = normalize(uv);");
396 }
397 fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,");
398 fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);");
399
400 // this gives us a smooth step across approximately one fragment
401 fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
402 }
403 fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
404
joshualitt2dd1ae02014-12-03 06:24:10 -0800405 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
jvanverthfa38a302014-10-06 05:59:05 -0700406 }
407
408 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800409 const GrPrimitiveProcessor& proc,
410 const GrBatchTracker& bt) SK_OVERRIDE {
reede4ef1ca2015-02-17 18:38:38 -0800411 SkASSERT(fTextureSizeUni.isValid());
jvanverthfa38a302014-10-06 05:59:05 -0700412
joshualitt87f48d92014-12-04 10:41:40 -0800413 GrTexture* texture = proc.texture(0);
jvanverthfa38a302014-10-06 05:59:05 -0700414 if (texture->width() != fTextureSize.width() ||
415 texture->height() != fTextureSize.height()) {
416 fTextureSize = SkISize::Make(texture->width(), texture->height());
reede4ef1ca2015-02-17 18:38:38 -0800417 pdman.set2f(fTextureSizeUni,
418 SkIntToScalar(fTextureSize.width()),
419 SkIntToScalar(fTextureSize.height()));
jvanverthfa38a302014-10-06 05:59:05 -0700420 }
joshualitt9b989322014-12-15 14:16:27 -0800421
joshualittee2af952014-12-30 09:04:15 -0800422 this->setUniformViewMatrix(pdman, proc.viewMatrix());
423
joshualitt9b989322014-12-15 14:16:27 -0800424 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
425 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
426 GrGLfloat c[4];
427 GrColorToRGBAFloat(local.fColor, c);
428 pdman.set4fv(fColorUniform, 1, c);
429 fColor = local.fColor;
430 }
jvanverthfa38a302014-10-06 05:59:05 -0700431 }
432
robertphillips46d36f02015-01-18 08:14:14 -0800433 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800434 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800435 const GrGLCaps&,
jvanverthfa38a302014-10-06 05:59:05 -0700436 GrProcessorKeyBuilder* b) {
437 const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
robertphillips46d36f02015-01-18 08:14:14 -0800438 gp.cast<GrDistanceFieldNoGammaTextureEffect>();
jvanverthfa38a302014-10-06 05:59:05 -0700439
joshualitt9b989322014-12-15 14:16:27 -0800440 const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800441 uint32_t key = dfTexEffect.getFlags();
442 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800443 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
444 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800445 b->add32(key);
jvanverthfa38a302014-10-06 05:59:05 -0700446 }
447
448private:
joshualitt9b989322014-12-15 14:16:27 -0800449 UniformHandle fColorUniform;
reede4ef1ca2015-02-17 18:38:38 -0800450 UniformHandle fTextureSizeUni;
joshualitt9b989322014-12-15 14:16:27 -0800451 GrColor fColor;
452 SkISize fTextureSize;
jvanverthfa38a302014-10-06 05:59:05 -0700453
454 typedef GrGLGeometryProcessor INHERITED;
455};
456
457///////////////////////////////////////////////////////////////////////////////
458
joshualitt2e3b3e32014-12-09 13:31:14 -0800459GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
460 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800461 const SkMatrix& viewMatrix,
joshualitt2e3b3e32014-12-09 13:31:14 -0800462 GrTexture* texture,
463 const GrTextureParams& params,
joshualitt56995b52014-12-11 15:44:02 -0800464 uint32_t flags,
465 bool opaqueVertexColors)
joshualitt8059eb92014-12-29 15:10:07 -0800466 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
joshualitt2e3b3e32014-12-09 13:31:14 -0800467 , fTextureAccess(texture, params)
jvanverthfa38a302014-10-06 05:59:05 -0700468 , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
joshualitt2dd1ae02014-12-03 06:24:10 -0800469 , fInColor(NULL) {
jvanverthfa38a302014-10-06 05:59:05 -0700470 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
joshualitteb2a6762014-12-04 11:35:33 -0800471 this->initClassID<GrDistanceFieldNoGammaTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800472 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800473 if (flags & kColorAttr_DistanceFieldEffectFlag) {
joshualitt71c92602015-01-14 08:12:47 -0800474 fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
joshualitt2dd1ae02014-12-03 06:24:10 -0800475 this->setHasVertexColor();
476 }
joshualitt71c92602015-01-14 08:12:47 -0800477 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
reede4ef1ca2015-02-17 18:38:38 -0800478 kVec2f_GrVertexAttribType));
jvanverthfa38a302014-10-06 05:59:05 -0700479 this->addTextureAccess(&fTextureAccess);
480}
481
bsalomon0e08fc12014-10-15 08:19:04 -0700482bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
jvanverthfa38a302014-10-06 05:59:05 -0700483 const GrDistanceFieldNoGammaTextureEffect& cte =
484 other.cast<GrDistanceFieldNoGammaTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700485 return fFlags == cte.fFlags;
jvanverthfa38a302014-10-06 05:59:05 -0700486}
487
joshualitt56995b52014-12-11 15:44:02 -0800488void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
489 out->setUnknownSingleComponent();
jvanverthfa38a302014-10-06 05:59:05 -0700490}
491
joshualitteb2a6762014-12-04 11:35:33 -0800492void GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
493 const GrGLCaps& caps,
494 GrProcessorKeyBuilder* b) const {
495 GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b);
496}
497
joshualittabb52a12015-01-13 15:02:10 -0800498GrGLPrimitiveProcessor*
499GrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt,
500 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800501 return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt));
jvanverthfa38a302014-10-06 05:59:05 -0700502}
503
joshualitt9b989322014-12-15 14:16:27 -0800504void GrDistanceFieldNoGammaTextureEffect::initBatchTracker(GrBatchTracker* bt,
joshualitt4d8da812015-01-28 12:53:54 -0800505 const GrPipelineInfo& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800506 DistanceFieldNoGammaBatchTracker* local = bt->cast<DistanceFieldNoGammaBatchTracker>();
507 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
508 SkToBool(fInColor));
joshualitt290c09b2014-12-19 13:45:20 -0800509 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800510}
511
512bool GrDistanceFieldNoGammaTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800513 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800514 const GrBatchTracker& t) const {
515 const DistanceFieldNoGammaBatchTracker& mine = m.cast<DistanceFieldNoGammaBatchTracker>();
516 const DistanceFieldNoGammaBatchTracker& theirs = t.cast<DistanceFieldNoGammaBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800517 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
518 that, theirs.fUsesLocalCoords) &&
519 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800520 theirs.fInputColorType, theirs.fColor);
521}
522
jvanverthfa38a302014-10-06 05:59:05 -0700523///////////////////////////////////////////////////////////////////////////////
524
525GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect);
526
527GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* random,
528 GrContext*,
529 const GrDrawTargetCaps&,
530 GrTexture* textures[]) {
531 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
532 : GrProcessorUnitTest::kAlphaTextureIdx;
533 static const SkShader::TileMode kTileModes[] = {
534 SkShader::kClamp_TileMode,
535 SkShader::kRepeat_TileMode,
536 SkShader::kMirror_TileMode,
537 };
538 SkShader::TileMode tileModes[] = {
539 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
540 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
541 };
542 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode
543 : GrTextureParams::kNone_FilterMode);
544
joshualitt8059eb92014-12-29 15:10:07 -0800545 return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random),
546 GrProcessorUnitTest::TestMatrix(random),
547 textures[texIdx],
joshualitt2e3b3e32014-12-09 13:31:14 -0800548 params,
joshualitt56995b52014-12-11 15:44:02 -0800549 random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
jvanverthfa38a302014-10-06 05:59:05 -0700550}
551
552///////////////////////////////////////////////////////////////////////////////
553
joshualitt9b989322014-12-15 14:16:27 -0800554struct DistanceFieldLCDBatchTracker {
555 GrGPInput fInputColorType;
556 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800557 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800558};
559
joshualitt249af152014-09-15 11:41:13 -0700560class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000561public:
joshualitteb2a6762014-12-04 11:35:33 -0800562 GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800563 const GrBatchTracker&)
joshualitt9b989322014-12-15 14:16:27 -0800564 : fColor(GrColor_ILLEGAL)
jvanverth9564ce62014-09-16 05:45:19 -0700565 , fTextColor(GrColor_ILLEGAL) {}
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000566
robertphillips46d36f02015-01-18 08:14:14 -0800567 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000568 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
joshualittc369e7c2014-10-22 10:56:26 -0700569 args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800570 const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>();
571 GrGLGPBuilder* pb = args.fPB;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000572
joshualittc369e7c2014-10-22 10:56:26 -0700573 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualittabb52a12015-01-13 15:02:10 -0800574
575 // emit attributes
576 vsBuilder->emitAttributes(dfTexEffect);
577
jvanverth5a105ff2015-02-18 11:36:35 -0800578 GrGLVertToFrag st(kVec2f_GrSLType);
jvanverth9671ecd2015-02-23 13:08:39 -0800579 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
jvanverth5a105ff2015-02-18 11:36:35 -0800580 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
581
582 GrGLVertToFrag uv(kVec2f_GrSLType);
jvanverth9671ecd2015-02-23 13:08:39 -0800583 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
jvanverth5a105ff2015-02-18 11:36:35 -0800584 // this is only used with text, so our texture bounds always match the glyph atlas
585 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
586 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
587 dfTexEffect.inTextureCoords()->fName);
588
joshualitt9b989322014-12-15 14:16:27 -0800589 // setup pass through color
590 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
591 &fColorUniform);
592
joshualittabb52a12015-01-13 15:02:10 -0800593 // Setup position
joshualittdd219872015-02-12 14:48:42 -0800594 this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
joshualitt4973d9d2014-11-08 09:24:25 -0800595
joshualittabb52a12015-01-13 15:02:10 -0800596 // emit transforms
robertphillips46d36f02015-01-18 08:14:14 -0800597 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
joshualittabb52a12015-01-13 15:02:10 -0800598 dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
599
joshualittc369e7c2014-10-22 10:56:26 -0700600 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
joshualitt30ba4362014-08-21 20:18:45 -0700601
602 SkAssertResult(fsBuilder->enableFeature(
603 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
604
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000605 // create LCD offset adjusted by inverse of transform
jvanverthfdf7ccc2015-01-27 08:19:33 -0800606 // Use highp to work around aliasing issues
607 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
608 pb->ctxInfo().standard()));
jvanverth5a105ff2015-02-18 11:36:35 -0800609 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
jvanverthfdf7ccc2015-01-27 08:19:33 -0800610 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
611 pb->ctxInfo().standard()));
jvanverth5a105ff2015-02-18 11:36:35 -0800612 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
jvanverth78f07182014-07-30 06:17:59 -0700613 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
jvanverth5a105ff2015-02-18 11:36:35 -0800614
615 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
616 fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n");
617 } else {
618 fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n");
619 }
jvanverth78f07182014-07-30 06:17:59 -0700620 if (isUniformScale) {
joshualitt30ba4362014-08-21 20:18:45 -0700621 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
jvanverth5a105ff2015-02-18 11:36:35 -0800622 fsBuilder->codeAppend("\tvec2 offset = vec2(dx*delta, 0.0);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000623 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700624 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
625 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
jvanverth5a105ff2015-02-18 11:36:35 -0800626 fsBuilder->codeAppend("\tvec2 offset = delta*Jdx;\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000627 }
628
629 // green is distance to uv center
joshualitt30ba4362014-08-21 20:18:45 -0700630 fsBuilder->codeAppend("\tvec4 texColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700631 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700632 fsBuilder->codeAppend(";\n");
633 fsBuilder->codeAppend("\tvec3 distance;\n");
634 fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000635 // red is distance to left offset
joshualitt30ba4362014-08-21 20:18:45 -0700636 fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
637 fsBuilder->codeAppend("\ttexColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700638 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700639 fsBuilder->codeAppend(";\n");
640 fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000641 // blue is distance to right offset
joshualitt30ba4362014-08-21 20:18:45 -0700642 fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
643 fsBuilder->codeAppend("\ttexColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700644 fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
joshualitt30ba4362014-08-21 20:18:45 -0700645 fsBuilder->codeAppend(";\n");
646 fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700647
joshualitt30ba4362014-08-21 20:18:45 -0700648 fsBuilder->codeAppend("\tdistance = "
jvanverthada68ef2014-11-03 14:00:24 -0800649 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
jvanverth2d2a68c2014-06-10 06:42:56 -0700650
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000651 // we adjust for the effect of the transformation on the distance by using
652 // the length of the gradient of the texture coordinates. We use st coordinates
653 // to ensure we're mapping 1:1 from texel space to pixel space.
654
655 // To be strictly correct, we should compute the anti-aliasing factor separately
656 // for each color component. However, this is only important when using perspective
657 // transformations, and even then using a single factor seems like a reasonable
658 // trade-off between quality and speed.
joshualitt30ba4362014-08-21 20:18:45 -0700659 fsBuilder->codeAppend("\tfloat afwidth;\n");
jvanverth78f07182014-07-30 06:17:59 -0700660 if (isUniformScale) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000661 // this gives us a smooth step across approximately one fragment
jvanverthfa38a302014-10-06 05:59:05 -0700662 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dx);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000663 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700664 fsBuilder->codeAppend("\tvec2 uv_grad;\n");
joshualittc369e7c2014-10-22 10:56:26 -0700665 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000666 // this is to compensate for the Adreno, which likes to drop tiles on division by 0
joshualitt30ba4362014-08-21 20:18:45 -0700667 fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
668 fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
669 fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
670 fsBuilder->codeAppend("\t} else {\n");
671 fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
672 fsBuilder->codeAppend("\t}\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000673 } else {
joshualitt30ba4362014-08-21 20:18:45 -0700674 fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000675 }
joshualitt30ba4362014-08-21 20:18:45 -0700676 fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
677 fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000678
679 // this gives us a smooth step across approximately one fragment
joshualitt30ba4362014-08-21 20:18:45 -0700680 fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000681 }
682
joshualitt30ba4362014-08-21 20:18:45 -0700683 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000684
jvanverth2d2a68c2014-06-10 06:42:56 -0700685 // adjust based on gamma
686 const char* textColorUniName = NULL;
joshualittc369e7c2014-10-22 10:56:26 -0700687 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
bsalomon422f56f2014-12-09 10:18:12 -0800688 kVec3f_GrSLType, kDefault_GrSLPrecision,
689 "TextColor", &textColorUniName);
jvanverth2d2a68c2014-06-10 06:42:56 -0700690
joshualitt30ba4362014-08-21 20:18:45 -0700691 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800692 fsBuilder->codeAppend("float gammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700693 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800694 fsBuilder->codeAppend(".r;\n");
695 fsBuilder->codeAppend("\tval.x = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700696
joshualitt30ba4362014-08-21 20:18:45 -0700697 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
698 fsBuilder->codeAppend("\tgammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700699 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800700 fsBuilder->codeAppend(".r;\n");
701 fsBuilder->codeAppend("\tval.y = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700702
joshualitt30ba4362014-08-21 20:18:45 -0700703 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
704 fsBuilder->codeAppend("\tgammaColor = ");
joshualittc369e7c2014-10-22 10:56:26 -0700705 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
jvanverthfdf7ccc2015-01-27 08:19:33 -0800706 fsBuilder->codeAppend(".r;\n");
707 fsBuilder->codeAppend("\tval.z = gammaColor;\n");
jvanverth2d2a68c2014-06-10 06:42:56 -0700708
joshualitt2dd1ae02014-12-03 06:24:10 -0800709 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000710 }
711
kkinnunen7510b222014-07-30 00:04:16 -0700712 virtual void setData(const GrGLProgramDataManager& pdman,
joshualitt9b989322014-12-15 14:16:27 -0800713 const GrPrimitiveProcessor& processor,
714 const GrBatchTracker& bt) SK_OVERRIDE {
jvanverth2d2a68c2014-06-10 06:42:56 -0700715 SkASSERT(fTextColorUni.isValid());
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000716
jvanverth2d2a68c2014-06-10 06:42:56 -0700717 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
joshualittb0a8a372014-09-23 09:50:21 -0700718 processor.cast<GrDistanceFieldLCDTextureEffect>();
jvanverth2d2a68c2014-06-10 06:42:56 -0700719 GrColor textColor = dfTexEffect.getTextColor();
720 if (textColor != fTextColor) {
721 static const float ONE_OVER_255 = 1.f / 255.f;
kkinnunen7510b222014-07-30 00:04:16 -0700722 pdman.set3f(fTextColorUni,
723 GrColorUnpackR(textColor) * ONE_OVER_255,
724 GrColorUnpackG(textColor) * ONE_OVER_255,
725 GrColorUnpackB(textColor) * ONE_OVER_255);
jvanverth2d2a68c2014-06-10 06:42:56 -0700726 fTextColor = textColor;
727 }
joshualitt9b989322014-12-15 14:16:27 -0800728
joshualittee2af952014-12-30 09:04:15 -0800729 this->setUniformViewMatrix(pdman, processor.viewMatrix());
730
joshualitt9b989322014-12-15 14:16:27 -0800731 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
732 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
733 GrGLfloat c[4];
734 GrColorToRGBAFloat(local.fColor, c);
735 pdman.set4fv(fColorUniform, 1, c);
736 fColor = local.fColor;
737 }
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000738 }
739
robertphillips46d36f02015-01-18 08:14:14 -0800740 static inline void GenKey(const GrGeometryProcessor& gp,
joshualitt9b989322014-12-15 14:16:27 -0800741 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800742 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700743 GrProcessorKeyBuilder* b) {
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000744 const GrDistanceFieldLCDTextureEffect& dfTexEffect =
robertphillips46d36f02015-01-18 08:14:14 -0800745 gp.cast<GrDistanceFieldLCDTextureEffect>();
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000746
joshualitt9b989322014-12-15 14:16:27 -0800747 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
joshualitt8fc6c2d2014-12-22 15:27:05 -0800748 uint32_t key = dfTexEffect.getFlags();
749 key |= local.fInputColorType << 16;
robertphillips46d36f02015-01-18 08:14:14 -0800750 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
751 key |= ComputePosKey(gp.viewMatrix()) << 25;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800752 b->add32(key);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000753 }
754
755private:
joshualitt9b989322014-12-15 14:16:27 -0800756 GrColor fColor;
757 UniformHandle fColorUniform;
joshualitt9b989322014-12-15 14:16:27 -0800758 UniformHandle fTextColorUni;
759 SkColor fTextColor;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000760
joshualitt249af152014-09-15 11:41:13 -0700761 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000762};
763
764///////////////////////////////////////////////////////////////////////////////
765
jvanverth2d2a68c2014-06-10 06:42:56 -0700766GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
joshualitt8059eb92014-12-29 15:10:07 -0800767 GrColor color, const SkMatrix& viewMatrix,
jvanverth2d2a68c2014-06-10 06:42:56 -0700768 GrTexture* texture, const GrTextureParams& params,
769 GrTexture* gamma, const GrTextureParams& gParams,
770 SkColor textColor,
jvanverth78f07182014-07-30 06:17:59 -0700771 uint32_t flags)
joshualitt8059eb92014-12-29 15:10:07 -0800772 : INHERITED(color, viewMatrix, SkMatrix::I())
joshualitt2e3b3e32014-12-09 13:31:14 -0800773 , fTextureAccess(texture, params)
jvanverth2d2a68c2014-06-10 06:42:56 -0700774 , fGammaTextureAccess(gamma, gParams)
775 , fTextColor(textColor)
joshualitt2dd1ae02014-12-03 06:24:10 -0800776 , fFlags(flags & kLCD_DistanceFieldEffectMask){
jvanverth78f07182014-07-30 06:17:59 -0700777 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
joshualitteb2a6762014-12-04 11:35:33 -0800778 this->initClassID<GrDistanceFieldLCDTextureEffect>();
joshualitt71c92602015-01-14 08:12:47 -0800779 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
780 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
jvanverth5a105ff2015-02-18 11:36:35 -0800781 kVec2s_GrVertexAttribType));
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000782 this->addTextureAccess(&fTextureAccess);
jvanverth2d2a68c2014-06-10 06:42:56 -0700783 this->addTextureAccess(&fGammaTextureAccess);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000784}
785
bsalomon0e08fc12014-10-15 08:19:04 -0700786bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700787 const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700788 return (fTextColor == cte.fTextColor &&
jvanverth78f07182014-07-30 06:17:59 -0700789 fFlags == cte.fFlags);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000790}
791
joshualitt56995b52014-12-11 15:44:02 -0800792void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
793 out->setUnknownFourComponents();
794 out->setUsingLCDCoverage();
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000795}
796
joshualitteb2a6762014-12-04 11:35:33 -0800797void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
798 const GrGLCaps& caps,
799 GrProcessorKeyBuilder* b) const {
800 GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b);
801}
802
joshualittabb52a12015-01-13 15:02:10 -0800803GrGLPrimitiveProcessor*
804GrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt,
805 const GrGLCaps&) const {
joshualitteb2a6762014-12-04 11:35:33 -0800806 return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt));
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000807}
808
joshualitt9b989322014-12-15 14:16:27 -0800809void GrDistanceFieldLCDTextureEffect::initBatchTracker(GrBatchTracker* bt,
joshualitt4d8da812015-01-28 12:53:54 -0800810 const GrPipelineInfo& init) const {
joshualitt9b989322014-12-15 14:16:27 -0800811 DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>();
812 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800813 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800814}
815
816bool GrDistanceFieldLCDTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
joshualitt290c09b2014-12-19 13:45:20 -0800817 const GrGeometryProcessor& that,
joshualitt9b989322014-12-15 14:16:27 -0800818 const GrBatchTracker& t) const {
819 const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>();
820 const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800821 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
822 that, theirs.fUsesLocalCoords) &&
823 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800824 theirs.fInputColorType, theirs.fColor);
825}
826
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000827///////////////////////////////////////////////////////////////////////////////
828
joshualittb0a8a372014-09-23 09:50:21 -0700829GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect);
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000830
joshualittb0a8a372014-09-23 09:50:21 -0700831GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
832 GrContext*,
833 const GrDrawTargetCaps&,
834 GrTexture* textures[]) {
835 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
836 GrProcessorUnitTest::kAlphaTextureIdx;
837 int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
838 GrProcessorUnitTest::kAlphaTextureIdx;
commit-bot@chromium.org609ced42014-04-03 18:25:48 +0000839 static const SkShader::TileMode kTileModes[] = {
840 SkShader::kClamp_TileMode,
841 SkShader::kRepeat_TileMode,
842 SkShader::kMirror_TileMode,
843 };
844 SkShader::TileMode tileModes[] = {
845 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
846 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
847 };
848 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
849 GrTextureParams::kNone_FilterMode);
jvanverth2d2a68c2014-06-10 06:42:56 -0700850 GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
851 GrTextureParams::kNone_FilterMode);
852 GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
853 random->nextULessThan(256),
854 random->nextULessThan(256),
855 random->nextULessThan(256));
jvanverth78f07182014-07-30 06:17:59 -0700856 uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
857 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
858 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
joshualitt8059eb92014-12-29 15:10:07 -0800859 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
860 GrProcessorUnitTest::TestMatrix(random),
861 textures[texIdx], params,
jvanverth2d2a68c2014-06-10 06:42:56 -0700862 textures[texIdx2], params2,
863 textColor,
jvanverth78f07182014-07-30 06:17:59 -0700864 flags);
jvanverth@google.comd830d132013-11-11 20:54:09 +0000865}