GrDistanceFieldGeoProc.cpp revision 64c4728c70001ed074fecf5c4e083781987b12e9
1d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/*
2d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Copyright 2013 Google Inc.
3d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *
4d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Use of this source code is governed by a BSD-style license that can be
5d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * found in the LICENSE file.
6d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com */
7d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
88ed3b9a386374d7996dfbe0c9de13b42f3dd245djvanverth#include "GrDistanceFieldGeoProc.h"
9605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
10eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrTexture.h"
1121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth
12eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkDistanceFieldGen.h"
1321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth
14249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h"
1564c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
162d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
172d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLProgramBuilder.h"
18018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
192d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLVertexShaderBuilder.h"
2064c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLUtil.h"
21d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
2221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth// Assuming a radius of a little less than the diagonal of the fragment
2324ba00825092be0d400074e0121ffc7221950dd9jvanverth#define SK_DistanceFieldAAFactor     "0.65"
242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
25502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor {
26d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic:
27465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldA8TextGeoProc()
285559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        : fViewMatrix(SkMatrix::InvalidMatrix())
295559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        , fColor(GrColor_ILLEGAL)
309564ce60a657acce89fb956deb8645b324eaad1ejvanverth#ifdef SK_GAMMA_APPLY_TO_A8
3121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        , fDistanceAdjust(-1.0f)
329564ce60a657acce89fb956deb8645b324eaad1ejvanverth#endif
339564ce60a657acce89fb956deb8645b324eaad1ejvanverth        {}
34d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
3536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
36502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldA8TextGeoProc& dfTexEffect =
37502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
388dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLGPBuilder* pb = args.fPB;
392d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
4030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        SkAssertResult(fsBuilder->enableFeature(
412d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel                GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
426c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
432d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
44abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
45abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
46abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
47abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
4821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
4921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        // adjust based on gamma
5096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        const char* distanceAdjustUniName = nullptr;
5121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        // width, height, 1/(3*width)
522d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
5321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            kFloat_GrSLType, kDefault_GrSLPrecision,
5421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            "DistanceAdjust", &distanceAdjustUniName);
5521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#endif
56d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // Setup pass through color
58b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        if (!dfTexEffect.colorIgnored()) {
59b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            if (dfTexEffect.hasVertexColor()) {
60b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
61b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            } else {
62b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
63b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            }
64b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        }
656c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
66abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
675559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
685559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                            &fViewMatrixUniform);
694973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
70abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
71f529439fea003851d986a0573a7e0465754b2a48egdaniel        this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
72e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt                             args.fTransformsIn, args.fTransformsOut);
73abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
74bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        // add varyings
758dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
768dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag st(kVec2f_GrSLType);
77bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
78f529439fea003851d986a0573a7e0465754b2a48egdaniel        pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
79221360a514fb4bfff5b461e83262306b2a0f36afjvanverth        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
80bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth
81922c8b13c512c3287509936795735c1b31bedba9joshualitt        // compute numbers to be hardcoded to convert texture coordinates from int to float
82922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(dfTexEffect.numTextures() == 1);
83922c8b13c512c3287509936795735c1b31bedba9joshualitt        GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
847375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
85922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkScalar recipWidth = 1.0f / atlas->width();
86922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkScalar recipHeight = 1.0f / atlas->height();
87922c8b13c512c3287509936795735c1b31bedba9joshualitt
888dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag uv(kVec2f_GrSLType);
89f529439fea003851d986a0573a7e0465754b2a48egdaniel        pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
90922c8b13c512c3287509936795735c1b31bedba9joshualitt        vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
917375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
927375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
93bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth                               dfTexEffect.inTextureCoords()->fName);
94bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth
95fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
960d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel        fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
970d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel                                                               kHigh_GrSLPrecision));
985a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
99fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth
100fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("\tfloat texColor = ");
101c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0],
102fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                       "uv",
103d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                       kVec2f_GrSLType);
104fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;\n");
10530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tfloat distance = "
106fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                       SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
10721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
10821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        // adjust width based on gamma
10921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
11021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#endif
1116c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
112354eba5cb61801130a84378356434d3cc0a4b71ajvanverth        fsBuilder->codeAppend("float afwidth;");
113bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        if (isSimilarity) {
114354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For uniform scale, we adjust for the effect of the transformation on the distance
115354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // by using the length of the gradient of the texture coordinates. We use st coordinates
116221360a514fb4bfff5b461e83262306b2a0f36afjvanverth            // to ensure we're mapping 1:1 from texel space to pixel space.
117354eba5cb61801130a84378356434d3cc0a4b71ajvanverth
1184362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
119221360a514fb4bfff5b461e83262306b2a0f36afjvanverth            // we use y to work around a Mali400 bug in the x direction
120221360a514fb4bfff5b461e83262306b2a0f36afjvanverth            fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
121bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth                                       st.fsIn());
1224362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org        } else {
123354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For general transforms, to determine the amount of correction we multiply a unit
124354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
125354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // (which is the inverse transform for this fragment) and take the length of the result.
126354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
127d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // the length of the gradient may be 0, so we need to check for this
128d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // this also compensates for the Adreno, which likes to drop tiles on division by 0
129d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
130d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
131d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
132d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("} else {");
133d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
134d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("}");
135d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth
136bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
137bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
138354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
139354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
1404362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org
1414362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
142354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
1434362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org        }
144354eba5cb61801130a84378356434d3cc0a4b71ajvanverth        fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
1454d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth
1462dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
147d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
148d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
149018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
1502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
151502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>();
15221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        float distanceAdjust = dfTexEffect.getDistanceAdjust();
15321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        if (distanceAdjust != fDistanceAdjust) {
15421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            pdman.set1f(fDistanceAdjustUni, distanceAdjust);
15521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            fDistanceAdjust = distanceAdjust;
1562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
1572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
158e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt        const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>();
1595559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt
1605559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        if (!dfa8gp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfa8gp.viewMatrix())) {
1615559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            fViewMatrix = dfa8gp.viewMatrix();
162018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float viewMatrix[3 * 3];
16364c4728c70001ed074fecf5c4e083781987b12e9egdaniel            GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
1645559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
1655559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        }
166ee2af95db72152dfa61c841875df0594ca93437djoshualitt
167b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        if (dfa8gp.color() != fColor && !dfa8gp.hasVertexColor()) {
168018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float c[4];
169b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            GrColorToRGBAFloat(dfa8gp.color(), c);
1709b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
171b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            fColor = dfa8gp.color();
1729b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
1736c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org    }
174d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
17546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
176cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                              const GrGLSLCaps&,
177b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              GrProcessorKeyBuilder* b) {
178502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>();
1798fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
180b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        key |= dfTexEffect.hasVertexColor() << 16;
181b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        key |= dfTexEffect.colorIgnored() << 17;
182e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt        key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25;
1838fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
184922c8b13c512c3287509936795735c1b31bedba9joshualitt
185922c8b13c512c3287509936795735c1b31bedba9joshualitt        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
186922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(gp.numTextures() == 1);
187922c8b13c512c3287509936795735c1b31bedba9joshualitt        GrTexture* atlas = gp.textureAccess(0).getTexture();
188922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(atlas);
189922c8b13c512c3287509936795735c1b31bedba9joshualitt        b->add32(atlas->width());
190922c8b13c512c3287509936795735c1b31bedba9joshualitt        b->add32(atlas->height());
1914362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org    }
1924362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org
193d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate:
1945559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    SkMatrix      fViewMatrix;
1959b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor       fColor;
1969b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fColorUniform;
1975559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    UniformHandle fViewMatrixUniform;
19850282b4390dcddcf3b1d51631c0133045ae1f233mtklein#ifdef SK_GAMMA_APPLY_TO_A8
19921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    float         fDistanceAdjust;
20021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    UniformHandle fDistanceAdjustUni;
20150282b4390dcddcf3b1d51631c0133045ae1f233mtklein#endif
2026c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
203249af15fb82833d2274850c589812b6e69df0033joshualitt    typedef GrGLGeometryProcessor INHERITED;
204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com};
205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
206d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com///////////////////////////////////////////////////////////////////////////////
207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
208502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color,
2098059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                           const SkMatrix& viewMatrix,
2102e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                                           GrTexture* texture,
2116c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org                                                           const GrTextureParams& params,
2122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
21321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                                                           float distanceAdjust,
2142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
215b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                           uint32_t flags,
216b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                           bool usesLocalCoords)
217e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt    : fColor(color)
218e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt    , fViewMatrix(viewMatrix)
2192e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
2202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
22121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    , fDistanceAdjust(distanceAdjust)
2222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
223249af15fb82833d2274850c589812b6e69df0033joshualitt    , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
22496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fInColor(nullptr)
225b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    , fUsesLocalCoords(usesLocalCoords) {
22678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
227502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth    this->initClassID<GrDistanceFieldA8TextGeoProc>();
228f2539d50f911914af0f80f0092ff8c654869e650senorblanco    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
229f2539d50f911914af0f80f0092ff8c654869e650senorblanco                                                   kHigh_GrSLPrecision));
2302dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    if (flags & kColorAttr_DistanceFieldEffectFlag) {
23171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt        fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
2322dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
23371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
2345a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                                                          kVec2s_GrVertexAttribType));
235d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    this->addTextureAccess(&fTextureAccess);
236d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
237d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
238465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittvoid GrDistanceFieldA8TextGeoProc::getGLProcessorKey(const GrGLSLCaps& caps,
239eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                     GrProcessorKeyBuilder* b) const {
240465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldA8TextGeoProc::GenKey(*this, caps, b);
241eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
242eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
243465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittGrGLPrimitiveProcessor* GrDistanceFieldA8TextGeoProc::createGLInstance(const GrGLSLCaps&) const {
244465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    return new GrGLDistanceFieldA8TextGeoProc();
245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
246d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
247d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com///////////////////////////////////////////////////////////////////////////////
248d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
249502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc);
250d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
251c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorTestData* d) {
2520067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
2530067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                          GrProcessorUnitTest::kAlphaTextureIdx;
254d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    static const SkShader::TileMode kTileModes[] = {
255d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kClamp_TileMode,
256d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kRepeat_TileMode,
257d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kMirror_TileMode,
258d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    };
259d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkShader::TileMode tileModes[] = {
2600067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
2610067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
262d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    };
2630067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
264d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                           GrTextureParams::kNone_FilterMode);
265d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
2660067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(d->fRandom),
2670067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                GrTest::TestMatrix(d->fRandom),
2680067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                d->fTextures[texIdx], params,
2692d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
2700067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                d->fRandom->nextF(),
2712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
2720067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                d->fRandom->nextBool() ?
273b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                    kSimilarity_DistanceFieldEffectFlag : 0,
2740067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                    d->fRandom->nextBool());
275609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
276609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
277609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
278609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
279502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldPathGeoProc : public GrGLGeometryProcessor {
280fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthpublic:
281465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldPathGeoProc()
2825559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        : fViewMatrix(SkMatrix::InvalidMatrix())
2835559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        , fColor(GrColor_ILLEGAL)
2845559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        , fTextureSize(SkISize::Make(-1, -1)) {}
285fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
28636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
287502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
288fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
2898dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLGPBuilder* pb = args.fPB;
2902d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
291fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkAssertResult(fsBuilder->enableFeature(
2922d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel                                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
293fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
2942d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
295abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
296abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
297abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
298abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
2998dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag v(kVec2f_GrSLType);
300f529439fea003851d986a0573a7e0465754b2a48egdaniel        pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
301fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3029b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // setup pass through color
303b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        if (!dfTexEffect.colorIgnored()) {
304b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            if (dfTexEffect.hasVertexColor()) {
305b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
306b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            } else {
307b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
308b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            }
309b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        }
310e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
311e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed
312abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
3135559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
3145559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                            &fViewMatrixUniform);
315abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
316abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
317f529439fea003851d986a0573a7e0465754b2a48egdaniel        this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
318e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt                             args.fTransformsIn, args.fTransformsOut);
3194973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
32096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        const char* textureSizeUniName = nullptr;
3212d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
322f529439fea003851d986a0573a7e0465754b2a48egdaniel                                         kVec2f_GrSLType, kDefault_GrSLPrecision,
323f529439fea003851d986a0573a7e0465754b2a48egdaniel                                         "TextureSize", &textureSizeUniName);
324e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed
325fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
3260d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel        fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
3270d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel                                                               kHigh_GrSLPrecision));
328e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
329fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth
330fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("float texColor = ");
331c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0],
332fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                       "uv",
333fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                       kVec2f_GrSLType);
334fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;");
335fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float distance = "
336fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth            SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
337fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3380d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel        fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
3390d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel                                                               kHigh_GrSLPrecision));
340e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
341fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float afwidth;");
342fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
343354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For uniform scale, we adjust for the effect of the transformation on the distance
344354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // by using the length of the gradient of the texture coordinates. We use st coordinates
345354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // to ensure we're mapping 1:1 from texel space to pixel space.
346354eba5cb61801130a84378356434d3cc0a4b71ajvanverth
347fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            // this gives us a smooth step across approximately one fragment
348bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth            fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
349fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        } else {
350354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For general transforms, to determine the amount of correction we multiply a unit
351354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
352354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // (which is the inverse transform for this fragment) and take the length of the result.
353354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
354d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // the length of the gradient may be 0, so we need to check for this
355d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // this also compensates for the Adreno, which likes to drop tiles on division by 0
356d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
357d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
358d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
359d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("} else {");
360d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
361d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("}");
362d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth
363354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
364354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
365354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
366354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
367fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
368fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            // this gives us a smooth step across approximately one fragment
369fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
370fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        }
371fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
372fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3732dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
374fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
375fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
376018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
377e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        SkASSERT(fTextureSizeUni.isValid());
378fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
37987f48d997ec29e5eeaa7567355775e93465dd60djoshualitt        GrTexture* texture = proc.texture(0);
380fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        if (texture->width() != fTextureSize.width() ||
381fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            texture->height() != fTextureSize.height()) {
382fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fTextureSize = SkISize::Make(texture->width(), texture->height());
383e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed            pdman.set2f(fTextureSizeUni,
384e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                        SkIntToScalar(fTextureSize.width()),
385e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                        SkIntToScalar(fTextureSize.height()));
386fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        }
3879b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
388e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt        const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
3895559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt
3905559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.viewMatrix())) {
3915559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            fViewMatrix = dfpgp.viewMatrix();
392018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float viewMatrix[3 * 3];
39364c4728c70001ed074fecf5c4e083781987b12e9egdaniel            GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
3945559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
3955559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        }
396ee2af95db72152dfa61c841875df0594ca93437djoshualitt
397b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        if (dfpgp.color() != fColor) {
398018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float c[4];
399b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            GrColorToRGBAFloat(dfpgp.color(), c);
4009b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
401b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            fColor = dfpgp.color();
4029b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
403fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
404fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
40546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
406cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                              const GrGLSLCaps&,
407fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                              GrProcessorKeyBuilder* b) {
408502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>();
409fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4108fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
411b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        key |= dfTexEffect.colorIgnored() << 16;
412b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        key |= dfTexEffect.hasVertexColor() << 17;
413e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt        key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25;
4148fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
415fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
416fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
417fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthprivate:
4189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fColorUniform;
419e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed    UniformHandle fTextureSizeUni;
4205559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    UniformHandle fViewMatrixUniform;
4215559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    SkMatrix      fViewMatrix;
4229b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor       fColor;
4239b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    SkISize       fTextureSize;
424fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
425fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    typedef GrGLGeometryProcessor INHERITED;
426fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth};
427fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
428fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
429fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
430502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
4312e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        GrColor color,
4328059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt        const SkMatrix& viewMatrix,
4332e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        GrTexture* texture,
4342e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        const GrTextureParams& params,
435b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        uint32_t flags,
436b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        bool usesLocalCoords)
437e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt    : fColor(color)
438e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt    , fViewMatrix(viewMatrix)
4392e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
440fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
44196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    , fInColor(nullptr)
442b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    , fUsesLocalCoords(usesLocalCoords) {
443fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
444502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth    this->initClassID<GrDistanceFieldPathGeoProc>();
445f2539d50f911914af0f80f0092ff8c654869e650senorblanco    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
446f2539d50f911914af0f80f0092ff8c654869e650senorblanco                                                   kHigh_GrSLPrecision));
4472dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    if (flags & kColorAttr_DistanceFieldEffectFlag) {
44871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt        fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
4492dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
45071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
451b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                        kVec2f_GrVertexAttribType));
452fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    this->addTextureAccess(&fTextureAccess);
453fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
454fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
455465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittvoid GrDistanceFieldPathGeoProc::getGLProcessorKey(const GrGLSLCaps& caps,
456502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                                                   GrProcessorKeyBuilder* b) const {
457465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldPathGeoProc::GenKey(*this, caps, b);
458eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
459eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
460465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittGrGLPrimitiveProcessor* GrDistanceFieldPathGeoProc::createGLInstance(const GrGLSLCaps&) const {
461465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    return new GrGLDistanceFieldPathGeoProc();
462fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
463fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
464fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
465fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
466502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc);
467fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
468c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTestData* d) {
4690067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
4700067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                        : GrProcessorUnitTest::kAlphaTextureIdx;
471fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    static const SkShader::TileMode kTileModes[] = {
472fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kClamp_TileMode,
473fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kRepeat_TileMode,
474fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kMirror_TileMode,
475fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    };
476fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    SkShader::TileMode tileModes[] = {
4770067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
4780067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
479fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    };
4800067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode
4810067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                             : GrTextureParams::kNone_FilterMode);
482fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4830067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    return GrDistanceFieldPathGeoProc::Create(GrRandomColor(d->fRandom),
4840067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                              GrTest::TestMatrix(d->fRandom),
4850067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                              d->fTextures[texIdx],
486502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                                              params,
4870067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                              d->fRandom->nextBool() ?
488b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                      kSimilarity_DistanceFieldEffectFlag : 0,
4890067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                      d->fRandom->nextBool());
490fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
491fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
492fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
493fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
494502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldLCDTextGeoProc : public GrGLGeometryProcessor {
495609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic:
496465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldLCDTextGeoProc()
4975559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) {
498502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
49921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    }
500609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
50136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
502502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
503502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
5048dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLGPBuilder* pb = args.fPB;
505609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
5062d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
507abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
508abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
509abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
510abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
5119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // setup pass through color
512b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        if (!dfTexEffect.colorIgnored()) {
513b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
514b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        }
5159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
516abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
5175559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
5185559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                            &fViewMatrixUniform);
5194973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
520abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
521f529439fea003851d986a0573a7e0465754b2a48egdaniel        this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
522e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt                             args.fTransformsIn, args.fTransformsOut);
5235b143038cb47763974d2750ed78d436eb6c38beajvanverth
524bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        // set up varyings
525bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
5268dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
5278dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag st(kVec2f_GrSLType);
528f529439fea003851d986a0573a7e0465754b2a48egdaniel        pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
529221360a514fb4bfff5b461e83262306b2a0f36afjvanverth        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
530bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth
531922c8b13c512c3287509936795735c1b31bedba9joshualitt        // compute numbers to be hardcoded to convert texture coordinates from int to float
532922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(dfTexEffect.numTextures() == 1);
533922c8b13c512c3287509936795735c1b31bedba9joshualitt        GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
5347375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
535922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkScalar recipWidth = 1.0f / atlas->width();
536922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkScalar recipHeight = 1.0f / atlas->height();
537922c8b13c512c3287509936795735c1b31bedba9joshualitt
5388dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        GrGLSLVertToFrag uv(kVec2f_GrSLType);
539f529439fea003851d986a0573a7e0465754b2a48egdaniel        pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
540922c8b13c512c3287509936795735c1b31bedba9joshualitt        vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
5417375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
5427375d6bab2ee8b02da276597ed4d60f22f54eb89joshualitt                               GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
543bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth                               dfTexEffect.inTextureCoords()->fName);
544bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth
545bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth        // add frag shader code
5462d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
54730ba436f04e61d4505fb854d5fc56079636e0788joshualitt
54830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        SkAssertResult(fsBuilder->enableFeature(
5492d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel                GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
55030ba436f04e61d4505fb854d5fc56079636e0788joshualitt
551609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // create LCD offset adjusted by inverse of transform
552fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
5530d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel        fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
5540d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel                                                               kHigh_GrSLPrecision));
5555a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
5560d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel        fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
5570d3f061262a53b775f0a92b0abf8a4a846290d65egdaniel                                                               kHigh_GrSLPrecision));
558922c8b13c512c3287509936795735c1b31bedba9joshualitt
559922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
5605a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
561922c8b13c512c3287509936795735c1b31bedba9joshualitt            fsBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
5625a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        } else {
563922c8b13c512c3287509936795735c1b31bedba9joshualitt            fsBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
5645a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        }
56578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        if (isUniformScale) {
566bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth            fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
567221360a514fb4bfff5b461e83262306b2a0f36afjvanverth            fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
568609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        } else {
569bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
570bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth
571bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
572bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
573bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth            fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
574609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        }
575609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
576609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // green is distance to uv center
57730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec4 texColor = ");
578c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
57930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
58030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec3 distance;\n");
58130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
582609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // red is distance to left offset
58330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
58430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\ttexColor = ");
585c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
58630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
58730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
588609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // blue is distance to right offset
58930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
59030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\ttexColor = ");
591c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
59230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
59330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
5942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
59530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance = "
596ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth           "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
5972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
59821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        // adjust width based on gamma
59996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        const char* distanceAdjustUniName = nullptr;
6002d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel        fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
60121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            kVec3f_GrSLType, kDefault_GrSLPrecision,
60221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            "DistanceAdjust", &distanceAdjustUniName);
60321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
60421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth
605609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // To be strictly correct, we should compute the anti-aliasing factor separately
606609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // for each color component. However, this is only important when using perspective
607609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // transformations, and even then using a single factor seems like a reasonable
608609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // trade-off between quality and speed.
609354eba5cb61801130a84378356434d3cc0a4b71ajvanverth        fsBuilder->codeAppend("float afwidth;");
61078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        if (isUniformScale) {
611354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For uniform scale, we adjust for the effect of the transformation on the distance
612354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // by using the length of the gradient of the texture coordinates. We use st coordinates
613354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // to ensure we're mapping 1:1 from texel space to pixel space.
614354eba5cb61801130a84378356434d3cc0a4b71ajvanverth
615609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
616bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
617609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        } else {
618354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // For general transforms, to determine the amount of correction we multiply a unit
619354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
620354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            // (which is the inverse transform for this fragment) and take the length of the result.
621354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
622d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // the length of the gradient may be 0, so we need to check for this
623d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            // this also compensates for the Adreno, which likes to drop tiles on division by 0
624d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
625d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
626d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
627d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("} else {");
628d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
629d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth            fsBuilder->codeAppend("}");
630354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
631354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
632609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
633609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
634354eba5cb61801130a84378356434d3cc0a4b71ajvanverth            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
635609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        }
636609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
63721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        fsBuilder->codeAppend(
63821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                      "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
63927b6335c71bccb96206ff0495793433bfa982777egdaniel        // set alpha to be max of rgb coverage
64027b6335c71bccb96206ff0495793433bfa982777egdaniel        fsBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
64130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
64227b6335c71bccb96206ff0495793433bfa982777egdaniel        fsBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
643609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
644609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
645018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void setData(const GrGLSLProgramDataManager& pdman,
646465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt                 const GrPrimitiveProcessor& processor) override {
64721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        SkASSERT(fDistanceAdjustUni.isValid());
648609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
6495559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFieldLCDTextGeoProc>();
6505559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdjust();
65121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth        if (wa != fDistanceAdjust) {
65221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            pdman.set3f(fDistanceAdjustUni,
65321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                        wa.fR,
65421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                        wa.fG,
65521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                        wa.fB);
65621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth            fDistanceAdjust = wa;
6572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
6589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
6595559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        if (!dflcd.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dflcd.viewMatrix())) {
6605559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            fViewMatrix = dflcd.viewMatrix();
661018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float viewMatrix[3 * 3];
66264c4728c70001ed074fecf5c4e083781987b12e9egdaniel            GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
6635559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
6645559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        }
665ee2af95db72152dfa61c841875df0594ca93437djoshualitt
6665559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        if (dflcd.color() != fColor) {
667018fb62d12d1febf121fe265da5b6117b86a6541egdaniel            float c[4];
6685559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            GrColorToRGBAFloat(dflcd.color(), c);
6699b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
6705559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            fColor = dflcd.color();
6719b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
672609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
673609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
67446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
675cfc18867d982119d9dc2888bf09f1093012daaddjvanverth                              const GrGLSLCaps&,
676b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              GrProcessorKeyBuilder* b) {
677502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth        const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>();
678609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
6798fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
680b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt        key |= dfTexEffect.colorIgnored() << 16;
681e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt        key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25;
6828fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
683922c8b13c512c3287509936795735c1b31bedba9joshualitt
684922c8b13c512c3287509936795735c1b31bedba9joshualitt        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
685922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(gp.numTextures() == 1);
686922c8b13c512c3287509936795735c1b31bedba9joshualitt        GrTexture* atlas = gp.textureAccess(0).getTexture();
687922c8b13c512c3287509936795735c1b31bedba9joshualitt        SkASSERT(atlas);
688922c8b13c512c3287509936795735c1b31bedba9joshualitt        b->add32(atlas->width());
689922c8b13c512c3287509936795735c1b31bedba9joshualitt        b->add32(atlas->height());
690609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
691609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
692609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate:
6935559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    SkMatrix                                     fViewMatrix;
69421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    GrColor                                      fColor;
6955559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt    UniformHandle                                fViewMatrixUniform;
69621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    UniformHandle                                fColorUniform;
697502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth    GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust;
69821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    UniformHandle                                fDistanceAdjustUni;
699609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
700249af15fb82833d2274850c589812b6e69df0033joshualitt    typedef GrGLGeometryProcessor INHERITED;
701609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org};
702609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
703609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
704609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
705502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
7068059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                  GrColor color, const SkMatrix& viewMatrix,
7072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                  GrTexture* texture, const GrTextureParams& params,
70821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth                                                  DistanceAdjust distanceAdjust,
709b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                  uint32_t flags, bool usesLocalCoords)
710e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt    : fColor(color)
711e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt    , fViewMatrix(viewMatrix)
7122e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
71321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    , fDistanceAdjust(distanceAdjust)
714b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    , fFlags(flags & kLCD_DistanceFieldEffectMask)
715b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    , fUsesLocalCoords(usesLocalCoords) {
71678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
717502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth    this->initClassID<GrDistanceFieldLCDTextGeoProc>();
718f2539d50f911914af0f80f0092ff8c654869e650senorblanco    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
719f2539d50f911914af0f80f0092ff8c654869e650senorblanco                                                   kHigh_GrSLPrecision));
72071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
721b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                        kVec2s_GrVertexAttribType));
722609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    this->addTextureAccess(&fTextureAccess);
723609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
724609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
725465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittvoid GrDistanceFieldLCDTextGeoProc::getGLProcessorKey(const GrGLSLCaps& caps,
726502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                                                      GrProcessorKeyBuilder* b) const {
727465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    GrGLDistanceFieldLCDTextGeoProc::GenKey(*this, caps, b);
728eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
729eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
730465283cdf98ed9ab5285ca7b9814e430fca1d452joshualittGrGLPrimitiveProcessor* GrDistanceFieldLCDTextGeoProc::createGLInstance(const GrGLSLCaps&) const {
731465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt    return new GrGLDistanceFieldLCDTextGeoProc();
732609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
733609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
734609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
735609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
736502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc);
737609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
738c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(GrProcessorTestData* d) {
7390067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
7400067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                          GrProcessorUnitTest::kAlphaTextureIdx;
741609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    static const SkShader::TileMode kTileModes[] = {
742609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kClamp_TileMode,
743609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kRepeat_TileMode,
744609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kMirror_TileMode,
745609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    };
746609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    SkShader::TileMode tileModes[] = {
7470067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
7480067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt        kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
749609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    };
7500067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
751609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                           GrTextureParams::kNone_FilterMode);
75221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth    DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
75378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
7540067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
7550067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
7560067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom),
7570067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                 GrTest::TestMatrix(d->fRandom),
7580067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                 d->fTextures[texIdx], params,
759502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth                                                 wa,
760b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                                                 flags,
7610067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt                                                 d->fRandom->nextBool());
762d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
763