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 GrGLGeometryProcessor_DEFINED
9 #define GrGLGeometryProcessor_DEFINED
10 
11 #include "GrGLPrimitiveProcessor.h"
12 
13 class GrGLGPBuilder;
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 GrGLGeometryProcessor : public GrGLPrimitiveProcessor {
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
setTransformData(const GrPrimitiveProcessor &,const GrGLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)26     virtual void setTransformData(const GrPrimitiveProcessor&,
27                                   const GrGLProgramDataManager& pdman,
28                                   int index,
29                                   const SkTArray<const GrCoordTransform*, true>& transforms) {
30         this->setTransformDataMatrix(SkMatrix::I(), pdman, index, transforms);
31     }
32 
33     // A helper which subclasses can use if needed
34     template <class GeometryProcessor>
setTransformDataHelper(const GrPrimitiveProcessor & primProc,const GrGLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)35     void setTransformDataHelper(const GrPrimitiveProcessor& primProc,
36                                 const GrGLProgramDataManager& 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     // A helper for subclasses which don't have an explicit local matrix
emitTransforms(GrGLGPBuilder * gp,const GrShaderVar & posVar,const char * localCoords,const TransformsIn & tin,TransformsOut * tout)45     void emitTransforms(GrGLGPBuilder* gp,
46                         const GrShaderVar& posVar,
47                         const char* localCoords,
48                         const TransformsIn& tin,
49                         TransformsOut* tout) {
50         this->emitTransforms(gp, posVar, localCoords, SkMatrix::I(), tin, tout);
51     }
52 
53     void emitTransforms(GrGLGPBuilder*,
54                         const GrShaderVar& posVar,
55                         const char* localCoords,
56                         const SkMatrix& localMatrix,
57                         const TransformsIn&,
58                         TransformsOut*);
59 
60     struct GrGPArgs {
61         // The variable used by a GP to store its position. It can be
62         // either a vec2 or a vec3 depending on the presence of perspective.
63         GrShaderVar fPositionVar;
64     };
65 
66     // Create the correct type of position variable given the CTM
67     void setupPosition(GrGLGPBuilder* pb,
68                        GrGPArgs* gpArgs,
69                        const char* posName,
70                        const SkMatrix& mat = SkMatrix::I());
71 
ComputePosKey(const SkMatrix & mat)72     static uint32_t ComputePosKey(const SkMatrix& mat) {
73         if (mat.isIdentity()) {
74             return 0x0;
75         } else if (!mat.hasPerspective()) {
76             return 0x01;
77         } else {
78             return 0x02;
79         }
80     }
81 
82 private:
setTransformDataMatrix(const SkMatrix & localMatrix,const GrGLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)83     void setTransformDataMatrix(const SkMatrix& localMatrix,
84                                 const GrGLProgramDataManager& pdman,
85                                 int index,
86                                 const SkTArray<const GrCoordTransform*, true>& transforms) {
87         SkSTArray<2, Transform, true>& procTransforms = fInstalledTransforms[index];
88         int numTransforms = transforms.count();
89         for (int t = 0; t < numTransforms; ++t) {
90             SkASSERT(procTransforms[t].fHandle.isValid());
91             const SkMatrix& transform = GetTransformMatrix(localMatrix, *transforms[t]);
92             if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) {
93                 pdman.setSkMatrix(procTransforms[t].fHandle.convertToUniformHandle(), transform);
94                 procTransforms[t].fCurrentValue = transform;
95             }
96         }
97     }
98 
99     virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
100 
101     typedef GrGLPrimitiveProcessor INHERITED;
102 };
103 
104 #endif
105