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