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 "GrGLGeometryProcessor.h" 9 10 #include "builders/GrGLProgramBuilder.h" 11 12 void GrGLGeometryProcessor::emitCode(EmitArgs& args) { 13 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 14 GrGPArgs gpArgs; 15 this->onEmitCode(args, &gpArgs); 16 vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar); 17 } 18 19 void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, 20 const GrShaderVar& posVar, 21 const char* localCoords, 22 const SkMatrix& localMatrix, 23 const TransformsIn& tin, 24 TransformsOut* tout) { 25 GrGLVertexBuilder* vb = pb->getVertexShaderBuilder(); 26 tout->push_back_n(tin.count()); 27 fInstalledTransforms.push_back_n(tin.count()); 28 for (int i = 0; i < tin.count(); i++) { 29 const ProcCoords& coordTransforms = tin[i]; 30 fInstalledTransforms[i].push_back_n(coordTransforms.count()); 31 for (int t = 0; t < coordTransforms.count(); t++) { 32 SkString strUniName("StageMatrix"); 33 strUniName.appendf("_%i_%i", i, t); 34 GrSLType varyingType; 35 36 GrCoordSet coordType = coordTransforms[t]->sourceCoords(); 37 uint32_t type = coordTransforms[t]->getMatrix().getType(); 38 if (kLocal_GrCoordSet == coordType) { 39 type |= localMatrix.getType(); 40 } 41 varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : 42 kVec2f_GrSLType; 43 GrSLPrecision precision = coordTransforms[t]->precision(); 44 45 const char* uniName; 46 fInstalledTransforms[i][t].fHandle = 47 pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, 48 kMat33f_GrSLType, precision, 49 strUniName.c_str(), 50 &uniName).toShaderBuilderIndex(); 51 52 SkString strVaryingName("MatrixCoord"); 53 strVaryingName.appendf("_%i_%i", i, t); 54 55 GrGLVertToFrag v(varyingType); 56 pb->addVarying(strVaryingName.c_str(), &v, precision); 57 58 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); 59 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords, 60 (SkString(v.fsIn()), varyingType)); 61 62 // varying = matrix * coords (logically) 63 if (kDevice_GrCoordSet == coordType) { 64 if (kVec2f_GrSLType == varyingType) { 65 if (kVec2f_GrSLType == posVar.getType()) { 66 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", 67 v.vsOut(), uniName, posVar.c_str()); 68 } else { 69 // The brackets here are just to scope the temp variable 70 vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str()); 71 vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut()); 72 } 73 } else { 74 if (kVec2f_GrSLType == posVar.getType()) { 75 vb->codeAppendf("%s = %s * vec3(%s, 1);", 76 v.vsOut(), uniName, posVar.c_str()); 77 } else { 78 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str()); 79 } 80 } 81 } else { 82 if (kVec2f_GrSLType == varyingType) { 83 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); 84 } else { 85 vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords); 86 } 87 } 88 } 89 } 90 } 91 92 void GrGLGeometryProcessor::setupPosition(GrGLGPBuilder* pb, 93 GrGPArgs* gpArgs, 94 const char* posName, 95 const SkMatrix& mat) { 96 GrGLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder(); 97 if (mat.isIdentity()) { 98 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 99 100 vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 101 } else if (!mat.hasPerspective()) { 102 this->addUniformViewMatrix(pb); 103 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 104 105 vsBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));", 106 gpArgs->fPositionVar.c_str(), this->uViewM(), posName); 107 } else { 108 this->addUniformViewMatrix(pb); 109 gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3"); 110 111 vsBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);", 112 gpArgs->fPositionVar.c_str(), this->uViewM(), posName); 113 } 114 } 115