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
29 virtual ~GrGLSLPrimitiveProcessor() {}
30
31 /**
32 * This class provides access to each GrFragmentProcessor in a GrPipeline that requires varying
33 * local coords to be produced by the primitive processor. It is also used by the primitive
34 * processor to specify the fragment shader variable that will hold the transformed coords for
35 * each of those GrFragmentProcessors. It is required that the primitive processor iterate over
36 * each fragment processor and insert a shader var result for each. The GrGLSLFragmentProcessors
37 * will reference these variables in their fragment code.
38 */
39 class FPCoordTransformHandler : public SkNoncopyable {
40 public:
41 FPCoordTransformHandler(const GrPipeline&, SkTArray<GrShaderVar>*);
42 ~FPCoordTransformHandler() { SkASSERT(!fIter); }
43
44 operator bool() const { return (bool)fIter; }
45
46 // Gets the current GrFragmentProcessor
47 const GrFragmentProcessor& get() const;
48
49 FPCoordTransformHandler& operator++();
50
51 void specifyCoordsForCurrCoordTransform(GrShaderVar varyingVar) {
52 SkASSERT(!fAddedCoord);
53 fTransformedCoordVars->push_back(varyingVar);
54 SkDEBUGCODE(fAddedCoord = true;)
55 }
56
57 private:
58 GrFragmentProcessor::CIter fIter;
59 SkDEBUGCODE(bool fAddedCoord = false;)
60 SkTArray<GrShaderVar>* fTransformedCoordVars;
61 };
62
63 struct EmitArgs {
64 EmitArgs(GrGLSLVertexBuilder* vertBuilder,
65 GrGLSLGeometryBuilder* geomBuilder,
66 GrGLSLFPFragmentBuilder* fragBuilder,
67 GrGLSLVaryingHandler* varyingHandler,
68 GrGLSLUniformHandler* uniformHandler,
69 const GrShaderCaps* caps,
70 const GrPrimitiveProcessor& gp,
71 const char* outputColor,
72 const char* outputCoverage,
73 const char* rtAdjustName,
74 const SamplerHandle* texSamplers,
75 FPCoordTransformHandler* transformHandler)
76 : fVertBuilder(vertBuilder)
77 , fGeomBuilder(geomBuilder)
78 , fFragBuilder(fragBuilder)
79 , fVaryingHandler(varyingHandler)
80 , fUniformHandler(uniformHandler)
81 , fShaderCaps(caps)
82 , fGP(gp)
83 , fOutputColor(outputColor)
84 , fOutputCoverage(outputCoverage)
85 , fRTAdjustName(rtAdjustName)
86 , fTexSamplers(texSamplers)
87 , fFPCoordTransformHandler(transformHandler) {}
88 GrGLSLVertexBuilder* fVertBuilder;
89 GrGLSLGeometryBuilder* fGeomBuilder;
90 GrGLSLFPFragmentBuilder* fFragBuilder;
91 GrGLSLVaryingHandler* fVaryingHandler;
92 GrGLSLUniformHandler* fUniformHandler;
93 const GrShaderCaps* fShaderCaps;
94 const GrPrimitiveProcessor& fGP;
95 const char* fOutputColor;
96 const char* fOutputCoverage;
97 const char* fRTAdjustName;
98 const SamplerHandle* fTexSamplers;
99 FPCoordTransformHandler* fFPCoordTransformHandler;
100 };
101
102 /**
103 * This is similar to emitCode() in the base class, except it takes a full shader builder.
104 * This allows the effect subclass to emit vertex code.
105 */
106 virtual void emitCode(EmitArgs&) = 0;
107
108 /**
109 * Called after all effect emitCode() functions, to give the processor a chance to write out
110 * additional transformation code now that all uniforms have been emitted.
111 */
112 virtual void emitTransformCode(GrGLSLVertexBuilder* vb,
113 GrGLSLUniformHandler* uniformHandler) {}
114 /**
115 * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
116 * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
117 * uploads any uniform variables required by the shaders created in emitCode(). The
118 * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
119 * identical processor key as the GrPrimitiveProcessor that created this
120 * GrGLSLPrimitiveProcessor.
121 * The subclass should use the transform range to perform any setup required for the coord
122 * transforms of the FPs that are part of the same program, such as updating matrix uniforms.
123 * The range will iterate over the transforms in the same order as the TransformHandler passed
124 * to emitCode.
125 */
126 virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) = 0;
127
128protected:
129 void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
130 GrGLSLUniformHandler* uniformHandler,
131 const char* outputName,
132 UniformHandle* colorUniform);
133};
134
135#endif
136