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 GrGLSLPrimitiveProcessor_DEFINED 9 #define GrGLSLPrimitiveProcessor_DEFINED 10 11 #include "src/gpu/GrFragmentProcessor.h" 12 #include "src/gpu/GrPrimitiveProcessor.h" 13 #include "src/gpu/glsl/GrGLSLProgramDataManager.h" 14 #include "src/gpu/glsl/GrGLSLUniformHandler.h" 15 16 class GrPrimitiveProcessor; 17 class GrGLSLFPFragmentBuilder; 18 class GrGLSLGeometryBuilder; 19 class GrGLSLGPBuilder; 20 class GrGLSLVaryingHandler; 21 class GrGLSLVertexBuilder; 22 class GrShaderCaps; 23 24 class GrGLSLPrimitiveProcessor { 25 public: 26 using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter; 27 ~GrGLSLPrimitiveProcessor()28 virtual ~GrGLSLPrimitiveProcessor() {} 29 30 using UniformHandle = GrGLSLProgramDataManager::UniformHandle; 31 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle; 32 33 /** 34 * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a 35 * GrPipeline. It is also used by the primitive processor to specify the fragment shader 36 * variable that will hold the transformed coords for each GrCoordTransform. It is required that 37 * the primitive processor iterate over each coord transform and insert a shader var result for 38 * each. The GrGLSLFragmentProcessors will reference these variables in their fragment code. 39 */ 40 class FPCoordTransformHandler : public SkNoncopyable { 41 public: FPCoordTransformHandler(const GrPipeline & pipeline,SkTArray<GrShaderVar> * transformedCoordVars)42 FPCoordTransformHandler(const GrPipeline& pipeline, 43 SkTArray<GrShaderVar>* transformedCoordVars) 44 : fIter(pipeline) 45 , fTransformedCoordVars(transformedCoordVars) {} 46 ~FPCoordTransformHandler()47 ~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());} 48 49 const GrCoordTransform* nextCoordTransform(); 50 51 // 'args' are constructor params to GrShaderVar. 52 template<typename... Args> specifyCoordsForCurrCoordTransform(Args &&...args)53 void specifyCoordsForCurrCoordTransform(Args&&... args) { 54 SkASSERT(!fAddedCoord); 55 fTransformedCoordVars->emplace_back(std::forward<Args>(args)...); 56 SkDEBUGCODE(fAddedCoord = true;) 57 } 58 59 private: 60 GrFragmentProcessor::CoordTransformIter fIter; 61 SkDEBUGCODE(bool fAddedCoord = false;) 62 SkDEBUGCODE(const GrCoordTransform* fCurr = nullptr;) 63 SkTArray<GrShaderVar>* fTransformedCoordVars; 64 }; 65 66 struct EmitArgs { EmitArgsEmitArgs67 EmitArgs(GrGLSLVertexBuilder* vertBuilder, 68 GrGLSLGeometryBuilder* geomBuilder, 69 GrGLSLFPFragmentBuilder* fragBuilder, 70 GrGLSLVaryingHandler* varyingHandler, 71 GrGLSLUniformHandler* uniformHandler, 72 const GrShaderCaps* caps, 73 const GrPrimitiveProcessor& gp, 74 const char* outputColor, 75 const char* outputCoverage, 76 const char* rtAdjustName, 77 const SamplerHandle* texSamplers, 78 FPCoordTransformHandler* transformHandler) 79 : fVertBuilder(vertBuilder) 80 , fGeomBuilder(geomBuilder) 81 , fFragBuilder(fragBuilder) 82 , fVaryingHandler(varyingHandler) 83 , fUniformHandler(uniformHandler) 84 , fShaderCaps(caps) 85 , fGP(gp) 86 , fOutputColor(outputColor) 87 , fOutputCoverage(outputCoverage) 88 , fRTAdjustName(rtAdjustName) 89 , fTexSamplers(texSamplers) 90 , fFPCoordTransformHandler(transformHandler) {} 91 GrGLSLVertexBuilder* fVertBuilder; 92 GrGLSLGeometryBuilder* fGeomBuilder; 93 GrGLSLFPFragmentBuilder* fFragBuilder; 94 GrGLSLVaryingHandler* fVaryingHandler; 95 GrGLSLUniformHandler* fUniformHandler; 96 const GrShaderCaps* fShaderCaps; 97 const GrPrimitiveProcessor& fGP; 98 const char* fOutputColor; 99 const char* fOutputCoverage; 100 const char* fRTAdjustName; 101 const SamplerHandle* fTexSamplers; 102 FPCoordTransformHandler* fFPCoordTransformHandler; 103 }; 104 105 /** 106 * This is similar to emitCode() in the base class, except it takes a full shader builder. 107 * This allows the effect subclass to emit vertex code. 108 */ 109 virtual void emitCode(EmitArgs&) = 0; 110 111 /** 112 * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that 113 * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and 114 * uploads any uniform variables required by the shaders created in emitCode(). The 115 * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an 116 * identical processor key as the GrPrimitiveProcessor that created this 117 * GrGLSLPrimitiveProcessor. 118 * The subclass may use the transform iterator to perform any setup required for the particular 119 * set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over 120 * the transforms in the same order as the TransformHandler passed to emitCode. 121 */ 122 virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&, 123 FPCoordTransformIter&&) = 0; 124 125 static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&); 126 127 protected: 128 void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder, 129 GrGLSLUniformHandler* uniformHandler, 130 const char* outputName, 131 UniformHandle* colorUniform); 132 }; 133 134 #endif 135