GrDistanceFieldGeoProc.cpp revision 2e3b3e369d79e78f7635d4c20e83a47ab571bdf2
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" 9605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 10eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrTexture.h" 11eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkDistanceFieldGen.h" 12b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 13d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLSL.h" 14d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "gl/GrGLTexture.h" 15249af15fb82833d2274850c589812b6e69df0033joshualitt#include "gl/GrGLGeometryProcessor.h" 16eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h" 17d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth// Assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2 192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SK_DistanceFieldAAFactor "0.7071" 202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 21249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldTextureEffect : public GrGLGeometryProcessor { 22d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.compublic: 23eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&, 2487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 25eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt : fTextureSize(SkISize::Make(-1,-1)) 269564ce60a657acce89fb956deb8645b324eaad1ejvanverth#ifdef SK_GAMMA_APPLY_TO_A8 279564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fLuminance(-1.0f) 289564ce60a657acce89fb956deb8645b324eaad1ejvanverth#endif 299564ce60a657acce89fb956deb8645b324eaad1ejvanverth {} 30d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 31c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 32249af15fb82833d2274850c589812b6e69df0033joshualitt const GrDistanceFieldTextureEffect& dfTexEffect = 33c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt args.fGP.cast<GrDistanceFieldTextureEffect>(); 34d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 35c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 3630ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 3730ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 386c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 392dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 4074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag v(kVec2f_GrSLType); 4174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("TextureCoords", &v); 422dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); 43d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 442dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt // setup color attribute 452dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if(dfTexEffect.inColor()) { 462dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); 472dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 486c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 494973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt // setup position varying 504973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), 512dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->uViewM(), dfTexEffect.inPosition()->fName); 522dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 532dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt // setup output coords 542dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), 552dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 562dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), 572dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 584973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 596c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const char* textureSizeUniName = NULL; 60c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 61422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kVec2f_GrSLType, kDefault_GrSLPrecision, 62422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "TextureSize", &textureSizeUniName); 63d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 6430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 65c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 6674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt v.fsIn(), 67d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kVec2f_GrSLType); 6830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 6930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat distance = " 70ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); 716c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 726c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 736c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 746c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 7574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); 7630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); 7730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 7878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 794362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 80fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));\n"); 814362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 8230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 8330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 844362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 8530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 86c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) { 874362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 8830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 8930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 9030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 9130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 9230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 9330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 944362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } else { 9530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 964362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 9830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 994362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 1004362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org // this gives us a smooth step across approximately one fragment 10130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 1024362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 10330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); 1044d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 1052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1062d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 1072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* luminanceUniName = NULL; 1082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 109c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 110422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kFloat_GrSLType, kDefault_GrSLPrecision, 111422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "Luminance", &luminanceUniName); 1122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 11330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName); 11430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 115c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType); 11630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 11730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval = gammaColor.r;\n"); 1182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 1202dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 121d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com } 122d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1237510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 12487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGeometryProcessor& proc, 12587f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) SK_OVERRIDE { 1266c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 1274362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 12887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt GrTexture* texture = proc.texture(0); 1294362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org if (texture->width() != fTextureSize.width() || 1304362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org texture->height() != fTextureSize.height()) { 1314362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 1327510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2f(fTextureSizeUni, 1337510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 1347510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height())); 1356c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 1362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1372d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldTextureEffect& dfTexEffect = 13887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt proc.cast<GrDistanceFieldTextureEffect>(); 1392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance = dfTexEffect.getLuminance(); 1402d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (luminance != fLuminance) { 1417510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set1f(fLuminanceUni, luminance); 1422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fLuminance = luminance; 1432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 1442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 1456c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org } 146d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 14787f48d997ec29e5eeaa7567355775e93465dd60djoshualitt static inline void GenKey(const GrGeometryProcessor& processor, 14887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&, 14987f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 150b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 1514362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org const GrDistanceFieldTextureEffect& dfTexEffect = 152b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldTextureEffect>(); 1534362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 15478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 1554362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org } 1564362a38563a958083aca2b456aaaa9f756f6f4e1commit-bot@chromium.org 157d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comprivate: 1587510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 1597510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 1607510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fLuminanceUni; 1617510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen float fLuminance; 1626c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org 163249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 164d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}; 165d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 166d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 167d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 1682e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualittGrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, 1692e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 1706c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org const GrTextureParams& params, 1712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, 1732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrTextureParams& gammaParams, 1742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth float luminance, 1752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 17678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 1772e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt : INHERITED(color) 1782e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 1792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1802d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gammaParams) 1812d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fLuminance(luminance) 1822d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 183249af15fb82833d2274850c589812b6e69df0033joshualitt , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 1842dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 18578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 186eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrDistanceFieldTextureEffect>(); 1872dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); 1882dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (flags & kColorAttr_DistanceFieldEffectFlag) { 1892dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType)); 1902dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt this->setHasVertexColor(); 1912dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 1922dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords", 1932dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 194d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com this->addTextureAccess(&fTextureAccess); 1952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 1962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 1972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 198d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 199d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 2000e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) const { 20149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>(); 202420d7e9a79358908850c74192b4949375563449absalomon return 20378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#ifdef SK_GAMMA_APPLY_TO_A8 20478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fLuminance == cte.fLuminance && 20578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth#endif 20678f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags; 207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 209605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrDistanceFieldTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 210ccb2e384a036f29d989d3c1468f879324e81a678egdaniel inout->mulByUnknownAlpha(); 211d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 212d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 213eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt, 214eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt const GrGLCaps& caps, 215eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 216eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldTextureEffect::GenKey(*this, bt, caps, b); 217eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 218eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 219eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLGeometryProcessor* 220eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt) const { 221eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt)); 222d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 223d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 224d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/////////////////////////////////////////////////////////////////////////////// 225d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 226b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldTextureEffect); 227d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 228b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, 229b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 230b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 231b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 232b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 233b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 2342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 235b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 236b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 2372d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 238d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com static const SkShader::TileMode kTileModes[] = { 239d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kClamp_TileMode, 240d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kRepeat_TileMode, 241d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::kMirror_TileMode, 242d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 243d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com SkShader::TileMode tileModes[] = { 244d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 246d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com }; 247d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 248d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com GrTextureParams::kNone_FilterMode); 2492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 2512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 2522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 253d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com 2542e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), textures[texIdx], params, 2552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8 2562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 2572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextF(), 2582d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif 25978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth random->nextBool() ? 26078f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth kSimilarity_DistanceFieldEffectFlag : 0); 261609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 262609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 263609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 264609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 265fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthclass GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { 266fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthpublic: 267eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&, 26887f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 269eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt : fTextureSize(SkISize::Make(-1, -1)) {} 270fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 271c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 272fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = 273c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt args.fGP.cast<GrDistanceFieldNoGammaTextureEffect>(); 274fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 275c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 276fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkAssertResult(fsBuilder->enableFeature( 277fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 278fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 2792dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 28074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag v(kVec2f_GrSLType); 28174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("TextureCoords", &v); 282fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 2832dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt // setup color attribute 2842dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if(dfTexEffect.inColor()) { 2852dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt args.fPB->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); 2862dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 2872dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 2882dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); 2892dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 2902dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt // setup coord outputs 2912dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), 2922dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 2932dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), 2942dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 295fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 2964973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt // setup position varying 2974973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), 2982dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->uViewM(), dfTexEffect.inPosition()->fName); 2994973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 300fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth const char* textureSizeUniName = NULL; 301c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 302422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kVec2f_GrSLType, kDefault_GrSLPrecision, 303422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "TextureSize", &textureSizeUniName); 304fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 305fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("vec4 texColor = "); 306c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], 30774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt v.fsIn(), 308fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kVec2f_GrSLType); 309fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend(";"); 310fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float distance = " 311fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); 312fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 313fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // we adjust for the effect of the transformation on the distance by using 314fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // the length of the gradient of the texture coordinates. We use st coordinates 315fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // to ensure we're mapping 1:1 from texel space to pixel space. 31674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); 317fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); 318fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float afwidth;"); 319fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { 320fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 321fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));"); 322fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } else { 323fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); 324fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); 325fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 326fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("vec2 uv_grad;"); 327c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) { 328fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this is to compensate for the Adreno, which likes to drop tiles on division by 0 329fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float uv_len2 = dot(uv, uv);"); 330fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("if (uv_len2 < 0.0001) {"); 331fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("uv_grad = vec2(0.7071, 0.7071);"); 332fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("} else {"); 333fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("uv_grad = uv*inversesqrt(uv_len2);"); 334fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("}"); 335fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } else { 336fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("uv_grad = normalize(uv);"); 337fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 338fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("vec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,"); 339fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend(" uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);"); 340fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 341fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth // this gives us a smooth step across approximately one fragment 342fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); 343fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 344fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); 345fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3462dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 347fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 348fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 349fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth virtual void setData(const GrGLProgramDataManager& pdman, 35087f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGeometryProcessor& proc, 35187f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) SK_OVERRIDE { 352fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkASSERT(fTextureSizeUni.isValid()); 353fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 35487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt GrTexture* texture = proc.texture(0); 355fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth if (texture->width() != fTextureSize.width() || 356fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth texture->height() != fTextureSize.height()) { 357fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fTextureSize = SkISize::Make(texture->width(), texture->height()); 358fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth pdman.set2f(fTextureSizeUni, 359fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkIntToScalar(fTextureSize.width()), 360fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkIntToScalar(fTextureSize.height())); 361fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 362fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 363fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 36487f48d997ec29e5eeaa7567355775e93465dd60djoshualitt static inline void GenKey(const GrGeometryProcessor& proc, 36587f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&, 36687f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 367fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrProcessorKeyBuilder* b) { 368fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = 36987f48d997ec29e5eeaa7567355775e93465dd60djoshualitt proc.cast<GrDistanceFieldNoGammaTextureEffect>(); 370fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 371fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth b->add32(dfTexEffect.getFlags()); 372fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth } 373fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 374fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthprivate: 375fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrGLProgramDataManager::UniformHandle fTextureSizeUni; 376fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkISize fTextureSize; 377fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 378fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth typedef GrGLGeometryProcessor INHERITED; 379fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth}; 380fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 381fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 382fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 3832e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualittGrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect( 3842e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 3852e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrTexture* texture, 3862e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt const GrTextureParams& params, 3872e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt uint32_t flags) 3882e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt : INHERITED(color) 3892e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 390fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth , fFlags(flags & kNonLCD_DistanceFieldEffectMask) 3912dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fInColor(NULL) { 392fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); 393eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrDistanceFieldNoGammaTextureEffect>(); 3942dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); 3952dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (flags & kColorAttr_DistanceFieldEffectFlag) { 3962dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInColor = &this->addVertexAttrib(GrAttribute("inColor", kVec4ub_GrVertexAttribType)); 3972dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt this->setHasVertexColor(); 3982dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt } 3992dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords", 4002dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 401fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth this->addTextureAccess(&fTextureAccess); 402fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 403fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 4040e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& other) const { 405fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth const GrDistanceFieldNoGammaTextureEffect& cte = 406fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth other.cast<GrDistanceFieldNoGammaTextureEffect>(); 407420d7e9a79358908850c74192b4949375563449absalomon return fFlags == cte.fFlags; 408fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 409fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 410605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrDistanceFieldNoGammaTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 411ccb2e384a036f29d989d3c1468f879324e81a678egdaniel inout->mulByUnknownAlpha(); 412fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 413fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 414eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt, 415eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt const GrGLCaps& caps, 416eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 417eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldNoGammaTextureEffect::GenKey(*this, bt, caps, b); 418eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 419eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 420eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLGeometryProcessor* 421eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrDistanceFieldNoGammaTextureEffect::createGLInstance(const GrBatchTracker& bt) const { 422eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GrGLDistanceFieldNoGammaTextureEffect, (*this, bt)); 423fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 424fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 425fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 426fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 427fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect); 428fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 429fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverthGrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* random, 430fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrContext*, 431fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth const GrDrawTargetCaps&, 432fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrTexture* textures[]) { 433fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx 434fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrProcessorUnitTest::kAlphaTextureIdx; 435fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth static const SkShader::TileMode kTileModes[] = { 436fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kClamp_TileMode, 437fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kRepeat_TileMode, 438fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::kMirror_TileMode, 439fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 440fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth SkShader::TileMode tileModes[] = { 441fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 442fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 443fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth }; 444fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode 445fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth : GrTextureParams::kNone_FilterMode); 446fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 4472e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), textures[texIdx], 4482e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt params, 449fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0); 450fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth} 451fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 452fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth/////////////////////////////////////////////////////////////////////////////// 453fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth 454249af15fb82833d2274850c589812b6e69df0033joshualittclass GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { 455609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgpublic: 456eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&, 45787f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) 458eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt : fTextureSize(SkISize::Make(-1,-1)) 4599564ce60a657acce89fb956deb8645b324eaad1ejvanverth , fTextColor(GrColor_ILLEGAL) {} 460609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 461c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt virtual void emitCode(const EmitArgs& args) SK_OVERRIDE { 462609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 463c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt args.fGP.cast<GrDistanceFieldLCDTextureEffect>(); 464609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4652dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 46674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag v(kVec2f_GrSLType); 46774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("TextureCoords", &v); 4682dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); 469609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4702dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt // setup coord outputs 4712dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), 4722dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 4732dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), 4742dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt dfTexEffect.inPosition()->fName); 475609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 4764973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt // setup position varying 4774973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), 4782dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->uViewM(), dfTexEffect.inPosition()->fName); 4794973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 480609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const char* textureSizeUniName = NULL; 481609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // width, height, 1/(3*width) 482c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 483422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kVec3f_GrSLType, kDefault_GrSLPrecision, 484422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "TextureSize", &textureSizeUniName); 485609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 486c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 48730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 48830ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 48930ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 49030ba436f04e61d4505fb854d5fc56079636e0788joshualitt 491609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // create LCD offset adjusted by inverse of transform 49274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); 49330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); 49478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); 49578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 49630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); 49730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName); 498609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 49930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); 50030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); 50130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName); 502609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 503609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 504609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // green is distance to uv center 50530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 texColor = "); 506c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType); 50730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 50830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec3 distance;\n"); 50930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.y = texColor.r;\n"); 510609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // red is distance to left offset 51130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n"); 51230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 513c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 51430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 51530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.x = texColor.r;\n"); 516609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // blue is distance to right offset 51730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); 51830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\ttexColor = "); 519c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType); 52030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 52130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance.z = texColor.r;\n"); 5222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 52330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tdistance = " 524ada68ef2dc986478288a8b8ad867fd3aca431162jvanverth "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));"); 5252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 526609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // we adjust for the effect of the transformation on the distance by using 527609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // the length of the gradient of the texture coordinates. We use st coordinates 528609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // to ensure we're mapping 1:1 from texel space to pixel space. 529609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 530609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // To be strictly correct, we should compute the anti-aliasing factor separately 531609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // for each color component. However, this is only important when using perspective 532609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // transformations, and even then using a single factor seems like a reasonable 533609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // trade-off between quality and speed. 53430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat afwidth;\n"); 53578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (isUniformScale) { 536609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 537fa38a30897ceda3e93355d69b8a6812c823f41f6jvanverth fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*dx);\n"); 538609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 53930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 uv_grad;\n"); 540c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) { 541609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this is to compensate for the Adreno, which likes to drop tiles on division by 0 54230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); 54330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); 54430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); 54530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t} else {\n"); 54630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); 54730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t}\n"); 548609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } else { 54930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); 550609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 55130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); 55230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); 553609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 554609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org // this gives us a smooth step across approximately one fragment 55530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); 556609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 557609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 55830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);\n"); 559609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 5602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // adjust based on gamma 5612d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const char* textColorUniName = NULL; 5622d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // width, height, 1/(3*width) 563c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, 564422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kVec3f_GrSLType, kDefault_GrSLPrecision, 565422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "TextColor", &textColorUniName); 5662d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 56730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); 56830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tvec4 gammaColor = "); 569c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType); 57030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 57130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); 57230ba436f04e61d4505fb854d5fc56079636e0788joshualitt 57330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); 57430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 575c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType); 57630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 57730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); 57830ba436f04e61d4505fb854d5fc56079636e0788joshualitt 57930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); 58030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tgammaColor = "); 581c369e7c9992a86151a3ea0516ce5308c211b196bjoshualitt fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType); 58230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(";\n"); 58330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); 58430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 5852dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); 586609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 587609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 5887510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen virtual void setData(const GrGLProgramDataManager& pdman, 58987f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGeometryProcessor& processor, 59087f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&) SK_OVERRIDE { 591609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkASSERT(fTextureSizeUni.isValid()); 5922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkASSERT(fTextColorUni.isValid()); 593609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 5942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const GrDistanceFieldLCDTextureEffect& dfTexEffect = 595b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldLCDTextureEffect>(); 596b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* texture = processor.texture(0); 597609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org if (texture->width() != fTextureSize.width() || 598609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org texture->height() != fTextureSize.height()) { 599609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org fTextureSize = SkISize::Make(texture->width(), texture->height()); 600609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org float delta = 1.0f/(3.0f*texture->width()); 60178f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { 602609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org delta = -delta; 603609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 6047510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextureSizeUni, 6057510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.width()), 6067510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkIntToScalar(fTextureSize.height()), 6077510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen delta); 608609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 6092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 6102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = dfTexEffect.getTextColor(); 6112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth if (textColor != fTextColor) { 6122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth static const float ONE_OVER_255 = 1.f / 255.f; 6137510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3f(fTextColorUni, 6147510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackR(textColor) * ONE_OVER_255, 6157510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackG(textColor) * ONE_OVER_255, 6167510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrColorUnpackB(textColor) * ONE_OVER_255); 6172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fTextColor = textColor; 6182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 619609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 620609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 62187f48d997ec29e5eeaa7567355775e93465dd60djoshualitt static inline void GenKey(const GrGeometryProcessor& processor, 62287f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrBatchTracker&, 62387f48d997ec29e5eeaa7567355775e93465dd60djoshualitt const GrGLCaps&, 624b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 625609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org const GrDistanceFieldLCDTextureEffect& dfTexEffect = 626b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt processor.cast<GrDistanceFieldLCDTextureEffect>(); 627609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 62878f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth b->add32(dfTexEffect.getFlags()); 629609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org } 630609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 631609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.orgprivate: 6327510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextureSizeUni; 6337510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkISize fTextureSize; 6347510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fTextColorUni; 6357510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkColor fTextColor; 636609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 637249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 638609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org}; 639609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 640609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 641609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 6422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthGrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( 6432e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 6442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* texture, const GrTextureParams& params, 6452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTexture* gamma, const GrTextureParams& gParams, 6462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkColor textColor, 64778f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags) 6482e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt : INHERITED(color) 6492e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt , fTextureAccess(texture, params) 6502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fGammaTextureAccess(gamma, gParams) 6512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth , fTextColor(textColor) 6522dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt , fFlags(flags & kLCD_DistanceFieldEffectMask){ 65378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag)); 654eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrDistanceFieldLCDTextureEffect>(); 6552dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); 6562dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fInTextureCoords = &this->addVertexAttrib(GrAttribute("inTextureCoords", 6572dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 658609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org this->addTextureAccess(&fTextureAccess); 6592d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->addTextureAccess(&fGammaTextureAccess); 660609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 661609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 6620e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other) const { 66349586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>(); 664420d7e9a79358908850c74192b4949375563449absalomon return (fTextColor == cte.fTextColor && 66578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth fFlags == cte.fFlags); 666609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 667609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 668605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 669ccb2e384a036f29d989d3c1468f879324e81a678egdaniel inout->mulByUnknownColor(); 670309e346744f57fadd66ba3c2f14875c86311682eegdaniel inout->setUsingLCDCoverage(); 671609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 672609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 673eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittvoid GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt, 674eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt const GrGLCaps& caps, 675eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 676eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLDistanceFieldLCDTextureEffect::GenKey(*this, bt, caps, b); 677eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 678eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 679eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLGeometryProcessor* 680eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrDistanceFieldLCDTextureEffect::createGLInstance(const GrBatchTracker& bt) const { 681eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GrGLDistanceFieldLCDTextureEffect, (*this, bt)); 682609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org} 683609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 684609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 685609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 686b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextureEffect); 687609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org 688b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* random, 689b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 690b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 691b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 692b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 693b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 694b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 695b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 696609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org static const SkShader::TileMode kTileModes[] = { 697609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kClamp_TileMode, 698609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kRepeat_TileMode, 699609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::kMirror_TileMode, 700609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 701609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org SkShader::TileMode tileModes[] = { 702609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 703609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], 704609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org }; 705609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 706609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org GrTextureParams::kNone_FilterMode); 7072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : 7082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrTextureParams::kNone_FilterMode); 7092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth GrColor textColor = GrColorPackRGBA(random->nextULessThan(256), 7102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 7112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256), 7122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth random->nextULessThan(256)); 71378f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth uint32_t flags = kUseLCD_DistanceFieldEffectFlag; 71478f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; 71578f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; 7162e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textures[texIdx], params, 7172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textures[texIdx2], params2, 7182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth textColor, 71978f0718f4dac8bdcc0df43a3280cf8a89d8cf87ajvanverth flags); 720d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com} 721