GrDistanceFieldGeoProc.cpp revision 30ba436f04e61d4505fb854d5fc56079636e0788
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 830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 9d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrDistanceFieldTextureEffect.h" 10d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLEffect.h" 11d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h" 12d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h" 13d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLVertexEffect.h" 14d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTBackendEffectFactory.h" 15d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTexture.h" 16d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 17762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org#include "SkDistanceFieldGen.h" 18d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// To get optical sizes people don't complain about when we blit correctly, 202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// we need to slightly bold each glyph. On the Mac, we need a larger bold value. 212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#if defined(SK_BUILD_FOR_MAC) 222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldLCDFactor "0.33" 232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldNonLCDFactor "0.25" 242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#else 252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldLCDFactor "0.05" 262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldNonLCDFactor "0.05" 272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2 302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldAAFactor "0.7071" 312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 32d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comclass GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { 33d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic: 34a3b532743dbb1d54a4c17a2574083ef93c949d50skia.committer@gmail.com GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, 356c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrDrawEffect& drawEffect) 366c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : INHERITED (factory) 374362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org , fTextureSize(SkISize::Make(-1,-1)) {} 38d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 3930ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 40d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const GrDrawEffect& drawEffect, 4163e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon const GrEffectKey& key, 42d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* outputColor, 43d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* inputColor, 44d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TransformedCoordsArray&, 45d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 46d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numVertexAttribs()); 47d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 4830ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 4930ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 5030ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 514362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 524362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 536c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 54d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkString fsCoordName; 556c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* vsCoordName; 566c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* fsCoordNamePtr; 576c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 586c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org fsCoordName = fsCoordNamePtr; 59d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 6030ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 6130ba436f04e61d4505fb854d5fc56079636e0788joshualitt const SkString* attr0Name = 6230ba436f04e61d4505fb854d5fc56079636e0788joshualitt vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); 6330ba436f04e61d4505fb854d5fc56079636e0788joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); 646c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 656c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* textureSizeUniName = NULL; 6630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 676c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org kVec2f_GrSLType, "TextureSize", 686c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org &textureSizeUniName); 69d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 7030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 7130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], 72d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com fsCoordName.c_str(), 73d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 7430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 7530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat distance = " 762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")" 772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ " SK_DistanceFieldNonLCDFactor ";\n"); 786c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 796c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 806c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 816c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 8230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 8330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 8430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 8578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 864362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 8730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n"); 884362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 9030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 914362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 9230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 934362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 944362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 9530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 9630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 9930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 10030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 1014362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 1034362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 10530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 1064362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1074362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 10830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 1094362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); 1114d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 1142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* luminanceUniName = NULL; 1152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 11630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 1172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kFloat_GrSLType, "Luminance", 1182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &luminanceUniName); 1192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 12030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); 12130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 12230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 12330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 12430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval = gammaColor.r;\n"); 1252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 12730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 128d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); 129d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 130d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1317510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 1326c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrDrawEffect& drawEffect) SK_OVERRIDE { 1336c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 1344362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 135f99f884cd82528684779e40413f1ceaf277dad2dbsalomon GrTexture* texture = drawEffect.effect()->texture(0); 1364362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (texture->width() != fTextureSize.width() || 1374362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org texture->height() != fTextureSize.height()) { 1384362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 1397510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fTextureSizeUni, 1407510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 1417510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height())); 1426c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 1432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldTextureEffect& dfTexEffect = 1452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 1462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance = dfTexEffect.getLuminance(); 1472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (luminance != fLuminance) { 1487510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fLuminanceUni, luminance); 1492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fLuminance = luminance; 1502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1526c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 153d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 15463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, 15563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon GrEffectKeyBuilder* b) { 1564362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 1574362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 1584362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 15978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 1604362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1614362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 162d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1637510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 1647510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 1657510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fLuminanceUni; 1667510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen float fLuminance; 1676c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 168d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com typedef GrGLVertexEffect INHERITED; 169d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 170d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 171d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 172d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 173d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, 1746c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 1752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, 1772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrTextureParams& gammaParams, 1782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance, 1792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 18078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 1816c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : fTextureAccess(texture, params) 1822d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gammaParams) 1842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fLuminance(luminance) 1852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 18678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth , fFlags(flags & kNonLCD_DistanceFieldEffectMask) { 18778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 188d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addTextureAccess(&fTextureAccess); 1892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 1912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 192d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addVertexAttrib(kVec2f_GrSLType); 193d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 194d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 195d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.combool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const { 196d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureEffect>(other); 19778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth return fTextureAccess == cte.fTextureAccess && 19878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8 19978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fGammaTextureAccess == cte.fGammaTextureAccess && 20078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fLuminance == cte.fLuminance && 20178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif 20278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags; 203d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comvoid GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, 206d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com uint32_t* validFlags) const { 207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrPixelConfigIsOpaque(this->texture(0)->config())) { 209d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = kA_GrColorComponentFlag; 210d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } else { 211d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = 0; 212d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 213d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 214d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 215d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comconst GrBackendEffectFactory& GrDistanceFieldTextureEffect::getFactory() const { 216d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com return GrTBackendEffectFactory<GrDistanceFieldTextureEffect>::getInstance(); 217d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 218d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 219d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 220d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 221d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGR_DEFINE_EFFECT_TEST(GrDistanceFieldTextureEffect); 222d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 22383d081ae1d731b5039e99823620f5e287542ee39bsalomonGrEffect* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 22483d081ae1d731b5039e99823620f5e287542ee39bsalomon GrContext*, 22583d081ae1d731b5039e99823620f5e287542ee39bsalomon const GrDrawTargetCaps&, 22683d081ae1d731b5039e99823620f5e287542ee39bsalomon GrTexture* textures[]) { 227d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 228d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrEffectUnitTest::kAlphaTextureIdx; 2292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 2312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 2322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 233d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 234d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 235d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 236d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 237d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 238d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 239d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 240d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 241d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 242d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 243d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 2442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 2462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 2472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 248d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 249609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, 2502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 2522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 2532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 25478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth random->nextBool() ? 25578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth kSimilarity_DistanceFieldEffectFlag : 0); 256609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 257609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 258609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 259609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 260609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgclass GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect { 261609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 262609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory, 263609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect) 264609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : INHERITED (factory) 265609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org , fTextureSize(SkISize::Make(-1,-1)) {} 266609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 26730ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 268609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect, 26963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon const GrEffectKey& key, 270609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* outputColor, 271609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* inputColor, 272609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TransformedCoordsArray&, 273609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TextureSamplerArray& samplers) SK_OVERRIDE { 274609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().numVertexAttribs()); 275609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 276609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 277609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 278609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 279609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkString fsCoordName; 280609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* vsCoordName; 281609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* fsCoordNamePtr; 282609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 283609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fsCoordName = fsCoordNamePtr; 284609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 28530ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 28630ba436f04e61d4505fb854d5fc56079636e0788joshualitt const SkString* attr0Name = 28730ba436f04e61d4505fb854d5fc56079636e0788joshualitt vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); 28830ba436f04e61d4505fb854d5fc56079636e0788joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, attr0Name->c_str()); 289609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 290609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* textureSizeUniName = NULL; 291609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // width, height, 1/(3*width) 29230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 293609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kVec3f_GrSLType, "TextureSize", 294609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org &textureSizeUniName); 295609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 29630ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 29730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 29830ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 29930ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 30030ba436f04e61d4505fb854d5fc56079636e0788joshualitt 301609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 30230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 30330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 30478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); 30578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 30630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); 30730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName); 308609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 30930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 31030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 31130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName); 312609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 313609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 314609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 31530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 31630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); 31730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 31830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec3 distance;\n"); 31930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 320609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 32130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 32230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 32330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 32430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 32530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 326609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 32730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 32830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 32930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 33030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 33130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 3322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 33330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance = " 3342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"))" 3352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); 3362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 337609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 338609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 339609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 340609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 341609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 342609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 343609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 344609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 34530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 34678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 347609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 34830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n"); 349609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 35030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 351609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 352609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 35330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 35430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 35530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 35630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 35730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 35830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 359609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 36030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 361609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 36230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 36330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 364609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 365609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 36630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 367609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 368609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 36930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n"); 370609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 3712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 3722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* textColorUniName = NULL; 3732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 37430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 3752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kVec3f_GrSLType, "TextColor", 3762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &textColorUniName); 3772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 37830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); 37930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 38030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 38130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 38230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); 38330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 38430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); 38530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 38630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 38730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 38830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); 38930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 39030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); 39130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 39230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 39330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 39430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); 39530ba436f04e61d4505fb854d5fc56079636e0788joshualitt 39630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 397609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_str()); 398609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 399609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4007510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 401609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect) SK_OVERRIDE { 402609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 4032d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkASSERT(fTextColorUni.isValid()); 404609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& dfTexEffect = 4062d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 407f99f884cd82528684779e40413f1ceaf277dad2dbsalomon GrTexture* texture = drawEffect.effect()->texture(0); 408609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (texture->width() != fTextureSize.width() || 409609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org texture->height() != fTextureSize.height()) { 410609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 411609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org float delta = 1.0f/(3.0f*texture->width()); 41278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 413609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org delta = -delta; 414609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 4157510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextureSizeUni, 4167510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 4177510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height()), 4187510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen delta); 419609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 4202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 4212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = dfTexEffect.getTextColor(); 4222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (textColor != fTextColor) { 4232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth static const float ONE_OVER_255 = 1.f / 255.f; 4247510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextColorUni, 4257510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackR(textColor) * ONE_OVER_255, 4267510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackG(textColor) * ONE_OVER_255, 4277510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackB(textColor) * ONE_OVER_255); 4282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fTextColor = textColor; 4292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 430609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 431609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 43263e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, 43363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon GrEffectKeyBuilder* b) { 434609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 435609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 436609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 43778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 438609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 439609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 440609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 4417510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 4427510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 4437510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextColorUni; 4447510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkColor fTextColor; 445609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 446609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org typedef GrGLVertexEffect INHERITED; 447609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 448609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 449609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 450609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthGrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 4522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 4532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, const GrTextureParams& gParams, 4542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkColor textColor, 45578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 456609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : fTextureAccess(texture, params) 4572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gParams) 4582d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fTextColor(textColor) 45978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth , fFlags(flags & kLCD_DistanceFieldEffectMask) { 46078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); 46178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth 462609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 4632d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 464609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addVertexAttrib(kVec2f_GrSLType); 465609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 466609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 467609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgbool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrEffect& other) const { 4682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& cte = 4692d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth CastEffect<GrDistanceFieldLCDTextureEffect>(other); 47078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth return (fTextureAccess == cte.fTextureAccess && 47178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fGammaTextureAccess == cte.fGammaTextureAccess && 47278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fTextColor == cte.fTextColor && 47378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags); 474609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 475609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 476609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgvoid GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color, 477609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org uint32_t* validFlags) const { 478609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 479609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrPixelConfigIsOpaque(this->texture(0)->config())) { 480609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = kA_GrColorComponentFlag; 481609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 482609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = 0; 483609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 484609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 485609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 486609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgconst GrBackendEffectFactory& GrDistanceFieldLCDTextureEffect::getFactory() const { 487609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrTBackendEffectFactory<GrDistanceFieldLCDTextureEffect>::getInstance(); 488609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 489609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 490609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 491609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 492609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(GrDistanceFieldLCDTextureEffect); 493609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 49483d081ae1d731b5039e99823620f5e287542ee39bsalomonGrEffect* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random, 49583d081ae1d731b5039e99823620f5e287542ee39bsalomon GrContext*, 49683d081ae1d731b5039e99823620f5e287542ee39bsalomon const GrDrawTargetCaps&, 49783d081ae1d731b5039e99823620f5e287542ee39bsalomon GrTexture* textures[]) { 498609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 4992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 5002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 5012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 502609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 503609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 504609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 505609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 506609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 507609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 508609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 509609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 510609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 511609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 512609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 5132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 5142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 5152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = GrColorPackRGBA(random->nextULessThan(256), 5162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 5172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 5182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256)); 51978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 52078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 52178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 522609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 5232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 5242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textColor, 52578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags); 526d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 527