GrDistanceFieldGeoProc.cpp revision cfc18867d982119d9dc2888bf09f1093012daadd
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" 95a105ff05303ac82a867b8b84a1edd145bd46218jvanverth#include "GrFontAtlasSizes.h" 10605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 11eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrTexture.h" 1221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth 13eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkDistanceFieldGen.h" 1421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth 15b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 16d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h" 17d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h" 18249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h" 19eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h" 20d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 2121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth// Assuming a radius of a little less than the diagonal of the fragment 2224ba00825092be0d400074e0121ffc7221950dd9jvanverth#define SK_DistanceFieldAAFactor "0.65" 232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 249b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldBatchTracker { 259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 27290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}; 299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 30502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor { 31d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic: 32502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldA8TextGeoProc(const GrGeometryProcessor&, 3387f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt : fColor(GrColor_ILLEGAL) 359564ce60a657acce89fb956deb8645b324eaad1ejvanverth#ifdef SK_GAMMA_APPLY_TO_A8 3621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth , fDistanceAdjust(-1.0f) 379564ce60a657acce89fb956deb8645b324eaad1ejvanverth#endif 389564ce60a657acce89fb956deb8645b324eaad1ejvanverth {} 39d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 4036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 41502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& dfTexEffect = 42502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); 439b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>(); 449b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 45c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 4630ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 4730ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 486c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 492dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 50abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 51abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 52abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(dfTexEffect); 53abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 5421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 5521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // adjust based on gamma 5621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth const char* distanceAdjustUniName = NULL; 5721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // width, height, 1/(3*width) 5821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 5921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth kFloat_GrSLType, kDefault_GrSLPrecision, 6021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth "DistanceAdjust", &distanceAdjustUniName); 6121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#endif 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 71bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const SkMatrix& localMatrix = dfTexEffect.localMatrix(); 7246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, 73bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth localMatrix, args.fTransformsIn, args.fTransformsOut); 74abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 75bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // add varyings 76bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag recipScale(kFloat_GrSLType); 77bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag st(kVec2f_GrSLType); 78bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); 79221360a514fb4bfff5b461e83262306b2a0f36afjvanverth args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 80221360a514fb4bfff5b461e83262306b2a0f36afjvanverth vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); 81bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 82bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag uv(kVec2f_GrSLType); 83bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 84bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // this is only used with text, so our texture bounds always match the glyph atlas 85bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " 86bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), 87bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth dfTexEffect.inTextureCoords()->fName); 88bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 89fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 90fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 91fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 925a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 93fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth 94fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend("\tfloat texColor = "); 95c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 96fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth "uv", 97d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 98fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(".r;\n"); 9930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat distance = " 100fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 10121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 10221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // adjust width based on gamma 10321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 10421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#endif 1056c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 106354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float afwidth;"); 107bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (isSimilarity) { 108354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 109354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 110221360a514fb4bfff5b461e83262306b2a0f36afjvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 111354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 1124362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 113221360a514fb4bfff5b461e83262306b2a0f36afjvanverth // we use y to work around a Mali400 bug in the x direction 114221360a514fb4bfff5b461e83262306b2a0f36afjvanverth fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));", 115bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth st.fsIn()); 1164362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 117354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 118354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 119354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 120354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));"); 121d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 122d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 123d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 124d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 125d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 126d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 127d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 128d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 129d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth 130bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); 131bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); 132354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 133354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 1344362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1354362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 136354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 1374362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 138354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); 1394d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1402dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 141d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 142d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1437510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 1449b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& proc, 14536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 1462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 147502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>(); 14821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float distanceAdjust = dfTexEffect.getDistanceAdjust(); 14921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth if (distanceAdjust != fDistanceAdjust) { 15021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth pdman.set1f(fDistanceAdjustUni, distanceAdjust); 15121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust = distanceAdjust; 1522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1549b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 155ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, proc.viewMatrix()); 156ee2af95db72152dfa61c841875df0594ca93437djoshualitt 1579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>(); 1589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 1599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 1609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 1619b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 1629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 1639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 1646c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 165d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 16646d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 1679b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 168cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 169b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 170502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>(); 1719b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>(); 1728fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 1738fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 17446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 17546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 1768fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 1774362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1784362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 179d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1809b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 1819b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 18250282b4390dcddcf3b1d51631c0133045ae1f233mtklein#ifdef SK_GAMMA_APPLY_TO_A8 18321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float fDistanceAdjust; 18421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fDistanceAdjustUni; 18550282b4390dcddcf3b1d51631c0133045ae1f233mtklein#endif 1866c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 187249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 188d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 189d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 190d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 191d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 192502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, 1938059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 1942e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 1956c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 1962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 19721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float distanceAdjust, 1982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 19956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt uint32_t flags, bool opaqueVertexColors) 200221360a514fb4bfff5b461e83262306b2a0f36afjvanverth : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) 2012e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 2022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 20321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth , fDistanceAdjust(distanceAdjust) 2042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 205249af15fb82833d2274850c589812b6e69df0033joshualitt , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 2062dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 20778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 208502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldA8TextGeoProc>(); 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); 217d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 218d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 219502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldA8TextGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 220502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& cte = other.cast<GrDistanceFieldA8TextGeoProc>(); 221420d7e9a79358908850c74192b4949375563449absalomon return 22278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8 22321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust == cte.fDistanceAdjust && 22478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif 22578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags; 226d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 227d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 228502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 22956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownSingleComponent(); 230d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 231d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 232502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 233cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 234eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 235502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldA8TextGeoProc::GenKey(*this, bt, caps, b); 236eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 237eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 238abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 239502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldA8TextGeoProc::createGLInstance(const GrBatchTracker& bt, 240cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const { 241502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldA8TextGeoProc, (*this, bt)); 242d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 243d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 244502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::initBatchTracker(GrBatchTracker* bt, 24521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth const GrPipelineInfo& init) const { 2469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>(); 2479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, 2489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkToBool(fInColor)); 249290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 2509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 2519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 252502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldA8TextGeoProc::onCanMakeEqual(const GrBatchTracker& m, 253290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt const GrGeometryProcessor& that, 2549b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& t) const { 2559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>(); 2569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>(); 257290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 258290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 259290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 2609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 2619b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 2629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 263d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 264d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 265502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc); 266d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 267502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(SkRandom* random, 268b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 269b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 270b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 271b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 272b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 273d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 274d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 275d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 276d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 277d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 278d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 279d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 280d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 281d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 282d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 283d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 284d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 285502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(random), 2868059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrProcessorUnitTest::TestMatrix(random), 2878059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt textures[texIdx], params, 2882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 2902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 29178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth random->nextBool() ? 29256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt kSimilarity_DistanceFieldEffectFlag : 0, 29356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt random->nextBool()); 294609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 295609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 296609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 297609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 298502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthstruct DistanceFieldPathBatchTracker { 2999b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 3009b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 301290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 3029b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}; 3039b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 304502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldPathGeoProc : public GrGLGeometryProcessor { 305fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthpublic: 306502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldPathGeoProc(const GrGeometryProcessor&, 30787f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 308e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {} 309fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 31036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 311502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>(); 312fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 313502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = args.fBT.cast<DistanceFieldPathBatchTracker>(); 3149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 315c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 316fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkAssertResult(fsBuilder->enableFeature( 317fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 318fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3192dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 320abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 321abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 322abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(dfTexEffect); 323abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 324e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed GrGLVertToFrag v(kVec2f_GrSLType); 3259671ecd44e48e8bbe1361830717b79c9c4dc9d17jvanverth args.fPB->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); 326fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3279b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // setup pass through color 3289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, 3299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt dfTexEffect.inColor(), &fColorUniform); 3302dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 331e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); 332e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed 333abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 334dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); 335abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 336abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 33746d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, 338abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); 3394973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 340e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed const char* textureSizeUniName = NULL; 341e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 342e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed kVec2f_GrSLType, kDefault_GrSLPrecision, 343e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed "TextureSize", &textureSizeUniName); 344e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed 345fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 346fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 347fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 348e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); 349fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth 350fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend("float texColor = "); 351c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 352fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth "uv", 353fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kVec2f_GrSLType); 354fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(".r;"); 355fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float distance = " 356fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 357fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 358fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 359fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 360e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 361fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float afwidth;"); 362fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 363354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 364354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 365354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 366354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 367fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 368bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));"); 369fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } else { 370354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 371354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 372354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 373354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));"); 374d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 375d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 376d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 377d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 378d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 379d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 380d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 381d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 382d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth 383354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 384354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 385354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 386354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 387fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 388fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 389fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 390fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 391fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); 392fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3932dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 394fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 395fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 396fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth virtual void setData(const GrGLProgramDataManager& pdman, 3979b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& proc, 39836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 399e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkASSERT(fTextureSizeUni.isValid()); 400fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 40187f48d997ec29e5eeaa7567355775e93465dd60djoshualitt GrTexture* texture = proc.texture(0); 402fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (texture->width() != fTextureSize.width() || 403fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth texture->height() != fTextureSize.height()) { 404fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fTextureSize = SkISize::Make(texture->width(), texture->height()); 405e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed pdman.set2f(fTextureSizeUni, 406e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkIntToScalar(fTextureSize.width()), 407e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkIntToScalar(fTextureSize.height())); 408fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 4099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 410ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, proc.viewMatrix()); 411ee2af95db72152dfa61c841875df0594ca93437djoshualitt 412502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>(); 4139b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 4149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 4159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 4169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 4179b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 4189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 419fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 420fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 42146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 4229b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 423cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 424fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrProcessorKeyBuilder* b) { 425502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>(); 426fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 427502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>(); 4288fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 4298fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 43046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 43146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 4328fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 433fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 434fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 435fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthprivate: 4369b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 437e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed UniformHandle fTextureSizeUni; 4389b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 4399b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkISize fTextureSize; 440fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 441fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth typedef GrGLGeometryProcessor INHERITED; 442fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}; 443fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 444fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 445fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 446502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc( 4472e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 4488059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 4492e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 4502e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt const GrTextureParams& params, 45156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt uint32_t flags, 45256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt bool opaqueVertexColors) 4538059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) 4542e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 455fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 4562dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 457fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 458502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldPathGeoProc>(); 45971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 4602dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (flags & kColorAttr_DistanceFieldEffectFlag) { 46171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 4622dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt this->setHasVertexColor(); 4632dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 46471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 465e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed kVec2f_GrVertexAttribType)); 466fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth this->addTextureAccess(&fTextureAccess); 467fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 468fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 469502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldPathGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 470502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& cte = other.cast<GrDistanceFieldPathGeoProc>(); 471420d7e9a79358908850c74192b4949375563449absalomon return fFlags == cte.fFlags; 472fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 473fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 474502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 47556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownSingleComponent(); 476fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 477fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 478502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 479cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 480502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorKeyBuilder* b) const { 481502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldPathGeoProc::GenKey(*this, bt, caps, b); 482eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 483eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 484abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 485cfc18867d982119d9dc2888bf09f1093012daaddjvanverthGrDistanceFieldPathGeoProc::createGLInstance(const GrBatchTracker& bt, const GrGLSLCaps&) const { 486502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldPathGeoProc, (*this, bt)); 487fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 488fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 489502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::initBatchTracker(GrBatchTracker* bt, 490502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrPipelineInfo& init) const { 491502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth DistanceFieldPathBatchTracker* local = bt->cast<DistanceFieldPathBatchTracker>(); 4929b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, 4939b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkToBool(fInColor)); 494290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 4959b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 4969b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 497502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldPathGeoProc::onCanMakeEqual(const GrBatchTracker& m, 498502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGeometryProcessor& that, 499502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrBatchTracker& t) const { 500502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& mine = m.cast<DistanceFieldPathBatchTracker>(); 501502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& theirs = t.cast<DistanceFieldPathBatchTracker>(); 502290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 503290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 504290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 5059b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 5069b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 5079b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 508fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 509fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 510502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc); 511fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 512502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(SkRandom* random, 513502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrContext*, 514502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDrawTargetCaps&, 515502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrTexture* textures[]) { 516fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 517fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrProcessorUnitTest::kAlphaTextureIdx; 518fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth static const SkShader::TileMode kTileModes[] = { 519fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kClamp_TileMode, 520fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kRepeat_TileMode, 521fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kMirror_TileMode, 522fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 523fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::TileMode tileModes[] = { 524fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 525fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 526fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 527fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode 528fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrTextureParams::kNone_FilterMode); 529fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 530502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldPathGeoProc::Create(GrRandomColor(random), 531502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorUnitTest::TestMatrix(random), 532502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth textures[texIdx], 533502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth params, 53456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool()); 535fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 536fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 537fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 538fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 5399b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldLCDBatchTracker { 5409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 5419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 542290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 5439b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}; 5449b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 545502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldLCDTextGeoProc : public GrGLGeometryProcessor { 546609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 547502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldLCDTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) 54821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth : fColor(GrColor_ILLEGAL) { 549502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f); 55021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth } 551609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 55236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 553502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = 554502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); 5559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>(); 5569b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 557609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 5582dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 559abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 560abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 561abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(dfTexEffect); 562abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 5639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // setup pass through color 5649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 5659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 5669b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 567abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 568dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); 5694973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 570abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 571bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const SkMatrix& localMatrix = dfTexEffect.localMatrix(); 57246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, 573bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth localMatrix, args.fTransformsIn, args.fTransformsOut); 5745b143038cb47763974d2750ed78d436eb6c38beajvanverth 575bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // set up varyings 576bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); 577bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag recipScale(kFloat_GrSLType); 578bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag st(kVec2f_GrSLType); 579221360a514fb4bfff5b461e83262306b2a0f36afjvanverth args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 580221360a514fb4bfff5b461e83262306b2a0f36afjvanverth vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); 581bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 582bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag uv(kVec2f_GrSLType); 583bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 584bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // this is only used with text, so our texture bounds always match the glyph atlas 585bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " 586bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), 587bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth dfTexEffect.inTextureCoords()->fName); 588bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 589bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // add frag shader code 590c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 59130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 59230ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 59330ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 59430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 595609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 596fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 597fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 598fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 5995a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 600fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 601fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 6025a105ff05303ac82a867b8b84a1edd145bd46218jvanverth if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 6035a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n"); 6045a105ff05303ac82a867b8b84a1edd145bd46218jvanverth } else { 6055a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n"); 6065a105ff05303ac82a867b8b84a1edd145bd46218jvanverth } 60778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 608bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn()); 609221360a514fb4bfff5b461e83262306b2a0f36afjvanverth fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); 610609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 611bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); 612bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 613bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 614bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 615bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); 616609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 617609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 618609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 61930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 620c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType); 62130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 62230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec3 distance;\n"); 62330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 624609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 62530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 62630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 627c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 62830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 62930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 630609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 63130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 63230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 633c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 63430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 63530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 6362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 63730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance = " 638ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));"); 6392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 64021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // adjust width based on gamma 64121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth const char* distanceAdjustUniName = NULL; 64221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 64321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth kVec3f_GrSLType, kDefault_GrSLPrecision, 64421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth "DistanceAdjust", &distanceAdjustUniName); 64521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 64621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth 647609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 648609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 649609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 650609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 651354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float afwidth;"); 65278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 653354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 654354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 655354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 656354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 657609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 658bc0273524b039c45dcea2c1ab5ab379c75486c07jvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;"); 659609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 660354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 661354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 662354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 663354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));"); 664d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 665d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 666d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 667d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 668d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 669d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 670d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 671d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 672354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 673354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 674609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 675609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 676354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 677609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 678609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 67921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppend( 68021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);"); 68130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 6822dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 683609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 684609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 6857510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 6869b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& processor, 68736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 68821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth SkASSERT(fDistanceAdjustUni.isValid()); 689609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 690502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = 691502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth processor.cast<GrDistanceFieldLCDTextGeoProc>(); 692502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dfTexEffect.getDistanceAdjust(); 69321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth if (wa != fDistanceAdjust) { 69421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth pdman.set3f(fDistanceAdjustUni, 69521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fR, 69621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fG, 69721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fB); 69821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust = wa; 6992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 7009b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 701ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, processor.viewMatrix()); 702ee2af95db72152dfa61c841875df0594ca93437djoshualitt 7039b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>(); 7049b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 7059b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 7069b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 7079b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 7089b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 7099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 710609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 711609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 71246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 7139b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 714cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 715b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 716502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>(); 717609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 7189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>(); 7198fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 7208fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 72146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 72246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 7238fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 724609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 725609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 726609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 72721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth GrColor fColor; 72821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fColorUniform; 729502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust; 73021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fDistanceAdjustUni; 731609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 732249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 733609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 734609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 735609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 736609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 737502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( 7388059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrColor color, const SkMatrix& viewMatrix, 7392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 74021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth DistanceAdjust distanceAdjust, 74178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 742221360a514fb4bfff5b461e83262306b2a0f36afjvanverth : INHERITED(color, viewMatrix, SkMatrix::I()) 7432e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 74421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth , fDistanceAdjust(distanceAdjust) 7452dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fFlags(flags & kLCD_DistanceFieldEffectMask){ 74678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); 747502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldLCDTextGeoProc>(); 74871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 74971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 7505a105ff05303ac82a867b8b84a1edd145bd46218jvanverth kVec2s_GrVertexAttribType)); 751609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 752609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 753609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 754502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldLCDTextGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 755502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& cte = other.cast<GrDistanceFieldLCDTextGeoProc>(); 75621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth return (fDistanceAdjust == cte.fDistanceAdjust && 75778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags); 758609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 759609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 760502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 76156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownFourComponents(); 76256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUsingLCDCoverage(); 763609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 764609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 765502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 766cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 767502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorKeyBuilder* b) const { 768502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldLCDTextGeoProc::GenKey(*this, bt, caps, b); 769eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 770eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 771abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 772502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldLCDTextGeoProc::createGLInstance(const GrBatchTracker& bt, 773cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const { 774502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldLCDTextGeoProc, (*this, bt)); 775609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 776609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 777502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::initBatchTracker(GrBatchTracker* bt, 778502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrPipelineInfo& init) const { 7799b98932adaceb7ad0a617ade16616923f6bffe84joshualitt DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>(); 7809b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 781290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 7829b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 7839b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 784502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldLCDTextGeoProc::onCanMakeEqual(const GrBatchTracker& m, 785502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGeometryProcessor& that, 786502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrBatchTracker& t) const { 7879b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>(); 7889b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>(); 789290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 790290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 791290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 7929b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 7939b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 7949b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 795609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 796609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 797502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc); 798609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 799502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(SkRandom* random, 800b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 801b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 802b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 803b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 804b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 805609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 806609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 807609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 808609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 809609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 810609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 811609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 812609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 813609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 814609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 815609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 81621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth DistanceAdjust wa = { 0.0f, 0.1f, -0.1f }; 81778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 81878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 81978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 820502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(random), 821502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorUnitTest::TestMatrix(random), 822502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth textures[texIdx], params, 823502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth wa, 824502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth flags); 825d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 826