aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLSL.h
blob: 869b0e180c44d0fd2a2ff68e556a23a6c8eba02a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrGLSL_DEFINED
#define GrGLSL_DEFINED

#include "gl/GrGLInterface.h"
#include "GrColor.h"
#include "GrTypesPriv.h"

class GrGLShaderVar;
class SkString;

// Limited set of GLSL versions we build shaders for. Caller should round
// down the GLSL version to one of these enums.
enum GrGLSLGeneration {
    /**
     * Desktop GLSL 1.10 and ES2 shading language (based on desktop GLSL 1.20)
     */
    k110_GrGLSLGeneration,
    /**
     * Desktop GLSL 1.30
     */
    k130_GrGLSLGeneration,
    /**
     * Desktop GLSL 1.40
     */
    k140_GrGLSLGeneration,
    /**
     * Desktop GLSL 1.50
     */
    k150_GrGLSLGeneration,
};

enum GrSLConstantVec {
    kZeros_GrSLConstantVec,
    kOnes_GrSLConstantVec,
    kNone_GrSLConstantVec,
};

namespace {
static inline int GrSLTypeToVecLength(GrSLType type) {
    static const int kVecLengths[] = {
        0, // kVoid_GrSLType
        1, // kFloat_GrSLType
        2, // kVec2f_GrSLType
        3, // kVec3f_GrSLType
        4, // kVec4f_GrSLType
        1, // kMat33f_GrSLType
        1, // kMat44f_GrSLType
        1, // kSampler2D_GrSLType
    };
    GrAssert((size_t) type < GR_ARRAY_COUNT(kVecLengths));
    return kVecLengths[type];
}

static inline const char* GrGLSLOnesVecf(int count) {
    static const char* kONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
                                     "vec3(1,1,1)", "vec4(1,1,1,1)"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(kONESVEC));
    return kONESVEC[count];
}

static inline const char* GrGLSLZerosVecf(int count) {
    static const char* kZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
                                      "vec3(0,0,0)", "vec4(0,0,0,0)"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(kZEROSVEC));
    return kZEROSVEC[count];
}
}

/**
 * Gets the most recent GLSL Generation compatible with the OpenGL context.
 */
GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
                                     const GrGLInterface* gl);

/**
 * Returns a string to include at the beginning of a shader to declare the GLSL
 * version.
 */
const char* GrGetGLSLVersionDecl(GrGLBinding binding,
                                 GrGLSLGeneration v);

/**
 * Depending on the GLSL version being emitted there may be an assumed output
 * variable from the fragment shader for the color. Otherwise, the shader must
 * declare an output variable for the color. If this function returns true:
 *    * Parameter var's name will be set to nameIfDeclared
 *    * The variable must be declared in the fragment shader
 *    * The variable has to be bound as the color output
 *      (using glBindFragDataLocation)
 *    If the function returns false:
 *    * Parameter var's name will be set to the GLSL built-in color output name.
 *    * Do not declare the variable in the shader.
 *    * Do not use glBindFragDataLocation to bind the variable
 * In either case var is initialized to represent the color output in the
 * shader.
 */
bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
                             const char* nameIfDeclared,
                             GrGLShaderVar* var);
/**
 * Converts a GrSLType to a string containing the name of the equivalent GLSL type.
 */
static const char* GrGLSLTypeString(GrSLType t) {
    switch (t) {
        case kVoid_GrSLType:
            return "void";
        case kFloat_GrSLType:
            return "float";
        case kVec2f_GrSLType:
            return "vec2";
        case kVec3f_GrSLType:
            return "vec3";
        case kVec4f_GrSLType:
            return "vec4";
        case kMat33f_GrSLType:
            return "mat3";
        case kMat44f_GrSLType:
            return "mat4";
        case kSampler2D_GrSLType:
            return "sampler2D";
        default:
            GrCrash("Unknown shader var type.");
            return ""; // suppress warning
    }
}

/** Return the type enum for a vector of floats of length n (1..4),
    e.g. 1 -> "float", 2 -> "vec2", ... */
static inline const char* GrGLSLFloatVectorTypeString(int n) {
    return GrGLSLTypeString(GrSLFloatVectorType(n));
}

