blob: 7a8d51ca832f71cab6fa2ed1e8e23c2aa24de704 [file] [log] [blame]
wangyix6af0c932015-07-22 10:21:17 -07001/*
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
egdaniel64c47282015-11-13 06:54:19 -08008#ifndef GrGLSLFragmentProcessor_DEFINED
9#define GrGLSLFragmentProcessor_DEFINED
wangyix6af0c932015-07-22 10:21:17 -070010
cdalton3f6f76f2016-04-11 12:18:09 -070011#include "GrFragmentProcessor.h"
bsalomon1a1aa932016-09-12 09:30:36 -070012#include "GrShaderVar.h"
egdaniel018fb622015-10-28 07:26:40 -070013#include "glsl/GrGLSLProgramDataManager.h"
Brian Salomonf9f45122016-11-29 11:59:17 -050014#include "glsl/GrGLSLUniformHandler.h"
wangyix6af0c932015-07-22 10:21:17 -070015
egdaniel7dc4bd02015-10-29 07:57:01 -070016class GrProcessor;
17class GrProcessorKeyBuilder;
egdaniel8dcdedc2015-11-11 06:27:20 -080018class GrGLSLFPBuilder;
cdalton85285412016-02-18 12:37:07 -080019class GrGLSLFPFragmentBuilder;
wangyix6af0c932015-07-22 10:21:17 -070020
egdaniel64c47282015-11-13 06:54:19 -080021class GrGLSLFragmentProcessor {
wangyix6af0c932015-07-22 10:21:17 -070022public:
egdaniel64c47282015-11-13 06:54:19 -080023 GrGLSLFragmentProcessor() {}
wangyix6af0c932015-07-22 10:21:17 -070024
egdaniel64c47282015-11-13 06:54:19 -080025 virtual ~GrGLSLFragmentProcessor() {
wangyixb1daa862015-08-18 11:29:31 -070026 for (int i = 0; i < fChildProcessors.count(); ++i) {
halcanary385fe4d2015-08-26 13:07:48 -070027 delete fChildProcessors[i];
wangyixb1daa862015-08-18 11:29:31 -070028 }
29 }
wangyix6af0c932015-07-22 10:21:17 -070030
Brian Salomonf9f45122016-11-29 11:59:17 -050031 using UniformHandle = GrGLSLUniformHandler::UniformHandle;
32 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
33 using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
wangyix6af0c932015-07-22 10:21:17 -070034
bsalomonb58a2b42016-09-26 06:55:02 -070035private:
bsalomona624bf32016-09-20 09:12:47 -070036 /**
bsalomonb58a2b42016-09-26 06:55:02 -070037 * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of
38 * generated variables where each generated variable corresponds to an element of an array on
39 * the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a
40 * variable holding transformed coords for each GrCoordTransform owned by the FP.
bsalomona624bf32016-09-20 09:12:47 -070041 */
bsalomonb58a2b42016-09-26 06:55:02 -070042 template <typename T, typename FPBASE, int (FPBASE::*COUNT)() const>
43 class BuilderInputProvider {
bsalomona624bf32016-09-20 09:12:47 -070044 public:
bsalomonb58a2b42016-09-26 06:55:02 -070045 BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {}
bsalomona624bf32016-09-20 09:12:47 -070046
bsalomonb58a2b42016-09-26 06:55:02 -070047 const T& operator[] (int i) const {
48 SkASSERT(i >= 0 && i < (fFP->*COUNT)());
49 return fTs[i];
bsalomona624bf32016-09-20 09:12:47 -070050 }
51
bsalomonb58a2b42016-09-26 06:55:02 -070052 BuilderInputProvider childInputs(int childIdx) const {
53 const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
54 GrFragmentProcessor::Iter iter(fFP);
55 int numToSkip = 0;
56 while (true) {
57 const GrFragmentProcessor* fp = iter.next();
58 if (fp == child) {
59 return BuilderInputProvider(child, fTs + numToSkip);
60 }
61 numToSkip += (fp->*COUNT)();
62 }
63 }
bsalomona624bf32016-09-20 09:12:47 -070064
65 private:
66 const GrFragmentProcessor* fFP;
bsalomonb58a2b42016-09-26 06:55:02 -070067 const T* fTs;
bsalomona624bf32016-09-20 09:12:47 -070068 };
69
bsalomonb58a2b42016-09-26 06:55:02 -070070public:
71 using TransformedCoordVars = BuilderInputProvider<GrShaderVar, GrFragmentProcessor,
72 &GrFragmentProcessor::numCoordTransforms>;
73 using TextureSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
Brian Salomon0bbecb22016-11-17 11:38:22 -050074 &GrProcessor::numTextureSamplers>;
bsalomonb58a2b42016-09-26 06:55:02 -070075 using BufferSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
76 &GrProcessor::numBuffers>;
Brian Salomonf9f45122016-11-29 11:59:17 -050077 using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrProcessor,
78 &GrProcessor::numImageStorages>;
bsalomonb58a2b42016-09-26 06:55:02 -070079
wangyix6af0c932015-07-22 10:21:17 -070080 /** Called when the program stage should insert its code into the shaders. The code in each
81 shader will be in its own block ({}) and so locally scoped names will not collide across
82 stages.
83
bsalomon1a1aa932016-09-12 09:30:36 -070084 @param fragBuilder Interface used to emit code in the shaders.
85 @param fp The processor that generated this program stage.
86 @param key The key that was computed by GenKey() from the generating
87 GrProcessor.
88 @param outputColor A predefined vec4 in the FS in which the stage should place its
89 output color (or coverage).
90 @param inputColor A vec4 that holds the input color to the stage in the FS. This may
91 be nullptr in which case the implied input is solid white (all
92 ones). TODO: Better system for communicating optimization info
93 (e.g. input color is solid white, trans black, known to be opaque,
94 etc.) that allows the processor to communicate back similar known
95 info about its output.
96 @param transformedCoords Fragment shader variables containing the coords computed using
bsalomona624bf32016-09-20 09:12:47 -070097 each of the GrFragmentProcessor's GrCoordTransforms.
Brian Salomon0bbecb22016-11-17 11:38:22 -050098 @param texSamplers Contains one entry for each TextureSampler of the GrProcessor.
bsalomon1a1aa932016-09-12 09:30:36 -070099 These can be passed to the builder to emit texture reads in the
100 generated code.
Brian Salomonb014cca2016-11-18 11:39:15 -0500101 @param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These
102 can be passed to the builder to emit buffer reads in the generated
103 code.
Brian Salomonf9f45122016-11-29 11:59:17 -0500104 @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor.
105 These can be passed to the builder to emit image loads and stores
106 in the generated code.
107 @param gpImplementsDistanceVector
108 Does the GrGeometryProcessor implement the feature where it
109 provides a vector to the nearest edge of the shape being rendered.
bsalomon38ddbad2015-09-24 06:00:00 -0700110 */
wangyix7c157a92015-07-22 15:08:53 -0700111 struct EmitArgs {
cdalton85285412016-02-18 12:37:07 -0800112 EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800113 GrGLSLUniformHandler* uniformHandler,
Brian Salomon94efbf52016-11-29 13:43:05 -0500114 const GrShaderCaps* caps,
wangyix7c157a92015-07-22 15:08:53 -0700115 const GrFragmentProcessor& fp,
116 const char* outputColor,
117 const char* inputColor,
bsalomona624bf32016-09-20 09:12:47 -0700118 const TransformedCoordVars& transformedCoordVars,
bsalomonb58a2b42016-09-26 06:55:02 -0700119 const TextureSamplers& textureSamplers,
120 const BufferSamplers& bufferSamplers,
Brian Salomonf9f45122016-11-29 11:59:17 -0500121 const ImageStorages& imageStorages,
dvonbeck9b03e7b2016-08-01 11:01:56 -0700122 bool gpImplementsDistanceVector)
egdaniel7ea439b2015-12-03 09:20:44 -0800123 : fFragBuilder(fragBuilder)
124 , fUniformHandler(uniformHandler)
Brian Salomon1edc5b92016-11-29 13:43:46 -0500125 , fShaderCaps(caps)
wangyix7c157a92015-07-22 15:08:53 -0700126 , fFp(fp)
127 , fOutputColor(outputColor)
128 , fInputColor(inputColor)
bsalomona624bf32016-09-20 09:12:47 -0700129 , fTransformedCoords(transformedCoordVars)
bsalomonb58a2b42016-09-26 06:55:02 -0700130 , fTexSamplers(textureSamplers)
dvonbeck9b03e7b2016-08-01 11:01:56 -0700131 , fBufferSamplers(bufferSamplers)
Brian Salomonf9f45122016-11-29 11:59:17 -0500132 , fImageStorages(imageStorages)
bsalomon1a1aa932016-09-12 09:30:36 -0700133 , fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
cdalton85285412016-02-18 12:37:07 -0800134 GrGLSLFPFragmentBuilder* fFragBuilder;
egdaniel7ea439b2015-12-03 09:20:44 -0800135 GrGLSLUniformHandler* fUniformHandler;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500136 const GrShaderCaps* fShaderCaps;
wangyix7c157a92015-07-22 15:08:53 -0700137 const GrFragmentProcessor& fFp;
138 const char* fOutputColor;
139 const char* fInputColor;
bsalomona624bf32016-09-20 09:12:47 -0700140 const TransformedCoordVars& fTransformedCoords;
bsalomonb58a2b42016-09-26 06:55:02 -0700141 const TextureSamplers& fTexSamplers;
142 const BufferSamplers& fBufferSamplers;
Brian Salomonf9f45122016-11-29 11:59:17 -0500143 const ImageStorages& fImageStorages;
dvonbeck9b03e7b2016-08-01 11:01:56 -0700144 bool fGpImplementsDistanceVector;
wangyix7c157a92015-07-22 15:08:53 -0700145 };
146
147 virtual void emitCode(EmitArgs&) = 0;
wangyix6af0c932015-07-22 10:21:17 -0700148
egdaniel018fb622015-10-28 07:26:40 -0700149 void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
wangyix6af0c932015-07-22 10:21:17 -0700150
Brian Salomon94efbf52016-11-29 13:43:05 -0500151 static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {}
wangyix6af0c932015-07-22 10:21:17 -0700152
wangyixb1daa862015-08-18 11:29:31 -0700153 int numChildProcessors() const { return fChildProcessors.count(); }
154
bsalomonb58a2b42016-09-26 06:55:02 -0700155 GrGLSLFragmentProcessor* childProcessor(int index) {
wangyixb1daa862015-08-18 11:29:31 -0700156 return fChildProcessors[index];
157 }
158
wangyix54a6b1a2015-09-08 08:41:51 -0700159 /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and
bsalomon38ddbad2015-09-24 06:00:00 -0700160 * emitChild will automatically extract the coords and samplers of that child and pass them
161 * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will
162 * have their names mangled to prevent redefinitions. The output color name is also mangled
163 * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is
164 * legal to pass nullptr as inputColor, since all fragment processors are required to work
165 * without an input color.
wangyix54a6b1a2015-09-08 08:41:51 -0700166 */
bsalomon38ddbad2015-09-24 06:00:00 -0700167 void emitChild(int childIndex, const char* inputColor, SkString* outputColor,
168 EmitArgs& parentArgs);
169
170 /** Variation that uses the parent's output color variable to hold the child's output.*/
171 void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
wangyix2a378432015-08-18 12:00:12 -0700172
bsalomonb58a2b42016-09-26 06:55:02 -0700173 /**
174 * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
175 * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter
176 */
177 class Iter : public SkNoncopyable {
178 public:
179 explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
180 explicit Iter(GrGLSLFragmentProcessor* fps[], int cnt) {
181 for (int i = cnt - 1; i >= 0; --i) {
182 fFPStack.push_back(fps[i]);
183 }
184 }
185 GrGLSLFragmentProcessor* next();
186
187 private:
188 SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
189 };
190
wangyixb1daa862015-08-18 11:29:31 -0700191protected:
egdaniel64c47282015-11-13 06:54:19 -0800192 /** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
wangyixb1daa862015-08-18 11:29:31 -0700193 the same stage key; this function reads data from a GrFragmentProcessor and uploads any
194 uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
egdaniel64c47282015-11-13 06:54:19 -0800195 parameter is guaranteed to be of the same type that created this GrGLSLFragmentProcessor and
196 to have an identical processor key as the one that created this GrGLSLFragmentProcessor. */
wangyixb1daa862015-08-18 11:29:31 -0700197 // TODO update this to pass in GrFragmentProcessor
egdaniel018fb622015-10-28 07:26:40 -0700198 virtual void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) {}
wangyixb1daa862015-08-18 11:29:31 -0700199
wangyix6af0c932015-07-22 10:21:17 -0700200private:
bsalomon38ddbad2015-09-24 06:00:00 -0700201 void internalEmitChild(int, const char*, const char*, EmitArgs&);
202
egdaniel64c47282015-11-13 06:54:19 -0800203 SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors;
wangyixb1daa862015-08-18 11:29:31 -0700204
205 friend class GrFragmentProcessor;
wangyix6af0c932015-07-22 10:21:17 -0700206};
207
208#endif