blob: 4cfe0286d8f0829f7f57b7b68bdb972e97a46be2 [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
2 * Copyright 2014 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 GrGLProgramBuilder_DEFINED
9#define GrGLProgramBuilder_DEFINED
10
joshualitt30ba4362014-08-21 20:18:45 -070011#include "GrGLFragmentShaderBuilder.h"
12#include "GrGLGeometryShaderBuilder.h"
13#include "GrGLVertexShaderBuilder.h"
joshualitt47bb3822014-10-07 16:43:25 -070014#include "../GrGLProgramDataManager.h"
15#include "../GrGLUniformHandle.h"
joshualitt8072caa2015-02-12 14:20:52 -080016#include "../GrGLPrimitiveProcessor.h"
egdanielc2304142014-12-11 13:15:13 -080017#include "../GrGLXferProcessor.h"
bsalomonae59b772014-11-19 08:23:49 -080018#include "../../GrPendingFragmentStage.h"
egdaniel8dd688b2015-01-22 10:16:09 -080019#include "../../GrPipeline.h"
joshualitt89c7a2e2014-10-10 14:11:59 -070020
joshualitt47bb3822014-10-07 16:43:25 -070021/*
22 * This is the base class for a series of interfaces. This base class *MUST* remain abstract with
23 * NO data members because it is used in multiple interface inheritance.
24 * Heirarchy:
25 * GrGLUniformBuilder
26 * / \
27 * GrGLFPBuilder GrGLGPBuilder
28 * \ /
29 * GrGLProgramBuilder(internal use only)
30 */
31class GrGLUniformBuilder {
joshualitt30ba4362014-08-21 20:18:45 -070032public:
33 enum ShaderVisibility {
bsalomon17168df2014-12-09 09:00:49 -080034 kVertex_Visibility = 1 << kVertex_GrShaderType,
35 kGeometry_Visibility = 1 << kGeometry_GrShaderType,
36 kFragment_Visibility = 1 << kFragment_GrShaderType,
joshualitt30ba4362014-08-21 20:18:45 -070037 };
38
joshualitt47bb3822014-10-07 16:43:25 -070039 virtual ~GrGLUniformBuilder() {}
40
joshualitt30ba4362014-08-21 20:18:45 -070041 typedef GrGLProgramDataManager::UniformHandle UniformHandle;
joshualitt47bb3822014-10-07 16:43:25 -070042
43 /** Add a uniform variable to the current program, that has visibility in one or more shaders.
44 visibility is a bitfield of ShaderVisibility values indicating from which shaders the
45 uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
46 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
47 it will refer to the final uniform name after return. Use the addUniformArray variant to add
48 an array of uniforms. */
bsalomon422f56f2014-12-09 10:18:12 -080049 UniformHandle addUniform(uint32_t visibility,
50 GrSLType type,
51 GrSLPrecision precision,
52 const char* name,
53 const char** outName = NULL) {
54 return this->addUniformArray(visibility, type, precision, name, 0, outName);
55 }
56
57 virtual UniformHandle addUniformArray(
58 uint32_t visibility,
59 GrSLType type,
60 GrSLPrecision precision,
61 const char* name,
62 int arrayCount,
63 const char** outName = NULL) = 0;
joshualitt47bb3822014-10-07 16:43:25 -070064
65 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const = 0;
66
67 /**
68 * Shortcut for getUniformVariable(u).c_str()
69 */
70 virtual const char* getUniformCStr(UniformHandle u) const = 0;
71
72 virtual const GrGLContextInfo& ctxInfo() const = 0;
73
bsalomon861e1032014-12-16 07:33:49 -080074 virtual GrGLGpu* gpu() const = 0;
joshualitt47bb3822014-10-07 16:43:25 -070075
76 /*
77 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
78 */
79};
80
joshualitt74077b92014-10-24 11:26:03 -070081// TODO move this into GrGLGPBuilder and move them both out of this file
82class GrGLVarying {
83public:
84 bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
85 kVertToGeo_Varying == fVarying; }
86 bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
87 kGeoToFrag_Varying == fVarying; }
88 const char* vsOut() const { return fVsOut; }
89 const char* gsIn() const { return fGsIn; }
90 const char* gsOut() const { return fGsOut; }
91 const char* fsIn() const { return fFsIn; }
joshualittabb52a12015-01-13 15:02:10 -080092 GrSLType type() const { return fType; }
joshualitt74077b92014-10-24 11:26:03 -070093
94protected:
95 enum Varying {
96 kVertToFrag_Varying,
97 kVertToGeo_Varying,
98 kGeoToFrag_Varying,
99 };
100
101 GrGLVarying(GrSLType type, Varying varying)
102 : fVarying(varying), fType(type), fVsOut(NULL), fGsIn(NULL), fGsOut(NULL),
103 fFsIn(NULL) {}
104
105 Varying fVarying;
106
107private:
108 GrSLType fType;
109 const char* fVsOut;
110 const char* fGsIn;
111 const char* fGsOut;
112 const char* fFsIn;
113
114 friend class GrGLVertexBuilder;
115 friend class GrGLGeometryBuilder;
egdanielc2304142014-12-11 13:15:13 -0800116 friend class GrGLXferBuilder;
joshualitt74077b92014-10-24 11:26:03 -0700117 friend class GrGLFragmentShaderBuilder;
118};
119
120struct GrGLVertToFrag : public GrGLVarying {
121 GrGLVertToFrag(GrSLType type)
122 : GrGLVarying(type, kVertToFrag_Varying) {}
123};
124
125struct GrGLVertToGeo : public GrGLVarying {
126 GrGLVertToGeo(GrSLType type)
127 : GrGLVarying(type, kVertToGeo_Varying) {}
128};
129
130struct GrGLGeoToFrag : public GrGLVarying {
131 GrGLGeoToFrag(GrSLType type)
132 : GrGLVarying(type, kGeoToFrag_Varying) {}
133};
134
joshualitt47bb3822014-10-07 16:43:25 -0700135/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
136class GrGLGPBuilder : public virtual GrGLUniformBuilder {
137public:
joshualitt2dd1ae02014-12-03 06:24:10 -0800138 /*
139 * addVarying allows fine grained control for setting up varyings between stages. If you just
140 * need to take an attribute and pass it through to an output value in a fragment shader, use
141 * addPassThroughAttribute.
142 * TODO convert most uses of addVarying to addPassThroughAttribute
143 */
joshualitt74077b92014-10-24 11:26:03 -0700144 virtual void addVarying(const char* name,
145 GrGLVarying*,
bsalomonc0bd6482014-12-09 10:04:14 -0800146 GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0;
joshualitt47bb3822014-10-07 16:43:25 -0700147
joshualitt2dd1ae02014-12-03 06:24:10 -0800148 /*
149 * This call can be used by GP to pass an attribute through all shaders directly to 'output' in
150 * the fragment shader. Though this call effects both the vertex shader and fragment shader,
151 * it expects 'output' to be defined in the fragment shader before this call is made.
152 * TODO it might be nicer behavior to have a flag to declare output inside this call
153 */
joshualitt71c92602015-01-14 08:12:47 -0800154 virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*,
joshualitt2dd1ae02014-12-03 06:24:10 -0800155 const char* output) = 0;
156
joshualitt47bb3822014-10-07 16:43:25 -0700157 // TODO rename getFragmentBuilder
egdaniel29bee0f2015-04-29 11:54:42 -0700158 virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
joshualitt47bb3822014-10-07 16:43:25 -0700159 virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
160
161 /*
162 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
163 */
164};
165
166/* a specializations for FPs. Lets the user add uniforms and FS code */
167class GrGLFPBuilder : public virtual GrGLUniformBuilder {
168public:
egdaniel29bee0f2015-04-29 11:54:42 -0700169 virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
joshualitt47bb3822014-10-07 16:43:25 -0700170
171 /*
172 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
173 */
174};
175
egdanielc2304142014-12-11 13:15:13 -0800176/* a specializations for XPs. Lets the user add uniforms and FS code */
177class GrGLXPBuilder : public virtual GrGLUniformBuilder {
178public:
egdaniel29bee0f2015-04-29 11:54:42 -0700179 virtual GrGLXPFragmentBuilder* getFragmentShaderBuilder() = 0;
egdanielc2304142014-12-11 13:15:13 -0800180
181 /*
182 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
183 */
184};
joshualittabb52a12015-01-13 15:02:10 -0800185
186/**
187 * The below struct represent processors installed in programs.
188 */
189template <class Proc>
190struct GrGLInstalledProc {
cdalton42717652015-06-18 11:54:30 -0700191 SkDEBUGCODE(int fSamplersIdx;)
192 SkAutoTDelete<Proc> fGLProc;
joshualittabb52a12015-01-13 15:02:10 -0800193};
194
195typedef GrGLInstalledProc<GrGLPrimitiveProcessor> GrGLInstalledGeoProc;
196typedef GrGLInstalledProc<GrGLXferProcessor> GrGLInstalledXferProc;
197typedef GrGLInstalledProc<GrGLFragmentProcessor> GrGLInstalledFragProc;
198
199struct GrGLInstalledFragProcs : public SkRefCnt {
200 virtual ~GrGLInstalledFragProcs();
201 SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
202};
joshualitta5305a12014-10-10 17:47:00 -0700203
joshualitt47bb3822014-10-07 16:43:25 -0700204/*
205 * Please note - no diamond problems because of virtual inheritance. Also, both base classes
206 * are pure virtual with no data members. This is the base class for program building.
207 * Subclasses are nearly identical but each has their own way of emitting transforms. State for
208 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, etc, lives in those
209 * respective builders
210*/
211class GrGLProgramBuilder : public GrGLGPBuilder,
egdanielc2304142014-12-11 13:15:13 -0800212 public GrGLFPBuilder,
213 public GrGLXPBuilder {
joshualitt47bb3822014-10-07 16:43:25 -0700214public:
joshualitt873ad0e2015-01-20 09:08:51 -0800215 typedef GrGpu::DrawArgs DrawArgs;
joshualitt47bb3822014-10-07 16:43:25 -0700216 /** Generates a shader program.
217 *
218 * The program implements what is specified in the stages given as input.
219 * After successful generation, the builder result objects are available
220 * to be used.
221 * @return true if generation was successful.
222 */
joshualitt873ad0e2015-01-20 09:08:51 -0800223 static GrGLProgram* CreateProgram(const DrawArgs&, GrGLGpu*);
joshualitt47bb3822014-10-07 16:43:25 -0700224
bsalomon422f56f2014-12-09 10:18:12 -0800225 UniformHandle addUniformArray(uint32_t visibility,
226 GrSLType type,
227 GrSLPrecision precision,
228 const char* name,
229 int arrayCount,
mtklein36352bf2015-03-25 18:17:31 -0700230 const char** outName) override;
joshualitt47bb3822014-10-07 16:43:25 -0700231
mtklein36352bf2015-03-25 18:17:31 -0700232 const GrGLShaderVar& getUniformVariable(UniformHandle u) const override {
joshualitt47bb3822014-10-07 16:43:25 -0700233 return fUniforms[u.toShaderBuilderIndex()].fVariable;
234 }
235
mtklein36352bf2015-03-25 18:17:31 -0700236 const char* getUniformCStr(UniformHandle u) const override {
joshualitt47bb3822014-10-07 16:43:25 -0700237 return this->getUniformVariable(u).c_str();
238 }
239
mtklein36352bf2015-03-25 18:17:31 -0700240 const GrGLContextInfo& ctxInfo() const override;
joshualitt47bb3822014-10-07 16:43:25 -0700241
mtklein36352bf2015-03-25 18:17:31 -0700242 GrGLGpu* gpu() const override { return fGpu; }
joshualitt47bb3822014-10-07 16:43:25 -0700243
egdaniel29bee0f2015-04-29 11:54:42 -0700244 GrGLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; }
mtklein36352bf2015-03-25 18:17:31 -0700245 GrGLVertexBuilder* getVertexShaderBuilder() override { return &fVS; }
joshualitt47bb3822014-10-07 16:43:25 -0700246
bsalomon422f56f2014-12-09 10:18:12 -0800247 void addVarying(
joshualitta5305a12014-10-10 17:47:00 -0700248 const char* name,
joshualitt74077b92014-10-24 11:26:03 -0700249 GrGLVarying*,
mtklein36352bf2015-03-25 18:17:31 -0700250 GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override;
joshualitt30ba4362014-08-21 20:18:45 -0700251
joshualitt71c92602015-01-14 08:12:47 -0800252 void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*,
mtklein36352bf2015-03-25 18:17:31 -0700253 const char* output) override;
joshualitt2dd1ae02014-12-03 06:24:10 -0800254
255
joshualitt30ba4362014-08-21 20:18:45 -0700256 // Handles for program uniforms (other than per-effect uniforms)
257 struct BuiltinUniformHandles {
joshualitt30ba4362014-08-21 20:18:45 -0700258 UniformHandle fRTAdjustmentUni;
joshualitt30ba4362014-08-21 20:18:45 -0700259
260 // We use the render target height to provide a y-down frag coord when specifying
261 // origin_upper_left is not supported.
262 UniformHandle fRTHeightUni;
joshualitt30ba4362014-08-21 20:18:45 -0700263 };
264
joshualittdb0d3ca2014-10-07 12:42:26 -0700265protected:
joshualitta5305a12014-10-10 17:47:00 -0700266 typedef GrGLProgramDataManager::UniformInfo UniformInfo;
267 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
268
joshualitt873ad0e2015-01-20 09:08:51 -0800269 static GrGLProgramBuilder* CreateProgramBuilder(const DrawArgs&, GrGLGpu*);
joshualitt47bb3822014-10-07 16:43:25 -0700270
joshualitt873ad0e2015-01-20 09:08:51 -0800271 GrGLProgramBuilder(GrGLGpu*, const DrawArgs&);
joshualitt30ba4362014-08-21 20:18:45 -0700272
joshualitt873ad0e2015-01-20 09:08:51 -0800273 const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; }
egdaniel8dd688b2015-01-22 10:16:09 -0800274 const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
joshualitt873ad0e2015-01-20 09:08:51 -0800275 const GrProgramDesc& desc() const { return *fArgs.fDesc; }
276 const GrBatchTracker& batchTracker() const { return *fArgs.fBatchTracker; }
277 const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); }
joshualitt23e280d2014-09-18 12:26:38 -0700278
joshualitt30ba4362014-08-21 20:18:45 -0700279 // Generates a name for a variable. The generated string will be name prefixed by the prefix
280 // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
281 // generating stage code.
282 void nameVariable(SkString* out, char prefix, const char* name);
joshualitt2dd1ae02014-12-03 06:24:10 -0800283 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
284 // If GrGLSLExpr4 has a valid name then it will use that instead
285 void nameExpression(GrGLSLExpr4*, const char* baseName);
joshualitt6c891102015-05-13 08:51:49 -0700286 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
joshualitta5305a12014-10-10 17:47:00 -0700287 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
joshualitt2dd1ae02014-12-03 06:24:10 -0800288 void emitAndInstallProc(const GrPendingFragmentStage&,
joshualitta5305a12014-10-10 17:47:00 -0700289 int index,
joshualitta5305a12014-10-10 17:47:00 -0700290 const GrGLSLExpr4& input,
291 GrGLSLExpr4* output);
292
joshualitt9b989322014-12-15 14:16:27 -0800293 void emitAndInstallProc(const GrPrimitiveProcessor&,
joshualitt2dd1ae02014-12-03 06:24:10 -0800294 GrGLSLExpr4* outputColor,
295 GrGLSLExpr4* outputCoverage);
296
joshualitta5305a12014-10-10 17:47:00 -0700297 // these emit functions help to keep the createAndEmitProcessors template general
bsalomonae59b772014-11-19 08:23:49 -0800298 void emitAndInstallProc(const GrPendingFragmentStage&,
joshualittabb52a12015-01-13 15:02:10 -0800299 int index,
joshualitta5305a12014-10-10 17:47:00 -0700300 const char* outColor,
301 const char* inColor);
joshualitt9b989322014-12-15 14:16:27 -0800302 void emitAndInstallProc(const GrPrimitiveProcessor&,
joshualitt2dd1ae02014-12-03 06:24:10 -0800303 const char* outColor,
304 const char* outCoverage);
egdanielc2304142014-12-11 13:15:13 -0800305 void emitAndInstallXferProc(const GrXferProcessor&,
306 const GrGLSLExpr4& colorIn,
307 const GrGLSLExpr4& coverageIn);
joshualitt2dd1ae02014-12-03 06:24:10 -0800308
joshualitt9b989322014-12-15 14:16:27 -0800309 void verify(const GrPrimitiveProcessor&);
egdanielc2304142014-12-11 13:15:13 -0800310 void verify(const GrXferProcessor&);
joshualitt47bb3822014-10-07 16:43:25 -0700311 void verify(const GrFragmentProcessor&);
joshualittabb52a12015-01-13 15:02:10 -0800312 template <class Proc>
joshualitt47bb3822014-10-07 16:43:25 -0700313 void emitSamplers(const GrProcessor&,
314 GrGLProcessor::TextureSamplerArray* outSamplers,
joshualittabb52a12015-01-13 15:02:10 -0800315 GrGLInstalledProc<Proc>*);
joshualitt30ba4362014-08-21 20:18:45 -0700316
joshualitt47bb3822014-10-07 16:43:25 -0700317 GrGLProgram* finalize();
318 void bindUniformLocations(GrGLuint programID);
319 bool checkLinkStatus(GrGLuint programID);
320 void resolveUniformLocations(GrGLuint programID);
joshualitt47bb3822014-10-07 16:43:25 -0700321 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
322 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
joshualitt30ba4362014-08-21 20:18:45 -0700323
joshualitt47bb3822014-10-07 16:43:25 -0700324 // Subclasses create different programs
325 virtual GrGLProgram* createProgram(GrGLuint programID);
326
joshualitt30ba4362014-08-21 20:18:45 -0700327 void appendUniformDecls(ShaderVisibility, SkString*) const;
328
joshualitt47bb3822014-10-07 16:43:25 -0700329 // reset is called by program creator between each processor's emit code. It increments the
330 // stage offset for variable name mangling, and also ensures verfication variables in the
331 // fragment shader are cleared.
332 void reset() {
333 this->enterStage();
334 this->addStage();
335 fFS.reset();
336 }
337 void addStage() { fStageIndex++; }
338
339 // This simple class exits the stage and then restores the stage when it goes out of scope
340 class AutoStageRestore {
joshualitt30ba4362014-08-21 20:18:45 -0700341 public:
joshualitt47bb3822014-10-07 16:43:25 -0700342 AutoStageRestore(GrGLProgramBuilder* pb)
343 : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); }
344 ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; }
joshualittb0a8a372014-09-23 09:50:21 -0700345 private:
joshualitt47bb3822014-10-07 16:43:25 -0700346 GrGLProgramBuilder* fPB;
347 bool fOutOfStage;
joshualittb0a8a372014-09-23 09:50:21 -0700348 };
joshualitt47bb3822014-10-07 16:43:25 -0700349 class AutoStageAdvance {
joshualittdb0d3ca2014-10-07 12:42:26 -0700350 public:
joshualitt43466a12015-02-13 17:18:27 -0800351 AutoStageAdvance(GrGLProgramBuilder* pb)
352 : fPB(pb) {
353 fPB->reset();
354 // Each output to the fragment processor gets its own code section
355 fPB->fFS.nextStage();
356 }
joshualitt47bb3822014-10-07 16:43:25 -0700357 ~AutoStageAdvance() { fPB->exitStage(); }
joshualittdb0d3ca2014-10-07 12:42:26 -0700358 private:
joshualitt47bb3822014-10-07 16:43:25 -0700359 GrGLProgramBuilder* fPB;
360 };
361 void exitStage() { fOutOfStage = true; }
362 void enterStage() { fOutOfStage = false; }
363 int stageIndex() const { return fStageIndex; }
364
joshualitt4973d9d2014-11-08 09:24:25 -0800365 const char* rtAdjustment() const { return "rtAdjustment"; }
366
joshualitt47bb3822014-10-07 16:43:25 -0700367 // number of each input/output type in a single allocation block, used by many builders
368 static const int kVarsPerBlock;
369
370 BuiltinUniformHandles fUniformHandles;
371 GrGLVertexBuilder fVS;
372 GrGLGeometryBuilder fGS;
373 GrGLFragmentShaderBuilder fFS;
374 bool fOutOfStage;
375 int fStageIndex;
376
joshualitta5305a12014-10-10 17:47:00 -0700377 GrGLInstalledGeoProc* fGeometryProcessor;
egdanielc2304142014-12-11 13:15:13 -0800378 GrGLInstalledXferProc* fXferProcessor;
joshualitta5305a12014-10-10 17:47:00 -0700379 SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
joshualitt47bb3822014-10-07 16:43:25 -0700380
joshualitt873ad0e2015-01-20 09:08:51 -0800381 const DrawArgs& fArgs;
bsalomon861e1032014-12-16 07:33:49 -0800382 GrGLGpu* fGpu;
joshualitt47bb3822014-10-07 16:43:25 -0700383 UniformInfoArray fUniforms;
joshualittabb52a12015-01-13 15:02:10 -0800384 GrGLPrimitiveProcessor::TransformsIn fCoordTransforms;
385 GrGLPrimitiveProcessor::TransformsOut fOutCoords;
cdalton42717652015-06-18 11:54:30 -0700386 SkTArray<UniformHandle> fSamplerUniforms;
joshualitt47bb3822014-10-07 16:43:25 -0700387
388 friend class GrGLShaderBuilder;
389 friend class GrGLVertexBuilder;
390 friend class GrGLFragmentShaderBuilder;
391 friend class GrGLGeometryBuilder;
392};
joshualitt30ba4362014-08-21 20:18:45 -0700393#endif