blob: c8154231b5d68c021f01cc08a90640e33277613e [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;
egdaniel7ea439b2015-12-03 09:20:44 -080018class GrGLSLCaps;
egdaniel8dcdedc2015-11-11 06:27:20 -080019class GrGLSLFPBuilder;
cdalton85285412016-02-18 12:37:07 -080020class GrGLSLFPFragmentBuilder;
wangyix6af0c932015-07-22 10:21:17 -070021
egdaniel64c47282015-11-13 06:54:19 -080022class GrGLSLFragmentProcessor {
wangyix6af0c932015-07-22 10:21:17 -070023public:
egdaniel64c47282015-11-13 06:54:19 -080024 GrGLSLFragmentProcessor() {}
wangyix6af0c932015-07-22 10:21:17 -070025
egdaniel64c47282015-11-13 06:54:19 -080026 virtual ~GrGLSLFragmentProcessor() {
wangyixb1daa862015-08-18 11:29:31 -070027 for (int i = 0; i < fChildProcessors.count(); ++i) {
halcanary385fe4d2015-08-26 13:07:48 -070028 delete fChildProcessors[i];
wangyixb1daa862015-08-18 11:29:31 -070029 }
30 }
wangyix6af0c932015-07-22 10:21:17 -070031
Brian Salomonf9f45122016-11-29 11:59:17 -050032 using UniformHandle = GrGLSLUniformHandler::UniformHandle;
33 using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
34 using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
wangyix6af0c932015-07-22 10:21:17 -070035
bsalomonb58a2b42016-09-26 06:55:02 -070036private:
bsalomona624bf32016-09-20 09:12:47 -070037 /**
bsalomonb58a2b42016-09-26 06:55:02 -070038 * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of
39 * generated variables where each generated variable corresponds to an element of an array on
40 * the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a
41 * variable holding transformed coords for each GrCoordTransform owned by the FP.
bsalomona624bf32016-09-20 09:12:47 -070042 */
bsalomonb58a2b42016-09-26 06:55:02 -070043 template <typename T, typename FPBASE, int (FPBASE::*COUNT)() const>
44 class BuilderInputProvider {
bsalomona624bf32016-09-20 09:12:47 -070045 public:
bsalomonb58a2b42016-09-26 06:55:02 -070046 BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {}
bsalomona624bf32016-09-20 09:12:47 -070047
bsalomonb58a2b42016-09-26 06:55:02 -070048 const T& operator[] (int i) const {
49 SkASSERT(i >= 0 && i < (fFP->*COUNT)());
50 return fTs[i];
bsalomona624bf32016-09-20 09:12:47 -070051 }
52
bsalomonb58a2b42016-09-26 06:55:02 -070053 BuilderInputProvider childInputs(int childIdx) const {
54 const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
55 GrFragmentProcessor::Iter iter(fFP);
56 int numToSkip = 0;
57 while (true) {
58 const GrFragmentProcessor* fp = iter.next();
59 if (fp == child) {
60 return BuilderInputProvider(child, fTs + numToSkip);
61 }
62 numToSkip += (fp->*COUNT)();
63 }
64 }
bsalomona624bf32016-09-20 09:12:47 -070065
66 private:
67 const GrFragmentProcessor* fFP;
bsalomonb58a2b42016-09-26 06:55:02 -070068 const T* fTs;
bsalomona624bf32016-09-20 09:12:47 -070069 };
70
bsalomonb58a2b42016-09-26 06:55:02 -070071public:
72 using TransformedCoordVars = BuilderInputProvider<GrShaderVar, GrFragmentProcessor,
73 &GrFragmentProcessor::numCoordTransforms>;
74 using TextureSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
Brian Salomon0bbecb22016-11-17 11:38:22 -050075 &GrProcessor::numTextureSamplers>;
bsalomonb58a2b42016-09-26 06:55:02 -070076 using BufferSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
77 &GrProcessor::numBuffers>;
Brian Salomonf9f45122016-11-29 11:59:17 -050078 using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrProcessor,
79 &GrProcessor::numImageStorages>;
bsalomonb58a2b42016-09-26 06:55:02 -070080
wangyix6af0c932015-07-22 10:21:17 -070081 /** Called when the program stage should insert its code into the shaders. The code in each
82 shader will be in its own block ({}) and so locally scoped names will not collide across
83 stages.
84
bsalomon1a1aa932016-09-12 09:30:36 -070085 @param fragBuilder Interface used to emit code in the shaders.
86 @param fp The processor that generated this program stage.
87 @param key The key that was computed by GenKey() from the generating
88 GrProcessor.
89 @param outputColor A predefined vec4 in the FS in which the stage should place its
90 output color (or coverage).
91 @param inputColor A vec4 that holds the input color to the stage in the FS. This may
92 be nullptr in which case the implied input is solid white (all
93 ones). TODO: Better system for communicating optimization info
94 (e.g. input color is solid white, trans black, known to be opaque,
95 etc.) that allows the processor to communicate back similar known
96 info about its output.
97 @param transformedCoords Fragment shader variables containing the coords computed using
bsalomona624bf32016-09-20 09:12:47 -070098 each of the GrFragmentProcessor's GrCoordTransforms.
Brian Salomon0bbecb22016-11-17 11:38:22 -050099 @param texSamplers Contains one entry for each TextureSampler of the GrProcessor.
bsalomon1a1aa932016-09-12 09:30:36 -0700100 These can be passed to the builder to emit texture reads in the
101 generated code.
Brian Salomonb014cca2016-11-18 11:39:15 -0500102 @param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These
103 can be passed to the builder to emit buffer reads in the generated
104 code.
Brian Salomonf9f45122016-11-29 11:59:17 -0500105 @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor.
106 These can be passed to the builder to emit image loads and stores
107 in the generated code.
108 @param gpImplementsDistanceVector
109 Does the GrGeometryProcessor implement the feature where it
110 provides a vector to the nearest edge of the shape being rendered.
bsalomon38ddbad2015-09-24 06:00:00 -0700111 */
wangyix7c157a92015-07-22 15:08:53 -0700112 struct EmitArgs {
cdalton85285412016-02-18 12:37:07 -0800113 EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800114 GrGLSLUniformHandler* uniformHandler,
egdaniela2e3e0f2015-11-19 07:23:45 -0800115 const GrGLSLCaps* caps,
wangyix7c157a92015-07-22 15:08:53 -0700116 const GrFragmentProcessor& fp,
117 const char* outputColor,
118 const char* inputColor,
bsalomona624bf32016-09-20 09:12:47 -0700119 const TransformedCoordVars& transformedCoordVars,
bsalomonb58a2b42016-09-26 06:55:02 -0700120 const TextureSamplers& textureSamplers,
121 const BufferSamplers& bufferSamplers,
Brian Salomonf9f45122016-11-29 11:59:17 -0500122 const ImageStorages& imageStorages,
dvonbeck9b03e7b2016-08-01 11:01:56 -0700123 bool gpImplementsDistanceVector)
egdaniel7ea439b2015-12-03 09:20:44 -0800124 : fFragBuilder(fragBuilder)
125 , fUniformHandler(uniformHandler)
egdaniela2e3e0f2015-11-19 07:23:45 -0800126 , fGLSLCaps(caps)
wangyix7c157a92015-07-22 15:08:53 -0700127 , fFp(fp)
128 , fOutputColor(outputColor)
129 , fInputColor(inputColor)
bsalomona624bf32016-09-20 09:12:47 -0700130 , fTransformedCoords(transformedCoordVars)
bsalomonb58a2b42016-09-26 06:55:02 -0700131 , fTexSamplers(textureSamplers)
dvonbeck9b03e7b2016-08-01 11:01:56 -0700132 , fBufferSamplers(bufferSamplers)
Brian Salomonf9f45122016-11-29 11:59:17 -0500133 , fImageStorages(imageStorages)
bsalomon1a1aa932016-09-12 09:30:36 -0700134 , fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
cdalton85285412016-02-18 12:37:07 -0800135 GrGLSLFPFragmentBuilder* fFragBuilder;
egdaniel7ea439b2015-12-03 09:20:44 -0800136 GrGLSLUniformHandler* fUniformHandler;
egdaniela2e3e0f2015-11-19 07:23:45 -0800137 const GrGLSLCaps* fGLSLCaps;
wangyix7c157a92015-07-22 15:08:53 -0700138 const GrFragmentProcessor& fFp;
139 const char* fOutputColor;
140 const char* fInputColor;
bsalomona624bf32016-09-20 09:12:47 -0700141 const TransformedCoordVars& fTransformedCoords;
bsalomonb58a2b42016-09-26 06:55:02 -0700142 const TextureSamplers& fTexSamplers;
143 const BufferSamplers& fBufferSamplers;
Brian Salomonf9f45122016-11-29 11:59:17 -0500144 const ImageStorages& fImageStorages;
dvonbeck9b03e7b2016-08-01 11:01:56 -0700145 bool fGpImplementsDistanceVector;
wangyix7c157a92015-07-22 15:08:53 -0700146 };
147
148 virtual void emitCode(EmitArgs&) = 0;
wangyix6af0c932015-07-22 10:21:17 -0700149
egdaniel018fb622015-10-28 07:26:40 -0700150 void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
wangyix6af0c932015-07-22 10:21:17 -0700151
152 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {}
153
wangyixb1daa862015-08-18 11:29:31 -0700154 int numChildProcessors() const { return fChildProcessors.count(); }
155
bsalomonb58a2b42016-09-26 06:55:02 -0700156 GrGLSLFragmentProcessor* childProcessor(int index) {
wangyixb1daa862015-08-18 11:29:31 -0700157 return fChildProcessors[index];
158 }
159
wangyix54a6b1a2015-09-08 08:41:51 -0700160 /** 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 -0700161 * emitChild will automatically extract the coords and samplers of that child and pass them
162 * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will
163 * have their names mangled to prevent redefinitions. The output color name is also mangled
164 * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is
165 * legal to pass nullptr as inputColor, since all fragment processors are required to work
166 * without an input color.
wangyix54a6b1a2015-09-08 08:41:51 -0700167 */
bsalomon38ddbad2015-09-24 06:00:00 -0700168 void emitChild(int childIndex, const char* inputColor, SkString* outputColor,
169 EmitArgs& parentArgs);
170
171 /** Variation that uses the parent's output color variable to hold the child's output.*/
172 void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
wangyix2a378432015-08-18 12:00:12 -0700173
bsalomonb58a2b42016-09-26 06:55:02 -0700174 /**
175 * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
176 * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter
177 */
178 class Iter : public SkNoncopyable {
179 public:
180 explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
181 explicit Iter(GrGLSLFragmentProcessor* fps[], int cnt) {
182 for (int i = cnt - 1; i >= 0; --i) {
183 fFPStack.push_back(fps[i]);
184 }
185 }
186 GrGLSLFragmentProcessor* next();
187
188 private:
189 SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
190 };
191
wangyixb1daa862015-08-18 11:29:31 -0700192protected:
egdaniel64c47282015-11-13 06:54:19 -0800193 /** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
wangyixb1daa862015-08-18 11:29:31 -0700194 the same stage key; this function reads data from a GrFragmentProcessor and uploads any
195 uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
egdaniel64c47282015-11-13 06:54:19 -0800196 parameter is guaranteed to be of the same type that created this GrGLSLFragmentProcessor and
197 to have an identical processor key as the one that created this GrGLSLFragmentProcessor. */
wangyixb1daa862015-08-18 11:29:31 -0700198 // TODO update this to pass in GrFragmentProcessor
egdaniel018fb622015-10-28 07:26:40 -0700199 virtual void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) {}
wangyixb1daa862015-08-18 11:29:31 -0700200
wangyix6af0c932015-07-22 10:21:17 -0700201private:
bsalomon38ddbad2015-09-24 06:00:00 -0700202 void internalEmitChild(int, const char*, const char*, EmitArgs&);
203
egdaniel64c47282015-11-13 06:54:19 -0800204 SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors;
wangyixb1daa862015-08-18 11:29:31 -0700205
206 friend class GrFragmentProcessor;
wangyix6af0c932015-07-22 10:21:17 -0700207};
208
209#endif