diff options
author | 2013-03-12 12:26:08 +0000 | |
---|---|---|
committer | 2013-03-12 12:26:08 +0000 | |
commit | ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3 (patch) | |
tree | 54941da56d3d90540bb21bfab8ca11f0504951e9 /src/gpu/gl | |
parent | 2e71f1619d9a2c51c1292e618f42a56ad2da1de8 (diff) |
Add GrEllipseEdgeEffect.
Adds the effect that replaces the old oval rendering code. Also hooks in code to set attribute names and indices for effects.
Author: jvanverth@google.com
Review URL: https://chromiumcodereview.appspot.com/12462008
git-svn-id: http://skia.googlecode.com/svn/trunk@8092 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLEffect.cpp | 15 | ||||
-rw-r--r-- | src/gpu/gl/GrGLEffect.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 35 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.h | 17 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 41 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 21 |
6 files changed, 94 insertions, 36 deletions
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp index ccea2698e2..f2cd37c93e 100644 --- a/src/gpu/gl/GrGLEffect.cpp +++ b/src/gpu/gl/GrGLEffect.cpp @@ -31,3 +31,18 @@ GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect, } return key; } + +GrGLEffect::EffectKey GrGLEffect::GenAttribKey(const GrEffectStage& stage) { + EffectKey key = 0; + + int numAttributes = stage.getVertexAttribIndexCount(); + GrAssert(numAttributes <= 2); + const int* attributeIndices = stage.getVertexAttribIndices(); + for (int index = 0; index < numAttributes; ++index) { + EffectKey value = attributeIndices[index] << 2*index; + GrAssert(0 == (value & key)); // keys for each attribute ought not to overlap + key |= value; + } + + return key; +} diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h index 76f865e57c..869fbdad7f 100644 --- a/src/gpu/gl/GrGLEffect.h +++ b/src/gpu/gl/GrGLEffect.h @@ -87,6 +87,7 @@ public: const char* name() const { return fFactory.name(); } static EffectKey GenTextureKey(const GrEffectRef*, const GrGLCaps&); + static EffectKey GenAttribKey(const GrEffectStage& stage); /** * GrGLEffect subclasses get passed a GrEffectStage in their emitCode and setData functions. diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 2b6ccbd0b2..c1643578ad 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -419,9 +419,7 @@ bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, if (fDesc.fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { const char *vsName, *fsName; builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName); - builder->fVSAttrs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kAttribute_TypeModifier, - EDGE_ATTR_NAME); + builder->addAttribute(kVec4f_GrSLType, EDGE_ATTR_NAME); builder->vsCodeAppendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); switch (fDesc.fVertexEdgeType) { case GrDrawState::kHairLine_EdgeType: @@ -467,13 +465,6 @@ bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, builder->fsCodeAppendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smoothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); builder->fsCodeAppend("\tedgeAlpha = outerAlpha * innerAlpha;\n"); break; - case GrDrawState::kEllipse_EdgeType: - builder->fsCodeAppend("\tfloat edgeAlpha;\n"); - builder->fsCodeAppendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder->fragmentPosition(), fsName); - builder->fsCodeAppendf("\toffset.y *= %s.w;\n", fsName); - builder->fsCodeAppend("\tfloat d = length(offset);\n"); - builder->fsCodeAppendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); - break; default: GrCrash("Unknown Edge Type!"); break; @@ -492,9 +483,7 @@ bool GrGLProgram::genEdgeCoverage(SkString* coverageVar, void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { switch (fDesc.fColorInput) { case GrGLProgram::Desc::kAttribute_ColorInput: { - builder->fVSAttrs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kAttribute_TypeModifier, - COL_ATTR_NAME); + builder->addAttribute(kVec4f_GrSLType, COL_ATTR_NAME); const char *vsName, *fsName; builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); builder->vsCodeAppendf("\t%s = " COL_ATTR_NAME ";\n", vsName); @@ -534,9 +523,7 @@ void GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOut namespace { void gen_attribute_coverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) { - builder->fVSAttrs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kAttribute_TypeModifier, - COV_ATTR_NAME); + builder->addAttribute(kVec4f_GrSLType, COV_ATTR_NAME); const char *vsName, *fsName; builder->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); builder->vsCodeAppendf("\t%s = " COV_ATTR_NAME ";\n", vsName); @@ -777,9 +764,7 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { // add texture coordinates that are used to the list of vertex attr decls if (GrDrawState::AttributesBindExplicitTexCoords(attribBindings)) { - builder.fVSAttrs.push_back().set(kVec2f_GrSLType, - GrGLShaderVar::kAttribute_TypeModifier, - TEX_ATTR_NAME); + builder.addAttribute(kVec2f_GrSLType, TEX_ATTR_NAME); } /////////////////////////////////////////////////////////////////////////// @@ -917,6 +902,11 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { inCoverage = outCoverage; } } + + // discard if coverage is zero + if (fDesc.fDiscardIfOutsideEdge && !outCoverage.isEmpty()) { + builder.fsCodeAppendf("\tif (all(lessThanEqual(%s, vec4(0.0)))) {\n\t\tdiscard;\n\t}\n", outCoverage.c_str()); + } } if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { @@ -1022,6 +1012,13 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& buil GL_CALL(BindAttribLocation(fProgramID, fDesc.fTexCoordAttributeIndex, TEX_ATTR_NAME)); } + const GrGLShaderBuilder::AttributePair* attribEnd = builder.getEffectAttributes().end(); + for (const GrGLShaderBuilder::AttributePair* attrib = builder.getEffectAttributes().begin(); + attrib != attribEnd; + ++attrib) { + GL_CALL(BindAttribLocation(fProgramID, attrib->fIndex, attrib->fName.c_str())); + } + GL_CALL(LinkProgram(fProgramID)); GrGLint linked = GR_GL_INIT_ZERO; diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h index 4559fddd36..940501cd3e 100644 --- a/src/gpu/gl/GrGLSL.h +++ b/src/gpu/gl/GrGLSL.h @@ -9,6 +9,7 @@ #define GrGLSL_DEFINED #include "gl/GrGLInterface.h" +#include "GrTypesPriv.h" class GrGLShaderVar; class SkString; @@ -34,22 +35,6 @@ enum GrGLSLGeneration { k150_GrGLSLGeneration, }; -/** - * Types of shader-language-specific boxed variables we can create. - * (Currently only GrGLShaderVars, but should be applicable to other shader - * languages.) - */ -enum GrSLType { - kVoid_GrSLType, - kFloat_GrSLType, - kVec2f_GrSLType, - kVec3f_GrSLType, - kVec4f_GrSLType, - kMat33f_GrSLType, - kMat44f_GrSLType, - kSampler2D_GrSLType -}; - enum GrSLConstantVec { kZeros_GrSLConstantVec, kOnes_GrSLConstantVec, diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 5c3f5b3fe8..1a238ae04b 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -258,6 +258,22 @@ const GrGLShaderVar& GrGLShaderBuilder::getUniformVariable(UniformHandle u) cons return fUniforms[handle_to_index(u)].fVariable; } +bool GrGLShaderBuilder::addAttribute(GrSLType type, + const char* name) { + for (int i = 0; i < fVSAttrs.count(); ++i) { + const GrGLShaderVar& attr = fVSAttrs[i]; + // if attribute already added, don't add it again + if (attr.getName().equals(name)) { + GrAssert(attr.getType() == type); + return false; + } + } + fVSAttrs.push_back().set(type, + GrGLShaderVar::kAttribute_TypeModifier, + name); + return true; +} + void GrGLShaderBuilder::addVarying(GrSLType type, const char* name, const char** vsOutName, @@ -491,6 +507,18 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect( samplerHandles->push_back(textureSamplers[i].fSamplerUniform); } + int numAttributes = stage.getVertexAttribIndexCount(); + const int* attributeIndices = stage.getVertexAttribIndices(); + SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames; + for (int i = 0; i < numAttributes; ++i) { + SkString attributeName("aAttr"); + attributeName.appendS32(attributeIndices[i]); + + if (this->addAttribute(effect->vertexAttribType(i), attributeName.c_str())) { + fEffectAttributes.push_back().set(attributeIndices[i], attributeName); + } + } + GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect); // Enclose custom code in a block to avoid namespace conflicts @@ -508,3 +536,16 @@ GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect( return glEffect; } + +const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const { + const AttributePair* attribEnd = this->getEffectAttributes().end(); + for (const AttributePair* attrib = this->getEffectAttributes().begin(); + attrib != attribEnd; + ++attrib) { + if (attrib->fIndex == attributeIndex) { + return &attrib->fName; + } + } + + return NULL; +} diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 08b3ef5ef5..524a8853ca 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -184,7 +184,11 @@ public: return this->getUniformVariable(u).c_str(); } - /** Add a varying variable to the current program to pass values between vertex and fragment + /** Add a vertex attribute to the current program that is passed in from the vertex data. + Returns false if the attribute was already there, true otherwise. */ + bool addAttribute(GrSLType type, const char* name); + + /** Add a varying variable to the current program to pass values between vertex and fragment shaders. If the last two parameters are non-NULL, they are filled in with the name generated. */ void addVarying(GrSLType type, @@ -222,6 +226,19 @@ public: const char* vsInCoord, SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles); GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; } + + struct AttributePair { + void set(int index, const SkString& name) { + fIndex = index; fName = name; + } + int fIndex; + SkString fName; + }; + const SkSTArray<10, AttributePair, true>& getEffectAttributes() const { + return fEffectAttributes; + } + const SkString* getEffectAttributeName(int attributeIndex) const; + // TODO: Make this do all the compiling, linking, etc. void finished(GrGLuint programID); @@ -270,6 +287,8 @@ private: bool fSetupFragPosition; GrGLUniformManager::UniformHandle fRTHeightUniform; + SkSTArray<10, AttributePair, true> fEffectAttributes; + GrGLShaderVar* fPositionVar; }; |