16c09952db60814e0c97611ba715db21000705d09tomhudson@google.com/* 26c09952db60814e0c97611ba715db21000705d09tomhudson@google.com * Copyright 2012 Google Inc. 36c09952db60814e0c97611ba715db21000705d09tomhudson@google.com * 46c09952db60814e0c97611ba715db21000705d09tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 56c09952db60814e0c97611ba715db21000705d09tomhudson@google.com * found in the LICENSE file. 66c09952db60814e0c97611ba715db21000705d09tomhudson@google.com */ 76c09952db60814e0c97611ba715db21000705d09tomhudson@google.com 86c09952db60814e0c97611ba715db21000705d09tomhudson@google.com#include "gl/GrGLShaderBuilder.h" 90878c5fc961357735119655af4aa41bbd35953b0tomhudson@google.com#include "gl/GrGLProgram.h" 10e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com#include "gl/GrGLUniformHandle.h" 118bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com#include "GrDrawEffect.h" 12069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com#include "GrTexture.h" 136c09952db60814e0c97611ba715db21000705d09tomhudson@google.com 146c09952db60814e0c97611ba715db21000705d09tomhudson@google.com// number of each input/output type in a single allocation block 15549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.comstatic const int kVarsPerBlock = 8; 166c09952db60814e0c97611ba715db21000705d09tomhudson@google.com 176c09952db60814e0c97611ba715db21000705d09tomhudson@google.com// except FS outputs where we expect 2 at most. 18549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.comstatic const int kMaxFSOutputs = 2; 196c09952db60814e0c97611ba715db21000705d09tomhudson@google.com 20e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com// ES2 FS only guarantees mediump and lowp support 21e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.comstatic const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision; 22e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com 23e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.comtypedef GrGLUniformManager::UniformHandle UniformHandle; 24e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 25e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com 260ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.comnamespace { 27069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 28eee0885f22929c914788f97737061524d06284efbsalomon@google.cominline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) { 290ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com if (kVec2f_GrSLType == type) { 30eee0885f22929c914788f97737061524d06284efbsalomon@google.com return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; 310ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com } else { 320ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com GrAssert(kVec3f_GrSLType == type); 33eee0885f22929c914788f97737061524d06284efbsalomon@google.com return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj"; 340ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com } 35069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com} 36069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 37dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com/** 3803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are 3903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com * present in the texture's config. swizzleComponentMask indicates the channels present in the 4003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com * shader swizzle. 41dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com */ 42dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.cominline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, 4303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com uint32_t configComponentMask, 4403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com uint32_t swizzleComponentMask) { 4503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (caps.textureSwizzleSupport()) { 4603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // Any remapping is handled using texture swizzling not shader modifications. 4703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com return false; 4803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 4903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // check if the texture is alpha-only 5003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (kA_GrColorComponentFlag == configComponentMask) { 5103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) { 5203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // we must map the swizzle 'a's to 'r'. 53dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return true; 54dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } 5503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (kRGB_GrColorComponentFlags & swizzleComponentMask) { 5603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that 5703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // alpha-only textures smear alpha across all four channels when read. 58dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return true; 59dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } 60069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com } 61dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return false; 62dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com} 63069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 64dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.comvoid append_swizzle(SkString* outAppend, 65c3abb7baff528b64f175e08350a92a0d72ca24bebsalomon@google.com const GrGLShaderBuilder::TextureSampler& texSampler, 66dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com const GrGLCaps& caps) { 67c3abb7baff528b64f175e08350a92a0d72ca24bebsalomon@google.com const char* swizzle = texSampler.swizzle(); 68dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com char mangledSwizzle[5]; 69dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com 70dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle 71dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com // is available. 72c3abb7baff528b64f175e08350a92a0d72ca24bebsalomon@google.com if (!caps.textureSwizzleSupport() && 73c3abb7baff528b64f175e08350a92a0d72ca24bebsalomon@google.com (kA_GrColorComponentFlag == texSampler.configComponentMask())) { 74dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com char alphaChar = caps.textureRedSupport() ? 'r' : 'a'; 75dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com int i; 76dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com for (i = 0; '\0' != swizzle[i]; ++i) { 77dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com mangledSwizzle[i] = alphaChar; 78069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com } 79dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com mangledSwizzle[i] ='\0'; 80dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com swizzle = mangledSwizzle; 81069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com } 824170fb6754377fbcbee376b918170844d4de7c79bsalomon@google.com // For shader prettiness we omit the swizzle rather than appending ".rgba". 834170fb6754377fbcbee376b918170844d4de7c79bsalomon@google.com if (memcmp(swizzle, "rgba", 4)) { 844170fb6754377fbcbee376b918170844d4de7c79bsalomon@google.com outAppend->appendf(".%s", swizzle); 854170fb6754377fbcbee376b918170844d4de7c79bsalomon@google.com } 86069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com} 87069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 880ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com} 890ff0afd5262591b0cf2b381c0767df5770ddc076bsalomon@google.com 90a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.comstatic const char kDstCopyColorName[] = "_dstColor"; 91069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 9203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 93eb1f13640c7f2d770a145a9568cd1483aaba4e0etomhudson@google.com 9459034d1330e77fb7749eae61d15b6dd5900c038askia.committer@gmail.comGrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, 958bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com GrGLUniformManager& uniformManager, 9603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com const GrGLProgramDesc& desc) 97894952f198be3090780ef2071fec83aed274bf8absalomon@google.com : fUniforms(kVarsPerBlock) 98549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fVSAttrs(kVarsPerBlock) 99549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fVSOutputs(kVarsPerBlock) 100549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fGSInputs(kVarsPerBlock) 101549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fGSOutputs(kVarsPerBlock) 102549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fFSInputs(kVarsPerBlock) 103549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com , fFSOutputs(kMaxFSOutputs) 104860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com , fCtxInfo(ctxInfo) 105f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com , fUniformManager(uniformManager) 1064661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com , fFSFeaturesAddedMask(0) 10703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com#if GR_GL_EXPERIMENTAL_GS 10866307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) 10903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com#else 11003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com , fUsesGS(false) 11103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com#endif 11225c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com , fSetupFragPosition(false) 11303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) 11403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) 115034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) 11666307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { 11766307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com 11866307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); 1193d9e74fa463118b4b3adb34571fc555ad7841397skia.committer@gmail.com 1208780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com fPositionVar = &fVSAttrs.push_back(); 1218780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); 12266307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com if (-1 != header.fLocalCoordAttributeIndex) { 1238bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com fLocalCoordsVar = &fVSAttrs.push_back(); 1248bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com fLocalCoordsVar->set(kVec2f_GrSLType, 1258bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com GrGLShaderVar::kAttribute_TypeModifier, 1268bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com "aLocalCoords"); 1278bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com } else { 1288bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com fLocalCoordsVar = fPositionVar; 1298bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com } 130a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com // Emit code to read the dst copy textue if necessary. 13166307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com if (kNoDstRead_DstReadKey != header.fDstReadKey && 132a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { 13366307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey); 13403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com const char* dstCopyTopLeftName; 13503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com const char* dstCopyCoordScaleName; 13603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com uint32_t configMask; 13766307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { 13803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com configMask = kA_GrColorComponentFlag; 13903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } else { 14003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com configMask = kRGBA_GrColorComponentFlags; 14103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 14203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com fDstCopySampler.init(this, configMask, "rgba", 0); 14303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com 14403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com fDstCopyTopLeftUniform = this->addUniform(kFragment_ShaderType, 14503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com kVec2f_GrSLType, 14603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com "DstCopyUpperLeft", 14703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com &dstCopyTopLeftName); 14803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com fDstCopyScaleUniform = this->addUniform(kFragment_ShaderType, 14903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com kVec2f_GrSLType, 15003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com "DstCopyCoordScale", 15103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com &dstCopyCoordScaleName); 15203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com const char* fragPos = this->fragmentPosition(); 15303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com this->fsCodeAppend("\t// Read color from copy of the destination.\n"); 15403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", 15503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); 15603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (!topDown) { 15703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); 15803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 159a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); 16003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com this->appendTextureLookup(kFragment_ShaderType, fDstCopySampler, "_dstTexCoord"); 16103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com this->fsCodeAppend(";\n\n"); 16203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 16303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com} 16403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com 1654661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.combool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { 1664661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com switch (feature) { 1674661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com case kStandardDerivatives_GLSLFeature: 1684661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com if (!fCtxInfo.caps()->shaderDerivativeSupport()) { 1694661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return false; 1704661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 1714661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com if (kES2_GrGLBinding == fCtxInfo.binding()) { 1724661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, 1734661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com "GL_OES_standard_derivatives"); 1744661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 1754661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return true; 1764661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com default: 1774661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com GrCrash("Unexpected GLSLFeature requested."); 1784661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return false; 1794661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 1804661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com} 1814661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com 1824661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.combool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { 1834661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com switch (feature) { 1844661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com case kFragCoordConventions_GLSLPrivateFeature: 1854661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com if (!fCtxInfo.caps()->fragCoordConventionsSupport()) { 1864661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return false; 1874661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 1884661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) { 1894661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature, 1904661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com "GL_ARB_fragment_coord_conventions"); 1914661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 1924661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return true; 193a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com case kEXTShaderFramebufferFetch_GLSLPrivateFeature: 194a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com if (GrGLCaps::kEXT_FBFetchType != fCtxInfo.caps()->fbFetchType()) { 195a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return false; 196a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com } 197a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature, 198a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com "GL_EXT_shader_framebuffer_fetch"); 199a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return true; 200a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com case kNVShaderFramebufferFetch_GLSLPrivateFeature: 201a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com if (GrGLCaps::kNV_FBFetchType != fCtxInfo.caps()->fbFetchType()) { 202a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return false; 203a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com } 204a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature, 205a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com "GL_NV_shader_framebuffer_fetch"); 206a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return true; 2074661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com default: 2084661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com GrCrash("Unexpected GLSLPrivateFeature requested."); 2094661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com return false; 2104661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 2114661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com} 2124661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com 2134661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.comvoid GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) { 2144661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com if (!(featureBit & fFSFeaturesAddedMask)) { 2154661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com fFSExtensions.appendf("#extension %s: require\n", extensionName); 2164661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com fFSFeaturesAddedMask |= featureBit; 2174661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com } 2184661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com} 2194661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com 2206bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.comvoid GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) { 2216bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if ('\0' == prefix) { 2226bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com *out = name; 2236bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } else { 2246bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com out->printf("%c%s", prefix, name); 2256bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 2266bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if (fCodeStage.inStageCode()) { 2276bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if (out->endsWith('_')) { 2286bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // Names containing "__" are reserved. 2296bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com out->append("x"); 2306bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 2316bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com out->appendf("_Stage%d", fCodeStage.stageIndex()); 2326bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 2336bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com} 2346bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 235a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.comconst char* GrGLShaderBuilder::dstColor() { 236dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org if (fCodeStage.inStageCode()) { 237dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); 238dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org if (!effect->willReadDstColor()) { 239dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org GrDebugCrash("GrGLEffect asked for dst color but its generating GrEffect " 240dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org "did not request access."); 241dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org return ""; 242dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org } 243dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org } 244a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com static const char kFBFetchColorName[] = "gl_LastFragData[0]"; 245a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType(); 246a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com if (GrGLCaps::kEXT_FBFetchType == fetchType) { 247a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLSLPrivateFeature)); 248a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return kFBFetchColorName; 249a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com } else if (GrGLCaps::kNV_FBFetchType == fetchType) { 250a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature)); 251a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return kFBFetchColorName; 252a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com } else if (fDstCopySampler.isInitialized()) { 253a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return kDstCopyColorName; 25403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } else { 255dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org return ""; 25603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 2576c09952db60814e0c97611ba715db21000705d09tomhudson@google.com} 2586c09952db60814e0c97611ba715db21000705d09tomhudson@google.com 259093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.comvoid GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) { 2604927640233ebcd54d09e2517692ada57cb69ce55sugoi@google.com SkString* string = NULL; 261093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com switch (type) { 262093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kVertex_ShaderType: 263093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fVSCode; 264093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 265093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kGeometry_ShaderType: 266093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fGSCode; 267093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 268093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kFragment_ShaderType: 269093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fFSCode; 270093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 271093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com default: 272093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrCrash("Invalid shader type"); 273093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com } 274093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string->appendf(format, args); 275093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com} 276093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com 277093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.comvoid GrGLShaderBuilder::codeAppend(ShaderType type, const char* str) { 2784927640233ebcd54d09e2517692ada57cb69ce55sugoi@google.com SkString* string = NULL; 279093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com switch (type) { 280093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kVertex_ShaderType: 281093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fVSCode; 282093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 283093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kGeometry_ShaderType: 284093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fGSCode; 285093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 286093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com case kFragment_ShaderType: 287093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string = &fFSCode; 288093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com break; 289093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com default: 290093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrCrash("Invalid shader type"); 291093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com } 292093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com string->append(str); 293093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com} 294093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com 295a365de8bd1dd9367e5b0a12197f0f70327da2b65bsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookup(SkString* out, 296f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 297a365de8bd1dd9367e5b0a12197f0f70327da2b65bsalomon@google.com const char* coordName, 298a365de8bd1dd9367e5b0a12197f0f70327da2b65bsalomon@google.com GrSLType varyingType) const { 2998f0339887c862ab42e1c8ecc7c9085183fd2953cbsalomon@google.com GrAssert(NULL != coordName); 3005c1e47ac3c2a31bd4109eb8b3c205782fe57c8b4bsalomon@google.com 301dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com out->appendf("%s(%s, %s)", 302eee0885f22929c914788f97737061524d06284efbsalomon@google.com sample_function_name(varyingType, fCtxInfo.glslGeneration()), 303f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com this->getUniformCStr(sampler.fSamplerUniform), 304dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com coordName); 305c3abb7baff528b64f175e08350a92a0d72ca24bebsalomon@google.com append_swizzle(out, sampler, *fCtxInfo.caps()); 3060878c5fc961357735119655af4aa41bbd35953b0tomhudson@google.com} 3070878c5fc961357735119655af4aa41bbd35953b0tomhudson@google.com 308093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookup(ShaderType type, 309093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 310093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com const char* coordName, 311093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrSLType varyingType) { 312093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrAssert(kFragment_ShaderType == type); 313093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com this->appendTextureLookup(&fFSCode, sampler, coordName, varyingType); 314093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com} 315093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com 316f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.comvoid GrGLShaderBuilder::appendTextureLookupAndModulate( 317093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com ShaderType type, 318f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com const char* modulation, 319f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com const GrGLShaderBuilder::TextureSampler& sampler, 320f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com const char* coordName, 321093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrSLType varyingType) { 322093bc9ad71adeb7a2a6a2aa3d123e846f2f6f8f4bsalomon@google.com GrAssert(kFragment_ShaderType == type); 323a365de8bd1dd9367e5b0a12197f0f70327da2b65bsalomon@google.com SkString lookup; 324f8cea0d62e6f4bf641e300a98be14bb2da65afb5bsalomon@google.com this->appendTextureLookup(&lookup, sampler, coordName, varyingType); 3251c1f300d25dcc959580badd34dd9d7e8b125f573bsalomon@google.com GrGLSLModulatef<4>(&fFSCode, modulation, lookup.c_str()); 3260878c5fc961357735119655af4aa41bbd35953b0tomhudson@google.com} 3270878c5fc961357735119655af4aa41bbd35953b0tomhudson@google.com 3288780f037626b5196962a39ab76afd51f094a7765bsalomon@google.comGrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( 3298780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com const GrTextureAccess& access, 3308780f037626b5196962a39ab76afd51f094a7765bsalomon@google.com const GrGLCaps& caps) { 33103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config()); 33203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) { 33303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com return 1; 33403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } else { 33503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com return 0; 33603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 33703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com} 33878ab92aa5c32b094205df9565e492d56ddce13cbbsalomon@google.com 33903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.comGrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy, 34003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com const GrGLCaps& caps) { 34103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com uint32_t key = kYesDstRead_DstReadKeyBit; 342a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) { 343a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com return key; 344a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com } 345a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com GrAssert(NULL != dstCopy); 34603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) { 34703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com // The fact that the config is alpha-only must be considered when generating code. 34803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com key |= kUseAlphaConfig_DstReadKeyBit; 34903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com } 35003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { 35103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com key |= kTopLeftOrigin_DstReadKeyBit; 352069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com } 35303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com GrAssert(static_cast<DstReadKey>(key) == key); 35403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com return static_cast<DstReadKey>(key); 355069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com} 356069700aef2be72c711e7f665e2250c41a83bd6datwiz@google.com 357034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.comGrGLShaderBuilder::FragPosKey GrGLShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst, 358034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com const GrGLCaps&) { 359034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com if (kTopLeft_GrSurfaceOrigin == dst->origin()) { 360034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com return kTopLeftFragPosRead_FragPosKey; 361034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com } else { 362034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com return kBottomLeftFragPosRead_FragPosKey; 363034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com } 364034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com} 365034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com 366034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com 367dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.comconst GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) { 368dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { 369dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com if (caps.textureRedSupport()) { 370dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED }; 371dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return gRedSmear; 372dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } else { 373dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, 374dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com GR_GL_ALPHA, GR_GL_ALPHA }; 375dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return gAlphaSmear; 376dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } 377dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } else { 378dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA }; 379dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com return gStraight; 380dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com } 381dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com} 382dcfd55e0e0f70857010de259a44b406f746c8e3dbsalomon@google.com 383f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.comGrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t visibility, 384f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com GrSLType type, 385f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com const char* name, 386f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com int count, 387f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com const char** outName) { 388bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com GrAssert(name && strlen(name)); 389afcc161571327871da95761248abefeaafed40a4humper@google.com SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_ShaderType | kFragment_ShaderType); 390549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com GrAssert(0 == (~kVisibilityMask & visibility)); 391549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com GrAssert(0 != visibility); 392bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com 393e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com BuilderUniform& uni = fUniforms.push_back(); 394894952f198be3090780ef2071fec83aed274bf8absalomon@google.com UniformHandle h = index_to_handle(fUniforms.count() - 1); 395e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com GR_DEBUGCODE(UniformHandle h2 =) 396e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com fUniformManager.appendUniform(type, count); 397e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com // We expect the uniform manager to initially have no uniforms and that all uniforms are added 398e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com // by this function. Therefore, the handles should match. 399e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com GrAssert(h2 == h); 400894952f198be3090780ef2071fec83aed274bf8absalomon@google.com uni.fVariable.setType(type); 401894952f198be3090780ef2071fec83aed274bf8absalomon@google.com uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 4026bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(uni.fVariable.accessName(), 'u', name); 403894952f198be3090780ef2071fec83aed274bf8absalomon@google.com uni.fVariable.setArrayCount(count); 404894952f198be3090780ef2071fec83aed274bf8absalomon@google.com uni.fVisibility = visibility; 405bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com 406894952f198be3090780ef2071fec83aed274bf8absalomon@google.com // If it is visible in both the VS and FS, the precision must match. 407894952f198be3090780ef2071fec83aed274bf8absalomon@google.com // We declare a default FS precision, but not a default VS. So set the var 408894952f198be3090780ef2071fec83aed274bf8absalomon@google.com // to use the default FS precision. 409549f60f1762d1629db3aabb1811365fb9731cb29bsalomon@google.com if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) { 410e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com // the fragment and vertex precisions must match 411894952f198be3090780ef2071fec83aed274bf8absalomon@google.com uni.fVariable.setPrecision(kDefaultFragmentPrecision); 412bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com } 413bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com 414f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com if (NULL != outName) { 415f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com *outName = uni.fVariable.c_str(); 416f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com } 417f017294c5402bcd37084f94dcd514d254b937710bsalomon@google.com 418894952f198be3090780ef2071fec83aed274bf8absalomon@google.com return h; 419894952f198be3090780ef2071fec83aed274bf8absalomon@google.com} 420894952f198be3090780ef2071fec83aed274bf8absalomon@google.com 421894952f198be3090780ef2071fec83aed274bf8absalomon@google.comconst GrGLShaderVar& GrGLShaderBuilder::getUniformVariable(UniformHandle u) const { 422894952f198be3090780ef2071fec83aed274bf8absalomon@google.com return fUniforms[handle_to_index(u)].fVariable; 423bac5902a49b892ef9d7581ee02476637aec0ca2atomhudson@google.com} 4247814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com 425f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.orgbool GrGLShaderBuilder::addAttribute(GrSLType type, 426f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org const char* name) { 427f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org for (int i = 0; i < fVSAttrs.count(); ++i) { 428f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org const GrGLShaderVar& attr = fVSAttrs[i]; 429f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org // if attribute already added, don't add it again 430f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org if (attr.getName().equals(name)) { 431f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org GrAssert(attr.getType() == type); 432f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org return false; 433f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org } 434f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org } 435f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org fVSAttrs.push_back().set(type, 436f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org GrGLShaderVar::kAttribute_TypeModifier, 437f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org name); 438f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org return true; 439f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org} 440f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org 4417814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.comvoid GrGLShaderBuilder::addVarying(GrSLType type, 4427814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com const char* name, 4437814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com const char** vsOutName, 4447814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com const char** fsInName) { 4457814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fVSOutputs.push_back(); 4467814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fVSOutputs.back().setType(type); 447314f1bb53e527e028f9f8a7b676b8d949c8a2ebebsalomon@google.com fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); 4486bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(fVSOutputs.back().accessName(), 'v', name); 4496bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 4507814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com if (vsOutName) { 4517814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com *vsOutName = fVSOutputs.back().getName().c_str(); 4527814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com } 4537814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com // input to FS comes either from VS or GS 454bfdf20d85e455c31aae4aa7800c65b149bde2cd2bsalomon@google.com const SkString* fsName; 4557814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com if (fUsesGS) { 4567814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com // if we have a GS take each varying in as an array 4577814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com // and output as non-array. 4587814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fGSInputs.push_back(); 4597814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fGSInputs.back().setType(type); 460314f1bb53e527e028f9f8a7b676b8d949c8a2ebebsalomon@google.com fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); 4617814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fGSInputs.back().setUnsizedArray(); 4627814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com *fGSInputs.back().accessName() = fVSOutputs.back().getName(); 4637814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fGSOutputs.push_back(); 4647814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fGSOutputs.back().setType(type); 465314f1bb53e527e028f9f8a7b676b8d949c8a2ebebsalomon@google.com fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); 4666bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(fGSOutputs.back().accessName(), 'g', name); 4677814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fsName = fGSOutputs.back().accessName(); 4687814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com } else { 4697814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fsName = fVSOutputs.back().accessName(); 4707814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com } 4717814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fFSInputs.push_back(); 4727814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fFSInputs.back().setType(type); 473314f1bb53e527e028f9f8a7b676b8d949c8a2ebebsalomon@google.com fFSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); 4747814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com fFSInputs.back().setName(*fsName); 4757814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com if (fsInName) { 4767814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com *fsInName = fsName->c_str(); 4777814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com } 4787814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com} 4797814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com 48025c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.comconst char* GrGLShaderBuilder::fragmentPosition() { 481dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org if (fCodeStage.inStageCode()) { 482dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); 483dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org if (!effect->willReadFragmentPosition()) { 484dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org GrDebugCrash("GrGLEffect asked for frag position but its generating GrEffect " 485dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org "did not request access."); 486dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org return ""; 487dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org } 488dfac782d850885a9bf2a55a51d9e802ddc0a4583commit-bot@chromium.org } 489034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com if (fTopLeftFragPosRead) { 490034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com if (!fSetupFragPosition) { 491034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com fFSInputs.push_back().set(kVec4f_GrSLType, 492034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com GrGLShaderVar::kIn_TypeModifier, 493034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com "gl_FragCoord", 494034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com GrGLShaderVar::kDefault_Precision); 495034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com fSetupFragPosition = true; 496034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com } 497034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com return "gl_FragCoord"; 498034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com } else if (fCtxInfo.caps()->fragCoordConventionsSupport()) { 49925c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com if (!fSetupFragPosition) { 5004661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature)); 501e13b024af858aeb5a5c71c06e81a3e7ac8840108bsalomon@google.com fFSInputs.push_back().set(kVec4f_GrSLType, 502e13b024af858aeb5a5c71c06e81a3e7ac8840108bsalomon@google.com GrGLShaderVar::kIn_TypeModifier, 503e13b024af858aeb5a5c71c06e81a3e7ac8840108bsalomon@google.com "gl_FragCoord", 504e13b024af858aeb5a5c71c06e81a3e7ac8840108bsalomon@google.com GrGLShaderVar::kDefault_Precision, 505e13b024af858aeb5a5c71c06e81a3e7ac8840108bsalomon@google.com GrGLShaderVar::kUpperLeft_Origin); 50625c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com fSetupFragPosition = true; 50725c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com } 5082dd7052351e6c52bf0347f9adaa5b2e497914f9fskia.committer@gmail.com return "gl_FragCoord"; 50925c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com } else { 51025c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com static const char* kCoordName = "fragCoordYDown"; 51125c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com if (!fSetupFragPosition) { 5126bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // temporarily change the stage index because we're inserting non-stage code. 5136bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com CodeStage::AutoStageRestore csar(&fCodeStage, NULL); 5146bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 51525c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUniform); 51625c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com const char* rtHeightName; 5172dd7052351e6c52bf0347f9adaa5b2e497914f9fskia.committer@gmail.com 51825c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com fRTHeightUniform = this->addUniform(kFragment_ShaderType, 51925c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com kFloat_GrSLType, 52025c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com "RTHeight", 52125c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com &rtHeightName); 5222dd7052351e6c52bf0347f9adaa5b2e497914f9fskia.committer@gmail.com 52325c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n", 52425c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com kCoordName, rtHeightName); 52525c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com fSetupFragPosition = true; 52625c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com } 52725c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle != fRTHeightUniform); 52825c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com return kCoordName; 52925c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com } 53025c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com} 53125c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com 53225c5de00a3906b6f60b407a80033cf32efc13eb0bsalomon@google.com 533d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.comvoid GrGLShaderBuilder::emitFunction(ShaderType shader, 534d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com GrSLType returnType, 535d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com const char* name, 536d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com int argCnt, 537d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com const GrGLShaderVar* args, 538d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com const char* body, 539d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com SkString* outName) { 540d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com GrAssert(kFragment_ShaderType == shader); 5411c1f300d25dcc959580badd34dd9d7e8b125f573bsalomon@google.com fFSFunctions.append(GrGLSLTypeString(returnType)); 5426bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(outName, '\0', name); 543314f1bb53e527e028f9f8a7b676b8d949c8a2ebebsalomon@google.com fFSFunctions.appendf(" %s", outName->c_str()); 544d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com fFSFunctions.append("("); 545d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com for (int i = 0; i < argCnt; ++i) { 546860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com args[i].appendDecl(fCtxInfo, &fFSFunctions); 547d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com if (i < argCnt - 1) { 548d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com fFSFunctions.append(", "); 549d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com } 550d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com } 551d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com fFSFunctions.append(") {\n"); 552d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com fFSFunctions.append(body); 553d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com fFSFunctions.append("}\n\n"); 554d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com} 5557814ede05ce151be3880a694fbcedf376fc58e19tomhudson@google.com 55614fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.comnamespace { 557e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com 558e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.cominline void append_default_precision_qualifier(GrGLShaderVar::Precision p, 559e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com GrGLBinding binding, 560e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com SkString* str) { 561e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com // Desktop GLSL has added precision qualifiers but they don't do anything. 562e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com if (kES2_GrGLBinding == binding) { 563e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com switch (p) { 564e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com case GrGLShaderVar::kHigh_Precision: 565e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com str->append("precision highp float;\n"); 566e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com break; 567e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com case GrGLShaderVar::kMedium_Precision: 568e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com str->append("precision mediump float;\n"); 569e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com break; 570e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com case GrGLShaderVar::kLow_Precision: 571e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com str->append("precision lowp float;\n"); 572e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com break; 573e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com case GrGLShaderVar::kDefault_Precision: 574e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com GrCrash("Default precision now allowed."); 575e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com default: 576e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com GrCrash("Unknown precision value."); 577e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com } 578e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com } 579e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com} 580894952f198be3090780ef2071fec83aed274bf8absalomon@google.com} 581e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com 582894952f198be3090780ef2071fec83aed274bf8absalomon@google.comvoid GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { 58314fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com for (int i = 0; i < vars.count(); ++i) { 584860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com vars[i].appendDecl(fCtxInfo, out); 585d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com out->append(";\n"); 58614fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com } 58714fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com} 588894952f198be3090780ef2071fec83aed274bf8absalomon@google.com 589894952f198be3090780ef2071fec83aed274bf8absalomon@google.comvoid GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) const { 590894952f198be3090780ef2071fec83aed274bf8absalomon@google.com for (int i = 0; i < fUniforms.count(); ++i) { 591894952f198be3090780ef2071fec83aed274bf8absalomon@google.com if (fUniforms[i].fVisibility & stype) { 592860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com fUniforms[i].fVariable.appendDecl(fCtxInfo, out); 593d3f53a1deffc295332cb5cd8c45c15342586e5ddbsalomon@google.com out->append(";\n"); 594894952f198be3090780ef2071fec83aed274bf8absalomon@google.com } 595894952f198be3090780ef2071fec83aed274bf8absalomon@google.com } 59614fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com} 59714fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com 59814fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.comvoid GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { 5994661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com const char* version = GrGetGLSLVersionDecl(fCtxInfo.binding(), fCtxInfo.glslGeneration()); 6004661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com 60114fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com switch (type) { 60214fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com case kVertex_ShaderType: 6034661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com *shaderStr = version; 604894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendUniformDecls(kVertex_ShaderType, shaderStr); 605894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fVSAttrs, shaderStr); 606894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fVSOutputs, shaderStr); 6075a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("void main() {\n"); 60814fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->append(fVSCode); 6095a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("}\n"); 61014fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com break; 61114fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com case kGeometry_ShaderType: 61214fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com if (fUsesGS) { 6134661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com *shaderStr = version; 61414fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->append(fGSHeader); 615894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fGSInputs, shaderStr); 616894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fGSOutputs, shaderStr); 6175a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("void main() {\n"); 61814fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->append(fGSCode); 6195a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("}\n"); 62014fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com } else { 62114fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->reset(); 62214fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com } 62314fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com break; 62414fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com case kFragment_ShaderType: 6254661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com *shaderStr = version; 6264661488d92dc1b477653ea8dc726debf7a6a8386bsalomon@google.com shaderStr->append(fFSExtensions); 627e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com append_default_precision_qualifier(kDefaultFragmentPrecision, 628860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com fCtxInfo.binding(), 629e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com shaderStr); 630894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendUniformDecls(kFragment_ShaderType, shaderStr); 631894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fFSInputs, shaderStr); 63214fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com // We shouldn't have declared outputs on 1.10 633860f3b88452e3dd2cf47282f1a1527e8876d41e1robertphillips@google.com GrAssert(k110_GrGLSLGeneration != fCtxInfo.glslGeneration() || fFSOutputs.empty()); 634894952f198be3090780ef2071fec83aed274bf8absalomon@google.com this->appendDecls(fFSOutputs, shaderStr); 63514fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->append(fFSFunctions); 6365a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("void main() {\n"); 63714fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com shaderStr->append(fFSCode); 6385a9d7b4e69bf715461bfa1d533ef184dd3d92bf7bsalomon@google.com shaderStr->append("}\n"); 63914fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com break; 64014fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com } 64114fbe0445e3bf24f86e05a1f58d33b184813efd4bsalomon@google.com } 642e183e55b0fbe55b54f7fabe212c4af08d6e081eabsalomon@google.com 643e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.comvoid GrGLShaderBuilder::finished(GrGLuint programID) { 644e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com fUniformManager.getUniformLocations(programID, fUniforms); 645e00b4571a397999a5120758f947bc00e812dee82bsalomon@google.com} 64657d258a610dff47be00cdc1c075557ac38b74a10bsalomon@google.com 6476bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.comvoid GrGLShaderBuilder::emitEffects( 6486bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com const GrEffectStage* effectStages[], 6496bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com const GrBackendEffectFactory::EffectKey effectKeys[], 6506bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com int effectCnt, 6516bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkString* fsInOutColor, 6526bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com GrSLConstantVec* fsInOutColorKnownValue, 6536bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[], 6546bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com GrGLEffect* glEffects[]) { 6556bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com bool effectEmitted = false; 6566bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6576bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkString inColor = *fsInOutColor; 6586bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkString outColor; 6596bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6606bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com for (int e = 0; e < effectCnt; ++e) { 66166307f1cfee47ae4d2a1f7dff821bdf1c0e853a8bsalomon@google.com GrAssert(NULL != effectStages[e] && NULL != effectStages[e]->getEffect()); 6626bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com const GrEffectStage& stage = *effectStages[e]; 6636bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com const GrEffectRef& effect = *stage.getEffect(); 6646bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6656bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com CodeStage::AutoStageRestore csar(&fCodeStage, &stage); 6666bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6676bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com int numTextures = effect->numTextures(); 6686bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers; 6696bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com textureSamplers.push_back_n(numTextures); 6706bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com for (int t = 0; t < numTextures; ++t) { 6716bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com textureSamplers[t].init(this, &effect->textureAccess(t), t); 6726bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform); 6736bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 6746bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords()); 6756bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6766bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com int numAttributes = stage.getVertexAttribIndexCount(); 6776bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com const int* attributeIndices = stage.getVertexAttribIndices(); 6786bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; 6796bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com for (int a = 0; a < numAttributes; ++a) { 6806bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // TODO: Make addAttribute mangle the name. 6816bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkString attributeName("aAttr"); 6826bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com attributeName.appendS32(attributeIndices[a]); 6836bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_str())) { 6846bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com fEffectAttributes.push_back().set(attributeIndices[a], attributeName); 6856bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 6866bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 6876bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6886bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com glEffects[e] = effect->getFactory().createGLInstance(drawEffect); 6896bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 6906bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) { 6916bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // Effects have no way to communicate zeros, they treat an empty string as ones. 6926bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(&inColor, '\0', "input"); 6936bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4)); 694f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org } 695f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org 6966bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // create var to hold stage result 6976bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->nameVariable(&outColor, '\0', "output"); 6986bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str()); 69957d258a610dff47be00cdc1c075557ac38b74a10bsalomon@google.com 7006bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com // Enclose custom code in a block to avoid namespace conflicts 7016bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com SkString openBrace; 7026bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEffects[e]->name()); 7036bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fVSCode.append(openBrace); 7046bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fFSCode.append(openBrace); 7058bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com 7066bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com glEffects[e]->emitCode(this, 7076bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com drawEffect, 7086bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com effectKeys[e], 7096bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com outColor.c_str(), 7106bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com inColor.isEmpty() ? NULL : inColor.c_str(), 7116bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com textureSamplers); 7126bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fVSCode.append("\t}\n"); 7136bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com this->fFSCode.append("\t}\n"); 71457d258a610dff47be00cdc1c075557ac38b74a10bsalomon@google.com 7156bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com inColor = outColor; 7166bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com *fsInOutColorKnownValue = kNone_GrSLConstantVec; 7176bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com effectEmitted = true; 7186bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 7196bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com 7206bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com if (effectEmitted) { 7216bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com *fsInOutColor = outColor; 7226bff201a977bb0560f462d14c54602ad0e2f6797bsalomon@google.com } 72357d258a610dff47be00cdc1c075557ac38b74a10bsalomon@google.com} 724f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org 725f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.orgconst SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const { 726f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org const AttributePair* attribEnd = this->getEffectAttributes().end(); 727010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com for (const AttributePair* attrib = this->getEffectAttributes().begin(); 728f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org attrib != attribEnd; 729f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org ++attrib) { 730f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org if (attrib->fIndex == attributeIndex) { 731f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org return &attrib->fName; 732f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org } 733010f1a42e85d8c8587869e436d093d7ed40a4598skia.committer@gmail.com } 734f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org 735f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org return NULL; 736f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org} 737