blob: ee7cf88c125e38a7e26d4a18f40f83f9efe61861 [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;
wangyix6af0c932015-07-22 10:21:17 -070033
bsalomonb58a2b42016-09-26 06:55:02 -070034private:
bsalomona624bf32016-09-20 09:12:47 -070035 /**
bsalomonb58a2b42016-09-26 06:55:02 -070036 * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of
37 * generated variables where each generated variable corresponds to an element of an array on
38 * the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a
39 * variable holding transformed coords for each GrCoordTransform owned by the FP.
bsalomona624bf32016-09-20 09:12:47 -070040 */
Brian Salomone782f842018-07-31 13:53:11 -040041 template <typename T, int (GrFragmentProcessor::*COUNT)() const>
bsalomonb58a2b42016-09-26 06:55:02 -070042 class BuilderInputProvider {
bsalomona624bf32016-09-20 09:12:47 -070043 public:
bsalomonb58a2b42016-09-26 06:55:02 -070044 BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {}
bsalomona624bf32016-09-20 09:12:47 -070045
bsalomonb58a2b42016-09-26 06:55:02 -070046 const T& operator[] (int i) const {
47 SkASSERT(i >= 0 && i < (fFP->*COUNT)());
48 return fTs[i];
bsalomona624bf32016-09-20 09:12:47 -070049 }
50
Robert Phillips94ade752018-10-09 12:32:31 -040051 int count() const { return (fFP->*COUNT)(); }
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:
Brian Salomone782f842018-07-31 13:53:11 -040072 using TransformedCoordVars =
73 BuilderInputProvider<GrShaderVar, &GrFragmentProcessor::numCoordTransforms>;
74 using TextureSamplers =
75 BuilderInputProvider<SamplerHandle, &GrFragmentProcessor::numTextureSamplers>;
bsalomonb58a2b42016-09-26 06:55:02 -070076
wangyix6af0c932015-07-22 10:21:17 -070077 /** Called when the program stage should insert its code into the shaders. The code in each
78 shader will be in its own block ({}) and so locally scoped names will not collide across
79 stages.
80
bsalomon1a1aa932016-09-12 09:30:36 -070081 @param fragBuilder Interface used to emit code in the shaders.
82 @param fp The processor that generated this program stage.
83 @param key The key that was computed by GenKey() from the generating
84 GrProcessor.
Ethan Nicholasf7b88202017-09-18 14:10:39 -040085 @param outputColor A predefined half4 in the FS in which the stage should place its
bsalomon1a1aa932016-09-12 09:30:36 -070086 output color (or coverage).
Ethan Nicholasf7b88202017-09-18 14:10:39 -040087 @param inputColor A half4 that holds the input color to the stage in the FS. This may
Michael Ludwig231de032018-08-30 14:33:01 -040088 be nullptr in which case the fInputColor is set to "half4(1.0)"
89 (solid white) so this is guaranteed non-null.
90 TODO: Better system for communicating optimization info
bsalomon1a1aa932016-09-12 09:30:36 -070091 (e.g. input color is solid white, trans black, known to be opaque,
92 etc.) that allows the processor to communicate back similar known
93 info about its output.
94 @param transformedCoords Fragment shader variables containing the coords computed using
bsalomona624bf32016-09-20 09:12:47 -070095 each of the GrFragmentProcessor's GrCoordTransforms.
Brian Salomon0bbecb22016-11-17 11:38:22 -050096 @param texSamplers Contains one entry for each TextureSampler of the GrProcessor.
bsalomon1a1aa932016-09-12 09:30:36 -070097 These can be passed to the builder to emit texture reads in the
98 generated code.
bsalomon38ddbad2015-09-24 06:00:00 -070099 */
wangyix7c157a92015-07-22 15:08:53 -0700100 struct EmitArgs {
cdalton85285412016-02-18 12:37:07 -0800101 EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
egdaniel7ea439b2015-12-03 09:20:44 -0800102 GrGLSLUniformHandler* uniformHandler,
Brian Salomon94efbf52016-11-29 13:43:05 -0500103 const GrShaderCaps* caps,
wangyix7c157a92015-07-22 15:08:53 -0700104 const GrFragmentProcessor& fp,
105 const char* outputColor,
106 const char* inputColor,
bsalomona624bf32016-09-20 09:12:47 -0700107 const TransformedCoordVars& transformedCoordVars,
Brian Salomon662ea4b2018-07-12 14:53:49 -0400108 const TextureSamplers& textureSamplers)
Brian Salomone23bffd2017-06-02 11:01:10 -0400109 : fFragBuilder(fragBuilder)
110 , fUniformHandler(uniformHandler)
111 , fShaderCaps(caps)
112 , fFp(fp)
113 , fOutputColor(outputColor)
Michael Ludwig231de032018-08-30 14:33:01 -0400114 , fInputColor(inputColor ? inputColor : "half4(1.0)")
Brian Salomone23bffd2017-06-02 11:01:10 -0400115 , fTransformedCoords(transformedCoordVars)
Brian Salomon662ea4b2018-07-12 14:53:49 -0400116 , fTexSamplers(textureSamplers) {}
cdalton85285412016-02-18 12:37:07 -0800117 GrGLSLFPFragmentBuilder* fFragBuilder;
egdaniel7ea439b2015-12-03 09:20:44 -0800118 GrGLSLUniformHandler* fUniformHandler;
Brian Salomon1edc5b92016-11-29 13:43:46 -0500119 const GrShaderCaps* fShaderCaps;
wangyix7c157a92015-07-22 15:08:53 -0700120 const GrFragmentProcessor& fFp;
121 const char* fOutputColor;
122 const char* fInputColor;
bsalomona624bf32016-09-20 09:12:47 -0700123 const TransformedCoordVars& fTransformedCoords;
bsalomonb58a2b42016-09-26 06:55:02 -0700124 const TextureSamplers& fTexSamplers;
wangyix7c157a92015-07-22 15:08:53 -0700125 };
126
127 virtual void emitCode(EmitArgs&) = 0;
wangyix6af0c932015-07-22 10:21:17 -0700128
Michael Ludwigd3a357d2018-09-27 17:31:08 -0400129 // This does not recurse to any attached child processors. Recursing the entire processor tree
130 // is the responsibility of the caller.
egdaniel018fb622015-10-28 07:26:40 -0700131 void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
wangyix6af0c932015-07-22 10:21:17 -0700132
wangyixb1daa862015-08-18 11:29:31 -0700133 int numChildProcessors() const { return fChildProcessors.count(); }
134
bsalomonb58a2b42016-09-26 06:55:02 -0700135 GrGLSLFragmentProcessor* childProcessor(int index) {
wangyixb1daa862015-08-18 11:29:31 -0700136 return fChildProcessors[index];
137 }
138
Michael Ludwig231de032018-08-30 14:33:01 -0400139 // Emit the child with the default input color (solid white)
Ethan Nicholas2983f402017-05-08 09:36:08 -0400140 inline void emitChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs) {
Michael Ludwig231de032018-08-30 14:33:01 -0400141 this->emitChild(childIndex, nullptr, outputColor, parentArgs);
Ethan Nicholas2983f402017-05-08 09:36:08 -0400142 }
143
wangyix54a6b1a2015-09-08 08:41:51 -0700144 /** 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 -0700145 * emitChild will automatically extract the coords and samplers of that child and pass them
146 * on to the child's emitCode(). Also, any uniforms or functions emitted by the child will
147 * have their names mangled to prevent redefinitions. The output color name is also mangled
148 * therefore in an in/out param. It will be declared in mangled form by emitChild(). It is
149 * legal to pass nullptr as inputColor, since all fragment processors are required to work
150 * without an input color.
wangyix54a6b1a2015-09-08 08:41:51 -0700151 */
bsalomon38ddbad2015-09-24 06:00:00 -0700152 void emitChild(int childIndex, const char* inputColor, SkString* outputColor,
153 EmitArgs& parentArgs);
154
Michael Ludwig231de032018-08-30 14:33:01 -0400155 // Use the parent's output color to hold child's output, and use the
156 // default input color of solid white
Ethan Nicholas2983f402017-05-08 09:36:08 -0400157 inline void emitChild(int childIndex, EmitArgs& args) {
Michael Ludwig231de032018-08-30 14:33:01 -0400158 // null pointer cast required to disambiguate the function call
159 this->emitChild(childIndex, (const char*) nullptr, args);
Ethan Nicholas2983f402017-05-08 09:36:08 -0400160 }
161
bsalomon38ddbad2015-09-24 06:00:00 -0700162 /** Variation that uses the parent's output color variable to hold the child's output.*/
163 void emitChild(int childIndex, const char* inputColor, EmitArgs& parentArgs);
wangyix2a378432015-08-18 12:00:12 -0700164
bsalomonb58a2b42016-09-26 06:55:02 -0700165 /**
166 * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
167 * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter
168 */
169 class Iter : public SkNoncopyable {
170 public:
171 explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
Brian Salomon4d3f5172018-06-07 14:42:52 -0400172 explicit Iter(std::unique_ptr<GrGLSLFragmentProcessor> fps[], int cnt) {
bsalomonb58a2b42016-09-26 06:55:02 -0700173 for (int i = cnt - 1; i >= 0; --i) {
Brian Salomon4d3f5172018-06-07 14:42:52 -0400174 fFPStack.push_back(fps[i].get());
bsalomonb58a2b42016-09-26 06:55:02 -0700175 }
176 }
177 GrGLSLFragmentProcessor* next();
178
179 private:
180 SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
181 };
182
wangyixb1daa862015-08-18 11:29:31 -0700183protected:
egdaniel64c47282015-11-13 06:54:19 -0800184 /** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
wangyixb1daa862015-08-18 11:29:31 -0700185 the same stage key; this function reads data from a GrFragmentProcessor and uploads any
186 uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
egdaniel64c47282015-11-13 06:54:19 -0800187 parameter is guaranteed to be of the same type that created this GrGLSLFragmentProcessor and
188 to have an identical processor key as the one that created this GrGLSLFragmentProcessor. */
Brian Salomonab015ef2017-04-04 10:15:51 -0400189 virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
wangyixb1daa862015-08-18 11:29:31 -0700190
wangyix6af0c932015-07-22 10:21:17 -0700191private:
bsalomon38ddbad2015-09-24 06:00:00 -0700192 void internalEmitChild(int, const char*, const char*, EmitArgs&);
193
egdaniel64c47282015-11-13 06:54:19 -0800194 SkTArray<GrGLSLFragmentProcessor*, true> fChildProcessors;
wangyixb1daa862015-08-18 11:29:31 -0700195
196 friend class GrFragmentProcessor;
wangyix6af0c932015-07-22 10:21:17 -0700197};
198
199#endif