GrGLShaderBuilder.h revision 26e18b593ab65e4d92dfbce92579d8bc180d4c2c
1f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/* 2f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Copyright 2012 Google Inc. 3f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * 4f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 5f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com * found in the LICENSE file. 6f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com */ 7f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 8f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#ifndef GrGLShaderBuilder_DEFINED 9f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#define GrGLShaderBuilder_DEFINED 10f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 11f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "GrAllocator.h" 122eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrBackendEffectFactory.h" 13b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com#include "GrColor.h" 14a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com#include "GrEffect.h" 15f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#include "gl/GrGLSL.h" 16dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "gl/GrGLUniformManager.h" 17f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 18f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com#include <stdarg.h> 19f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 20ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comclass GrGLContextInfo; 21c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.comclass GrEffectStage; 2226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.comclass GrGLProgramDesc; 23dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 24f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com/** 25eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com Contains all the incremental state of a shader as it is being built,as well as helpers to 26eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com manipulate that state. 27f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com*/ 28f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.comclass GrGLShaderBuilder { 29f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.compublic: 30f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com /** 3134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * Passed to GrGLEffects to add texture reads to their shader code. 32f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com */ 33f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com class TextureSampler { 34f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com public: 35f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com TextureSampler() 36b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com : fConfigComponentMask(0) 37b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com , fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) { 38b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is 39b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com // terminated. 40b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com fSwizzle[4] = '\0'; 41b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com } 42f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 43f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com TextureSampler(const TextureSampler& other) { *this = other; } 44f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 45f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com TextureSampler& operator= (const TextureSampler& other) { 46b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com GrAssert(0 == fConfigComponentMask); 47f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform); 48f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 49b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com fConfigComponentMask = other.fConfigComponentMask; 50f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com fSamplerUniform = other.fSamplerUniform; 51f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com return *this; 52f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com } 53f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 54b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com // bitfield of GrColorComponentFlags present in the texture's config. 55b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com uint32_t configComponentMask() const { return fConfigComponentMask; } 56b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com 57b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com const char* swizzle() const { return fSwizzle; } 58f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 5926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com bool isInitialized() const { return 0 != fConfigComponentMask; } 6026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 61f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com private: 6234cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // The idx param is used to ensure multiple samplers within a single effect have unique 63b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'. 64b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com void init(GrGLShaderBuilder* builder, 65b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com uint32_t configComponentMask, 66b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com const char* swizzle, 67b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com int idx) { 6826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrAssert(!this->isInitialized()); 6926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrAssert(0 != configComponentMask); 70f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform); 71f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 72f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com GrAssert(NULL != builder); 7334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com SkString name; 7434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com name.printf("Sampler%d_", idx); 75f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 76f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com kSampler2D_GrSLType, 7734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com name.c_str()); 78f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform); 79f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 80b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com fConfigComponentMask = configComponentMask; 81b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com memcpy(fSwizzle, swizzle, 4); 82b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com } 83b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com 84b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) { 85b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com GrAssert(NULL != access); 86b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com this->init(builder, 87b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com GrPixelConfigComponentMask(access->getTexture()->config()), 88b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com access->getSwizzle(), 89b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com idx); 90f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com } 91f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 92b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com uint32_t fConfigComponentMask; 93b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com char fSwizzle[5]; 94f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com GrGLUniformManager::UniformHandle fSamplerUniform; 95f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 96b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com friend class GrGLShaderBuilder; // to call init(). 97f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com }; 98f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 99f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com typedef SkTArray<TextureSampler> TextureSamplerArray; 100f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com 101eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com enum ShaderType { 102eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com kVertex_ShaderType = 0x1, 103eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com kGeometry_ShaderType = 0x2, 104eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com kFragment_ShaderType = 0x4, 105eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com }; 106eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com 10726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&); 108f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 109f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com /** 110f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com * Called by GrGLEffects to add code to one of the shaders. 111f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com */ 112f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 113f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_list args; 114f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_start(args, format); 115f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com this->codeAppendf(kVertex_ShaderType, format, args); 116f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_end(args); 117f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 118f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 119f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 120f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_list args; 121f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_start(args, format); 122f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com this->codeAppendf(kGeometry_ShaderType, format, args); 123f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_end(args); 124f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 125f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 126f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { 127f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_list args; 128f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_start(args, format); 129f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com this->codeAppendf(kFragment_ShaderType, format, args); 130f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com va_end(args); 131f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com } 132f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 133f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, str); } 134f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType, str); } 135f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType, str); } 136f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 137dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or 138dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle 139dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com order of the result depends on the GrTextureAccess associated with the TextureSampler. */ 140868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com void appendTextureLookup(SkString* out, 141f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const TextureSampler&, 142dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com const char* coordName, 143868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com GrSLType coordType = kVec2f_GrSLType) const; 144868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com 145f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com /** Version of above that appends the result to the shader code rather than an SkString. 146f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com Currently the shader type must be kFragment */ 147f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void appendTextureLookup(ShaderType, 148f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com const TextureSampler&, 149f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com const char* coordName, 150f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrSLType coordType = kVec2f_GrSLType); 151f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 152f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 1532d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com /** Does the work of appendTextureLookup and modulates the result by modulation. The result is 1542d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or 1552d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com float. If modulation is "" or NULL it this function acts as though appendTextureLookup were 1562d8edaf17510e50261b8a4e2a0daf7e617674999bsalomon@google.com called. */ 157f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void appendTextureLookupAndModulate(ShaderType, 158868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com const char* modulation, 159f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com const TextureSampler&, 160dbe49f735484f8862e378b63d0a074a301093dd0bsalomon@google.com const char* coordName, 161f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrSLType coordType = kVec2f_GrSLType); 16234bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com 163a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com /** Emits a helper function outside of main(). Currently ShaderType must be 164a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com kFragment_ShaderType. */ 165a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com void emitFunction(ShaderType shader, 166a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com GrSLType returnType, 167a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const char* name, 168a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com int argCnt, 169a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const GrGLShaderVar* args, 170a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com const char* body, 171a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkString* outName); 172a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 17346fba0d79335f17429bb71d87a04d93fb2ee992bbsalomon@google.com /** Generates a EffectKey for the shader code based on the texture access parameters and the 174a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com capabilities of the GL context. This is useful for keying the shader programs that may 175a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com have multiple representations, based on the type/format of textures used. */ 1762eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&, 1772eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const GrGLCaps&); 178a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 17926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com typedef uint8_t DstReadKey; 18026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 18126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com /** Returns a key for adding code to read the copy-of-dst color in service of effects that 18226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com require reading the dst. It must not return 0 because 0 indicates that there is no dst 18326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com copy read at all. */ 18426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); 18526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 1866d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com /** If texture swizzling is available using tex parameters then it is preferred over mangling 1876d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com the generated shader code. This potentially allows greater reuse of cached shaders. */ 1886d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps); 1896d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com 190706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com /** Add a uniform variable to the current program, that has visibility in one or more shaders. 191777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com visibility is a bitfield of ShaderType values indicating from which shaders the uniform 192777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com should be accessible. At least one bit must be set. Geometry shader uniforms are not 193777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com supported at this time. The actual uniform name will be mangled. If outName is not NULL then 194777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com it will refer to the final uniform name after return. Use the addUniformArray variant to add 195777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com an array of uniforms. 196242ed6fb6c3c0dff780ed3bef47d36a3b34a352ctomhudson@google.com */ 197dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GrGLUniformManager::UniformHandle addUniform(uint32_t visibility, 198dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GrSLType type, 199dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com const char* name, 200777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com const char** outName = NULL) { 201777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName); 202777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com } 203777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility, 204777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com GrSLType type, 205777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com const char* name, 206777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com int arrayCount, 207777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com const char** outName = NULL); 208032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 209dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle) const; 210032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 211032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com /** 212706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com * Shortcut for getUniformVariable(u).c_str() 213032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com */ 214dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const { 215032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com return this->getUniformVariable(u).c_str(); 216032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com } 217eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com 218ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org /** Add a vertex attribute to the current program that is passed in from the vertex data. 219ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org Returns false if the attribute was already there, true otherwise. */ 220ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org bool addAttribute(GrSLType type, const char* name); 221ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 222ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org /** Add a varying variable to the current program to pass values between vertex and fragment 223eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com shaders. If the last two parameters are non-NULL, they are filled in with the name 224eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com generated. */ 22523cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com void addVarying(GrSLType type, 22623cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char* name, 22723cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char** vsOutName = NULL, 22823cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com const char** fsInName = NULL); 22923cb2299ddf8fc87df0d3f9bda78934382cf714dtomhudson@google.com 230706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com /** Returns a variable name that represents the position of the fragment in the FS. The position 231706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */ 232706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com const char* fragmentPosition(); 233706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com 23417504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com /** Returns a vertex attribute that represents the vertex position in the VS. This is the 23517504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com pre-matrix position and is commonly used by effects to compute texture coords via a matrix. 23617504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com */ 23717504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } 23817504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com 239c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com /** Returns a vertex attribute that represents the local coords in the VS. This may be the same 240c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com as positionAttribute() or it may not be. It depends upon whether the rendering code 241c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com specified explicit local coords or not in the GrDrawState. */ 242c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; } 243c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com 24426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com /** Returns the color of the destination pixel. This may be NULL if no effect advertised 24526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com that it will read the destination. */ 24626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const char* dstColor() const; 24726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 248c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com /** 249c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com * Are explicit local coordinates provided as input to the vertex shader. 250c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com */ 251c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); } 252c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com 253dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com /** 25434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * Interfaces used by GrGLProgram. 25534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * TODO: Hide these from the GrEffects using friend or splitting this into two related classes. 25634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * Also, GrGLProgram's shader string construction should be moved to this class. 257dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com */ 258dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 25934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com /** Called after building is complete to get the final shader string. */ 26034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com void getShader(ShaderType, SkString*) const; 26134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com 26208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com void setCurrentStage(int stageIdx) { fCurrentStageIdx = stageIdx; } 26308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com void setNonStage() { fCurrentStageIdx = kNonStageIdx; } 26434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // TODO: move remainder of shader code generation to this class and call this privately 26534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // Handles of sampler uniforms generated for the effect are appended to samplerHandles. 26634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com GrGLEffect* createAndEmitGLEffect( 26734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const GrEffectStage& stage, 26834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com GrBackendEffectFactory::EffectKey key, 26934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const char* fsInColor, // NULL means no incoming color 27034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com const char* fsOutColor, 27134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles); 27226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 273706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; } 27426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const { 27526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com return fDstCopyTopLeftUniform; 27626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 27726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const { 27826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com return fDstCopyScaleUniform; 27926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 28026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const { 28126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com return fDstCopySampler.fSamplerUniform; 28226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com } 283ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 284ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org struct AttributePair { 285ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org void set(int index, const SkString& name) { 286ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org fIndex = index; fName = name; 287ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 288ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org int fIndex; 289ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org SkString fName; 290ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org }; 29126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const SkTArray<AttributePair, true>& getEffectAttributes() const { 292ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org return fEffectAttributes; 293ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org } 294ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org const SkString* getEffectAttributeName(int attributeIndex) const; 295ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 29634cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // TODO: Make this do all the compiling, linking, etc. 29734cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com void finished(GrGLuint programID); 298706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com 29913f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } 30013f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com 301032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.comprivate: 302f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void codeAppendf(ShaderType type, const char format[], va_list args); 303f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com void codeAppend(ShaderType type, const char* str); 304f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 305dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com typedef GrTAllocator<GrGLShaderVar> VarArray; 306032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 307032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com void appendDecls(const VarArray&, SkString*) const; 308032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com void appendUniformDecls(ShaderType, SkString*) const; 309032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 310dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com typedef GrGLUniformManager::BuilderUniform BuilderUniform; 311dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GrGLUniformManager::BuilderUniformArray fUniforms; 312032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.com 313eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com // TODO: Everything below here private. 314032b221dadb6eb8283ac2d1bc8913ee7bb5cfe7absalomon@google.compublic: 315eb715c8d5caa2191d611c4f9cfb22b4afc6c8d02bsalomon@google.com 316f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com SkString fHeader; // VS+FS, GLSL version, etc 317f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fVSAttrs; 318f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fVSOutputs; 319f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fGSInputs; 320f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fGSOutputs; 321f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fFSInputs; 322f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com SkString fGSHeader; // layout qualifiers specific to GS 323f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com VarArray fFSOutputs; 324040c41a97c58b069015be3f5062eeb6ffe5adbfdtomhudson@google.com 325ad5e937c110efaf9630159d2859fabc4f38f7ab2bsalomon@google.comprivate: 326777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com enum { 327777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com kNonStageIdx = -1, 328777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com }; 329777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com 33026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com // Interpretation of DstReadKey when generating code 33126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com enum { 33226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com kNoDstRead_DstReadKey = 0, 33326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read. 33426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only. 33526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left. 33626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com }; 33726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 3386177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com const GrGLContextInfo& fCtxInfo; 339706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com GrGLUniformManager& fUniformManager; 34008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com int fCurrentStageIdx; 341706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com SkString fFSFunctions; 342706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com SkString fFSHeader; 343706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com 34426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com bool fUsesGS; 34526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 346f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString fFSCode; 347f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString fVSCode; 348f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString fGSCode; 349f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com 350706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com bool fSetupFragPosition; 35126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com TextureSampler fDstCopySampler; 35226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 353706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com GrGLUniformManager::UniformHandle fRTHeightUniform; 35426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform; 35526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com GrGLUniformManager::UniformHandle fDstCopyScaleUniform; 35634bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com 357ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org SkSTArray<10, AttributePair, true> fEffectAttributes; 358ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 35917504f5d5ea2550d29d2118193627129beb7f8b2bsalomon@google.com GrGLShaderVar* fPositionVar; 360c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com GrGLShaderVar* fLocalCoordsVar; 361c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com 362f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com}; 363f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com 364f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.com#endif 365