/** Return the GLSL swizzle operator for a homogenous component of a vector
    with the given number of coordinates, e.g. 2 -> ".y", 3 -> ".z" */
const char* GrGLSLVectorHomogCoord(int count);
const char* GrGLSLVectorHomogCoord(GrSLType type);

/** Return the GLSL swizzle operator for a nonhomogenous components of a vector
    with the given number of coordinates, e.g. 2 -> ".x", 3 -> ".xy" */
const char* GrGLSLVectorNonhomogCoords(int count);
const char* GrGLSLVectorNonhomogCoords(GrSLType type);

/**
  * Produces a string that is the result of modulating two inputs. The inputs must be vecN or
  * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
  * Either can be NULL or "" in which case the default params control whether a vector of ones or
  * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
  * function determines that the result is a zeros or ones vec then any expression represented by
  * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
  * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
  * by passing true for omitIfConstVec.
  */
template <int N>
GrSLConstantVec GrGLSLModulatef(SkString* outAppend,
                                const char* in0,
                                const char* in1,
                                GrSLConstantVec default0 = kOnes_GrSLConstantVec,
                                GrSLConstantVec default1 = kOnes_GrSLConstantVec,
                                bool omitIfConstVec = false);

/**
 * Produces a string that is the result of adding two inputs. The inputs must be vecN or
 * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
 * Either can be NULL or "" in which case the default params control whether a vector of ones or
 * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
 * function determines that the result is a zeros or ones vec then any expression represented by
 * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
 * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
 * by passing true for omitIfConstVec.
 */
template <int N>
GrSLConstantVec GrGLSLAddf(SkString* outAppend,
                           const char* in0,
                           const char* in1,
                           GrSLConstantVec default0 = kZeros_GrSLConstantVec,
                           GrSLConstantVec default1 = kZeros_GrSLConstantVec,
                           bool omitIfConstVec = false);

/**
 * Produces a string that is the result of subtracting two inputs. The inputs must be vecN or
 * float. The result is always a vecN. The inputs may be expressions, not just identifier names.
 * Either can be NULL or "" in which case the default params control whether a vector of ones or
 * zeros. It is an error to pass kNone for default<i> if in<i> is NULL or "". Note that when the
 * function determines that the result is a zeros or ones vec then any expression represented by
 * or in1 will not be emitted (side effects won't occur). The return value indicates whether a
 * known zeros or ones vector resulted. The output can be suppressed when known vector is produced
 * by passing true for omitIfConstVec.
 */
template <int N>
GrSLConstantVec GrGLSLSubtractf(SkString* outAppend,
                                const char* in0,
                                const char* in1,
                                GrSLConstantVec default0 = kZeros_GrSLConstantVec,
                                GrSLConstantVec default1 = kZeros_GrSLConstantVec,
                                bool omitIfConstVec = false);

/**
 * Does an inplace mul, *=, of vec4VarName by mulFactor. If mulFactorDefault is not kNone then
 * mulFactor may be either "" or NULL. In this case either nothing will be appended (kOnes) or an
 * assignment of vec(0,0,0,0) will be appended (kZeros). The assignment is prepended by tabCnt tabs.
 * A semicolon and newline are added after the assignment. (TODO: Remove tabCnt when we auto-insert
 * tabs to GrGLEffect-generated lines.) If a zeros vec is assigned then the return value is
 * kZeros, otherwise kNone.
 */
GrSLConstantVec GrGLSLMulVarBy4f(SkString* outAppend,
                                 int tabCnt,
                                 const char* vec4VarName,
                                 const char* mulFactor,
                                 GrSLConstantVec mulFactorDefault = kOnes_GrSLConstantVec);

/**
 * Given an expression that evaluates to a GLSL vec4, extract a component. If expr is NULL or ""
 * the value of defaultExpr is used. It is an error to pass an empty expr and have set defaultExpr
 * to kNone. The return value indicates whether the value is known to be 0 or 1. If omitIfConst is
 * set then nothing is appended when the return is not kNone.
 */
GrSLConstantVec GrGLSLGetComponent4f(SkString* outAppend,
                                     const char* expr,
                                     GrColorComponentFlags component,
                                     GrSLConstantVec defaultExpr = kNone_GrSLConstantVec,
                                     bool omitIfConst = false);

#include "GrGLSL_impl.h"

#endif