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 "SkTo.h" 12 #include "gl/GrGLGpu.h" 13 #include "gl/GrGLVaryingHandler.h" 14 #include "glsl/GrGLSLFragmentShaderBuilder.h" 15 #include "glsl/GrGLSLPrimitiveProcessor.h" 16 #include "glsl/GrGLSLUniformHandler.h" 17 #include "glsl/GrGLSLVarying.h" 18 19 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor { 20 public: 21 GrGLPathProcessor() : fColor(SK_PMColor4fILLEGAL) {} 22 23 static void GenKey(const GrPathProcessor& pathProc, 24 const GrShaderCaps&, 25 GrProcessorKeyBuilder* b) { 26 b->add32(SkToInt(pathProc.viewMatrix().hasPerspective())); 27 } 28 29 void emitCode(EmitArgs& args) override { 30 GrGLSLFPFragmentBuilder* 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.fFPCoordTransformHandler); 39 40 // Setup uniform color 41 const char* stagedLocalVarName; 42 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 43 kHalf4_GrSLType, 44 "Color", 45 &stagedLocalVarName); 46 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); 47 48 // setup constant solid coverage 49 fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage); 50 } 51 52 void emitTransforms(GrGLSLVaryingHandler* varyingHandler, 53 FPCoordTransformHandler* transformHandler) { 54 int i = 0; 55 while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) { 56 GrSLType varyingType = 57 coordTransform->getMatrix().hasPerspective() ? kHalf3_GrSLType 58 : kHalf2_GrSLType; 59 60 SkString strVaryingName; 61 strVaryingName.printf("TransformedCoord_%d", i); 62 GrGLSLVarying v(varyingType); 63 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; 64 fInstalledTransforms.push_back().fHandle = 65 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), 66 &v).toIndex(); 67 fInstalledTransforms.back().fType = varyingType; 68 69 transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); 70 ++i; 71 } 72 } 73 74 void setData(const GrGLSLProgramDataManager& pd, 75 const GrPrimitiveProcessor& primProc, 76 FPCoordTransformIter&& transformIter) override { 77 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); 78 if (pathProc.color() != fColor) { 79 pd.set4fv(fColorUniform, 1, pathProc.color().vec()); 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 == kHalf2_GrSLType || 93 fInstalledTransforms[t].fType == kHalf3_GrSLType); 94 unsigned components = fInstalledTransforms[t].fType == kHalf2_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 SkPMColor4f fColor; 112 113 typedef GrGLSLPrimitiveProcessor INHERITED; 114 }; 115 116 GrPathProcessor::GrPathProcessor(const SkPMColor4f& color, 117 const SkMatrix& viewMatrix, 118 const SkMatrix& localMatrix) 119 : INHERITED(kGrPathProcessor_ClassID) 120 , fColor(color) 121 , fViewMatrix(viewMatrix) 122 , fLocalMatrix(localMatrix) {} 123 124 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, 125 GrProcessorKeyBuilder* b) const { 126 GrGLPathProcessor::GenKey(*this, caps, b); 127 } 128 129 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const { 130 SkASSERT(caps.pathRenderingSupport()); 131 return new GrGLPathProcessor(); 132 } 133