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 onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(cte); GrGLVertToFrag v(kVec2f_GrSLType); pb->addVarying("TextureCoords", &v); // this is only used with text, so our texture bounds always match the glyph atlas if (cte.maskFormat() == kA8_GrMaskFormat) { vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut(), cte.inTextureCoords()->fName); } else { vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", " GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut(), cte.inTextureCoords()->fName); } // Setup pass through color if (!cte.colorIgnored()) { if (cte.hasVertexColor()) { pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor); } else { this->setupUniformColor(pb, args.fOutputColor, &fColorUniform); } } // Setup position this->setupPosition(pb, gpArgs, cte.inPosition()->fName); // emit transforms this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->fName, cte.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); if (cte.maskFormat() == kARGB_GrMaskFormat) { fsBuilder->codeAppendf("%s = ", args.fOutputColor); fsBuilder->appendTextureLookupAndModulate(args.fOutputColor, args.fSamplers[0], v.fsIn(), kVec2f_GrSLType); fsBuilder->codeAppend(";"); fsBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage); } else { fsBuilder->codeAppendf("%s = ", args.fOutputCoverage); fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType); fsBuilder->codeAppend(";"); } }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>(); GrGLGPBuilder* pb = args.fPB; GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); // emit attributes vsBuilder->emitAttributes(qe); GrGLVertToFrag v(kVec4f_GrSLType); args.fPB->addVarying("QuadEdge", &v); vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName); const BatchTracker& local = args.fBT.cast<BatchTracker>(); // Setup pass through color this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, qe.inPosition()->fName, qe.viewMatrix()); // emit transforms this->emitTransforms(args.fPB, gpArgs->fPositionVar, qe.inPosition()->fName, qe.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); fsBuilder->codeAppendf("float edgeAlpha;"); // keep the derivative instructions outside the conditional fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn()); fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn()); fsBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn()); // today we know z and w are in device space. We could use derivatives fsBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(), v.fsIn()); fsBuilder->codeAppendf ("} else {"); fsBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y," " 2.0*%s.x*duvdy.x - duvdy.y);", v.fsIn(), v.fsIn()); fsBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn()); fsBuilder->codeAppendf("edgeAlpha = " "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}"); fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); }