blob: 2249c3c712ea631ebe4880785e85bb050589049f [file] [log] [blame]
egdaniel8dcdedc2015-11-11 06:27:20 -08001/*
2 * Copyright 2015 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 GrGLSLProgramBuilder_DEFINED
9#define GrGLSLProgramBuilder_DEFINED
10
11#include "GrGeometryProcessor.h"
12#include "GrGpu.h"
egdaniel2d721d32015-11-11 13:06:05 -080013#include "glsl/GrGLSLFragmentShaderBuilder.h"
14#include "glsl/GrGLSLGeometryShaderBuilder.h"
egdanielfa896322016-01-13 12:19:30 -080015#include "glsl/GrGLSLPrimitiveProcessor.h"
egdaniel8dcdedc2015-11-11 06:27:20 -080016#include "glsl/GrGLSLProgramDataManager.h"
egdaniel7ea439b2015-12-03 09:20:44 -080017#include "glsl/GrGLSLUniformHandler.h"
egdanielfa896322016-01-13 12:19:30 -080018#include "glsl/GrGLSLTextureSampler.h"
egdaniel2d721d32015-11-11 13:06:05 -080019#include "glsl/GrGLSLVertexShaderBuilder.h"
egdanielfa896322016-01-13 12:19:30 -080020#include "glsl/GrGLSLXferProcessor.h"
egdaniel8dcdedc2015-11-11 06:27:20 -080021
22class GrGLSLCaps;
23class GrGLSLShaderVar;
egdaniel0eafe792015-11-20 14:01:22 -080024class GrGLSLVaryingHandler;
egdaniel8dcdedc2015-11-11 06:27:20 -080025
egdanielfa896322016-01-13 12:19:30 -080026typedef SkSTArray<8, GrGLSLFragmentProcessor*, true> GrGLSLFragProcs;
27
egdaniel7ea439b2015-12-03 09:20:44 -080028class GrGLSLProgramBuilder {
egdaniel8dcdedc2015-11-11 06:27:20 -080029public:
30 typedef GrGpu::DrawArgs DrawArgs;
egdaniel7ea439b2015-12-03 09:20:44 -080031 typedef GrGLSLUniformHandler::ShaderVisibility ShaderVisibility;
32 typedef GrGLSLUniformHandler::UniformHandle UniformHandle;
33
34 virtual ~GrGLSLProgramBuilder() {}
egdaniel8dcdedc2015-11-11 06:27:20 -080035
egdanielfa896322016-01-13 12:19:30 -080036 virtual const GrCaps* caps() const = 0;
egdaniela2e3e0f2015-11-19 07:23:45 -080037 virtual const GrGLSLCaps* glslCaps() const = 0;
38
egdaniel7ea439b2015-12-03 09:20:44 -080039 const GrPrimitiveProcessor& primitiveProcessor() const { return *fArgs.fPrimitiveProcessor; }
40 const GrPipeline& pipeline() const { return *fArgs.fPipeline; }
41 const GrProgramDesc& desc() const { return *fArgs.fDesc; }
42 const GrProgramDesc::KeyHeader& header() const { return fArgs.fDesc->header(); }
43
44 void appendUniformDecls(ShaderVisibility, SkString*) const;
45
egdaniel8dcdedc2015-11-11 06:27:20 -080046 // Handles for program uniforms (other than per-effect uniforms)
47 struct BuiltinUniformHandles {
48 UniformHandle fRTAdjustmentUni;
49
50 // We use the render target height to provide a y-down frag coord when specifying
51 // origin_upper_left is not supported.
52 UniformHandle fRTHeightUni;
53 };
54
egdaniel7ea439b2015-12-03 09:20:44 -080055 // Used to add a uniform in the vertex shader for transforming into normalized device space.
56 void addRTAdjustmentUniform(GrSLPrecision precision, const char* name, const char** outName);
egdaniel8dcdedc2015-11-11 06:27:20 -080057 const char* rtAdjustment() const { return "rtAdjustment"; }
egdaniel7ea439b2015-12-03 09:20:44 -080058
59 // Used to add a uniform for the RenderTarget height (used for frag position) without mangling
60 // the name of the uniform inside of a stage.
61 void addRTHeightUniform(const char* name, const char** outName);
egdaniel8dcdedc2015-11-11 06:27:20 -080062
63 // Generates a name for a variable. The generated string will be name prefixed by the prefix
64 // char (unless the prefix is '\0'). It also will mangle the name to be stage-specific unless
65 // explicitly asked not to.
66 void nameVariable(SkString* out, char prefix, const char* name, bool mangle = true);
67
egdaniel7ea439b2015-12-03 09:20:44 -080068 virtual GrGLSLUniformHandler* uniformHandler() = 0;
69 virtual const GrGLSLUniformHandler* uniformHandler() const = 0;
egdaniel0eafe792015-11-20 14:01:22 -080070 virtual GrGLSLVaryingHandler* varyingHandler() = 0;
71
egdaniel8dcdedc2015-11-11 06:27:20 -080072 // number of each input/output type in a single allocation block, used by many builders
73 static const int kVarsPerBlock;
74
egdaniel0eafe792015-11-20 14:01:22 -080075 GrGLSLVertexBuilder fVS;
76 GrGLSLGeometryBuilder fGS;
egdaniel2d721d32015-11-11 13:06:05 -080077 GrGLSLFragmentShaderBuilder fFS;
egdaniel0eafe792015-11-20 14:01:22 -080078
egdaniel8dcdedc2015-11-11 06:27:20 -080079 int fStageIndex;
80
egdaniel8dcdedc2015-11-11 06:27:20 -080081 const DrawArgs& fArgs;
82
egdaniel7ea439b2015-12-03 09:20:44 -080083 BuiltinUniformHandles fUniformHandles;
egdaniel8dcdedc2015-11-11 06:27:20 -080084
egdanielfa896322016-01-13 12:19:30 -080085 GrGLSLPrimitiveProcessor* fGeometryProcessor;
86 GrGLSLXferProcessor* fXferProcessor;
87 GrGLSLFragProcs fFragmentProcessors;
88
egdaniel7ea439b2015-12-03 09:20:44 -080089protected:
90 explicit GrGLSLProgramBuilder(const DrawArgs& args);
egdanielfa896322016-01-13 12:19:30 -080091
92 bool emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage, int maxTextures);
93
94 void cleanupFragmentProcessors();
95
96private:
97 // reset is called by program creator between each processor's emit code. It increments the
98 // stage offset for variable name mangling, and also ensures verfication variables in the
99 // fragment shader are cleared.
100 void reset() {
101 this->addStage();
102 fFS.reset();
103 }
104 void addStage() { fStageIndex++; }
105
106 class AutoStageAdvance {
107 public:
108 AutoStageAdvance(GrGLSLProgramBuilder* pb)
109 : fPB(pb) {
110 fPB->reset();
111 // Each output to the fragment processor gets its own code section
112 fPB->fFS.nextStage();
113 }
114 ~AutoStageAdvance() {}
115 private:
116 GrGLSLProgramBuilder* fPB;
117 };
118
119 // Generates a possibly mangled name for a stage variable and writes it to the fragment shader.
120 // If GrGLSLExpr4 has a valid name then it will use that instead
121 void nameExpression(GrGLSLExpr4*, const char* baseName);
122
123 void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
124 GrGLSLExpr4* outputColor,
125 GrGLSLExpr4* outputCoverage);
126 void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
127 void emitAndInstallFragProc(const GrFragmentProcessor&,
128 int index,
129 const GrGLSLExpr4& input,
130 GrGLSLExpr4* output);
131 void emitAndInstallXferProc(const GrXferProcessor&,
132 const GrGLSLExpr4& colorIn,
133 const GrGLSLExpr4& coverageIn,
ethannicholas22793252016-01-30 09:59:10 -0800134 bool ignoresCoverage,
135 GrPixelLocalStorageState plsState);
egdanielfa896322016-01-13 12:19:30 -0800136 void emitFSOutputSwizzle(bool hasSecondaryOutput);
137
138 void verify(const GrPrimitiveProcessor&);
139 void verify(const GrXferProcessor&);
140 void verify(const GrFragmentProcessor&);
141
142 virtual void emitSamplers(const GrProcessor& processor,
143 GrGLSLTextureSampler::TextureSamplerArray* outSamplers) = 0;
144
145 GrGLSLPrimitiveProcessor::TransformsIn fCoordTransforms;
146 GrGLSLPrimitiveProcessor::TransformsOut fOutCoords;
egdaniel8dcdedc2015-11-11 06:27:20 -0800147};
148
149#endif