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/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