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 "GrPathProcessor.h" 9 10 #include "gl/GrGLGpu.h" 11 #include "glsl/GrGLSLCaps.h" 12 #include "glsl/GrGLSLFragmentShaderBuilder.h" 13 #include "glsl/GrGLSLProcessorTypes.h" 14 #include "glsl/GrGLSLUniformHandler.h" 15 #include "glsl/GrGLSLVarying.h" 16 17 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor { 18 public: 19 GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {} 20 21 static void GenKey(const GrPathProcessor& pathProc, 22 const GrGLSLCaps&, 23 GrProcessorKeyBuilder* b) { 24 b->add32(SkToInt(pathProc.overrides().readsColor()) | 25 (SkToInt(pathProc.overrides().readsCoverage()) << 1) | 26 (SkToInt(pathProc.viewMatrix().hasPerspective()) << 2)); 27 } 28 29 void emitCode(EmitArgs& args) override { 30 GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; 31 const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>(); 32 33 if (!pathProc.viewMatrix().hasPerspective()) { 34 args.fVaryingHandler->setNoPerspective(); 35 } 36 37 // emit transforms 38 this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut); 39 40 // Setup uniform color 41 if (pathProc.overrides().readsColor()) { 42 const char* stagedLocalVarName; 43 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 44 kVec4f_GrSLType, 45 kDefault_GrSLPrecision, 46 "Color", 47 &stagedLocalVarName); 48 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); 49 } 50 51 // setup constant solid coverage 52 if (pathProc.overrides().readsCoverage()) { 53 fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage); 54 } 55 } 56 57 void emitTransforms(GrGLSLVaryingHandler* varyingHandler, 58 const TransformsIn& tin, 59 TransformsOut* tout) { 60 tout->push_back_n(tin.count()); 61 fInstalledTransforms.push_back_n(tin.count()); 62 for (int i = 0; i < tin.count(); i++) { 63 const ProcCoords& coordTransforms = tin[i]; 64 fInstalledTransforms[i].push_back_n(coordTransforms.count()); 65 for (int t = 0; t < coordTransforms.count(); t++) { 66 GrSLType varyingType = 67 coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType : 68 kVec2f_GrSLType; 69 70 SkString strVaryingName("MatrixCoord"); 71 strVaryingName.appendf("_%i_%i", i, t); 72 GrGLSLVertToFrag v(varyingType); 73 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; 74 fInstalledTransforms[i][t].fHandle = 75 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), 76 &v).toIndex(); 77 fInstalledTransforms[i][t].fType = varyingType; 78 79 (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType); 80 } 81 } 82 } 83 84 void setData(const GrGLSLProgramDataManager& pd, 85 const GrPrimitiveProcessor& primProc) override { 86 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); 87 if (pathProc.overrides().readsColor() && pathProc.color() != fColor) { 88 float c[4]; 89 GrColorToRGBAFloat(pathProc.color(), c); 90 pd.set4fv(fColorUniform, 1, c); 91 fColor = pathProc.color(); 92 } 93 } 94 95 void setTransformData(const GrPrimitiveProcessor& primProc, 96 const GrGLSLProgramDataManager& pdman, 97 int index, 98 const SkTArray<const GrCoordTransform*, true>& coordTransforms) override { 99 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); 100 SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index]; 101 int numTransforms = transforms.count(); 102 for (int t = 0; t < numTransforms; ++t) { 103 SkASSERT(transforms[t].fHandle.isValid()); 104 const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(), 105 *coordTransforms[t]); 106 if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { 107 continue; 108 } 109 transforms[t].fCurrentValue = transform; 110 111 SkASSERT(transforms[t].fType == kVec2f_GrSLType || 112 transforms[t].fType == kVec3f_GrSLType); 113 unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3; 114 pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform); 115 } 116 } 117 118 private: 119 UniformHandle fColorUniform; 120 GrColor fColor; 121 122 typedef GrGLSLPrimitiveProcessor INHERITED; 123 }; 124 125 GrPathProcessor::GrPathProcessor(GrColor color, 126 const GrXPOverridesForBatch& overrides, 127 const SkMatrix& viewMatrix, 128 const SkMatrix& localMatrix) 129 : fColor(color) 130 , fViewMatrix(viewMatrix) 131 , fLocalMatrix(localMatrix) 132 , fOverrides(overrides) { 133 this->initClassID<GrPathProcessor>(); 134 } 135 136 void GrPathProcessor::getGLSLProcessorKey(const GrGLSLCaps& caps, 137 GrProcessorKeyBuilder* b) const { 138 GrGLPathProcessor::GenKey(*this, caps, b); 139 } 140 141 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrGLSLCaps& caps) const { 142 SkASSERT(caps.pathRenderingSupport()); 143 return new GrGLPathProcessor(); 144 } 145