GrGLShaderBuilder.cpp revision 91274b99722d9be62e077ab979c630c23cdd04b1
1f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/* 2f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Copyright 2012 Google Inc. 3f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * 4f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 5f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * found in the LICENSE file. 6f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com */ 7f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 8f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "gl/GrGLShaderBuilder.h" 95259814305e3290dea3b197301f7824a14c5fa6ftomhudson@google.com#include "gl/GrGLProgram.h" 10dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLUniformHandle.h" 11a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com#include "GrTexture.h" 12f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 13f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com// number of each input/output type in a single allocation block 14eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.comstatic const int kVarsPerBlock = 8; 15f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 16f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com// except FS outputs where we expect 2 at most. 17eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.comstatic const int kMaxFSOutputs = 2; 18f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 19d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com// ES2 FS only guarantees mediump and lowp support 20d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.comstatic const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision; 21d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com 22dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.comtypedef GrGLUniformManager::UniformHandle UniformHandle; 23dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com/////////////////////////////////////////////////////////////////////////////// 24dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 2534bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.comnamespace { 26a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 272b1b8c083b969a2a798b03d1754a3fc99ea054dfbsalomon@google.cominline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) { 2834bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com if (kVec2f_GrSLType == type) { 292b1b8c083b969a2a798b03d1754a3fc99ea054dfbsalomon@google.com return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; 3034bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com } else { 3134bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com GrAssert(kVec3f_GrSLType == type); 322b1b8c083b969a2a798b03d1754a3fc99ea054dfbsalomon@google.com return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj"; 3334bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com } 34a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com} 35a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 366d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com/** 376d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com * Do we need to either map r,g,b->a or a->r. 386d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com */ 396d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.cominline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, 406d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com const GrTextureAccess& access) { 416d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (GrPixelConfigIsAlphaOnly(access.getTexture()->config())) { 426d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (caps.textureRedSupport() && (GrTextureAccess::kA_SwizzleFlag & access.swizzleMask())) { 436d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return true; 446d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } 456d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (GrTextureAccess::kRGB_SwizzleMask & access.swizzleMask()) { 466d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return true; 476d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } 48a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com } 496d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return false; 506d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com} 51a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 526d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.comvoid append_swizzle(SkString* outAppend, 536d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com const GrTextureAccess& access, 546d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com const GrGLCaps& caps) { 556d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com const char* swizzle = access.getSwizzle(); 566d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com char mangledSwizzle[5]; 576d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com 586d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle 596d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com // is available. 606d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(access.getTexture()->config())) { 616d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com char alphaChar = caps.textureRedSupport() ? 'r' : 'a'; 626d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com int i; 636d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com for (i = 0; '\0' != swizzle[i]; ++i) { 646d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com mangledSwizzle[i] = alphaChar; 65a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com } 666d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com mangledSwizzle[i] ='\0'; 676d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com swizzle = mangledSwizzle; 68a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com } 6973d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com // For shader prettiness we omit the swizzle rather than appending ".rgba". 7073d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com if (memcmp(swizzle, "rgba", 4)) { 7173d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com outAppend->appendf(".%s", swizzle); 7273d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com } 73a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com} 74a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 7534bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com} 7634bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com 77a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com/////////////////////////////////////////////////////////////////////////////// 78a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 799c639a406eec42c8f5169bd78ad93e58f00ea9f6tomhudson@google.com// Architectural assumption: always 2-d input coords. 809c639a406eec42c8f5169bd78ad93e58f00ea9f6tomhudson@google.com// Likely to become non-constant and non-static, perhaps even 819c639a406eec42c8f5169bd78ad93e58f00ea9f6tomhudson@google.com// varying by stage, if we use 1D textures for gradients! 829c639a406eec42c8f5169bd78ad93e58f00ea9f6tomhudson@google.com//const int GrGLShaderBuilder::fCoordDims = 2; 839c639a406eec42c8f5169bd78ad93e58f00ea9f6tomhudson@google.com 84631cdcb4a6b926b6447f328b81911a4499fb3698skia.committer@gmail.comGrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, 856177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com GrGLUniformManager& uniformManager) 86032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com : fUniforms(kVarsPerBlock) 87eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fVSAttrs(kVarsPerBlock) 88eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fVSOutputs(kVarsPerBlock) 89eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fGSInputs(kVarsPerBlock) 90eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fGSOutputs(kVarsPerBlock) 91eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fFSInputs(kVarsPerBlock) 92eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com , fFSOutputs(kMaxFSOutputs) 93040c41a97c58b069015be3f5062eeb6ffe5adbfdtomhudson@google.com , fUsesGS(false) 946177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com , fCtxInfo(ctxInfo) 95777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com , fUniformManager(uniformManager) 9608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com , fCurrentStageIdx(kNonStageIdx) 97706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com , fSetupFragPosition(false) 98dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) { 99e862d16162fd46ad9b2832c8844b00c81bedbac0skia.committer@gmail.com 10017504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com fPositionVar = &fVSAttrs.push_back(); 10117504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); 102f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com} 103f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 104f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.comvoid GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) { 1059c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com SkString* string = NULL; 106f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com switch (type) { 107f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kVertex_ShaderType: 108f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fVSCode; 109f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 110f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kGeometry_ShaderType: 111f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fGSCode; 112f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 113f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kFragment_ShaderType: 114f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fFSCode; 115f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 116f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com default: 117f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrCrash("Invalid shader type"); 118f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 119f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string->appendf(format, args); 120f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com} 121f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 122f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.comvoid GrGLShaderBuilder::codeAppend(ShaderType type, const char* str) { 1239c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com SkString* string = NULL; 124f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com switch (type) { 125f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kVertex_ShaderType: 126f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fVSCode; 127f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 128f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kGeometry_ShaderType: 129f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fGSCode; 130f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 131f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com case kFragment_ShaderType: 132f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string = &fFSCode; 133f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com break; 134f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com default: 135f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrCrash("Invalid shader type"); 136f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 137f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com string->append(str); 138f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com} 139f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 140868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookup(SkString* out, 141f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 142868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com const char* coordName, 143868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com GrSLType varyingType) const { 1442d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com GrAssert(NULL != sampler.textureAccess()); 145dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com GrAssert(NULL != coordName); 1462d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com 1476d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com out->appendf("%s(%s, %s)", 1482b1b8c083b969a2a798b03d1754a3fc99ea054dfbsalomon@google.com sample_function_name(varyingType, fCtxInfo.glslGeneration()), 149f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com this->getUniformCStr(sampler.fSamplerUniform), 1506d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com coordName); 1516177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com append_swizzle(out, *sampler.textureAccess(), fCtxInfo.caps()); 1525259814305e3290dea3b197301f7824a14c5fa6ftomhudson@google.com} 1535259814305e3290dea3b197301f7824a14c5fa6ftomhudson@google.com 154f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookup(ShaderType type, 155f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 156f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com const char* coordName, 157f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrSLType varyingType) { 158f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrAssert(kFragment_ShaderType == type); 159f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); 160f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com} 161f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 162f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookupAndModulate( 163f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com ShaderType type, 164f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const char* modulation, 165f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 166f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const char* coordName, 167f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrSLType varyingType) { 168f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrAssert(kFragment_ShaderType == type); 169868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com SkString lookup; 170f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com this->appendTextureLookup(&lookup, sampler, coordName, varyingType); 171f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrGLSLModulate4f(&fFSCode, modulation, lookup.c_str()); 1725259814305e3290dea3b197301f7824a14c5fa6ftomhudson@google.com} 1735259814305e3290dea3b197301f7824a14c5fa6ftomhudson@google.com 1742eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.comGrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( 1752eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const GrTextureAccess& access, 1762eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const GrGLCaps& caps) { 1772eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com GrBackendEffectFactory::EffectKey key = 0; 178d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com 179a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com // Assume that swizzle support implies that we never have to modify a shader to adjust 180a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com // for texture format/swizzle settings. 1816d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (!caps.textureSwizzleSupport() && swizzle_requires_alpha_remapping(caps, access)) { 182a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com key = 1; 183a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com } 18473d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com#if GR_DEBUG 18573d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com // Assert that key is set iff the swizzle will be modified. 18673d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com SkString origString(access.getSwizzle()); 18773d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com origString.prepend("."); 18873d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com SkString modifiedString; 18973d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com append_swizzle(&modifiedString, access, caps); 19073d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com if (!modifiedString.size()) { 19173d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com modifiedString = ".rgba"; 19273d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com } 19373d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com GrAssert(SkToBool(key) == (modifiedString != origString)); 19473d5b2f620c02f0741c9ce13091f108855f066aebsalomon@google.com#endif 195a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com return key; 196a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com} 197a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 1986d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.comconst GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) { 1996d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { 2006d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com if (caps.textureRedSupport()) { 2016d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED }; 2026d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return gRedSmear; 2036d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } else { 2046d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, 2056d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com GR_GL_ALPHA, GR_GL_ALPHA }; 2066d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return gAlphaSmear; 2076d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } 2086d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } else { 2096d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA }; 2106d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com return gStraight; 2116d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com } 2126d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com} 2136d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com 214777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.comGrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility, 215777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com GrSLType type, 216777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com const char* name, 217777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com int count, 218777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com const char** outName) { 219242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com GrAssert(name && strlen(name)); 2200e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_ShaderType | kFragment_ShaderType); 221eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com GrAssert(0 == (~kVisibilityMask & visibility)); 222eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com GrAssert(0 != visibility); 223242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com 224dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com BuilderUniform& uni = fUniforms.push_back(); 225032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com UniformHandle h = index_to_handle(fUniforms.count() - 1); 226dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GR_DEBUGCODE(UniformHandle h2 =) 227dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com fUniformManager.appendUniform(type, count); 228dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com // We expect the uniform manager to initially have no uniforms and that all uniforms are added 229dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com // by this function. Therefore, the handles should match. 230dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GrAssert(h2 == h); 231032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com uni.fVariable.setType(type); 232032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 233777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com SkString* uniName = uni.fVariable.accessName(); 23408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (kNonStageIdx == fCurrentStageIdx) { 235777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com uniName->printf("u%s", name); 236777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com } else { 23708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com uniName->printf("u%s%d", name, fCurrentStageIdx); 238242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com } 239032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com uni.fVariable.setArrayCount(count); 240032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com uni.fVisibility = visibility; 241242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com 242032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com // If it is visible in both the VS and FS, the precision must match. 243032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com // We declare a default FS precision, but not a default VS. So set the var 244032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com // to use the default FS precision. 245eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { 246d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com // the fragment and vertex precisions must match 247032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com uni.fVariable.setPrecision(kDefaultFragmentPrecision); 248242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com } 249242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com 250777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com if (NULL != outName) { 251777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com *outName = uni.fVariable.c_str(); 252777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com } 253777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com 254032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com return h; 255032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com} 256032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 257032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comconst GrGLShaderVar& GrGLShaderBuilder::getUniformVariable(UniformHandle u) const { 258032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com return fUniforms[handle_to_index(u)].fVariable; 259242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com} 26023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com 261ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.orgbool GrGLShaderBuilder::addAttribute(GrSLType type, 262ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org const char* name) { 263ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org for (int i = 0; i < fVSAttrs.count(); ++i) { 264ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org const GrGLShaderVar& attr = fVSAttrs[i]; 265ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org // if attribute already added, don't add it again 266ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (attr.getName().equals(name)) { 267ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org GrAssert(attr.getType() == type); 268ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return false; 269ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 270ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 271ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org fVSAttrs.push_back().set(type, 272ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org GrGLShaderVar::kAttribute_TypeModifier, 273ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org name); 274ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return true; 275ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org} 276ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 27723cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.comvoid GrGLShaderBuilder::addVarying(GrSLType type, 27823cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char* name, 27923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char** vsOutName, 28023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char** fsInName) { 28123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fVSOutputs.push_back(); 28223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fVSOutputs.back().setType(type); 28323cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fVSOutputs.back().setTypeModifier(GrGLShaderVar::kOut_TypeModifier); 28408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (kNonStageIdx == fCurrentStageIdx) { 285777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com fVSOutputs.back().accessName()->printf("v%s", name); 286777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com } else { 28708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fVSOutputs.back().accessName()->printf("v%s%d", name, fCurrentStageIdx); 288777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com } 28923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com if (vsOutName) { 29023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com *vsOutName = fVSOutputs.back().getName().c_str(); 29123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com } 29223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com // input to FS comes either from VS or GS 293f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com const SkString* fsName; 29423cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com if (fUsesGS) { 29523cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com // if we have a GS take each varying in as an array 29623cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com // and output as non-array. 29723cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSInputs.push_back(); 29823cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSInputs.back().setType(type); 29923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSInputs.back().setTypeModifier(GrGLShaderVar::kIn_TypeModifier); 30023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSInputs.back().setUnsizedArray(); 30123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com *fGSInputs.back().accessName() = fVSOutputs.back().getName(); 30223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSOutputs.push_back(); 30323cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSOutputs.back().setType(type); 30423cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fGSOutputs.back().setTypeModifier(GrGLShaderVar::kOut_TypeModifier); 30508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (kNonStageIdx == fCurrentStageIdx) { 306d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com fGSOutputs.back().accessName()->printf("g%s", name); 307d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com } else { 30808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fGSOutputs.back().accessName()->printf("g%s%d", name, fCurrentStageIdx); 309d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com } 31023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fsName = fGSOutputs.back().accessName(); 31123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com } else { 31223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fsName = fVSOutputs.back().accessName(); 31323cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com } 31423cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fFSInputs.push_back(); 31523cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fFSInputs.back().setType(type); 31623cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fFSInputs.back().setTypeModifier(GrGLShaderVar::kIn_TypeModifier); 31723cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com fFSInputs.back().setName(*fsName); 31823cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com if (fsInName) { 31923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com *fsInName = fsName->c_str(); 32023cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com } 32123cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com} 32223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com 323706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.comconst char* GrGLShaderBuilder::fragmentPosition() { 3243cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org#if 1 3256177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com if (fCtxInfo.caps().fragCoordConventionsSupport()) { 326706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com if (!fSetupFragPosition) { 3276918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) { 3286918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com fFSHeader.append("#extension GL_ARB_fragment_coord_conventions: require\n"); 3296918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 3305fa2107842e017ee5932955ecf89ceca179e4630bsalomon@google.com fFSInputs.push_back().set(kVec4f_GrSLType, 3315fa2107842e017ee5932955ecf89ceca179e4630bsalomon@google.com GrGLShaderVar::kIn_TypeModifier, 3325fa2107842e017ee5932955ecf89ceca179e4630bsalomon@google.com "gl_FragCoord", 3335fa2107842e017ee5932955ecf89ceca179e4630bsalomon@google.com GrGLShaderVar::kDefault_Precision, 3345fa2107842e017ee5932955ecf89ceca179e4630bsalomon@google.com GrGLShaderVar::kUpperLeft_Origin); 335706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com fSetupFragPosition = true; 336706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com } 3371e34ff7030c95a96c3cd5940de9b4dda4e1cef86skia.committer@gmail.com return "gl_FragCoord"; 338706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com } else { 339706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com static const char* kCoordName = "fragCoordYDown"; 340706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com if (!fSetupFragPosition) { 341706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUniform); 342706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com const char* rtHeightName; 3431e34ff7030c95a96c3cd5940de9b4dda4e1cef86skia.committer@gmail.com 344706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com // temporarily change the stage index because we're inserting a uniform whose name 345706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com // shouldn't be mangled to be stage-specific. 34608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com int oldStageIdx = fCurrentStageIdx; 34708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fCurrentStageIdx = kNonStageIdx; 348706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com fRTHeightUniform = this->addUniform(kFragment_ShaderType, 349706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com kFloat_GrSLType, 350706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com "RTHeight", 351706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com &rtHeightName); 35208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com fCurrentStageIdx = oldStageIdx; 3531e34ff7030c95a96c3cd5940de9b4dda4e1cef86skia.committer@gmail.com 354706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n", 355706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com kCoordName, rtHeightName); 356706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com fSetupFragPosition = true; 357706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com } 358706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform); 359706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com return kCoordName; 360706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com } 3613cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org#else 3623cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // This is the path we'll need to use once we have support for TopLeft 3633cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org // render targets. 3643cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org if (!fSetupFragPosition) { 3653cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org fFSInputs.push_back().set(kVec4f_GrSLType, 3663cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org GrGLShaderVar::kIn_TypeModifier, 3673cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org "gl_FragCoord", 3683cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org GrGLShaderVar::kDefault_Precision); 3693cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org fSetupFragPosition = true; 3703cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org } 3713cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org return "gl_FragCoord"; 3723cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org#endif 373706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com} 374706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com 375706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com 376a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.comvoid GrGLShaderBuilder::emitFunction(ShaderType shader, 377a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com GrSLType returnType, 378a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const char* name, 379a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com int argCnt, 380a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const GrGLShaderVar* args, 381a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const char* body, 382a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString* outName) { 383a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com GrAssert(kFragment_ShaderType == shader); 384a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append(GrGLShaderVar::TypeString(returnType)); 38508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com if (kNonStageIdx != fCurrentStageIdx) { 38608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com outName->printf(" %s_%d", name, fCurrentStageIdx); 387a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com } else { 388a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com *outName = name; 389a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com } 390a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append(*outName); 391a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append("("); 392a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com for (int i = 0; i < argCnt; ++i) { 3936177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com args[i].appendDecl(fCtxInfo, &fFSFunctions); 394a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com if (i < argCnt - 1) { 395a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append(", "); 396a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com } 397a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com } 398a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append(") {\n"); 399a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append(body); 400a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com fFSFunctions.append("}\n\n"); 401a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com} 40223cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com 403ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comnamespace { 404d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com 405d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.cominline void append_default_precision_qualifier(GrGLShaderVar::Precision p, 406d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com GrGLBinding binding, 407d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com SkString* str) { 408d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com // Desktop GLSL has added precision qualifiers but they don't do anything. 409d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com if (kES2_GrGLBinding == binding) { 410d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com switch (p) { 411d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com case GrGLShaderVar::kHigh_Precision: 412d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com str->append("precision highp float;\n"); 413d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com break; 414d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com case GrGLShaderVar::kMedium_Precision: 415d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com str->append("precision mediump float;\n"); 416d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com break; 417d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com case GrGLShaderVar::kLow_Precision: 418d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com str->append("precision lowp float;\n"); 419d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com break; 420d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com case GrGLShaderVar::kDefault_Precision: 421d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com GrCrash("Default precision now allowed."); 422d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com default: 423d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com GrCrash("Unknown precision value."); 424d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com } 425d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com } 426d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com} 427032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com} 428d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com 429032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comvoid GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { 430ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com for (int i = 0; i < vars.count(); ++i) { 4316177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com vars[i].appendDecl(fCtxInfo, out); 432a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com out->append(";\n"); 433ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com } 434ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com} 435032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 436032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comvoid GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) const { 437032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com for (int i = 0; i < fUniforms.count(); ++i) { 438032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com if (fUniforms[i].fVisibility & stype) { 4396177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com fUniforms[i].fVariable.appendDecl(fCtxInfo, out); 440a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com out->append(";\n"); 441032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com } 442032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com } 443ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com} 444ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com 445ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comvoid GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { 446ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com switch (type) { 447ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com case kVertex_ShaderType: 448ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com *shaderStr = fHeader; 449032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendUniformDecls(kVertex_ShaderType, shaderStr); 450032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fVSAttrs, shaderStr); 451032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fVSOutputs, shaderStr); 452d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("void main() {\n"); 453ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->append(fVSCode); 454d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("}\n"); 455ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com break; 456ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com case kGeometry_ShaderType: 457ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com if (fUsesGS) { 458ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com *shaderStr = fHeader; 459ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->append(fGSHeader); 460032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fGSInputs, shaderStr); 461032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fGSOutputs, shaderStr); 462d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("void main() {\n"); 463ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->append(fGSCode); 464d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("}\n"); 465ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com } else { 466ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->reset(); 467ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com } 468ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com break; 469ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com case kFragment_ShaderType: 470ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com *shaderStr = fHeader; 471d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com append_default_precision_qualifier(kDefaultFragmentPrecision, 4726177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com fCtxInfo.binding(), 473d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com shaderStr); 474706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com shaderStr->append(fFSHeader); 475032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendUniformDecls(kFragment_ShaderType, shaderStr); 476032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fFSInputs, shaderStr); 477ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com // We shouldn't have declared outputs on 1.10 4786177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com GrAssert(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.empty()); 479032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com this->appendDecls(fFSOutputs, shaderStr); 480ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->append(fFSFunctions); 481d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("void main() {\n"); 482ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com shaderStr->append(fFSCode); 483d7bafb700c62dff466a88bee81d793e51737284bbsalomon@google.com shaderStr->append("}\n"); 484ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com break; 485ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com } 486ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.com } 487d7727ceb82e271f8b5580c51571c57b09c5e3cedbsalomon@google.com 488dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.comvoid GrGLShaderBuilder::finished(GrGLuint programID) { 489dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com fUniformManager.getUniformLocations(programID, fUniforms); 490dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com} 49134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 49234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.comGrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect( 49334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const GrEffectStage& stage, 49434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com GrGLEffect::EffectKey key, 49534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const char* fsInColor, 49634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const char* fsOutColor, 49734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const char* vsInCoord, 49834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) { 49934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com GrAssert(NULL != stage.getEffect()); 50034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 5016340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com const GrEffectRef& effect = *stage.getEffect(); 5026340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com int numTextures = effect->numTextures(); 50334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; 50434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com textureSamplers.push_back_n(numTextures); 50534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com for (int i = 0; i < numTextures; ++i) { 5066340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com textureSamplers[i].init(this, &effect->textureAccess(i), i); 50734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com samplerHandles->push_back(textureSamplers[i].fSamplerUniform); 50834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com } 50934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 510ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org int numAttributes = stage.getVertexAttribIndexCount(); 511ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org const int* attributeIndices = stage.getVertexAttribIndices(); 512ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; 513ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org for (int i = 0; i < numAttributes; ++i) { 514ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org SkString attributeName("aAttr"); 515ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org attributeName.appendS32(attributeIndices[i]); 516ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 517ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (this->addAttribute(effect->vertexAttribType(i), attributeName.c_str())) { 518ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org fEffectAttributes.push_back().set(attributeIndices[i], attributeName); 519ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 520ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 521ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 5226340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect); 52334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 52434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // Enclose custom code in a block to avoid namespace conflicts 52534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->fVSCode.appendf("\t{ // %s\n", glEffect->name()); 52634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->fFSCode.appendf("\t{ // %s \n", glEffect->name()); 52734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com glEffect->emitCode(this, 52834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com stage, 52934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com key, 53034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com vsInCoord, 53134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com fsOutColor, 53234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com fsInColor, 53334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com textureSamplers); 53434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->fVSCode.appendf("\t}\n"); 53534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com this->fFSCode.appendf("\t}\n"); 53634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 53734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com return glEffect; 53834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com} 539ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 540ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.orgconst SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const { 541ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org const AttributePair* attribEnd = this->getEffectAttributes().end(); 54291274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com for (const AttributePair* attrib = this->getEffectAttributes().begin(); 543ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org attrib != attribEnd; 544ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org ++attrib) { 545ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org if (attrib->fIndex == attributeIndex) { 546ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return &attrib->fName; 547ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 54891274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com } 549ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 550ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return NULL; 551ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org} 552