1 /* 2 * Copyright 2014 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 "GrGLSLGeometryProcessor.h" 9 10 #include "GrCoordTransform.h" 11 #include "glsl/GrGLSLFragmentShaderBuilder.h" 12 #include "glsl/GrGLSLProcessorTypes.h" 13 #include "glsl/GrGLSLUniformHandler.h" 14 #include "glsl/GrGLSLVarying.h" 15 #include "glsl/GrGLSLVertexShaderBuilder.h" 16 17 void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { 18 GrGLSLVertexBuilder* vBuilder = args.fVertBuilder; 19 GrGPArgs gpArgs; 20 this->onEmitCode(args, &gpArgs); 21 vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar); 22 if (kVec2f_GrSLType == gpArgs.fPositionVar.getType()) { 23 args.fVaryingHandler->setNoPerspective(); 24 } 25 } 26 27 void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, 28 GrGLSLVaryingHandler* varyingHandler, 29 GrGLSLUniformHandler* uniformHandler, 30 const GrShaderVar& posVar, 31 const char* localCoords, 32 const SkMatrix& localMatrix, 33 const TransformsIn& tin, 34 TransformsOut* tout) { 35 tout->push_back_n(tin.count()); 36 fInstalledTransforms.push_back_n(tin.count()); 37 for (int i = 0; i < tin.count(); i++) { 38 const ProcCoords& coordTransforms = tin[i]; 39 fInstalledTransforms[i].push_back_n(coordTransforms.count()); 40 for (int t = 0; t < coordTransforms.count(); t++) { 41 SkString strUniName("StageMatrix"); 42 strUniName.appendf("_%i_%i", i, t); 43 GrSLType varyingType; 44 45 GrCoordSet coordType = coordTransforms[t]->sourceCoords(); 46 uint32_t type = coordTransforms[t]->getMatrix().getType(); 47 if (kLocal_GrCoordSet == coordType) { 48 type |= localMatrix.getType(); 49 } 50 varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : 51 kVec2f_GrSLType; 52 GrSLPrecision precision = coordTransforms[t]->precision(); 53 54 const char* uniName; 55 fInstalledTransforms[i][t].fHandle = 56 uniformHandler->addUniform(kVertex_GrShaderFlag, 57 kMat33f_GrSLType, precision, 58 strUniName.c_str(), 59 &uniName).toIndex(); 60 61 SkString strVaryingName("MatrixCoord"); 62 strVaryingName.appendf("_%i_%i", i, t); 63 64 GrGLSLVertToFrag v(varyingType); 65 varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); 66 67 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); 68 (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType); 69 70 // varying = matrix * coords (logically) 71 if (kDevice_GrCoordSet == coordType) { 72 if (kVec2f_GrSLType == varyingType) { 73 if (kVec2f_GrSLType == posVar.getType()) { 74 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", 75 v.vsOut(), uniName, posVar.c_str()); 76 } else { 77 // The brackets here are just to scope the temp variable 78 vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str()); 79 vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut()); 80 } 81 } else { 82 if (kVec2f_GrSLType == posVar.getType()) { 83 vb->codeAppendf("%s = %s * vec3(%s, 1);", 84 v.vsOut(), uniName, posVar.c_str()); 85 } else { 86 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str()); 87 } 88 } 89 } else { 90 if (kVec2f_GrSLType == varyingType) { 91 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); 92 } else { 93 vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords); 94 } 95 } 96 } 97 } 98 } 99 100 void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, 101 GrGLSLVaryingHandler* varyingHandler, 102 const char* localCoords, 103 const TransformsIn& tin, 104 TransformsOut* tout) { 105 tout->push_back_n(tin.count()); 106 for (int i = 0; i < tin.count(); i++) { 107 const ProcCoords& coordTransforms = tin[i]; 108 for (int t = 0; t < coordTransforms.count(); t++) { 109 GrSLType varyingType = kVec2f_GrSLType; 110 111 // Device coords aren't supported 112 SkASSERT(kDevice_GrCoordSet != coordTransforms[t]->sourceCoords()); 113 GrSLPrecision precision = coordTransforms[t]->precision(); 114 115 SkString strVaryingName("MatrixCoord"); 116 strVaryingName.appendf("_%i_%i", i, t); 117 118 GrGLSLVertToFrag v(varyingType); 119 varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); 120 vb->codeAppendf("%s = %s;", v.vsOut(), localCoords); 121 122 (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType); 123 } 124 } 125 } 126 127 void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder, 128 GrGPArgs* gpArgs, 129 const char* posName) { 130 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 131 vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 132 } 133 134 void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder, 135 GrGLSLUniformHandler* uniformHandler, 136 GrGPArgs* gpArgs, 137 const char* posName, 138 const SkMatrix& mat, 139 UniformHandle* viewMatrixUniform) { 140 if (mat.isIdentity()) { 141 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 142 vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 143 } else { 144 const char* viewMatrixName; 145 *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, 146 kMat33f_GrSLType, kHigh_GrSLPrecision, 147 "uViewM", 148 &viewMatrixName); 149 if (!mat.hasPerspective()) { 150 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 151 vertBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));", 152 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 153 } else { 154 gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3"); 155 vertBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);", 156 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 157 } 158 } 159 } 160