GrDistanceFieldGeoProc.cpp revision 8ed3b9a386374d7996dfbe0c9de13b42f3dd245d
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); 79bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const char* viewMatrixName = this->uViewM(); 80bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // view matrix name is NULL if identity matrix 81bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName; 82bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (isSimilarity && useInverseScale) { 83bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision); 84bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", 85bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth viewMatrixName, viewMatrixName); 86bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); 87bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut()); 88bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } else { 89bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 90bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); 91bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } 92bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 93bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag uv(kVec2f_GrSLType); 94bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 95bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // this is only used with text, so our texture bounds always match the glyph atlas 96bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " 97bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), 98bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth dfTexEffect.inTextureCoords()->fName); 99bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 100fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 101fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 102fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 1035a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 104fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth 105fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend("\tfloat texColor = "); 106c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 107fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth "uv", 108d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 109fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(".r;\n"); 11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat distance = " 111fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 11221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 11321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // adjust width based on gamma 11421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 11521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth#endif 1166c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 117354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float afwidth;"); 118bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (isSimilarity) { 119354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 120bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // either by using the inverse scale in the view matrix, or (if there is no view matrix) 121354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 122bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // with the latter to ensure we're mapping 1:1 from texel space to pixel space. 123354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 1244362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 125bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (useInverseScale) { 126bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*%s);", 127bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth recipScale.fsIn()); 128bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } else { 129bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));", 130bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth st.fsIn()); 131bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } 1324362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 133354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 134354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 135354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 136354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));"); 137d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 138d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 139d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 140d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 141d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 142d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 143d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 144d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 145d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth 146bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); 147bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); 148354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 149354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 1504362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1514362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 152354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 1534362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 154354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); 1554d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1562dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 157d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 158d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1597510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 1609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& proc, 16136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 1622d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 163502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>(); 16421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float distanceAdjust = dfTexEffect.getDistanceAdjust(); 16521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth if (distanceAdjust != fDistanceAdjust) { 16621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth pdman.set1f(fDistanceAdjustUni, distanceAdjust); 16721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust = distanceAdjust; 1682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1692d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1709b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 171ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, proc.viewMatrix()); 172ee2af95db72152dfa61c841875df0594ca93437djoshualitt 1739b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>(); 1749b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 1759b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 1769b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 1779b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 1789b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 1799b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 1806c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 181d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 18246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 1839b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 18487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 185b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 186502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>(); 1879b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>(); 1888fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 1898fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 19046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 19146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 192bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0; 1938fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 1944362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1954362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 196d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1979b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 1989b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 19950282b4390dcddcf3b1d51631c0133045ae1f233mtklein#ifdef SK_GAMMA_APPLY_TO_A8 20021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float fDistanceAdjust; 20121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fDistanceAdjustUni; 20250282b4390dcddcf3b1d51631c0133045ae1f233mtklein#endif 2036c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 204249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 206d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 209502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, 2108059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 211bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const SkMatrix& localMatrix, 2122e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 2136c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 2142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 21521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth float distanceAdjust, 2162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 21756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt uint32_t flags, bool opaqueVertexColors) 218bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors) 2192e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 2202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 22121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth , fDistanceAdjust(distanceAdjust) 2222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 223249af15fb82833d2274850c589812b6e69df0033joshualitt , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 2242dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 22578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 226502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldA8TextGeoProc>(); 22771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 2282dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (flags & kColorAttr_DistanceFieldEffectFlag) { 22971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 2302dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt this->setHasVertexColor(); 2312dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 23271c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 2335a105ff05303ac82a867b8b84a1edd145bd46218jvanverth kVec2s_GrVertexAttribType)); 234d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addTextureAccess(&fTextureAccess); 235d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 236d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 237502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldA8TextGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 238502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldA8TextGeoProc& cte = other.cast<GrDistanceFieldA8TextGeoProc>(); 239420d7e9a79358908850c74192b4949375563449absalomon return 24078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8 24121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust == cte.fDistanceAdjust && 24278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif 24378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags; 244d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 246502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 24756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownSingleComponent(); 248d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 249d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 250502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 251eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt const GrGLCaps& caps, 252eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 253502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldA8TextGeoProc::GenKey(*this, bt, caps, b); 254eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 255eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 256abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 257502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldA8TextGeoProc::createGLInstance(const GrBatchTracker& bt, 258abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt const GrGLCaps&) const { 259502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldA8TextGeoProc, (*this, bt)); 260d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 261d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 262502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldA8TextGeoProc::initBatchTracker(GrBatchTracker* bt, 26321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth const GrPipelineInfo& init) const { 2649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>(); 2659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, 2669b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkToBool(fInColor)); 267290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 2689b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 2699b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 270502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldA8TextGeoProc::onCanMakeEqual(const GrBatchTracker& m, 271290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt const GrGeometryProcessor& that, 2729b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& t) const { 2739b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>(); 2749b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>(); 275290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 276290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 277290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 2789b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 2799b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 2809b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 281d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 282d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 283502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc); 284d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 285502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(SkRandom* random, 286b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 287b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 288b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 289b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 290b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 291d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 292d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 293d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 294d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 295d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 296d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 297d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 298d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 299d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 300d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 301d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 302d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 303502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(random), 3048059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrProcessorUnitTest::TestMatrix(random), 305bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrProcessorUnitTest::TestMatrix(random), 3068059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt textures[texIdx], params, 3072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 3082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 3092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 31078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth random->nextBool() ? 31156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt kSimilarity_DistanceFieldEffectFlag : 0, 31256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt random->nextBool()); 313609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 314609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 315609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 316609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 317502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthstruct DistanceFieldPathBatchTracker { 3189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 3199b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 320290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 3219b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}; 3229b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 323502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldPathGeoProc : public GrGLGeometryProcessor { 324fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthpublic: 325502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldPathGeoProc(const GrGeometryProcessor&, 32687f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 327e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {} 328fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 32936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 330502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>(); 331fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 332502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = args.fBT.cast<DistanceFieldPathBatchTracker>(); 3339b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 334c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 335fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkAssertResult(fsBuilder->enableFeature( 336fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 337fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3382dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 339abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 340abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 341abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(dfTexEffect); 342abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 343e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed GrGLVertToFrag v(kVec2f_GrSLType); 3449671ecd44e48e8bbe1361830717b79c9c4dc9d17jvanverth args.fPB->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); 345fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // setup pass through color 3479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, 3489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt dfTexEffect.inColor(), &fColorUniform); 3492dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 350e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); 351e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed 352abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 353dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); 354abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 355abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 35646d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, 357abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); 3584973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 359e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed const char* textureSizeUniName = NULL; 360e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 361e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed kVec2f_GrSLType, kDefault_GrSLPrecision, 362e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed "TextureSize", &textureSizeUniName); 363e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed 364fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 365fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 366fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 367e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); 368fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth 369fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend("float texColor = "); 370c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 371fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth "uv", 372fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kVec2f_GrSLType); 373fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(".r;"); 374fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float distance = " 375fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); 376fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 377fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 378fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 379e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 380fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float afwidth;"); 381fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 382354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 383354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 384354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 385354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 386fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 387fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));"); 388fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } else { 389354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 390354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 391354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 392354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));"); 393d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 394d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 395d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 396d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 397d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 398d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 399d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 400d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 401d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth 402354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 403354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 404354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 405354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 406fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 407fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 408fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 409fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 410fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); 411fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 4122dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 413fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 414fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 415fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth virtual void setData(const GrGLProgramDataManager& pdman, 4169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& proc, 41736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 418e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkASSERT(fTextureSizeUni.isValid()); 419fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 42087f48d997ec29e5eeaa7567355775e93465dd60djoshualitt GrTexture* texture = proc.texture(0); 421fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (texture->width() != fTextureSize.width() || 422fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth texture->height() != fTextureSize.height()) { 423fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fTextureSize = SkISize::Make(texture->width(), texture->height()); 424e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed pdman.set2f(fTextureSizeUni, 425e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkIntToScalar(fTextureSize.width()), 426e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed SkIntToScalar(fTextureSize.height())); 427fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 4289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 429ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, proc.viewMatrix()); 430ee2af95db72152dfa61c841875df0594ca93437djoshualitt 431502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>(); 4329b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 4339b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 4349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 4359b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 4369b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 4379b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 438fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 439fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 44046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 4419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 44287f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 443fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrProcessorKeyBuilder* b) { 444502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>(); 445fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 446502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>(); 4478fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 4488fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 44946d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 45046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 4518fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 452fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 453fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 454fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthprivate: 4559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 456e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed UniformHandle fTextureSizeUni; 4579b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 4589b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkISize fTextureSize; 459fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 460fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth typedef GrGLGeometryProcessor INHERITED; 461fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}; 462fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 463fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 464fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 465502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc( 4662e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 4678059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 4682e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 4692e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt const GrTextureParams& params, 47056995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt uint32_t flags, 47156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt bool opaqueVertexColors) 4728059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) 4732e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 474fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 4752dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 476fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 477502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldPathGeoProc>(); 47871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 4792dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (flags & kColorAttr_DistanceFieldEffectFlag) { 48071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 4812dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt this->setHasVertexColor(); 4822dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 48371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 484e4ef1ca5be11aed67c0ed0c7eb1862696fb063e3reed kVec2f_GrVertexAttribType)); 485fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth this->addTextureAccess(&fTextureAccess); 486fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 487fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 488502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldPathGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 489502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldPathGeoProc& cte = other.cast<GrDistanceFieldPathGeoProc>(); 490420d7e9a79358908850c74192b4949375563449absalomon return fFlags == cte.fFlags; 491fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 492fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 493502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 49456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownSingleComponent(); 495fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 496fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 497502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 498502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGLCaps& caps, 499502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorKeyBuilder* b) const { 500502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldPathGeoProc::GenKey(*this, bt, caps, b); 501eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 502eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 503abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 504502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldPathGeoProc::createGLInstance(const GrBatchTracker& bt, const GrGLCaps&) const { 505502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldPathGeoProc, (*this, bt)); 506fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 507fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 508502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldPathGeoProc::initBatchTracker(GrBatchTracker* bt, 509502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrPipelineInfo& init) const { 510502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth DistanceFieldPathBatchTracker* local = bt->cast<DistanceFieldPathBatchTracker>(); 5119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, 5129b98932adaceb7ad0a617ade16616923f6bffe84joshualitt SkToBool(fInColor)); 513290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 5149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 5159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 516502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldPathGeoProc::onCanMakeEqual(const GrBatchTracker& m, 517502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGeometryProcessor& that, 518502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrBatchTracker& t) const { 519502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& mine = m.cast<DistanceFieldPathBatchTracker>(); 520502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const DistanceFieldPathBatchTracker& theirs = t.cast<DistanceFieldPathBatchTracker>(); 521290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 522290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 523290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 5249b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 5259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 5269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 527fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 528fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 529502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc); 530fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 531502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(SkRandom* random, 532502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrContext*, 533502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDrawTargetCaps&, 534502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrTexture* textures[]) { 535fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 536fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrProcessorUnitTest::kAlphaTextureIdx; 537fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth static const SkShader::TileMode kTileModes[] = { 538fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kClamp_TileMode, 539fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kRepeat_TileMode, 540fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kMirror_TileMode, 541fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 542fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::TileMode tileModes[] = { 543fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 544fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 545fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 546fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode 547fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrTextureParams::kNone_FilterMode); 548fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 549502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldPathGeoProc::Create(GrRandomColor(random), 550502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorUnitTest::TestMatrix(random), 551502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth textures[texIdx], 552502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth params, 55356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool()); 554fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 555fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 556fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 557fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 5589b98932adaceb7ad0a617ade16616923f6bffe84joshualittstruct DistanceFieldLCDBatchTracker { 5599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 5609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 561290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 5629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt}; 5639b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 564502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthclass GrGLDistanceFieldLCDTextGeoProc : public GrGLGeometryProcessor { 565609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 566502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldLCDTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&) 56721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth : fColor(GrColor_ILLEGAL) { 568502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f); 56921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth } 570609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 57136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 572502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = 573502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); 5749b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>(); 5759b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 576609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 5772dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 578abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 579abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 580abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(dfTexEffect); 581abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 5829b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // setup pass through color 5839b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 5849b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 5859b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 586abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 587dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); 5884973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 589abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 590bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const SkMatrix& localMatrix = dfTexEffect.localMatrix(); 59146d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, 592bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth localMatrix, args.fTransformsIn, args.fTransformsOut); 5935b143038cb47763974d2750ed78d436eb6c38beajvanverth 594bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // set up varyings 595bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); 596bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag recipScale(kFloat_GrSLType); 597bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag st(kVec2f_GrSLType); 598bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const char* viewMatrixName = this->uViewM(); 599bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // view matrix name is NULL if identity matrix 600bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName; 601bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (isUniformScale && useInverseScale) { 602bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision); 603bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", 604bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth viewMatrixName, viewMatrixName); 605bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); 606bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut()); 607bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } else { 608bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); 609bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); 610bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } 611bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 612bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GrGLVertToFrag uv(kVec2f_GrSLType); 613bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); 614bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // this is only used with text, so our texture bounds always match the glyph atlas 615bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " 616bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), 617bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth dfTexEffect.inTextureCoords()->fName); 618bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 619bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth // add frag shader code 620c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 62130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 62230ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 62330ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 62430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 625609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 626fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth // Use highp to work around aliasing issues 627fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 628fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 6295a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); 630fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, 631fdf7ccc2012dd06305cc3a0fbc788a483fce7b6ajvanverth pb->ctxInfo().standard())); 6325a105ff05303ac82a867b8b84a1edd145bd46218jvanverth if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 6335a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n"); 6345a105ff05303ac82a867b8b84a1edd145bd46218jvanverth } else { 6355a105ff05303ac82a867b8b84a1edd145bd46218jvanverth fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n"); 6365a105ff05303ac82a867b8b84a1edd145bd46218jvanverth } 63778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 638bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth if (useInverseScale) { 639bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("float dx = %s;", recipScale.fsIn()); 640bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } else { 641bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("float dx = dFdx(%s.x);", st.fsIn()); 642bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth } 643bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 offset = vec2(dx*delta, 0.0);"); 644609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 645bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); 646bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth 647bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 648bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 649bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); 650609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 651609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 652609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 65330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 654c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType); 65530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 65630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec3 distance;\n"); 65730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 658609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 65930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 66030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 661c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 66230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 66330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 664609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 66530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 66630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 667c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 66830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 66930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 6702d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 67130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance = " 672ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));"); 6732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 67421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth // adjust width based on gamma 67521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth const char* distanceAdjustUniName = NULL; 67621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 67721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth kVec3f_GrSLType, kDefault_GrSLPrecision, 67821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth "DistanceAdjust", &distanceAdjustUniName); 67921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); 68021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth 681609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 682609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 683609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 684609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 685354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("float afwidth;"); 68678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 687354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For uniform scale, we adjust for the effect of the transformation on the distance 688354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // by using the length of the gradient of the texture coordinates. We use st coordinates 689354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 690354eba5cb61801130a84378356434d3cc0a4b71ajvanverth 691609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 692354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dx);"); 693609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 694354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // For general transforms, to determine the amount of correction we multiply a unit 695354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // vector pointing along the SDF gradient direction by the Jacobian of the st coords 696354eba5cb61801130a84378356434d3cc0a4b71ajvanverth // (which is the inverse transform for this fragment) and take the length of the result. 697354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));"); 698d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // the length of the gradient may be 0, so we need to check for this 699d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth // this also compensates for the Adreno, which likes to drop tiles on division by 0 700d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); 701d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); 702d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); 703d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("} else {"); 704d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); 705d68a550ec890c3e3135ffa119621e17e55d58dd6jvanverth fsBuilder->codeAppend("}"); 706354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); 707354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); 708609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 709609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 710354eba5cb61801130a84378356434d3cc0a4b71ajvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 711609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 712609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 71321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fsBuilder->codeAppend( 71421deace8efc8e167d8626187ef0e6b4c241324b6jvanverth "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);"); 71530ba436f04e61d4505fb854d5fc56079636e0788joshualitt 7162dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 717609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 718609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 7197510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 7209b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& processor, 72136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 72221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth SkASSERT(fDistanceAdjustUni.isValid()); 723609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 724502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = 725502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth processor.cast<GrDistanceFieldLCDTextGeoProc>(); 726502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dfTexEffect.getDistanceAdjust(); 72721deace8efc8e167d8626187ef0e6b4c241324b6jvanverth if (wa != fDistanceAdjust) { 72821deace8efc8e167d8626187ef0e6b4c241324b6jvanverth pdman.set3f(fDistanceAdjustUni, 72921deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fR, 73021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fG, 73121deace8efc8e167d8626187ef0e6b4c241324b6jvanverth wa.fB); 73221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth fDistanceAdjust = wa; 7332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 7349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 735ee2af95db72152dfa61c841875df0594ca93437djoshualitt this->setUniformViewMatrix(pdman, processor.viewMatrix()); 736ee2af95db72152dfa61c841875df0594ca93437djoshualitt 7379b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>(); 7389b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 7399b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 7409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 7419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 7429b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 7439b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 744609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 745609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 74646d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static inline void GenKey(const GrGeometryProcessor& gp, 7479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 74887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 749b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 750502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>(); 751609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 7529b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>(); 7538fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint32_t key = dfTexEffect.getFlags(); 7548fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt key |= local.fInputColorType << 16; 75546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0; 75646d36f0e7b709a077c647841eee23bd3efdc4117robertphillips key |= ComputePosKey(gp.viewMatrix()) << 25; 757bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0; 7588fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key); 759609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 760609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 761609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 76221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth GrColor fColor; 76321deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fColorUniform; 764502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust; 76521deace8efc8e167d8626187ef0e6b4c241324b6jvanverth UniformHandle fDistanceAdjustUni; 766609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 767249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 768609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 769609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 770609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 771609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 772502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( 7738059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt GrColor color, const SkMatrix& viewMatrix, 774bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth const SkMatrix& localMatrix, 7752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 77621deace8efc8e167d8626187ef0e6b4c241324b6jvanverth DistanceAdjust distanceAdjust, 77778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 778bb4a1cf0e66c98c723f04f473a3221b2a4d8ece1jvanverth : INHERITED(color, viewMatrix, localMatrix) 7792e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 78021deace8efc8e167d8626187ef0e6b4c241324b6jvanverth , fDistanceAdjust(distanceAdjust) 7812dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fFlags(flags & kLCD_DistanceFieldEffectMask){ 78278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); 783502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth this->initClassID<GrDistanceFieldLCDTextGeoProc>(); 78471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 78571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", 7865a105ff05303ac82a867b8b84a1edd145bd46218jvanverth kVec2s_GrVertexAttribType)); 787609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 788609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 789609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 790502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldLCDTextGeoProc::onIsEqual(const GrGeometryProcessor& other) const { 791502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrDistanceFieldLCDTextGeoProc& cte = other.cast<GrDistanceFieldLCDTextGeoProc>(); 79221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth return (fDistanceAdjust == cte.fDistanceAdjust && 79378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags); 794609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 795609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 796502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const { 79756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUnknownFourComponents(); 79856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt out->setUsingLCDCoverage(); 799609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 800609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 801502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt, 802502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGLCaps& caps, 803502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorKeyBuilder* b) const { 804502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrGLDistanceFieldLCDTextGeoProc::GenKey(*this, bt, caps, b); 805eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 806eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 807abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualittGrGLPrimitiveProcessor* 808502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrDistanceFieldLCDTextGeoProc::createGLInstance(const GrBatchTracker& bt, 809502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGLCaps&) const { 810502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return SkNEW_ARGS(GrGLDistanceFieldLCDTextGeoProc, (*this, bt)); 811609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 812609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 813502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthvoid GrDistanceFieldLCDTextGeoProc::initBatchTracker(GrBatchTracker* bt, 814502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrPipelineInfo& init) const { 8159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>(); 8169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 817290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 8189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 8199b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 820502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthbool GrDistanceFieldLCDTextGeoProc::onCanMakeEqual(const GrBatchTracker& m, 821502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrGeometryProcessor& that, 822502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth const GrBatchTracker& t) const { 8239b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>(); 8249b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>(); 825290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords, 826290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt that, theirs.fUsesLocalCoords) && 827290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt CanCombineOutput(mine.fInputColorType, mine.fColor, 8289b98932adaceb7ad0a617ade16616923f6bffe84joshualitt theirs.fInputColorType, theirs.fColor); 8299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt} 8309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 831609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 832609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 833502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc); 834609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 835502286d7b8ecf26a3a33e8098335034e21e4b082jvanverthGrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(SkRandom* random, 836b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 837b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 839b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 840b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 841609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 842609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 843609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 844609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 845609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 846609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 847609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 848609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 849609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 850609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 851609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 85221deace8efc8e167d8626187ef0e6b4c241324b6jvanverth DistanceAdjust wa = { 0.0f, 0.1f, -0.1f }; 85378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 85478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 85578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 856502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(random), 857502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorUnitTest::TestMatrix(random), 858502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth GrProcessorUnitTest::TestMatrix(random), 859502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth textures[texIdx], params, 860502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth wa, 861502286d7b8ecf26a3a33e8098335034e21e4b082jvanverth flags); 862d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 863