GrDistanceFieldGeoProc.cpp revision b0a8a377f832c59cee939ad721e1f87d378b7142
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" 9408d6125b32c86e1f81ce60465e3bf4491e755fcjoshualitt#include "gl/builders/GrGLFullProgramBuilder.h" 10b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 11d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h" 12d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h" 13249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h" 14b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.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 32249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { 33d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic: 34b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLDistanceFieldTextureEffect(const GrBackendProcessorFactory& factory, 35b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 366c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : INHERITED (factory) 379564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fTextureSize(SkISize::Make(-1,-1)) 389564ce60a657acce89fb956deb8645b324eaad1ejvanverth#ifdef SK_GAMMA_APPLY_TO_A8 399564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fLuminance(-1.0f) 409564ce60a657acce89fb956deb8645b324eaad1ejvanverth#endif 419564ce60a657acce89fb956deb8645b324eaad1ejvanverth {} 42d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 4330ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 44b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 46d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* outputColor, 47d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const char* inputColor, 48d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TransformedCoordsArray&, 49d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com const TextureSamplerArray& samplers) SK_OVERRIDE { 50249af15fb82833d2274850c589812b6e69df0033joshualitt const GrDistanceFieldTextureEffect& dfTexEffect = 51b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt geometryProcessor.cast<GrDistanceFieldTextureEffect>(); 52249af15fb82833d2274850c589812b6e69df0033joshualitt SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); 53d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 54b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 5530ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 5630ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 576c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 58d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkString fsCoordName; 596c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* vsCoordName; 606c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* fsCoordNamePtr; 616c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 626c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org fsCoordName = fsCoordNamePtr; 63d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 6430ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 65249af15fb82833d2274850c589812b6e69df0033joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str()); 666c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 676c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* textureSizeUniName = NULL; 6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 696c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org kVec2f_GrSLType, "TextureSize", 706c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org &textureSizeUniName); 71d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 7230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 7330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], 74d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com fsCoordName.c_str(), 75d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 7630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 7730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat distance = " 782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")" 792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ " SK_DistanceFieldNonLCDFactor ";\n"); 806c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 816c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 826c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 836c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 8430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 8530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 8630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 8778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 884362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n"); 904362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 9130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 9230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 934362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 9430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 954362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 964362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 9930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 10030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 10230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 1034362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 10430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 1054362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 10630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 10730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 1084362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1094362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 1114362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 11230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); 1134d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 1162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* luminanceUniName = NULL; 1172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 11830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fLuminanceUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 1192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kFloat_GrSLType, "Luminance", 1202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &luminanceUniName); 1212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 12230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); 12330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 12430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 12530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 12630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval = gammaColor.r;\n"); 1272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 12930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 130d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); 131d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 132d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1337510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 134b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& effect) SK_OVERRIDE { 1356c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 1364362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 13749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt GrTexture* texture = effect.texture(0); 1384362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (texture->width() != fTextureSize.width() || 1394362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org texture->height() != fTextureSize.height()) { 1404362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 1417510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fTextureSizeUni, 1427510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 1437510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height())); 1446c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 1452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldTextureEffect& dfTexEffect = 147b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt effect.cast<GrDistanceFieldTextureEffect>(); 1482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance = dfTexEffect.getLuminance(); 1492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (luminance != fLuminance) { 1507510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fLuminanceUni, luminance); 1512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fLuminance = luminance; 1522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1546c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 155d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 156b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor& processor, const GrGLCaps&, 157b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 1584362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 159b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldTextureEffect>(); 1604362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 16178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 1624362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1634362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 164d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1657510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 1667510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 1677510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fLuminanceUni; 1687510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen float fLuminance; 1696c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 170249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 171d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 172d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 173d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 174d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 175d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, 1766c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 1772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, 1792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrTextureParams& gammaParams, 1802d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance, 1812d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 18278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 1836c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org : fTextureAccess(texture, params) 1842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gammaParams) 1862d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fLuminance(luminance) 1872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 188249af15fb82833d2274850c589812b6e69df0033joshualitt , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 189249af15fb82833d2274850c589812b6e69df0033joshualitt , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords", 190249af15fb82833d2274850c589812b6e69df0033joshualitt kVec2f_GrSLType, 191249af15fb82833d2274850c589812b6e69df0033joshualitt GrShaderVar::kAttribute_TypeModifier))) { 19278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 193d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addTextureAccess(&fTextureAccess); 1942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 1962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 197d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 198d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 199b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrDistanceFieldTextureEffect::onIsEqual(const GrProcessor& other) const { 20049586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>(); 20178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth return fTextureAccess == cte.fTextureAccess && 20278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8 20378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fGammaTextureAccess == cte.fGammaTextureAccess && 20478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fLuminance == cte.fLuminance && 20578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif 20678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags; 207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 209d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comvoid GrDistanceFieldTextureEffect::getConstantColorComponents(GrColor* color, 210d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com uint32_t* validFlags) const { 211d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 212d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrPixelConfigIsOpaque(this->texture(0)->config())) { 213d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = kA_GrColorComponentFlag; 214d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } else { 215d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *validFlags = 0; 216d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 217d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 218d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 219b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendGeometryProcessorFactory& GrDistanceFieldTextureEffect::getFactory() const { 220b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendGeometryProcessorFactory<GrDistanceFieldTextureEffect>::getInstance(); 221d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 222d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 223d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 224d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 225b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect); 226d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 227b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 228b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 229b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 230b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 231b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 232b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 2332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 234b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 235b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 2362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 237d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 238d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 239d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 240d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 241d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 242d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 243d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 244d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 246d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 247d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 2482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 2502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 2512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 252d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 253609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, 2542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 2562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 2572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 25878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth random->nextBool() ? 25978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth kSimilarity_DistanceFieldEffectFlag : 0); 260609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 261609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 262609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 263609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 264249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 265609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 266b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, 267b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor&) 268609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : INHERITED (factory) 2699564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fTextureSize(SkISize::Make(-1,-1)) 2709564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fTextColor(GrColor_ILLEGAL) {} 271609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 27230ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLFullProgramBuilder* builder, 273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor& geometryProcessor, 274b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 275609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* outputColor, 276609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* inputColor, 277609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TransformedCoordsArray&, 278609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const TextureSamplerArray& samplers) SK_OVERRIDE { 279609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 280b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt geometryProcessor.cast<GrDistanceFieldLCDTextureEffect>(); 281249af15fb82833d2274850c589812b6e69df0033joshualitt SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); 282609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 283609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkString fsCoordName; 284609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* vsCoordName; 285609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* fsCoordNamePtr; 286609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); 287609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fsCoordName = fsCoordNamePtr; 288609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 28930ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); 290249af15fb82833d2274850c589812b6e69df0033joshualitt vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str()); 291609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 292609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* textureSizeUniName = NULL; 293609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // width, height, 1/(3*width) 29430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 295609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kVec3f_GrSLType, "TextureSize", 296609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org &textureSizeUniName); 297609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 298b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 29930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 30030ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 30130ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 30230ba436f04e61d4505fb854d5fc56079636e0788joshualitt 303609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 30430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); 30530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 30678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); 30778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 30830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); 30930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName); 310609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 31130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 31230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 31330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName); 314609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 315609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 316609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 31730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 31830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); 31930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 32030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec3 distance;\n"); 32130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 322609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 32330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 32430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 32530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 32630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 32730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 328609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 32930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 33030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 33130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); 33230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 33330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 3342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 33530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance = " 3362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"))" 3372d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth "+ vec3(" SK_DistanceFieldLCDFactor ");\n"); 3382d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 339609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 340609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 341609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 342609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 343609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 344609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 345609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 346609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 34730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 34878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 349609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 35030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dx;\n"); 351609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 35230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 353609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { 354609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 35530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 35630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 35730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 35830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 35930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 36030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 361609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 36230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 363609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 36430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 36530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 366609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 367609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 36830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 369609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 370609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 37130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n"); 372609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 3732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 3742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* textColorUniName = NULL; 3752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 37630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fTextColorUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 3772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth kVec3f_GrSLType, "TextColor", 3782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth &textColorUniName); 3792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 38030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); 38130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 38230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 38330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 38430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); 38530ba436f04e61d4505fb854d5fc56079636e0788joshualitt 38630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); 38730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 38830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 38930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 39030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); 39130ba436f04e61d4505fb854d5fc56079636e0788joshualitt 39230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); 39330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 39430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[1], "uv", kVec2f_GrSLType); 39530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 39630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); 39730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 39830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 399609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr4("val")).c_str()); 400609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 401609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4027510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 403b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& processor) SK_OVERRIDE { 404609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 4052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkASSERT(fTextColorUni.isValid()); 406609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& dfTexEffect = 408b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldLCDTextureEffect>(); 409b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* texture = processor.texture(0); 410609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (texture->width() != fTextureSize.width() || 411609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org texture->height() != fTextureSize.height()) { 412609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 413609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org float delta = 1.0f/(3.0f*texture->width()); 41478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 415609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org delta = -delta; 416609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 4177510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextureSizeUni, 4187510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 4197510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height()), 4207510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen delta); 421609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 4222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 4232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = dfTexEffect.getTextColor(); 4242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (textColor != fTextColor) { 4252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth static const float ONE_OVER_255 = 1.f / 255.f; 4267510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextColorUni, 4277510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackR(textColor) * ONE_OVER_255, 4287510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackG(textColor) * ONE_OVER_255, 4297510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackB(textColor) * ONE_OVER_255); 4302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fTextColor = textColor; 4312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 432609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 433609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 434b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor& processor, const GrGLCaps&, 435b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 436609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 437b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldLCDTextureEffect>(); 438609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 43978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 440609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 441609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 442609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 4437510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 4447510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 4457510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextColorUni; 4467510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkColor fTextColor; 447609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 448249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 449609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 450609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 451609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 452609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthGrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 4542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 4552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, const GrTextureParams& gParams, 4562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkColor textColor, 45778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 458609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org : fTextureAccess(texture, params) 4592d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gParams) 4602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fTextColor(textColor) 461249af15fb82833d2274850c589812b6e69df0033joshualitt , fFlags(flags & kLCD_DistanceFieldEffectMask) 462249af15fb82833d2274850c589812b6e69df0033joshualitt , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords", 463249af15fb82833d2274850c589812b6e69df0033joshualitt kVec2f_GrSLType, 464249af15fb82833d2274850c589812b6e69df0033joshualitt GrShaderVar::kAttribute_TypeModifier))) { 46578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); 46678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth 467609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 4682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 469609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 470609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 471b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrProcessor& other) const { 47249586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>(); 47378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth return (fTextureAccess == cte.fTextureAccess && 47478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fGammaTextureAccess == cte.fGammaTextureAccess && 47578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fTextColor == cte.fTextColor && 47678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags); 477609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 478609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 479609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgvoid GrDistanceFieldLCDTextureEffect::getConstantColorComponents(GrColor* color, 480609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org uint32_t* validFlags) const { 481609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && 482609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrPixelConfigIsOpaque(this->texture(0)->config())) { 483609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = kA_GrColorComponentFlag; 484609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 485609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org *validFlags = 0; 486609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 487609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 488609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 489b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendGeometryProcessorFactory& GrDistanceFieldLCDTextureEffect::getFactory() const { 490b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendGeometryProcessorFactory<GrDistanceFieldLCDTextureEffect>::getInstance(); 491609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 492609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 493609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 494609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 495b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect); 496609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 497b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random, 498b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 499b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 500b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 501b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 502b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 503b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 504b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 505609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 506609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 507609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 508609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 509609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 510609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 511609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 512609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 513609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 514609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 515609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 5162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 5172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 5182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = GrColorPackRGBA(random->nextULessThan(256), 5192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 5202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 5212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256)); 52278f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 52378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 52478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 525609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, 5262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 5272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textColor, 52878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags); 529d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 530