• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
emitCode(EmitArgs & args)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 
emitTransforms(GrGLSLVertexBuilder * vb,GrGLSLVaryingHandler * varyingHandler,GrGLSLUniformHandler * uniformHandler,const GrShaderVar & posVar,const char * localCoords,const SkMatrix & localMatrix,const TransformsIn & tin,TransformsOut * tout)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 
emitTransforms(GrGLSLVertexBuilder * vb,GrGLSLVaryingHandler * varyingHandler,const char * localCoords,const TransformsIn & tin,TransformsOut * tout)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 
setupPosition(GrGLSLVertexBuilder * vertBuilder,GrGPArgs * gpArgs,const char * posName)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 
setupPosition(GrGLSLVertexBuilder * vertBuilder,GrGLSLUniformHandler * uniformHandler,GrGPArgs * gpArgs,const char * posName,const SkMatrix & mat,UniformHandle * viewMatrixUniform)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