Home | History | Annotate | Download | only in glsl
      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 
     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 
     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 
    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 
    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 
    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