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