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 setTransformData(const GrPrimitiveProcessor &,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)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> setTransformDataHelper(const GrPrimitiveProcessor & primProc,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)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. emitTransforms(GrGLSLVertexBuilder * vb,GrGLSLVaryingHandler * varyingHandler,GrGLSLUniformHandler * uniformHandler,const GrShaderVar & posVar,const char * localCoords,const TransformsIn & tin,TransformsOut * tout)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 ComputePosKey(const SkMatrix & mat)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: setTransformDataMatrix(const SkMatrix & localMatrix,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)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