/*
* 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"
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,
};
/**
* Types of shader-language-specific boxed variables we can create.
* (Currently only GrGLShaderVars, but should be applicable to other shader
* languages.)
*/
enum GrSLType {
kVoid_GrSLType,
kFloat_GrSLType,
kVec2f_GrSLType,
kVec3f_GrSLType,
kVec4f_GrSLType,
kMat33f_GrSLType,
kMat44f_GrSLType,
kSampler2D_GrSLType
};
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);
/** Convert a count of 1..n floats into the corresponding type enum,
e.g. 1 -> kFloat_GrSLType, 2 -> kVec2_GrSLType, ... */
GrSLType GrSLFloatVectorType(int count);
/** 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 vec4 or
* float. The result is always a vec4. The inputs may be expressions, not just identifier names.
* Either can be NULL or "" in which case the default params control whether vec4(1,1,1,1) or
* vec4(0,0,0,0) is assumed. It is an error to pass kNone for default<i> if in<i> is NULL or "".
* Note that when if function determines that the result is a zeros or ones vec then any expression
* represented by in0 or in1 will not be emitted. The return value indicates whether a zeros, ones
* or neither was appended.
*/
GrSLConstantVec GrGLSLModulate4f(SkString* outAppend,
const char* in0,
const char* in1,
GrSLConstantVec default0 = kOnes_GrSLConstantVec,
GrSLConstantVec default1 = kOnes_GrSLConstantVec);
/**
* 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);
/**
* Produces a string that is the result of adding two inputs. The inputs must be vec4 or float.
* The result is always a vec4. The inputs may be expressions, not just identifier names. Either
* can be NULL or "" in which case if the default is kZeros then vec4(0,0,0,0) is assumed. It is an
* error to pass kOnes for either default or to pass kNone for default<i> if in<i> is NULL or "".
* Note that if the function determines that the result is a zeros vec any expression represented
* by in0 or in1 will not be emitted. The return value indicates whether a zeros vec was appended
* or not.
*/
GrSLConstantVec GrGLSLAdd4f(SkString* outAppend,
const char* in0,
const char* in1,
GrSLConstantVec default0 = kZeros_GrSLConstantVec,
GrSLConstantVec default1 = kZeros_GrSLConstantVec);
#endif