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/GrGLSLUniformHandler.h" 13 #include "glsl/GrGLSLVarying.h" 14 #include "glsl/GrGLSLVertexGeoBuilder.h" 15 16 void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { 17 GrGPArgs gpArgs; 18 this->onEmitCode(args, &gpArgs); 19 20 GrGLSLVertexBuilder* vBuilder = args.fVertBuilder; 21 if (!args.fGP.willUseGeoShader()) { 22 // Emit the vertex position to the hardware in the normalized window coordinates it expects. 23 SkASSERT(kFloat2_GrSLType == gpArgs.fPositionVar.getType() || 24 kFloat3_GrSLType == gpArgs.fPositionVar.getType()); 25 vBuilder->emitNormalizedSkPosition(gpArgs.fPositionVar.c_str(), args.fRTAdjustName, 26 gpArgs.fPositionVar.getType()); 27 if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) { 28 args.fVaryingHandler->setNoPerspective(); 29 } 30 } else { 31 // Since we have a geometry shader, leave the vertex position in Skia device space for now. 32 // The geometry Shader will operate in device space, and then convert the final positions to 33 // normalized hardware window coordinates under the hood, once everything else has finished. 34 // The subclass must call setNoPerspective on the varying handler, if applicable. 35 vBuilder->codeAppendf("sk_Position = float4(%s", gpArgs.fPositionVar.c_str()); 36 switch (gpArgs.fPositionVar.getType()) { 37 case kFloat_GrSLType: 38 vBuilder->codeAppend(", 0"); // fallthru. 39 case kFloat2_GrSLType: 40 vBuilder->codeAppend(", 0"); // fallthru. 41 case kFloat3_GrSLType: 42 vBuilder->codeAppend(", 1"); // fallthru. 43 case kFloat4_GrSLType: 44 vBuilder->codeAppend(");"); 45 break; 46 default: 47 SK_ABORT("Invalid position var type"); 48 break; 49 } 50 } 51 } 52 53 void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, 54 GrGLSLVaryingHandler* varyingHandler, 55 GrGLSLUniformHandler* uniformHandler, 56 const GrShaderVar& localCoordsVar, 57 const SkMatrix& localMatrix, 58 FPCoordTransformHandler* handler) { 59 SkASSERT(GrSLTypeIsFloatType(localCoordsVar.getType())); 60 SkASSERT(2 == GrSLTypeVecLength(localCoordsVar.getType()) || 61 3 == GrSLTypeVecLength(localCoordsVar.getType())); 62 63 bool threeComponentLocalCoords = 3 == GrSLTypeVecLength(localCoordsVar.getType()); 64 SkString localCoords; 65 if (threeComponentLocalCoords) { 66 localCoords = localCoordsVar.getName(); 67 } else { 68 localCoords.printf("float3(%s, 1)", localCoordsVar.c_str()); 69 } 70 int i = 0; 71 while (const GrCoordTransform* coordTransform = handler->nextCoordTransform()) { 72 SkString strUniName; 73 strUniName.printf("CoordTransformMatrix_%d", i); 74 const char* uniName; 75 fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag, 76 kFloat3x3_GrSLType, 77 strUniName.c_str(), 78 &uniName).toIndex(); 79 GrSLType varyingType = kFloat2_GrSLType; 80 if (localMatrix.hasPerspective() || coordTransform->getMatrix().hasPerspective()) { 81 varyingType = kFloat3_GrSLType; 82 } 83 SkString strVaryingName; 84 strVaryingName.printf("TransformedCoords_%d", i); 85 GrGLSLVarying v(varyingType); 86 varyingHandler->addVarying(strVaryingName.c_str(), &v); 87 88 handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); 89 90 if (kFloat2_GrSLType == varyingType) { 91 vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, localCoords.c_str()); 92 if (threeComponentLocalCoords) { 93 vb->codeAppendf("%s /= %s.z;", v.vsOut(), localCoords.c_str()); 94 } 95 } else { 96 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, localCoords.c_str()); 97 } 98 ++i; 99 } 100 } 101 102 void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix, 103 const GrGLSLProgramDataManager& pdman, 104 FPCoordTransformIter* transformIter) { 105 int i = 0; 106 while (const GrCoordTransform* coordTransform = transformIter->next()) { 107 const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform); 108 if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) { 109 pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m); 110 fInstalledTransforms[i].fCurrentValue = m; 111 } 112 ++i; 113 } 114 SkASSERT(i == fInstalledTransforms.count()); 115 } 116 117 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, 118 GrGPArgs* gpArgs, 119 const char* posName) { 120 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 121 vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 122 } 123 124 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, 125 GrGLSLUniformHandler* uniformHandler, 126 GrGPArgs* gpArgs, 127 const char* posName, 128 const SkMatrix& mat, 129 UniformHandle* viewMatrixUniform) { 130 if (mat.isIdentity()) { 131 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 132 vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 133 } else { 134 const char* viewMatrixName; 135 *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, 136 kFloat3x3_GrSLType, 137 "uViewM", 138 &viewMatrixName); 139 if (!mat.hasPerspective()) { 140 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 141 vertBuilder->codeAppendf("float2 %s = (%s * float3(%s, 1)).xy;", 142 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 143 } else { 144 gpArgs->fPositionVar.set(kFloat3_GrSLType, "pos3"); 145 vertBuilder->codeAppendf("float3 %s = %s * float3(%s, 1);", 146 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 147 } 148 } 149 } 150