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 || threeComponentLocalCoords) { 82 varyingType = kFloat3_GrSLType; 83 } 84 SkString strVaryingName; 85 strVaryingName.printf("TransformedCoords_%d", i); 86 GrGLSLVarying v(varyingType); 87 varyingHandler->addVarying(strVaryingName.c_str(), &v); 88 89 handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); 90 91 if (kFloat2_GrSLType == varyingType) { 92 vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, localCoords.c_str()); 93 } else { 94 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, localCoords.c_str()); 95 } 96 ++i; 97 } 98 } 99 100 void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix, 101 const GrGLSLProgramDataManager& pdman, 102 FPCoordTransformIter* transformIter) { 103 int i = 0; 104 while (const GrCoordTransform* coordTransform = transformIter->next()) { 105 const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform); 106 if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) { 107 pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m); 108 fInstalledTransforms[i].fCurrentValue = m; 109 } 110 ++i; 111 } 112 SkASSERT(i == fInstalledTransforms.count()); 113 } 114 115 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, 116 GrGPArgs* gpArgs, 117 const char* posName) { 118 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 119 vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 120 } 121 122 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, 123 GrGLSLUniformHandler* uniformHandler, 124 GrGPArgs* gpArgs, 125 const char* posName, 126 const SkMatrix& mat, 127 UniformHandle* viewMatrixUniform) { 128 if (mat.isIdentity()) { 129 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 130 vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 131 } else { 132 const char* viewMatrixName; 133 *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, 134 kFloat3x3_GrSLType, 135 "uViewM", 136 &viewMatrixName); 137 if (!mat.hasPerspective()) { 138 gpArgs->fPositionVar.set(kFloat2_GrSLType, "pos2"); 139 vertBuilder->codeAppendf("float2 %s = (%s * float3(%s, 1)).xy;", 140 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 141 } else { 142 gpArgs->fPositionVar.set(kFloat3_GrSLType, "pos3"); 143 vertBuilder->codeAppendf("float3 %s = %s * float3(%s, 1);", 144 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 145 } 146 } 147 } 148