GrGLShaderBuilder.h revision e2022cc36e47b9f0d219eb5cd24be61772c28d3b
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrGLShaderBuilder_DEFINED 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrGLShaderBuilder_DEFINED 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrAllocator.h" 12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrBackendEffectFactory.h" 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrEffect.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLSL.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLUniformManager.h" 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include <stdarg.h> 18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLContextInfo; 20e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenbergerclass GrEffectStage; 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Contains all the incremental state of a shader as it is being built,as well as helpers to 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru manipulate that state. 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrGLShaderBuilder { 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 29d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Passed to GrGLEffects to add texture reads to their shader code. 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru class TextureSampler { 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public: 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TextureSampler() 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fTextureAccess(NULL) 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {} 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TextureSampler(const TextureSampler& other) { *this = other; } 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TextureSampler& operator= (const TextureSampler& other) { 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fTextureAccess); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureAccess = other.fTextureAccess; 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSamplerUniform = other.fSamplerUniform; 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *this; 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureAccess* textureAccess() const { return fTextureAccess; } 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru private: 51d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // The idx param is used to ensure multiple samplers within a single effect have unique 52d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // uniform names. 53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fTextureAccess); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform); 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != builder); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != access); 59d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkString name; 60d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger name.printf("Sampler%d_", idx); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kSampler2D_GrSLType, 63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger name.c_str()); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureAccess = access; 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureAccess* fTextureAccess; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLUniformManager::UniformHandle fSamplerUniform; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class GrGLShaderBuilder; // to access fSamplerUniform 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class GrGLProgram; // to construct these and access fSamplerUniform. 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkTArray<TextureSampler> TextureSamplerArray; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum ShaderType { 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kVertex_ShaderType = 0x1, 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kGeometry_ShaderType = 0x2, 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kFragment_ShaderType = 0x4, 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, bool explicitLocalCoords); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** 87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger * Called by GrGLEffects to add code to one of the shaders. 88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger */ 89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 90096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_list args; 91096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_start(args, format); 92096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->codeAppendf(kVertex_ShaderType, format, args); 93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_end(args); 94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 95096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 96096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 97096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_list args; 98096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_start(args, format); 99096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->codeAppendf(kGeometry_ShaderType, format, args); 100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_end(args); 101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 104096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_list args; 105096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_start(args, format); 106096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->codeAppendf(kFragment_ShaderType, format, args); 107096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger va_end(args); 108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, str); } 111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType, str); } 112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType, str); } 113096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle 116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger order of the result depends on the GrTextureAccess associated with the TextureSampler. */ 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void appendTextureLookup(SkString* out, 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const TextureSampler&, 119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const char* coordName, 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSLType coordType = kVec2f_GrSLType) const; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** Version of above that appends the result to the shader code rather than an SkString. 123096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger Currently the shader type must be kFragment */ 124096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void appendTextureLookup(ShaderType, 125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const TextureSampler&, 126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const char* coordName, 127096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrSLType coordType = kVec2f_GrSLType); 128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Does the work of appendTextureLookup and modulates the result by modulation. The result is 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float. If modulation is "" or NULL it this function acts as though appendTextureLookup were 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru called. */ 134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void appendTextureLookupAndModulate(ShaderType, 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* modulation, 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const TextureSampler&, 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const char* coordName, 138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrSLType coordType = kVec2f_GrSLType); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Emits a helper function outside of main(). Currently ShaderType must be 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kFragment_ShaderType. */ 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void emitFunction(ShaderType shader, 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSLType returnType, 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* name, 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int argCnt, 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrGLShaderVar* args, 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* body, 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString* outName); 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Generates a EffectKey for the shader code based on the texture access parameters and the 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru capabilities of the GL context. This is useful for keying the shader programs that may 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru have multiple representations, based on the type/format of textures used. */ 153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&, 154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrGLCaps&); 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** If texture swizzling is available using tex parameters then it is preferred over mangling 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru the generated shader code. This potentially allows greater reuse of cached shaders. */ 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Add a uniform variable to the current program, that has visibility in one or more shaders. 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru visibility is a bitfield of ShaderType values indicating from which shaders the uniform 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru should be accessible. At least one bit must be set. Geometry shader uniforms are not 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru supported at this time. The actual uniform name will be mangled. If outName is not NULL then 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru it will refer to the final uniform name after return. Use the addUniformArray variant to add 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru an array of uniforms. 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLUniformManager::UniformHandle addUniform(uint32_t visibility, 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSLType type, 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* name, 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char** outName = NULL) { 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility, 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSLType type, 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* name, 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int arrayCount, 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char** outName = NULL); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const; 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Shortcut for getUniformVariable(u).c_str() 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const { 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->getUniformVariable(u).c_str(); 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 188096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** Add a vertex attribute to the current program that is passed in from the vertex data. 189096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger Returns false if the attribute was already there, true otherwise. */ 190096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger bool addAttribute(GrSLType type, const char* name); 191096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 192096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger /** Add a varying variable to the current program to pass values between vertex and fragment 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shaders. If the last two parameters are non-NULL, they are filled in with the name 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru generated. */ 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void addVarying(GrSLType type, 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* name, 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char** vsOutName = NULL, 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char** fsInName = NULL); 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Returns a variable name that represents the position of the fragment in the FS. The position 201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */ 202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const char* fragmentPosition(); 203363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 204363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Returns a vertex attribute that represents the vertex position in the VS. This is the 205363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger pre-matrix position and is commonly used by effects to compute texture coords via a matrix. 206363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 207363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } 208363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 209e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger /** Returns a vertex attribute that represents the local coords in the VS. This may be the same 210e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger as positionAttribute() or it may not be. It depends upon whether the rendering code 211e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger specified explicit local coords or not in the GrDrawState. */ 212e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; } 213e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 214e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger /** 215e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger * Are explicit local coordinates provided as input to the vertex shader. 216e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger */ 217e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); } 218e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 220d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Interfaces used by GrGLProgram. 221d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * TODO: Hide these from the GrEffects using friend or splitting this into two related classes. 222d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Also, GrGLProgram's shader string construction should be moved to this class. 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 225d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger /** Called after building is complete to get the final shader string. */ 226d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger void getShader(ShaderType, SkString*) const; 227d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger void setCurrentStage(int stageIdx) { fCurrentStageIdx = stageIdx; } 229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger void setNonStage() { fCurrentStageIdx = kNonStageIdx; } 230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // TODO: move remainder of shader code generation to this class and call this privately 231d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Handles of sampler uniforms generated for the effect are appended to samplerHandles. 232d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrGLEffect* createAndEmitGLEffect( 233d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrEffectStage& stage, 234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrBackendEffectFactory::EffectKey key, 235d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const char* fsInColor, // NULL means no incoming color 236d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const char* fsOutColor, 237d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles); 238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; } 239096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger struct AttributePair { 241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void set(int index, const SkString& name) { 242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fIndex = index; fName = name; 243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int fIndex; 245096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString fName; 246096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger }; 247096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkSTArray<10, AttributePair, true>& getEffectAttributes() const { 248096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return fEffectAttributes; 249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkString* getEffectAttributeName(int attributeIndex) const; 251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 252d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // TODO: Make this do all the compiling, linking, etc. 253d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger void finished(GrGLuint programID); 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } 256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void codeAppendf(ShaderType type, const char format[], va_list args); 259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger void codeAppend(ShaderType type, const char* str); 260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GrTAllocator<GrGLShaderVar> VarArray; 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void appendDecls(const VarArray&, SkString*) const; 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void appendUniformDecls(ShaderType, SkString*) const; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef GrGLUniformManager::BuilderUniform BuilderUniform; 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrGLUniformManager::BuilderUniformArray fUniforms; 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: Everything below here private. 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString fHeader; // VS+FS, GLSL version, etc 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fVSAttrs; 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fVSOutputs; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fGSInputs; 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fGSOutputs; 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fFSInputs; 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString fGSHeader; // layout qualifiers specific to GS 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru VarArray fFSOutputs; 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fUsesGS; 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNonStageIdx = -1, 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const GrGLContextInfo& fCtxInfo; 288363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrGLUniformManager& fUniformManager; 289363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger int fCurrentStageIdx; 290363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkString fFSFunctions; 291363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkString fFSHeader; 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString fFSCode; 294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString fVSCode; 295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkString fGSCode; 296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 297363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool fSetupFragPosition; 298363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrGLUniformManager::UniformHandle fRTHeightUniform; 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkSTArray<10, AttributePair, true> fEffectAttributes; 301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 302363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrGLShaderVar* fPositionVar; 303e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger GrGLShaderVar* fLocalCoordsVar; 304e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 308