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
16class GrPrimitiveProcessor;
17class GrGLSLFPFragmentBuilder;
18class GrGLSLGeometryBuilder;
19class GrGLSLGPBuilder;
20class GrGLSLVaryingHandler;
21class GrGLSLVertexBuilder;
22class GrShaderCaps;
23
24class GrGLSLPrimitiveProcessor {
25public:
26 using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
27 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
28 using CoordTransformRange = GrFragmentProcessor::PipelineCoordTransformRange;
29
30 struct TransformVar {
31 // The transform as a variable. This may be a kFloat3x3 matrix or a kFloat4 representing
32 // {scaleX, transX, scaleY, transY}. For explicitly sampled FPs this is visible in the
33 // FS. This is not available for NV_path_rendering with non-explicitly sampled FPs.
34 GrShaderVar fTransform;
35 // The transformed coordinate output by the vertex shader and consumed by the fragment
36 // shader. Only valid for non-explicitly sampled FPs.
37 GrShaderVar fVaryingPoint;
38 };
39
40
41 virtual ~GrGLSLPrimitiveProcessor() {}
42
43 /**
44 * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
45 * GrPipeline. It is also used by the primitive processor to specify the fragment shader
46 * variable that will hold the transformed coords for each GrCoordTransform. It is required that
47 * the primitive processor iterate over each coord transform and insert a shader var result for
48 * each. The GrGLSLFragmentProcessors will reference these variables in their fragment code.
49 */
50 class FPCoordTransformHandler : public SkNoncopyable {
51 public:
52 FPCoordTransformHandler(const GrPipeline&, SkTArray<TransformVar>*);
53 ~FPCoordTransformHandler() { SkASSERT(!fIter); }
54
55 operator bool() const { return (bool)fIter; }
56
57 // Gets the current coord transform and its owning GrFragmentProcessor.
58 std::pair<const GrCoordTransform&, const GrFragmentProcessor&> get() const;
59
60 FPCoordTransformHandler& operator++();
61
62 // 'args' are constructor params to GrShaderVar.
63 void specifyCoordsForCurrCoordTransform(GrShaderVar transformVar, GrShaderVar varyingVar) {
64 SkASSERT(!fAddedCoord);
65 fTransformedCoordVars->push_back({transformVar, varyingVar});
66 SkDEBUGCODE(fAddedCoord = true;)
67 }
68
69 void omitCoordsForCurrCoordTransform() {
70 SkASSERT(!fAddedCoord);
71 fTransformedCoordVars->push_back();
72 SkDEBUGCODE(fAddedCoord = true;)
73 }
74
75 private:
76 GrFragmentProcessor::CoordTransformIter fIter;
77 SkDEBUGCODE(bool fAddedCoord = false;)
78 SkTArray<TransformVar>* fTransformedCoordVars;
79 };
80
81 struct EmitArgs {
82 EmitArgs(GrGLSLVertexBuilder* vertBuilder,
83 GrGLSLGeometryBuilder* geomBuilder,
84 GrGLSLFPFragmentBuilder* fragBuilder,
85 GrGLSLVaryingHandler* varyingHandler,
86 GrGLSLUniformHandler* uniformHandler,
87 const GrShaderCaps* caps,
88 const GrPrimitiveProcessor& gp,
89 const char* outputColor,
90 const char* outputCoverage,
91 const char* rtAdjustName,
92 const SamplerHandle* texSamplers,
93 FPCoordTransformHandler* transformHandler)
94 : fVertBuilder(vertBuilder)
95 , fGeomBuilder(geomBuilder)
96 , fFragBuilder(fragBuilder)
97 , fVaryingHandler(varyingHandler)
98 , fUniformHandler(uniformHandler)
99 , fShaderCaps(caps)
100 , fGP(gp)
101 , fOutputColor(outputColor)
102 , fOutputCoverage(outputCoverage)
103 , fRTAdjustName(rtAdjustName)
104 , fTexSamplers(texSamplers)
105 , fFPCoordTransformHandler(transformHandler) {}
106 GrGLSLVertexBuilder* fVertBuilder;
107 GrGLSLGeometryBuilder* fGeomBuilder;
108 GrGLSLFPFragmentBuilder* fFragBuilder;
109 GrGLSLVaryingHandler* fVaryingHandler;
110 GrGLSLUniformHandler* fUniformHandler;
111 const GrShaderCaps* fShaderCaps;
112 const GrPrimitiveProcessor& fGP;
113 const char* fOutputColor;
114 const char* fOutputCoverage;
115 const char* fRTAdjustName;
116 const SamplerHandle* fTexSamplers;
117 FPCoordTransformHandler* fFPCoordTransformHandler;
118 };
119
120 /**
121 * This is similar to emitCode() in the base class, except it takes a full shader builder.
122 * This allows the effect subclass to emit vertex code.
123 */
124 virtual void emitCode(EmitArgs&) = 0;
125
126 /**
127 * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
128 * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
129 * uploads any uniform variables required by the shaders created in emitCode(). The
130 * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
131 * identical processor key as the GrPrimitiveProcessor that created this
132 * GrGLSLPrimitiveProcessor.
133 * The subclass should use the transform range to perform any setup required for the coord
134 * transforms of the FPs that are part of the same program, such as updating matrix uniforms.
135 * The range will iterate over the transforms in the same order as the TransformHandler passed
136 * to emitCode.
137 */
138 virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
139 const CoordTransformRange&) = 0;
140
141 static SkMatrix GetTransformMatrix(const GrCoordTransform&, const SkMatrix& preMatrix);
142
143protected:
144 void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
145 GrGLSLUniformHandler* uniformHandler,
146 const char* outputName,
147 UniformHandle* colorUniform);
148};
149
150#endif
151