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 GrGLSLFPFragmentBuilder* 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 kHalf4_GrSLType, 41 "Color", 42 &stagedLocalVarName); 43 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); 44 45 // setup constant solid coverage 46 fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage); 47 } 48 49 void emitTransforms(GrGLSLVaryingHandler* varyingHandler, 50 FPCoordTransformHandler* transformHandler) { 51 int i = 0; 52 while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) { 53 GrSLType varyingType = 54 coordTransform->getMatrix().hasPerspective() ? kHalf3_GrSLType 55 : kHalf2_GrSLType; 56 57 SkString strVaryingName; 58 strVaryingName.printf("TransformedCoord_%d", i); 59 GrGLSLVarying v(varyingType); 60 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; 61 fInstalledTransforms.push_back().fHandle = 62 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), 63 &v).toIndex(); 64 fInstalledTransforms.back().fType = varyingType; 65 66 transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); 67 ++i; 68 } 69 } 70 71 void setData(const GrGLSLProgramDataManager& pd, 72 const GrPrimitiveProcessor& primProc, 73 FPCoordTransformIter&& transformIter) override { 74 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); 75 if (pathProc.color() != fColor) { 76 float c[4]; 77 GrColorToRGBAFloat(pathProc.color(), c); 78 pd.set4fv(fColorUniform, 1, c); 79 fColor = pathProc.color(); 80 } 81 82 int t = 0; 83 while (const GrCoordTransform* coordTransform = transformIter.next()) { 84 SkASSERT(fInstalledTransforms[t].fHandle.isValid()); 85 const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform); 86 if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) { 87 continue; 88 } 89 fInstalledTransforms[t].fCurrentValue = m; 90 91 SkASSERT(fInstalledTransforms[t].fType == kHalf2_GrSLType || 92 fInstalledTransforms[t].fType == kHalf3_GrSLType); 93 unsigned components = fInstalledTransforms[t].fType == kHalf2_GrSLType ? 2 : 3; 94 pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m); 95 ++t; 96 } 97 } 98 99 private: 100 typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; 101 struct TransformVarying { 102 VaryingHandle fHandle; 103 SkMatrix fCurrentValue = SkMatrix::InvalidMatrix(); 104 GrSLType fType = kVoid_GrSLType; 105 }; 106 107 SkTArray<TransformVarying, true> fInstalledTransforms; 108 109 UniformHandle fColorUniform; 110 GrColor fColor; 111 112 typedef GrGLSLPrimitiveProcessor INHERITED; 113 }; 114 115 GrPathProcessor::GrPathProcessor(GrColor color, 116 const SkMatrix& viewMatrix, 117 const SkMatrix& localMatrix) 118 : INHERITED(kGrPathProcessor_ClassID) 119 , fColor(color) 120 , fViewMatrix(viewMatrix) 121 , fLocalMatrix(localMatrix) {} 122 123 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, 124 GrProcessorKeyBuilder* b) const { 125 GrGLPathProcessor::GenKey(*this, caps, b); 126 } 127 128 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const { 129 SkASSERT(caps.pathRenderingSupport()); 130 return new GrGLPathProcessor(); 131 } 132