void GLAARectEffect::emitCode(GrGLFPBuilder* builder, const GrFragmentProcessor& fp, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { const AARectEffect& aare = fp.cast<AARectEffect>(); const char *rectName; // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), // respectively. fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType, kDefault_GrSLPrecision, "rect", &rectName); GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); const char* fragmentPos = fsBuilder->fragmentPosition(); if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) { // The amount of coverage removed in x and y by the edges is computed as a pair of negative // numbers, xSub and ySub. fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); // Now compute coverage in x and y and multiply them to get the fraction of the pixel // covered. fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); } else { fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); } if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) { fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); } fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); }
void GrGLConvexPolyEffect::emitCode(GrGLFPBuilder* builder, const GrFragmentProcessor& fp, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>(); const char *edgeArrayName; fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, kVec3f_GrSLType, kDefault_GrSLPrecision, "edges", cpe.getEdgeCount(), &edgeArrayName); GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n"); fsBuilder->codeAppend("\t\tfloat edge;\n"); const char* fragmentPos = fsBuilder->fragmentPosition(); for (int i = 0; i < cpe.getEdgeCount(); ++i) { fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", edgeArrayName, i, fragmentPos, fragmentPos); if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) { fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); } else { fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); } fsBuilder->codeAppend("\t\talpha *= edge;\n"); } // Woe is me. See skbug.com/2149. if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); } if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) { fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n"); } fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); }