GrDistanceFieldGeoProc.cpp revision 5a105ff05303ac82a867b8b84a1edd145bd46218
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
8d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrDistanceFieldTextureEffect.h"
95a105ff05303ac82a867b8b84a1edd145bd46218jvanverth#include "GrFontAtlasSizes.h"
10605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h"
11eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrTexture.h"
12eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkDistanceFieldGen.h"
13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
14d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h"
15d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h"
16249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h"
17eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h"
18d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2
202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldAAFactor     "0.7071"
212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
229b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldBatchTracker {
239b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrGPInput fInputColorType;
249b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor fColor;
25290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    bool fUsesLocalCoords;
269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt};
279b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
28249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor {
29d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic:
30eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&,
3187f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                                   const GrBatchTracker&)
329b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        : fColor(GrColor_ILLEGAL)
339564ce60a657acce89fb956deb8645b324eaad1ejvanverth#ifdef SK_GAMMA_APPLY_TO_A8
349564ce60a657acce89fb956deb8645b324eaad1ejvanverth        , fLuminance(-1.0f)
359564ce60a657acce89fb956deb8645b324eaad1ejvanverth#endif
369564ce60a657acce89fb956deb8645b324eaad1ejvanverth        {}
37d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
3846d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
39249af15fb82833d2274850c589812b6e69df0033joshualitt        const GrDistanceFieldTextureEffect& dfTexEffect =
40c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt                args.fGP.cast<GrDistanceFieldTextureEffect>();
419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>();
429b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        GrGLGPBuilder* pb = args.fPB;
43c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
4430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        SkAssertResult(fsBuilder->enableFeature(
4530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
466c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
472dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
48abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
49abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
50abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
51abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
525a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        GrGLVertToFrag st(kVec2f_GrSLType);
535a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        args.fPB->addVarying("IntTextureCoords", &st);
545a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
555a105ff05303ac82a867b8b84a1edd145bd46218jvanverth
565a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        GrGLVertToFrag uv(kVec2f_GrSLType);
575a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        args.fPB->addVarying("TextureCoords", &uv);
585a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        // this is only used with text, so our texture bounds always match the glyph atlas
595a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
605a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                               GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
615a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                               dfTexEffect.inTextureCoords()->fName);
62d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // Setup pass through color
649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                    dfTexEffect.inColor(), &fColorUniform);
666c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
67abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
68dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
694973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
70abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
7146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
72abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                             dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
73abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
74fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
75fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
76fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
775a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
78fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth
79fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("\tfloat texColor = ");
80c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0],
81fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                       "uv",
82d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                       kVec2f_GrSLType);
83fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;\n");
8430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tfloat distance = "
85fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                       SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
866c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
876c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org        // we adjust for the effect of the transformation on the distance by using
886c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org        // the length of the gradient of the texture coordinates. We use st coordinates
896c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org        // to ensure we're mapping 1:1 from texel space to pixel space.
90fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
91fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
925a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
9330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tfloat afwidth;\n");
9478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
954362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
96fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));\n");
974362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org        } else {
9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
9930ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
1004362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org
10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 uv_grad;\n");
102c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt            if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
1034362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org                // this is to compensate for the Adreno, which likes to drop tiles on division by 0
10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
10530ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
10630ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
10730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t} else {\n");
10830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
10930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t}\n");
1104362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            } else {
11130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
1124362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            }
11330ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
11430ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
1154362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org
1164362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
11730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
1184362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org        }
11930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
1204d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth
1212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
1222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        // adjust based on gamma
1232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        const char* luminanceUniName = NULL;
1242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        // width, height, 1/(3*width)
125c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
126422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                             kFloat_GrSLType, kDefault_GrSLPrecision,
127422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                             "Luminance", &luminanceUniName);
1282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
12930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
13030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec4 gammaColor = ");
131c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
13230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tval = gammaColor.r;\n");
1342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
1352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
1362dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
137d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
138d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
1397510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    virtual void setData(const GrGLProgramDataManager& pdman,
1409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrPrimitiveProcessor& proc,
1419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrBatchTracker& bt) SK_OVERRIDE {
1422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
1432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        const GrDistanceFieldTextureEffect& dfTexEffect =
14487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                proc.cast<GrDistanceFieldTextureEffect>();
1452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        float luminance = dfTexEffect.getLuminance();
1462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        if (luminance != fLuminance) {
1477510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen            pdman.set1f(fLuminanceUni, luminance);
1482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            fLuminance = luminance;
1492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
1502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
1519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
152ee2af95db72152dfa61c841875df0594ca93437djoshualitt        this->setUniformViewMatrix(pdman, proc.viewMatrix());
153ee2af95db72152dfa61c841875df0594ca93437djoshualitt
1549b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
1559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
1569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrGLfloat c[4];
1579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrColorToRGBAFloat(local.fColor, c);
1589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
1599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            fColor = local.fColor;
1609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
1616c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org    }
162d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
16346d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
1649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                              const GrBatchTracker& bt,
16587f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                              const GrGLCaps&,
166b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              GrProcessorKeyBuilder* b) {
16746d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        const GrDistanceFieldTextureEffect& dfTexEffect = gp.cast<GrDistanceFieldTextureEffect>();
1689b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
1698fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
1708fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        key |= local.fInputColorType << 16;
17146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
17246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= ComputePosKey(gp.viewMatrix()) << 25;
1738fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
1744362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org    }
1754362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org
176d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate:
1779b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor       fColor;
1789b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fColorUniform;
17950282b4390dcddcf3b1d51631c0133045ae1f233mtklein#ifdef SK_GAMMA_APPLY_TO_A8
1805a105ff05303ac82a867b8b84a1edd145bd46218jvanverth    UniformHandle fLuminanceUni;
1819b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    float         fLuminance;
18250282b4390dcddcf3b1d51631c0133045ae1f233mtklein#endif
1836c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org
184249af15fb82833d2274850c589812b6e69df0033joshualitt    typedef GrGLGeometryProcessor INHERITED;
185d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com};
186d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
187d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com///////////////////////////////////////////////////////////////////////////////
188d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
1892e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualittGrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
1908059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                           const SkMatrix& viewMatrix,
1912e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                                           GrTexture* texture,
1926c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org                                                           const GrTextureParams& params,
1932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
1942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                           GrTexture* gamma,
1952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                           const GrTextureParams& gammaParams,
1962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                           float luminance,
1972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
19856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                           uint32_t flags, bool opaqueVertexColors)
1998059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
2002e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
2012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
2022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    , fGammaTextureAccess(gamma, gammaParams)
2032d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    , fLuminance(luminance)
2042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
205249af15fb82833d2274850c589812b6e69df0033joshualitt    , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
2062dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    , fInColor(NULL) {
20778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
208eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<GrDistanceFieldTextureEffect>();
20971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
2102dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    if (flags & kColorAttr_DistanceFieldEffectFlag) {
21171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt        fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
2122dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        this->setHasVertexColor();
2132dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
21471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
2155a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                                                          kVec2s_GrVertexAttribType));
216d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    this->addTextureAccess(&fTextureAccess);
2172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
2182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    this->addTextureAccess(&fGammaTextureAccess);
2192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
220d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
221d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
2220e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
22349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>();
224420d7e9a79358908850c74192b4949375563449absalomon    return
22578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8
22678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth           fLuminance == cte.fLuminance &&
22778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif
22878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth           fFlags == cte.fFlags;
229d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
230d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
23156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualittvoid GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
23256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    out->setUnknownSingleComponent();
233d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
234d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
235eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
236eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                     const GrGLCaps& caps,
237eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                     GrProcessorKeyBuilder* b) const {
238eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b);
239eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
240eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
241abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor*
242abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt,
243abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                                               const GrGLCaps&) const {
244eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt));
245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
246d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
2474d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittvoid GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
2489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
2499b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
2509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                               SkToBool(fInColor));
251290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    local->fUsesLocalCoords = init.fUsesLocalCoords;
2529b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
2539b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
2549b98932adaceb7ad0a617ade16616923f6bffe84joshualittbool GrDistanceFieldTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
255290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                                  const GrGeometryProcessor& that,
2569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                                  const GrBatchTracker& t) const {
2579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>();
2589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>();
259290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
260290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                   that, theirs.fUsesLocalCoords) &&
261290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt           CanCombineOutput(mine.fInputColorType, mine.fColor,
2629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                            theirs.fInputColorType, theirs.fColor);
2639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
2649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
265d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com///////////////////////////////////////////////////////////////////////////////
266d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
267b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect);
268d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
269b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
270b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrContext*,
271b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              const GrDrawTargetCaps&,
272b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                              GrTexture* textures[]) {
273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
274b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      GrProcessorUnitTest::kAlphaTextureIdx;
2752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
276b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
277b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       GrProcessorUnitTest::kAlphaTextureIdx;
2782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
279d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    static const SkShader::TileMode kTileModes[] = {
280d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kClamp_TileMode,
281d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kRepeat_TileMode,
282d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkShader::kMirror_TileMode,
283d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    };
284d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkShader::TileMode tileModes[] = {
285d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
286d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
287d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    };
288d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
289d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                           GrTextureParams::kNone_FilterMode);
2902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
2912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
2922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                            GrTextureParams::kNone_FilterMode);
2932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
294d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
2958059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
2968059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                GrProcessorUnitTest::TestMatrix(random),
2978059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                textures[texIdx], params,
2982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
2992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                textures[texIdx2], params2,
3002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                random->nextF(),
3012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
30278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth                                                random->nextBool() ?
30356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                    kSimilarity_DistanceFieldEffectFlag : 0,
30456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                random->nextBool());
305609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
306609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
307609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
308609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
3099b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldNoGammaBatchTracker {
3109b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrGPInput fInputColorType;
3119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor fColor;
312290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    bool fUsesLocalCoords;
3139b98932adaceb7ad0a617ade16616923f6bffe84joshualitt};
3149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
315fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthclass GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor {
316fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthpublic:
317eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&,
31887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                                          const GrBatchTracker&)
319e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {}
320fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
32146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
322fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
323c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt                args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>();
324fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldNoGammaBatchTracker& local =
3269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                args.fBT.cast<DistanceFieldNoGammaBatchTracker>();
3279b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        GrGLGPBuilder* pb = args.fPB;
328c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
329fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkAssertResult(fsBuilder->enableFeature(
330fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
331fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3322dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
333abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
334abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
335abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
336abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
337e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        GrGLVertToFrag v(kVec2f_GrSLType);
338e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        args.fPB->addVarying("TextureCoords", &v);
339fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
3409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // setup pass through color
3419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
3429b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                    dfTexEffect.inColor(), &fColorUniform);
3432dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt
344e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
345e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed
346abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
347dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
348abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
349abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
35046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
351abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                             dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
3524973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
353e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        const char* textureSizeUniName = NULL;
354e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
355e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                                              kVec2f_GrSLType, kDefault_GrSLPrecision,
356e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                                              "TextureSize", &textureSizeUniName);
357e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed
358fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
359fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
360fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
361e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
362fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth
363fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("float texColor = ");
364c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0],
365fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                       "uv",
366fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                       kVec2f_GrSLType);
367fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;");
368fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float distance = "
369fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth            SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
370fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
371fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        // we adjust for the effect of the transformation on the distance by using
372fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        // the length of the gradient of the texture coordinates. We use st coordinates
373fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        // to ensure we're mapping 1:1 from texel space to pixel space.
374fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
375fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
376e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
377fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float afwidth;");
378fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
379fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            // this gives us a smooth step across approximately one fragment
380fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
381fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        } else {
382fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
383fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
384fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
385fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("vec2 uv_grad;");
386c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt            if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
387fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                // this is to compensate for the Adreno, which likes to drop tiles on division by 0
388fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);");
389fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("if (uv_len2 < 0.0001) {");
390fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);");
391fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("} else {");
392fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);");
393fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("}");
394fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            } else {
395fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                fsBuilder->codeAppend("uv_grad = normalize(uv);");
396fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            }
397fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,");
398fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);");
399fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
400fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            // this gives us a smooth step across approximately one fragment
401fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
402fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        }
403fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
404fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4052dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
406fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
407fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
408fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    virtual void setData(const GrGLProgramDataManager& pdman,
4099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrPrimitiveProcessor& proc,
4109b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrBatchTracker& bt) SK_OVERRIDE {
411e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed        SkASSERT(fTextureSizeUni.isValid());
412fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
41387f48d997ec29e5eeaa7567355775e93465dd60djoshualitt        GrTexture* texture = proc.texture(0);
414fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        if (texture->width() != fTextureSize.width() ||
415fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            texture->height() != fTextureSize.height()) {
416fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fTextureSize = SkISize::Make(texture->width(), texture->height());
417e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed            pdman.set2f(fTextureSizeUni,
418e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                        SkIntToScalar(fTextureSize.width()),
419e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                        SkIntToScalar(fTextureSize.height()));
420fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        }
4219b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
422ee2af95db72152dfa61c841875df0594ca93437djoshualitt        this->setUniformViewMatrix(pdman, proc.viewMatrix());
423ee2af95db72152dfa61c841875df0594ca93437djoshualitt
4249b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
4259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
4269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrGLfloat c[4];
4279b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrColorToRGBAFloat(local.fColor, c);
4289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
4299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            fColor = local.fColor;
4309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
431fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
432fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
43346d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
4349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                              const GrBatchTracker& bt,
43587f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                              const GrGLCaps&,
436fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                              GrProcessorKeyBuilder* b) {
437fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        const GrDistanceFieldNoGammaTextureEffect& dfTexEffect =
43846d36f0e7b709a077c647841eee23bd3efdc4117robertphillips            gp.cast<GrDistanceFieldNoGammaTextureEffect>();
439fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldNoGammaBatchTracker& local = bt.cast<DistanceFieldNoGammaBatchTracker>();
4418fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
4428fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        key |= local.fInputColorType << 16;
44346d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
44446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= ComputePosKey(gp.viewMatrix()) << 25;
4458fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
446fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    }
447fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
448fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthprivate:
4499b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fColorUniform;
450e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed    UniformHandle fTextureSizeUni;
4519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor       fColor;
4529b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    SkISize       fTextureSize;
453fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
454fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    typedef GrGLGeometryProcessor INHERITED;
455fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth};
456fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
457fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
458fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4592e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualittGrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
4602e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        GrColor color,
4618059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt        const SkMatrix& viewMatrix,
4622e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        GrTexture* texture,
4632e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        const GrTextureParams& params,
46456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        uint32_t flags,
46556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        bool opaqueVertexColors)
4668059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
4672e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
468fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
4692dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    , fInColor(NULL) {
470fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
471eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<GrDistanceFieldNoGammaTextureEffect>();
47271c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
4732dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    if (flags & kColorAttr_DistanceFieldEffectFlag) {
47471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt        fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
4752dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        this->setHasVertexColor();
4762dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
47771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
478e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed                                                          kVec2f_GrVertexAttribType));
479fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    this->addTextureAccess(&fTextureAccess);
480fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
481fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
4820e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
483fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    const GrDistanceFieldNoGammaTextureEffect& cte =
484fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                                 other.cast<GrDistanceFieldNoGammaTextureEffect>();
485420d7e9a79358908850c74192b4949375563449absalomon    return fFlags == cte.fFlags;
486fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
487fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
48856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualittvoid GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
48956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    out->setUnknownSingleComponent();
490fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
491fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
492eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
493eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                            const GrGLCaps& caps,
494eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                            GrProcessorKeyBuilder* b) const {
495eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b);
496eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
497eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
498abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor*
499abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt,
500abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                                                      const GrGLCaps&) const {
501eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt));
502fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
503fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
5049b98932adaceb7ad0a617ade16616923f6bffe84joshualittvoid GrDistanceFieldNoGammaTextureEffect::initBatchTracker(GrBatchTracker* bt,
5054d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt                                                           const GrPipelineInfo& init) const {
5069b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    DistanceFieldNoGammaBatchTracker* local = bt->cast<DistanceFieldNoGammaBatchTracker>();
5079b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
5089b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                               SkToBool(fInColor));
509290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    local->fUsesLocalCoords = init.fUsesLocalCoords;
5109b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
5119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
5129b98932adaceb7ad0a617ade16616923f6bffe84joshualittbool GrDistanceFieldNoGammaTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
513290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                                         const GrGeometryProcessor& that,
5149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                                         const GrBatchTracker& t) const {
5159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldNoGammaBatchTracker& mine = m.cast<DistanceFieldNoGammaBatchTracker>();
5169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldNoGammaBatchTracker& theirs = t.cast<DistanceFieldNoGammaBatchTracker>();
517290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
518290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                   that, theirs.fUsesLocalCoords) &&
519290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt           CanCombineOutput(mine.fInputColorType, mine.fColor,
5209b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                            theirs.fInputColorType, theirs.fColor);
5219b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
5229b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
523fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
524fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
525fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect);
526fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
527fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthGrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* random,
528fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                                                     GrContext*,
529fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                                                     const GrDrawTargetCaps&,
530fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                                                     GrTexture* textures[]) {
531fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
532fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                    : GrProcessorUnitTest::kAlphaTextureIdx;
533fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    static const SkShader::TileMode kTileModes[] = {
534fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kClamp_TileMode,
535fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kRepeat_TileMode,
536fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        SkShader::kMirror_TileMode,
537fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    };
538fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    SkShader::TileMode tileModes[] = {
539fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
540fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
541fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    };
542fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth    GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode
543fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth                                                         : GrTextureParams::kNone_FilterMode);
544fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
5458059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random),
5468059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                       GrProcessorUnitTest::TestMatrix(random),
5478059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                       textures[texIdx],
5482e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                                       params,
54956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
550fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}
551fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
552fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth///////////////////////////////////////////////////////////////////////////////
553fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth
5549b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldLCDBatchTracker {
5559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrGPInput fInputColorType;
5569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor fColor;
557290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    bool fUsesLocalCoords;
5589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt};
5599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
560249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
561609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic:
562eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&,
56387f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                                      const GrBatchTracker&)
5649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    : fColor(GrColor_ILLEGAL)
5659564ce60a657acce89fb956deb8645b324eaad1ejvanverth    , fTextColor(GrColor_ILLEGAL) {}
566609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
56746d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{
568609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        const GrDistanceFieldLCDTextureEffect& dfTexEffect =
569c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt                args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
5709b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>();
5719b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        GrGLGPBuilder* pb = args.fPB;
572609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
5732dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
574abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
575abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit attributes
576abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        vsBuilder->emitAttributes(dfTexEffect);
577abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
5785a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        GrGLVertToFrag st(kVec2f_GrSLType);
5795a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        args.fPB->addVarying("IntTextureCoords", &st);
5805a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
5815a105ff05303ac82a867b8b84a1edd145bd46218jvanverth
5825a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        GrGLVertToFrag uv(kVec2f_GrSLType);
5835a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        args.fPB->addVarying("TextureCoords", &uv);
5845a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        // this is only used with text, so our texture bounds always match the glyph atlas
5855a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
5865a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                               GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
5875a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                               dfTexEffect.inTextureCoords()->fName);
5885a105ff05303ac82a867b8b84a1edd145bd46218jvanverth
5899b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        // setup pass through color
5909b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
5919b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                    &fColorUniform);
5929b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
593abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // Setup position
594dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
5954973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
596abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt        // emit transforms
59746d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
598abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                             dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
599abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
600c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
60130ba436f04e61d4505fb854d5fc56079636e0788joshualitt
60230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        SkAssertResult(fsBuilder->enableFeature(
60330ba436f04e61d4505fb854d5fc56079636e0788joshualitt                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
60430ba436f04e61d4505fb854d5fc56079636e0788joshualitt
605609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // create LCD offset adjusted by inverse of transform
606fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        // Use highp to work around aliasing issues
607fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
608fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
6095a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
610fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
611fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth                                                             pb->ctxInfo().standard()));
6125a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
61378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
6145a105ff05303ac82a867b8b84a1edd145bd46218jvanverth
6155a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
6165a105ff05303ac82a867b8b84a1edd145bd46218jvanverth            fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n");
6175a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        } else {
6185a105ff05303ac82a867b8b84a1edd145bd46218jvanverth            fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n");
6195a105ff05303ac82a867b8b84a1edd145bd46218jvanverth        }
62078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        if (isUniformScale) {
62130ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
6225a105ff05303ac82a867b8b84a1edd145bd46218jvanverth            fsBuilder->codeAppend("\tvec2 offset = vec2(dx*delta, 0.0);\n");
623609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        } else {
62430ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
62530ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
6265a105ff05303ac82a867b8b84a1edd145bd46218jvanverth            fsBuilder->codeAppend("\tvec2 offset = delta*Jdx;\n");
627609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        }
628609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
629609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // green is distance to uv center
63030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec4 texColor = ");
631c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
63230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
63330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec3 distance;\n");
63430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
635609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // red is distance to left offset
63630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
63730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\ttexColor = ");
638c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
63930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
64030ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
641609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // blue is distance to right offset
64230ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
64330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\ttexColor = ");
644c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
64530ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend(";\n");
64630ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
6472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
64830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tdistance = "
649ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth           "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
6502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
651609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // we adjust for the effect of the transformation on the distance by using
652609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // the length of the gradient of the texture coordinates. We use st coordinates
653609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // to ensure we're mapping 1:1 from texel space to pixel space.
654609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
655609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // To be strictly correct, we should compute the anti-aliasing factor separately
656609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // for each color component. However, this is only important when using perspective
657609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // transformations, and even then using a single factor seems like a reasonable
658609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // trade-off between quality and speed.
65930ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tfloat afwidth;\n");
66078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth        if (isUniformScale) {
661609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
662fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth            fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dx);\n");
663609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        } else {
66430ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 uv_grad;\n");
665c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt            if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) {
666609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                // this is to compensate for the Adreno, which likes to drop tiles on division by 0
66730ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
66830ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n");
66930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
67030ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t} else {\n");
67130ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
67230ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\t}\n");
673609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            } else {
67430ba436f04e61d4505fb854d5fc56079636e0788joshualitt                fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n");
675609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            }
67630ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
67730ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\t                 uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
678609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
679609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            // this gives us a smooth step across approximately one fragment
68030ba436f04e61d4505fb854d5fc56079636e0788joshualitt            fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n");
681609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        }
682609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
68330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n");
684609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
6852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        // adjust based on gamma
6862d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        const char* textColorUniName = NULL;
687c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
688422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                             kVec3f_GrSLType, kDefault_GrSLPrecision,
689422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon                                             "TextColor", &textColorUniName);
6902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
69130ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
692fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("float gammaColor = ");
693c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
694fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;\n");
695fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("\tval.x = gammaColor;\n");
69630ba436f04e61d4505fb854d5fc56079636e0788joshualitt
69730ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
69830ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tgammaColor = ");
699c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
700fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;\n");
701fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("\tval.y = gammaColor;\n");
70230ba436f04e61d4505fb854d5fc56079636e0788joshualitt
70330ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
70430ba436f04e61d4505fb854d5fc56079636e0788joshualitt        fsBuilder->codeAppend("\tgammaColor = ");
705c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt        fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
706fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend(".r;\n");
707fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth        fsBuilder->codeAppend("\tval.z = gammaColor;\n");
70830ba436f04e61d4505fb854d5fc56079636e0788joshualitt
7092dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
710609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
711609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
7127510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen    virtual void setData(const GrGLProgramDataManager& pdman,
7139b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrPrimitiveProcessor& processor,
7149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                         const GrBatchTracker& bt) SK_OVERRIDE {
7152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkASSERT(fTextColorUni.isValid());
716609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
7172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        const GrDistanceFieldLCDTextureEffect& dfTexEffect =
718b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                processor.cast<GrDistanceFieldLCDTextureEffect>();
7192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        GrColor textColor = dfTexEffect.getTextColor();
7202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        if (textColor != fTextColor) {
7212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            static const float ONE_OVER_255 = 1.f / 255.f;
7227510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen            pdman.set3f(fTextColorUni,
7237510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen                        GrColorUnpackR(textColor) * ONE_OVER_255,
7247510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen                        GrColorUnpackG(textColor) * ONE_OVER_255,
7257510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen                        GrColorUnpackB(textColor) * ONE_OVER_255);
7262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            fTextColor = textColor;
7272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
7289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
729ee2af95db72152dfa61c841875df0594ca93437djoshualitt        this->setUniformViewMatrix(pdman, processor.viewMatrix());
730ee2af95db72152dfa61c841875df0594ca93437djoshualitt
7319b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
7329b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
7339b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrGLfloat c[4];
7349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            GrColorToRGBAFloat(local.fColor, c);
7359b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            pdman.set4fv(fColorUniform, 1, c);
7369b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            fColor = local.fColor;
7379b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        }
738609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
739609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
74046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips    static inline void GenKey(const GrGeometryProcessor& gp,
7419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                              const GrBatchTracker& bt,
74287f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                              const GrGLCaps&,
743b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              GrProcessorKeyBuilder* b) {
744609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        const GrDistanceFieldLCDTextureEffect& dfTexEffect =
74546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips                gp.cast<GrDistanceFieldLCDTextureEffect>();
746609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
7479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
7488fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        uint32_t key = dfTexEffect.getFlags();
7498fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        key |= local.fInputColorType << 16;
75046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
75146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips        key |= ComputePosKey(gp.viewMatrix()) << 25;
7528fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        b->add32(key);
753609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    }
754609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
755609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate:
7569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    GrColor       fColor;
7579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fColorUniform;
7589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    UniformHandle fTextColorUni;
7599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    SkColor       fTextColor;
760609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
761249af15fb82833d2274850c589812b6e69df0033joshualitt    typedef GrGLGeometryProcessor INHERITED;
762609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org};
763609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
764609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
765609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
7662d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthGrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
7678059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                  GrColor color, const SkMatrix& viewMatrix,
7682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                  GrTexture* texture, const GrTextureParams& params,
7692d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                  GrTexture* gamma, const GrTextureParams& gParams,
7702d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                  SkColor textColor,
77178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth                                                  uint32_t flags)
7728059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    : INHERITED(color, viewMatrix, SkMatrix::I())
7732e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    , fTextureAccess(texture, params)
7742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    , fGammaTextureAccess(gamma, gParams)
7752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    , fTextColor(textColor)
7762dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    , fFlags(flags & kLCD_DistanceFieldEffectMask){
77778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
778eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    this->initClassID<GrDistanceFieldLCDTextureEffect>();
77971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
78071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
7815a105ff05303ac82a867b8b84a1edd145bd46218jvanverth                                                          kVec2s_GrVertexAttribType));
782609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    this->addTextureAccess(&fTextureAccess);
7832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    this->addTextureAccess(&fGammaTextureAccess);
784609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
785609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
7860e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
78749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt    const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>();
788420d7e9a79358908850c74192b4949375563449absalomon    return (fTextColor == cte.fTextColor &&
78978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth            fFlags == cte.fFlags);
790609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
791609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
79256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualittvoid GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
79356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    out->setUnknownFourComponents();
79456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    out->setUsingLCDCoverage();
795609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
796609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
797eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
798eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                        const GrGLCaps& caps,
799eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt                                                        GrProcessorKeyBuilder* b) const {
800eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b);
801eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt}
802eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
803abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor*
804abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt,
805abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                                                  const GrGLCaps&) const {
806eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt));
807609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}
808609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
8099b98932adaceb7ad0a617ade16616923f6bffe84joshualittvoid GrDistanceFieldLCDTextureEffect::initBatchTracker(GrBatchTracker* bt,
8104d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt                                                       const GrPipelineInfo& init) const {
8119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>();
8129b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
813290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    local->fUsesLocalCoords = init.fUsesLocalCoords;
8149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
8159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
8169b98932adaceb7ad0a617ade16616923f6bffe84joshualittbool GrDistanceFieldLCDTextureEffect::onCanMakeEqual(const GrBatchTracker& m,
817290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                                     const GrGeometryProcessor& that,
8189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                                                     const GrBatchTracker& t) const {
8199b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>();
8209b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>();
821290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt    return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
822290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt                                   that, theirs.fUsesLocalCoords) &&
823290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt           CanCombineOutput(mine.fInputColorType, mine.fColor,
8249b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                            theirs.fInputColorType, theirs.fColor);
8259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}
8269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
827609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
828609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
829b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect);
830609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org
831b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random,
832b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                                 GrContext*,
833b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                                 const GrDrawTargetCaps&,
834b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                                 GrTexture* textures[]) {
835b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
836b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                      GrProcessorUnitTest::kAlphaTextureIdx;
837b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                       GrProcessorUnitTest::kAlphaTextureIdx;
839609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    static const SkShader::TileMode kTileModes[] = {
840609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kClamp_TileMode,
841609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kRepeat_TileMode,
842609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        SkShader::kMirror_TileMode,
843609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    };
844609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    SkShader::TileMode tileModes[] = {
845609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
846609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
847609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    };
848609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
849609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                           GrTextureParams::kNone_FilterMode);
8502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
8512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                           GrTextureParams::kNone_FilterMode);
8522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
8532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                        random->nextULessThan(256),
8542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                        random->nextULessThan(256),
8552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                        random->nextULessThan(256));
85678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
85778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
85878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth    flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
8598059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
8608059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                   GrProcessorUnitTest::TestMatrix(random),
8618059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                   textures[texIdx], params,
8622d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                   textures[texIdx2], params2,
8632d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                   textColor,
86478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth                                                   flags);
865d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
866