void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); // emit attributes vsBuilder->emitAttributes(gp); // Setup pass through color if (!gp.colorIgnored()) { if (gp.hasVertexColor()) { pb->addPassThroughAttribute(gp.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); } } // Setup position this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix(), &fViewMatrixUniform); if (gp.hasExplicitLocalCoords()) { // emit transforms with explicit local coords this->emitTransforms(pb, gpArgs->fPositionVar, gp.inLocalCoords()->fName, gp.localMatrix(), args.fTransformsIn, args.fTransformsOut); } else if(gp.hasTransformedLocalCoords()) { // transforms have already been applied to vertex attributes on the cpu this->emitTransforms(pb, gp.inLocalCoords()->fName, args.fTransformsIn, args.fTransformsOut); } else { // emit transforms with position this->emitTransforms(pb, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), args.fTransformsIn, args.fTransformsOut); } // Setup coverage as pass through if (!gp.coverageWillBeIgnored()) { if (gp.hasVertexCoverage()) { fs->codeAppendf("float alpha = 1.0;"); args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha"); fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage); } else if (gp.coverage() == 0xff) { fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); } else { const char* fragCoverage; fCoverageUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, kDefault_GrSLPrecision, "Coverage", &fragCoverage); fs->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage); } } }
void GrGLPathProcessor::emitCode(EmitArgs& args) { GrGLGPBuilder* pb = args.fPB; GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>(); // emit transforms this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut); // Setup uniform color if (kUniform_GrGPInput == local.fInputColorType) { const char* stagedLocalVarName; fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec4f_GrSLType, kDefault_GrSLPrecision, "Color", &stagedLocalVarName); fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); } // setup constant solid coverage if (kAllOnes_GrGPInput == local.fInputCoverageType) { fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); } }
void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); const GrConicEffect& gp = args.fGP.cast<GrConicEffect>(); const ConicBatchTracker& local = args.fBT.cast<ConicBatchTracker>(); // emit attributes vsBuilder->emitAttributes(gp); GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("ConicCoeffs", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); // Setup pass through color this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix()); // emit transforms with position this->emitTransforms(pb, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); fsBuilder->codeAppend("float edgeAlpha;"); switch (fEdgeType) { case kHairlineAA_GrProcessorEdgeType: { SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn()); fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn()); fsBuilder->codeAppendf("float dfdx =" "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;", v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppendf("float dfdy =" "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;", v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);"); fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));"); fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppend("func = abs(func);"); fsBuilder->codeAppend("edgeAlpha = func / gFM;"); fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);"); // Add line below for smooth cubic ramp // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); break; } case kFillAA_GrProcessorEdgeType: { SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn()); fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn()); fsBuilder->codeAppendf("float dfdx =" "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;", v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppendf("float dfdy =" "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;", v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);"); fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));"); fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppend("edgeAlpha = func / gFM;"); fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);"); // Add line below for smooth cubic ramp // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);"); break; } case kFillBW_GrProcessorEdgeType: { fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);"); break; } default: SkFAIL("Shouldn't get here"); } if (0xff != local.fCoverageScale) { const char* coverageScale; fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType, kDefault_GrSLPrecision, "Coverage", &coverageScale); fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale); } else { fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); } }