OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gl/GrGLShaderBuilder.h" | 8 #include "gl/GrGLShaderBuilder.h" |
9 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
10 #include "gl/GrGLUniformHandle.h" | 10 #include "gl/GrGLUniformHandle.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ | 28 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ |
29 if (kVec2f_GrSLType == type) { | 29 if (kVec2f_GrSLType == type) { |
30 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; | 30 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; |
31 } else { | 31 } else { |
32 GrAssert(kVec3f_GrSLType == type); | 32 GrAssert(kVec3f_GrSLType == type); |
33 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; | 33 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 /** | 37 /** |
38 * Do we need to either map r,g,b->a or a->r. | 38 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates whic
h channels are |
| 39 * present in the texture's config. swizzleComponentMask indicates the channels
present in the |
| 40 * shader swizzle. |
39 */ | 41 */ |
40 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, | 42 inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, |
41 const GrTextureAccess& access) { | 43 uint32_t configComponentMask, |
42 if (GrPixelConfigIsAlphaOnly(access.getTexture()->config())) { | 44 uint32_t swizzleComponentMask) { |
43 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & access.swizzl
eMask())) { | 45 if (caps.textureSwizzleSupport()) { |
| 46 // Any remapping is handled using texture swizzling not shader modificat
ions. |
| 47 return false; |
| 48 } |
| 49 // check if the texture is alpha-only |
| 50 if (kA_GrColorComponentFlag == configComponentMask) { |
| 51 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleCompon
entMask)) { |
| 52 // we must map the swizzle 'a's to 'r'. |
44 return true; | 53 return true; |
45 } | 54 } |
46 if (kRGB_GrColorComponentFlags & access.swizzleMask()) { | 55 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { |
| 56 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our
semantics that |
| 57 // alpha-only textures smear alpha across all four channels when rea
d. |
47 return true; | 58 return true; |
48 } | 59 } |
49 } | 60 } |
50 return false; | 61 return false; |
51 } | 62 } |
52 | 63 |
53 void append_swizzle(SkString* outAppend, | 64 void append_swizzle(SkString* outAppend, |
54 const GrGLShaderBuilder::TextureSampler& texSampler, | 65 const GrGLShaderBuilder::TextureSampler& texSampler, |
55 const GrGLCaps& caps) { | 66 const GrGLCaps& caps) { |
56 const char* swizzle = texSampler.swizzle(); | 67 const char* swizzle = texSampler.swizzle(); |
(...skipping 12 matching lines...) Expand all Loading... |
69 swizzle = mangledSwizzle; | 80 swizzle = mangledSwizzle; |
70 } | 81 } |
71 // For shader prettiness we omit the swizzle rather than appending ".rgba". | 82 // For shader prettiness we omit the swizzle rather than appending ".rgba". |
72 if (memcmp(swizzle, "rgba", 4)) { | 83 if (memcmp(swizzle, "rgba", 4)) { |
73 outAppend->appendf(".%s", swizzle); | 84 outAppend->appendf(".%s", swizzle); |
74 } | 85 } |
75 } | 86 } |
76 | 87 |
77 } | 88 } |
78 | 89 |
| 90 static const char kDstColorName[] = "_dstColor"; |
| 91 |
79 /////////////////////////////////////////////////////////////////////////////// | 92 /////////////////////////////////////////////////////////////////////////////// |
80 | 93 |
81 // Architectural assumption: always 2-d input coords. | |
82 // Likely to become non-constant and non-static, perhaps even | |
83 // varying by stage, if we use 1D textures for gradients! | |
84 //const int GrGLShaderBuilder::fCoordDims = 2; | |
85 | |
86 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, | 94 GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, |
87 GrGLUniformManager& uniformManager, | 95 GrGLUniformManager& uniformManager, |
88 bool explicitLocalCoords) | 96 const GrGLProgramDesc& desc) |
89 : fUniforms(kVarsPerBlock) | 97 : fUniforms(kVarsPerBlock) |
90 , fVSAttrs(kVarsPerBlock) | 98 , fVSAttrs(kVarsPerBlock) |
91 , fVSOutputs(kVarsPerBlock) | 99 , fVSOutputs(kVarsPerBlock) |
92 , fGSInputs(kVarsPerBlock) | 100 , fGSInputs(kVarsPerBlock) |
93 , fGSOutputs(kVarsPerBlock) | 101 , fGSOutputs(kVarsPerBlock) |
94 , fFSInputs(kVarsPerBlock) | 102 , fFSInputs(kVarsPerBlock) |
95 , fFSOutputs(kMaxFSOutputs) | 103 , fFSOutputs(kMaxFSOutputs) |
96 , fUsesGS(false) | |
97 , fCtxInfo(ctxInfo) | 104 , fCtxInfo(ctxInfo) |
98 , fUniformManager(uniformManager) | 105 , fUniformManager(uniformManager) |
99 , fCurrentStageIdx(kNonStageIdx) | 106 , fCurrentStageIdx(kNonStageIdx) |
| 107 #if GR_GL_EXPERIMENTAL_GS |
| 108 , fUsesGS(desc.fExperimentalGS) |
| 109 #else |
| 110 , fUsesGS(false) |
| 111 #endif |
100 , fSetupFragPosition(false) | 112 , fSetupFragPosition(false) |
101 , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) { | 113 , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) |
| 114 , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) |
| 115 , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) { |
102 | 116 |
103 fPositionVar = &fVSAttrs.push_back(); | 117 fPositionVar = &fVSAttrs.push_back(); |
104 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); | 118 fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "
aPosition"); |
105 if (explicitLocalCoords) { | 119 if (desc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { |
106 fLocalCoordsVar = &fVSAttrs.push_back(); | 120 fLocalCoordsVar = &fVSAttrs.push_back(); |
107 fLocalCoordsVar->set(kVec2f_GrSLType, | 121 fLocalCoordsVar->set(kVec2f_GrSLType, |
108 GrGLShaderVar::kAttribute_TypeModifier, | 122 GrGLShaderVar::kAttribute_TypeModifier, |
109 "aLocalCoords"); | 123 "aLocalCoords"); |
110 } else { | 124 } else { |
111 fLocalCoordsVar = fPositionVar; | 125 fLocalCoordsVar = fPositionVar; |
112 } | 126 } |
| 127 if (kNoDstRead_DstReadKey != desc.fDstRead) { |
| 128 bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & desc.fDstRead); |
| 129 const char* dstCopyTopLeftName; |
| 130 const char* dstCopyCoordScaleName; |
| 131 uint32_t configMask; |
| 132 if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstRead)) { |
| 133 configMask = kA_GrColorComponentFlag; |
| 134 } else { |
| 135 configMask = kRGBA_GrColorComponentFlags; |
| 136 } |
| 137 fDstCopySampler.init(this, configMask, "rgba", 0); |
| 138 |
| 139 fDstCopyTopLeftUniform = this->addUniform(kFragment_ShaderType, |
| 140 kVec2f_GrSLType, |
| 141 "DstCopyUpperLeft", |
| 142 &dstCopyTopLeftName); |
| 143 fDstCopyScaleUniform = this->addUniform(kFragment_ShaderType, |
| 144 kVec2f_GrSLType, |
| 145 "DstCopyCoordScale", |
| 146 &dstCopyCoordScaleName); |
| 147 const char* fragPos = this->fragmentPosition(); |
| 148 this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
| 149 this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
| 150 fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); |
| 151 if (!topDown) { |
| 152 this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); |
| 153 } |
| 154 this->fsCodeAppendf("\tvec4 %s = ", kDstColorName); |
| 155 this->appendTextureLookup(kFragment_ShaderType, fDstCopySampler, "_dstTe
xCoord"); |
| 156 this->fsCodeAppend(";\n\n"); |
| 157 } |
| 158 } |
| 159 |
| 160 const char* GrGLShaderBuilder::dstColor() const { |
| 161 if (fDstCopySampler.isInitialized()) { |
| 162 return kDstColorName; |
| 163 } else { |
| 164 return NULL; |
| 165 } |
113 } | 166 } |
114 | 167 |
115 void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_lis
t args) { | 168 void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_lis
t args) { |
116 SkString* string = NULL; | 169 SkString* string = NULL; |
117 switch (type) { | 170 switch (type) { |
118 case kVertex_ShaderType: | 171 case kVertex_ShaderType: |
119 string = &fVSCode; | 172 string = &fVSCode; |
120 break; | 173 break; |
121 case kGeometry_ShaderType: | 174 case kGeometry_ShaderType: |
122 string = &fGSCode; | 175 string = &fGSCode; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 GrSLType varyingType) { | 230 GrSLType varyingType) { |
178 GrAssert(kFragment_ShaderType == type); | 231 GrAssert(kFragment_ShaderType == type); |
179 SkString lookup; | 232 SkString lookup; |
180 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 233 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
181 GrGLSLModulate4f(&fFSCode, modulation, lookup.c_str()); | 234 GrGLSLModulate4f(&fFSCode, modulation, lookup.c_str()); |
182 } | 235 } |
183 | 236 |
184 GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( | 237 GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( |
185 const GrTextureAcces
s& access, | 238 const GrTextureAcces
s& access, |
186 const GrGLCaps& caps
) { | 239 const GrGLCaps& caps
) { |
187 GrBackendEffectFactory::EffectKey key = 0; | 240 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture(
)->config()); |
| 241 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizz
leMask())) { |
| 242 return 1; |
| 243 } else { |
| 244 return 0; |
| 245 } |
| 246 } |
188 | 247 |
189 // Assume that swizzle support implies that we never have to modify a shader
to adjust | 248 GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture*
dstCopy, |
190 // for texture format/swizzle settings. | 249 const GrGLCaps& c
aps) { |
191 if (!caps.textureSwizzleSupport() && swizzle_requires_alpha_remapping(caps,
access)) { | 250 uint32_t key = kYesDstRead_DstReadKeyBit; |
192 key = 1; | 251 if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->confi
g())) { |
| 252 // The fact that the config is alpha-only must be considered when genera
ting code. |
| 253 key |= kUseAlphaConfig_DstReadKeyBit; |
193 } | 254 } |
194 return key; | 255 if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { |
| 256 key |= kTopLeftOrigin_DstReadKeyBit; |
| 257 } |
| 258 GrAssert(static_cast<DstReadKey>(key) == key); |
| 259 return static_cast<DstReadKey>(key); |
195 } | 260 } |
196 | 261 |
197 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, cons
t GrGLCaps& caps) { | 262 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, cons
t GrGLCaps& caps) { |
198 if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { | 263 if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { |
199 if (caps.textureRedSupport()) { | 264 if (caps.textureRedSupport()) { |
200 static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RE
D, GR_GL_RED }; | 265 static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RE
D, GR_GL_RED }; |
201 return gRedSmear; | 266 return gRedSmear; |
202 } else { | 267 } else { |
203 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, | 268 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, |
204 GR_GL_ALPHA, GR_GL_ALPHA }; | 269 GR_GL_ALPHA, GR_GL_ALPHA }; |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 for (const AttributePair* attrib = this->getEffectAttributes().begin(); | 606 for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
542 attrib != attribEnd; | 607 attrib != attribEnd; |
543 ++attrib) { | 608 ++attrib) { |
544 if (attrib->fIndex == attributeIndex) { | 609 if (attrib->fIndex == attributeIndex) { |
545 return &attrib->fName; | 610 return &attrib->fName; |
546 } | 611 } |
547 } | 612 } |
548 | 613 |
549 return NULL; | 614 return NULL; |
550 } | 615 } |
OLD | NEW |