Index: src/gpu/gl/GrGLShaderBuilder.cpp |
=================================================================== |
--- src/gpu/gl/GrGLShaderBuilder.cpp (revision 8448) |
+++ src/gpu/gl/GrGLShaderBuilder.cpp (working copy) |
@@ -35,15 +35,26 @@ |
} |
/** |
- * Do we need to either map r,g,b->a or a->r. |
+ * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are |
+ * present in the texture's config. swizzleComponentMask indicates the channels present in the |
+ * shader swizzle. |
*/ |
inline bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, |
- const GrTextureAccess& access) { |
- if (GrPixelConfigIsAlphaOnly(access.getTexture()->config())) { |
- if (caps.textureRedSupport() && (kA_GrColorComponentFlag & access.swizzleMask())) { |
+ uint32_t configComponentMask, |
+ uint32_t swizzleComponentMask) { |
+ if (caps.textureSwizzleSupport()) { |
+ // Any remapping is handled using texture swizzling not shader modifications. |
+ return false; |
+ } |
+ // check if the texture is alpha-only |
+ if (kA_GrColorComponentFlag == configComponentMask) { |
+ if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) { |
+ // we must map the swizzle 'a's to 'r'. |
return true; |
} |
- if (kRGB_GrColorComponentFlags & access.swizzleMask()) { |
+ if (kRGB_GrColorComponentFlags & swizzleComponentMask) { |
+ // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that |
+ // alpha-only textures smear alpha across all four channels when read. |
return true; |
} |
} |
@@ -76,16 +87,13 @@ |
} |
+static const char kDstColorName[] = "_dstColor"; |
+ |
/////////////////////////////////////////////////////////////////////////////// |
-// Architectural assumption: always 2-d input coords. |
-// Likely to become non-constant and non-static, perhaps even |
-// varying by stage, if we use 1D textures for gradients! |
-//const int GrGLShaderBuilder::fCoordDims = 2; |
- |
GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, |
GrGLUniformManager& uniformManager, |
- bool explicitLocalCoords) |
+ const GrGLProgramDesc& desc) |
: fUniforms(kVarsPerBlock) |
, fVSAttrs(kVarsPerBlock) |
, fVSOutputs(kVarsPerBlock) |
@@ -93,16 +101,22 @@ |
, fGSOutputs(kVarsPerBlock) |
, fFSInputs(kVarsPerBlock) |
, fFSOutputs(kMaxFSOutputs) |
- , fUsesGS(false) |
, fCtxInfo(ctxInfo) |
, fUniformManager(uniformManager) |
, fCurrentStageIdx(kNonStageIdx) |
+#if GR_GL_EXPERIMENTAL_GS |
+ , fUsesGS(desc.fExperimentalGS) |
+#else |
+ , fUsesGS(false) |
+#endif |
, fSetupFragPosition(false) |
- , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) { |
+ , fRTHeightUniform(GrGLUniformManager::kInvalidUniformHandle) |
+ , fDstCopyTopLeftUniform (GrGLUniformManager::kInvalidUniformHandle) |
+ , fDstCopyScaleUniform (GrGLUniformManager::kInvalidUniformHandle) { |
fPositionVar = &fVSAttrs.push_back(); |
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); |
- if (explicitLocalCoords) { |
+ if (desc.fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { |
fLocalCoordsVar = &fVSAttrs.push_back(); |
fLocalCoordsVar->set(kVec2f_GrSLType, |
GrGLShaderVar::kAttribute_TypeModifier, |
@@ -110,8 +124,47 @@ |
} else { |
fLocalCoordsVar = fPositionVar; |
} |
+ if (kNoDstRead_DstReadKey != desc.fDstRead) { |
+ bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & desc.fDstRead); |
+ const char* dstCopyTopLeftName; |
+ const char* dstCopyCoordScaleName; |
+ uint32_t configMask; |
+ if (SkToBool(kUseAlphaConfig_DstReadKeyBit & desc.fDstRead)) { |
+ configMask = kA_GrColorComponentFlag; |
+ } else { |
+ configMask = kRGBA_GrColorComponentFlags; |
+ } |
+ fDstCopySampler.init(this, configMask, "rgba", 0); |
+ |
+ fDstCopyTopLeftUniform = this->addUniform(kFragment_ShaderType, |
+ kVec2f_GrSLType, |
+ "DstCopyUpperLeft", |
+ &dstCopyTopLeftName); |
+ fDstCopyScaleUniform = this->addUniform(kFragment_ShaderType, |
+ kVec2f_GrSLType, |
+ "DstCopyCoordScale", |
+ &dstCopyCoordScaleName); |
+ const char* fragPos = this->fragmentPosition(); |
+ this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
+ this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
+ fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); |
+ if (!topDown) { |
+ this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); |
+ } |
+ this->fsCodeAppendf("\tvec4 %s = ", kDstColorName); |
+ this->appendTextureLookup(kFragment_ShaderType, fDstCopySampler, "_dstTexCoord"); |
+ this->fsCodeAppend(";\n\n"); |
+ } |
} |
+const char* GrGLShaderBuilder::dstColor() const { |
+ if (fDstCopySampler.isInitialized()) { |
+ return kDstColorName; |
+ } else { |
+ return NULL; |
+ } |
+} |
+ |
void GrGLShaderBuilder::codeAppendf(ShaderType type, const char format[], va_list args) { |
SkString* string = NULL; |
switch (type) { |
@@ -184,14 +237,26 @@ |
GrBackendEffectFactory::EffectKey GrGLShaderBuilder::KeyForTextureAccess( |
const GrTextureAccess& access, |
const GrGLCaps& caps) { |
- GrBackendEffectFactory::EffectKey key = 0; |
+ uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config()); |
+ if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) { |
+ return 1; |
+ } else { |
+ return 0; |
+ } |
+} |
- // Assume that swizzle support implies that we never have to modify a shader to adjust |
- // for texture format/swizzle settings. |
- if (!caps.textureSwizzleSupport() && swizzle_requires_alpha_remapping(caps, access)) { |
- key = 1; |
+GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy, |
+ const GrGLCaps& caps) { |
+ uint32_t key = kYesDstRead_DstReadKeyBit; |
+ if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) { |
+ // The fact that the config is alpha-only must be considered when generating code. |
+ key |= kUseAlphaConfig_DstReadKeyBit; |
} |
- return key; |
+ if (kTopLeft_GrSurfaceOrigin == dstCopy->origin()) { |
+ key |= kTopLeftOrigin_DstReadKeyBit; |
+ } |
+ GrAssert(static_cast<DstReadKey>(key) == key); |
+ return static_cast<DstReadKey>(key); |
} |
const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) { |