Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright 2013 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 #ifndef GrGLSLGeometryProcessor_DEFINED
      9 #define GrGLSLGeometryProcessor_DEFINED
     10 
     11 #include "GrGLSLPrimitiveProcessor.h"
     12 
     13 class GrGLSLGPBuilder;
     14 
     15 /**
     16  * If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit
     17  * from this class. Since paths don't have vertices, this class is only meant to be used internally
     18  * by skia, for special cases.
     19  */
     20 class GrGLSLGeometryProcessor : public GrGLSLPrimitiveProcessor {
     21 public:
     22     /* Any general emit code goes in the base class emitCode.  Subclasses override onEmitCode */
     23     void emitCode(EmitArgs&) override;
     24 
     25     // By default we use the identity matrix
     26     void setTransformData(const GrPrimitiveProcessor&,
     27                           const GrGLSLProgramDataManager& pdman,
     28                           int index,
     29                           const SkTArray<const GrCoordTransform*, true>& transforms) override {
     30         this->setTransformDataMatrix(SkMatrix::I(), pdman, index, transforms);
     31     }
     32 
     33     // A helper which subclasses can use if needed
     34     template <class GeometryProcessor>
     35     void setTransformDataHelper(const GrPrimitiveProcessor& primProc,
     36                                 const GrGLSLProgramDataManager& pdman,
     37                                 int index,
     38                                 const SkTArray<const GrCoordTransform*, true>& transforms) {
     39         const GeometryProcessor& gp = primProc.cast<GeometryProcessor>();
     40         this->setTransformDataMatrix(gp.localMatrix(), pdman, index, transforms);
     41     }
     42 
     43 protected:
     44     // Emit a uniform matrix for each coord transform.
     45     void emitTransforms(GrGLSLVertexBuilder* vb,
     46                         GrGLSLVaryingHandler* varyingHandler,
     47                         GrGLSLUniformHandler* uniformHandler,
     48                         const GrShaderVar& posVar,
     49                         const char* localCoords,
     50                         const TransformsIn& tin,
     51                         TransformsOut* tout) {
     52         this->emitTransforms(vb, varyingHandler, uniformHandler,
     53                              posVar, localCoords, SkMatrix::I(), tin, tout);
     54     }
     55 
     56     // Emit pre-transformed coords as a vertex attribute per coord-transform.
     57     void emitTransforms(GrGLSLVertexBuilder*,
     58                         GrGLSLVaryingHandler*,
     59                         GrGLSLUniformHandler*,
     60                         const GrShaderVar& posVar,
     61                         const char* localCoords,
     62                         const SkMatrix& localMatrix,
     63                         const TransformsIn&,
     64                         TransformsOut*);
     65 
     66     // caller has emitted transforms via attributes
     67     void emitTransforms(GrGLSLVertexBuilder*,
     68                         GrGLSLVaryingHandler*,
     69                         const char* localCoords,
     70                         const TransformsIn& tin,
     71                         TransformsOut* tout);
     72 
     73     struct GrGPArgs {
     74         // The variable used by a GP to store its position. It can be
     75         // either a vec2 or a vec3 depending on the presence of perspective.
     76         GrShaderVar fPositionVar;
     77     };
     78 
     79     // Create the correct type of position variable given the CTM
     80     void setupPosition(GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
     81     void setupPosition(GrGLSLVertexBuilder*,
     82                        GrGLSLUniformHandler* uniformHandler,
     83                        GrGPArgs*,
     84                        const char* posName,
     85                        const SkMatrix& mat,
     86                        UniformHandle* viewMatrixUniform);
     87 
     88     static uint32_t ComputePosKey(const SkMatrix& mat) {
     89         if (mat.isIdentity()) {
     90             return 0x0;
     91         } else if (!mat.hasPerspective()) {
     92             return 0x01;
     93         } else {
     94             return 0x02;
     95         }
     96     }
     97 
     98 private:
     99     void setTransformDataMatrix(const SkMatrix& localMatrix,
    100                                 const GrGLSLProgramDataManager& pdman,
    101                                 int index,
    102                                 const SkTArray<const GrCoordTransform*, true>& transforms) {
    103         SkSTArray<2, Transform, true>& procTransforms = fInstalledTransforms[index];
    104         int numTransforms = transforms.count();
    105         for (int t = 0; t < numTransforms; ++t) {
    106             SkASSERT(procTransforms[t].fHandle.isValid());
    107             const SkMatrix& transform = GetTransformMatrix(localMatrix, *transforms[t]);
    108             if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) {
    109                 pdman.setSkMatrix(procTransforms[t].fHandle.toIndex(), transform);
    110                 procTransforms[t].fCurrentValue = transform;
    111             }
    112         }
    113     }
    114 
    115     virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
    116 
    117     typedef GrGLSLPrimitiveProcessor INHERITED;
    118 };
    119 
    120 #endif
    121