/* * 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 if in 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 if in 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