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/GrGLSLVertexShaderBuilder.h" 15 16 void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { 17 GrGLSLVertexBuilder* vBuilder = args.fVertBuilder; 18 GrGPArgs gpArgs; 19 this->onEmitCode(args, &gpArgs); 20 vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar, args.fRTAdjustName); 21 if (kVec2f_GrSLType == gpArgs.fPositionVar.getType()) { 22 args.fVaryingHandler->setNoPerspective(); 23 } 24 } 25 26 void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, 27 GrGLSLVaryingHandler* varyingHandler, 28 GrGLSLUniformHandler* uniformHandler, 29 const GrShaderVar& posVar, 30 const char* localCoords, 31 const SkMatrix& localMatrix, 32 FPCoordTransformHandler* handler) { 33 int i = 0; 34 while (const GrCoordTransform* coordTransform = handler->nextCoordTransform()) { 35 SkString strUniName; 36 strUniName.printf("CoordTransformMatrix_%d", i); 37 GrSLType varyingType; 38 39 uint32_t type = coordTransform->getMatrix().getType(); 40 type |= localMatrix.getType(); 41 42 varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : 43 kVec2f_GrSLType; 44 // Coord transforms are always handled at high precision 45 const GrSLPrecision precision = kHigh_GrSLPrecision; 46 47 const char* uniName; 48 49 50 fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag, 51 kMat33f_GrSLType, 52 precision, 53 strUniName.c_str(), 54 &uniName).toIndex(); 55 SkString strVaryingName; 56 strVaryingName.printf("TransformedCoords_%d", i); 57 58 GrGLSLVertToFrag v(varyingType); 59 varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); 60 61 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); 62 handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); 63 64 if (kVec2f_GrSLType == varyingType) { 65 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); 66 } else { 67 vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords); 68 } 69 ++i; 70 } 71 } 72 73 void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix, 74 const GrGLSLProgramDataManager& pdman, 75 FPCoordTransformIter* transformIter) { 76 int i = 0; 77 while (const GrCoordTransform* coordTransform = transformIter->next()) { 78 const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform); 79 if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) { 80 pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m); 81 fInstalledTransforms[i].fCurrentValue = m; 82 } 83 ++i; 84 } 85 SkASSERT(i == fInstalledTransforms.count()); 86 } 87 88 void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder, 89 GrGPArgs* gpArgs, 90 const char* posName) { 91 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 92 vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 93 } 94 95 void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder, 96 GrGLSLUniformHandler* uniformHandler, 97 GrGPArgs* gpArgs, 98 const char* posName, 99 const SkMatrix& mat, 100 UniformHandle* viewMatrixUniform) { 101 if (mat.isIdentity()) { 102 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 103 vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); 104 } else { 105 const char* viewMatrixName; 106 *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, 107 kMat33f_GrSLType, kHigh_GrSLPrecision, 108 "uViewM", 109 &viewMatrixName); 110 if (!mat.hasPerspective()) { 111 gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); 112 vertBuilder->codeAppendf("vec2 %s = (%s * vec3(%s, 1)).xy;", 113 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 114 } else { 115 gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3"); 116 vertBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);", 117 gpArgs->fPositionVar.c_str(), viewMatrixName, posName); 118 } 119 } 120 } 121