1d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/* 2d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Copyright 2013 Google Inc. 3d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * 4d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Use of this source code is governed by a BSD-style license that can be 5d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * found in the LICENSE file. 6d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com */ 7d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 8d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrDistanceFieldTextureEffect.h" 9d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLEffect.h" 10d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h" 11d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h" 12d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLVertexEffect.h" 13d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTBackendEffectFactory.h" 14d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTexture.h" 15d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 16762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org#include "SkDistanceFieldGen.h" 17d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// To get optical sizes people don't complain about when we blit correctly, 192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// we need to slightly bold each glyph. On the Mac, we need a larger bold value. 202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#if defined(SK_BUILD_FOR_MAC) 212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldLCDFactor "0.33" 222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldNonLCDFactor "0.25" 232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#else 242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldLCDFactor "0.05" 252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldNonLCDFactor "0.05" 262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2 292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldAAFactor "0.7071" 302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 31d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comclass GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { 32d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic: 33a3b532743dbb1d54a4c17a2574083ef93c949d50skia.committer@gmail.com GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, 346c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrDrawEffect& drawEffect) 356c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : INHERITED (factory) 364362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org , fTextureSize(SkISize::Make(-1,-1)) {} 37d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 38d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com virtual void emitCode(GrGLFullShaderBuilder* builder, 39d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const GrDrawEffect& drawEffect, 40d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com EffectKey key, 41d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* outputColor, 42d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* inputColor, 43d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TransformedCoordsArray&, 44d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 45d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numVertexAttribs()); 46d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 476c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); 484362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 494362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 506c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 51d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkString fsCoordName; 526c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* vsCoordName; 536c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* fsCoordNamePtr; 546c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 556c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org fsCoordName = fsCoordNamePtr; 56d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 576c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* attrName0 = 58d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str(); 596c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); 606c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 616c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* textureSizeUniName = NULL; 626c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 636c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org kVec2f_GrSLType, "TextureSize", 646c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org &textureSizeUniName); 65d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 66d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com builder->fsCodeAppend("\tvec4 texColor = "); 67d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com builder->fsAppendTextureLookup(samplers[0], 68d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com fsCoordName.c_str(), 69d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 70d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com builder->fsCodeAppend(";\n"); 71a1ed7aec95eb8c77d1a39834fea476780007cadeskia.committer@gmail.com builder->fsCodeAppend("\tfloat distance = " 722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")" 732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ " SK_DistanceFieldNonLCDFactor ";\n"); 746c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 756c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 766c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 776c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 784362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 794362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 804362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tfloat afwidth;\n"); 81609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (dfTexEffect.isSimilarity()) { 824362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n"); 844362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 854362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); 864362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); 874362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 884362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tvec2 uv_grad;\n"); 894362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 904362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 914362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 924362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); 934362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 944362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\t} else {\n"); 954362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 964362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\t}\n"); 974362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 984362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); 994362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1004362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 1014362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 1024362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1034362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 1042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 1054362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 106919ed4c73633e92bfc6694161360c5c3f45728e8scroggo builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); 1074d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 1102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* luminanceUniName = NULL; 1112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 1122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fLuminanceUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 1132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kFloat_GrSLType, "Luminance", 1142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &luminanceUniName); 1152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 1162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); 1172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tvec4 gammaColor = "); 1182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 1192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend(";\n"); 1202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tval = gammaColor.r;\n"); 1212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 123d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com builder->fsCodeAppendf("\t%s = %s;\n", outputColor, 124d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); 125d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 126d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 127d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com virtual void setData(const GrGLUniformManager& uman, 1286c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrDrawEffect& drawEffect) SK_OVERRIDE { 1296c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 1304362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1314362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org GrTexture* texture = drawEffect.effect()->get()->texture(0); 1324362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (texture->width() != fTextureSize.width() || 1334362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org texture->height() != fTextureSize.height()) { 1344362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 135a3b532743dbb1d54a4c17a2574083ef93c949d50skia.committer@gmail.com uman.set2f(fTextureSizeUni, 1364362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org SkIntToScalar(fTextureSize.width()), 1374362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org SkIntToScalar(fTextureSize.height())); 1386c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 1392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1402d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldTextureEffect& dfTexEffect = 1412d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 1422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance = dfTexEffect.getLuminance(); 1432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (luminance != fLuminance) { 1442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth uman.set1f(fLuminanceUni, luminance); 1452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fLuminance = luminance; 1462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1486c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 149d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1504362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { 1514362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 1524362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldTextureEffect>(); 1534362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 154609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return dfTexEffect.isSimilarity() ? 0x1 : 0x0; 1554362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1564362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 157d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1586c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org GrGLUniformManager::UniformHandle fTextureSizeUni; 1594362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org SkISize fTextureSize; 1602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrGLUniformManager::UniformHandle fLuminanceUni; 1612d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float fLuminance; 1626c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 163d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com typedef GrGLVertexEffect INHERITED; 164d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 165d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 166d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 167d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 168d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, 1696c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 1702d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, 1722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrTextureParams& gammaParams, 1732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance, 1742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 175609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org bool similarity) 1766c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : fTextureAccess(texture, params) 1772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gammaParams) 1792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fLuminance(luminance) 1802d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 181609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org , fIsSimilarity(similarity) { 182d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addTextureAccess(&fTextureAccess); 1832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 1852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 186d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addVertexAttrib(kVec2f_GrSLType); 187d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 188d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 189d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.combool GrDistanceFieldTextureEffect::onIsEqual(const GrEffect& other) const { 190d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const GrDistanceFieldTextureEffect& cte = CastEffect<GrDistanceFieldTextureEffect>(other); 191d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com return fTextureAccess == cte.fTextureAccess; 192d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 193d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 194d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comvoid GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, 195d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com uint32_t* validFlags) const { 196d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 197d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrPixelConfigIsOpaque(this->texture(0)->config())) { 198d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = kA_GrColorComponentFlag; 199d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } else { 200d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = 0; 201d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 202d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 203d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comconst GrBackendEffectFactory& GrDistanceFieldTextureEffect::getFactory() const { 205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com return GrTBackendEffectFactory<GrDistanceFieldTextureEffect>::getInstance(); 206d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 209d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 210d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGR_DEFINE_EFFECT_TEST(GrDistanceFieldTextureEffect); 211d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 212d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 213d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrContext*, 214d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const GrDrawTargetCaps&, 215d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTexture* textures[]) { 216d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 217d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrEffectUnitTest::kAlphaTextureIdx; 2182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 2202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 2212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 222d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 223d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 224d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 225d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 226d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 227d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 228d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 229d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 230d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 231d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 232d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 2332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 2352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 2362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 237d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 238609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, 2392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2402d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 2412d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 2422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 243609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org random->nextBool()); 244609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 245609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 246609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 247609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 248609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgclass GrGLDistanceFieldLCDTextureEffect : public GrGLVertexEffect { 249609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 250609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory, 251609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect) 252609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : INHERITED (factory) 253609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org , fTextureSize(SkISize::Make(-1,-1)) {} 254609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 255609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org virtual void emitCode(GrGLFullShaderBuilder* builder, 256609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect, 257609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org EffectKey key, 258609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* outputColor, 259609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* inputColor, 260609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TransformedCoordsArray&, 261609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TextureSamplerArray& samplers) SK_OVERRIDE { 262609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>().numVertexAttribs()); 263609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 264609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); 265609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 266609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 267609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 268609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkString fsCoordName; 269609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* vsCoordName; 270609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* fsCoordNamePtr; 271609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 272609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fsCoordName = fsCoordNamePtr; 273609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 274609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* attrName0 = 2752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str(); 276609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); 277609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 278609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* textureSizeUniName = NULL; 279609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // width, height, 1/(3*width) 280609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 281609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kVec3f_GrSLType, "TextureSize", 282609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org &textureSizeUniName); 283609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 284609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 285609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 286609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 287609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (dfTexEffect.isUniformScale()) { 288609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tfloat dx = dFdx(st.x);\n"); 289609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName); 290609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 291609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); 292609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); 293609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName); 294609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 295609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 296609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 297609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec4 texColor = "); 298609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); 299609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend(";\n"); 300609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec3 distance;\n"); 3012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tdistance.y = texColor.r;\n"); 302609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 303609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 304609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\ttexColor = "); 305609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 306609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend(";\n"); 3072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tdistance.x = texColor.r;\n"); 308609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 309609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); 310609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\ttexColor = "); 311609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 312609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend(";\n"); 3132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tdistance.z = texColor.r;\n"); 3142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 3152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tdistance = " 3162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"))" 3172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); 3182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 319609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 320609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 321609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 322609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 323609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 324609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 325609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 326609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 327609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tfloat afwidth;\n"); 328609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (dfTexEffect.isUniformScale()) { 329609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 3302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n"); 331609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 332609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec2 uv_grad;\n"); 333609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 334609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 335609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 336609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n"); 337609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 338609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\t} else {\n"); 339609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 340609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\t}\n"); 341609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 342609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tuv_grad = normalize(uv);\n"); 343609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 344609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 345609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 346609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 347609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 3482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 349609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 350609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 351609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n"); 352609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 3532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 3542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* textColorUniName = NULL; 3552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 3562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fTextColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 3572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kVec3f_GrSLType, "TextColor", 3582d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &textColorUniName); 3592d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 3602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); 3612d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tvec4 gammaColor = "); 3622d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 3632d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend(";\n"); 3642d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tval.x = gammaColor.r;\n"); 3652d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 3662d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); 3672d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tgammaColor = "); 3682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 3692d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend(";\n"); 3702d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tval.y = gammaColor.r;\n"); 3712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 3722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); 3732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tgammaColor = "); 3742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsAppendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 3752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend(";\n"); 3762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth builder->fsCodeAppend("\tval.z = gammaColor.r;\n"); 3772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 378609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->fsCodeAppendf("\t%s = %s;\n", outputColor, 379609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_str()); 380609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 381609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 382609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org virtual void setData(const GrGLUniformManager& uman, 383609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawEffect& drawEffect) SK_OVERRIDE { 384609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 3852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkASSERT(fTextColorUni.isValid()); 386609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 3872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& dfTexEffect = 3882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 389609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTexture* texture = drawEffect.effect()->get()->texture(0); 390609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (texture->width() != fTextureSize.width() || 391609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org texture->height() != fTextureSize.height()) { 392609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 393609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org float delta = 1.0f/(3.0f*texture->width()); 394609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (dfTexEffect.useBGR()) { 395609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org delta = -delta; 396609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 397609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org uman.set3f(fTextureSizeUni, 398609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkIntToScalar(fTextureSize.width()), 399609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkIntToScalar(fTextureSize.height()), 400609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org delta); 401609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 4022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 4032d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = dfTexEffect.getTextColor(); 4042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (textColor != fTextColor) { 4052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth static const float ONE_OVER_255 = 1.f / 255.f; 4062d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth uman.set3f(fTextColorUni, 4072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColorUnpackR(textColor) * ONE_OVER_255, 4082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColorUnpackG(textColor) * ONE_OVER_255, 4092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColorUnpackB(textColor) * ONE_OVER_255); 4102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fTextColor = textColor; 4112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 412609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 413609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 414609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { 415609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 416609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>(); 417609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth return dfTexEffect.isUniformScale() ? 0x01 : 0x00;; 419609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 420609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 421609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 422609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrGLUniformManager::UniformHandle fTextureSizeUni; 423609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkISize fTextureSize; 4242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrGLUniformManager::UniformHandle fTextColorUni; 4252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkColor fTextColor; 426609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 427609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org typedef GrGLVertexEffect INHERITED; 428609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 429609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 430609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 431609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthGrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 4332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 4342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, const GrTextureParams& gParams, 4352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkColor textColor, 4362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth bool uniformScale, bool useBGR) 437609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : fTextureAccess(texture, params) 4382d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gParams) 4392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fTextColor(textColor) 440609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org , fUniformScale(uniformScale) 441609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org , fUseBGR(useBGR) { 442609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 4432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 444609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addVertexAttrib(kVec2f_GrSLType); 445609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 446609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 447609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgbool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrEffect& other) const { 4482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& cte = 4492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth CastEffect<GrDistanceFieldLCDTextureEffect>(other); 4502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth return (fTextureAccess == cte.fTextureAccess && fGammaTextureAccess == cte.fGammaTextureAccess); 451609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 452609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 453609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgvoid GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color, 454609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org uint32_t* validFlags) const { 455609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 456609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrPixelConfigIsOpaque(this->texture(0)->config())) { 457609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = kA_GrColorComponentFlag; 458609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 459609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = 0; 460609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 461609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 462609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 463609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgconst GrBackendEffectFactory& GrDistanceFieldLCDTextureEffect::getFactory() const { 464609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrTBackendEffectFactory<GrDistanceFieldLCDTextureEffect>::getInstance(); 465609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 466609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 467609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 468609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 469609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(GrDistanceFieldLCDTextureEffect); 470609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 471609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgGrEffectRef* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random, 472609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrContext*, 473609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDrawTargetCaps&, 474609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTexture* textures[]) { 475609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 4762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 4772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int texIdx2 = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 4782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrEffectUnitTest::kAlphaTextureIdx; 479609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 480609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 481609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 482609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 483609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 484609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 485609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 486609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 487609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 488609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 489609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 4902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 4912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 4922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = GrColorPackRGBA(random->nextULessThan(256), 4932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 4942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 4952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256)); 496609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 4972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 4982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textColor, 499609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org random->nextBool(), random->nextBool()); 500d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 501