void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); const BitmapTextBatchTracker& local = args.fBT.cast<BitmapTextBatchTracker>(); 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 this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, cte.inColor(), &fColorUniform); // Setup position this->setupPosition(pb, gpArgs, cte.inPosition()->fName, cte.viewMatrix()); // emit transforms this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->fName, cte.localMatrix(), args.fTransformsIn, args.fTransformsOut); GrGLGPFragmentBuilder* 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(";"); } }