Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2013 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "GrEdgeEffect.h" | |
| 9 #include "gl/GrGLEffect.h" | |
| 10 #include "gl/GrGLSL.h" | |
| 11 #include "GrTBackendEffectFactory.h" | |
| 12 | |
| 13 class GrGLEdgeEffect : public GrGLEffect { | |
| 14 public: | |
| 15 GrGLEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) | |
| 16 : INHERITED (factory) {} | |
| 17 | |
| 18 virtual void emitCode(GrGLShaderBuilder* builder, | |
| 19 const GrDrawEffect& drawEffect, | |
| 20 EffectKey key, | |
| 21 const char* outputColor, | |
| 22 const char* inputColor, | |
| 23 const TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 24 const GrEdgeEffect& edgeEffect = drawEffect.castEffect<GrEdgeEffect>(); | |
| 25 GrEdgeEffect::EdgeType type = edgeEffect.edgeType(); | |
| 26 | |
| 27 const char *vsName, *fsName; | |
| 28 const SkString* attrName = | |
| 29 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[ 0]); | |
| 30 builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); | |
| 31 | |
| 32 switch (type) { | |
| 33 case GrEdgeEffect::kHairLine_EdgeType: | |
| 34 builder->addVarying(kVec4f_GrSLType, "HairEdge", &vsName, &fsName); | |
| 35 | |
| 36 builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xy z));\n", | |
| 37 builder->fragmentPosition(), fsName); | |
| 38 builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n "); | |
| 39 break; | |
| 40 case GrEdgeEffect::kQuad_EdgeType: | |
| 41 GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport()); | |
| 42 builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); | |
| 43 | |
| 44 // keep the derivative instructions outside the conditional | |
| 45 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | |
| 46 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | |
| 47 builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsNa me, fsName); | |
| 48 // today we know z and w are in device space. We could use derivativ es | |
| 49 builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, | |
| 50 fsName); | |
| 51 builder->fsCodeAppendf ("\t\t} else {\n"); | |
| 52 builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvd x.y,\n" | |
| 53 "\t\t\t 2.0*%s.x*duvdy.x - duvd y.y);\n", | |
| 54 fsName, fsName); | |
| 55 builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fs Name, fsName, | |
| 56 fsName); | |
| 57 builder->fsCodeAppendf("\t\t\tedgeAlpha = " | |
| 58 "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0 );\n\t\t}\n"); | |
| 59 if (kES2_GrGLBinding == builder->ctxInfo().binding()) { | |
| 60 builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); | |
| 61 } | |
| 62 break; | |
| 63 case GrEdgeEffect::kHairQuad_EdgeType: | |
| 64 GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport()); | |
| 65 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsNam e); | |
| 66 | |
| 67 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); | |
| 68 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); | |
| 69 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx. y,\n" | |
| 70 "\t\t 2.0*%s.x*duvdy.x - duvdy. y);\n", | |
| 71 fsName, fsName); | |
| 72 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsNa me, fsName, | |
| 73 fsName); | |
| 74 builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / do t(gF, gF));\n"); | |
| 75 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n" ); | |
| 76 if (kES2_GrGLBinding == builder->ctxInfo().binding()) { | |
| 77 builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); | |
| 78 } | |
| 79 break; | |
| 80 }; | |
| 81 | |
| 82 SkString modulate; | |
| 83 GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); | |
| 84 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); | |
| 85 | |
| 86 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); | |
| 87 } | |
| 88 | |
| 89 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCap s&) { | |
| 90 const GrEdgeEffect& QuadEffect = drawEffect.castEffect<GrEdgeEffect>(); | |
| 91 | |
| 92 return QuadEffect.edgeType(); | |
| 93 } | |
| 94 | |
| 95 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE { | |
| 96 } | |
| 97 | |
| 98 private: | |
| 99 typedef GrGLEffect INHERITED; | |
| 100 }; | |
| 101 | |
| 102 /////////////////////////////////////////////////////////////////////////////// | |
| 103 | |
| 104 GrEdgeEffect::GrEdgeEffect(EdgeType edgeType) : GrEffect() { | |
| 105 if (edgeType == kQuad_EdgeType) { | |
| 106 this->addVertexAttrib(kVec4f_GrSLType); | |
| 107 } else { | |
|
robertphillips
2013/03/26 14:09:20
convert the "someday" comment into a "TODO"?
bsalomon
2013/03/26 14:45:30
Done.
| |
| 108 this->addVertexAttrib(kVec4f_GrSLType); // someday this will matter | |
| 109 } | |
| 110 fEdgeType = edgeType; | |
| 111 } | |
| 112 | |
| 113 void GrEdgeEffect::getConstantColorComponents(GrColor* color, uint32_t* validFla gs) const { | |
| 114 *validFlags = 0; | |
| 115 } | |
| 116 | |
| 117 const GrBackendEffectFactory& GrEdgeEffect::getFactory() const { | |
| 118 return GrTBackendEffectFactory<GrEdgeEffect>::getInstance(); | |
| 119 } | |
| 120 | |
| 121 /////////////////////////////////////////////////////////////////////////////// | |
| 122 | |
| 123 GR_DEFINE_EFFECT_TEST(GrEdgeEffect); | |
| 124 | |
| 125 GrEffectRef* GrEdgeEffect::TestCreate(SkMWCRandom* random, | |
| 126 GrContext*, | |
| 127 const GrDrawTargetCaps& caps, | |
| 128 GrTexture*[]) { | |
| 129 // Only kHairLine works without derivative instructions. | |
| 130 EdgeType edgeType; | |
| 131 if (caps.shaderDerivativeSupport()) { | |
| 132 edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCount)); | |
| 133 } else { | |
| 134 edgeType = kHairLine_EdgeType; | |
| 135 } | |
| 136 return GrEdgeEffect::Create(edgeType); | |
| 137 } | |
| OLD | NEW |