GrGLProgram.cpp revision 46d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24
1b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/* 2b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Copyright 2011 Google Inc. 3b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 4b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Use of this source code is governed by a BSD-style license that can be 5b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * found in the LICENSE file. 6b1928704201034c785a26296a49f69355eb56a05Nick Lewycky */ 7b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 8b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrGLProgram.h" 9b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 10b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrAllocator.h" 11b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrEffect.h" 12b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrGLEffect.h" 13b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrGpuGL.h" 14b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrGLShaderVar.h" 15b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "GrBackendEffectFactory.h" 16b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "SkTrace.h" 17b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "SkXfermode.h" 18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 19b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "SkRTConf.h" 20b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 210bcbd1df7a204e1e512f1a27066d725309de1b13Bill WendlingSK_DEFINE_INST_COUNT(GrGLProgram) 2206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth 2306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#define GL_CALL(X) GR_GL_CALL(fContextInfo.interface(), X) 24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fContextInfo.interface(), R, X) 25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 26b1928704201034c785a26296a49f69355eb56a05Nick LewyckySK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, "Print the source code for all shaders generated."); 27b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#define COL_ATTR_NAME "aColor" 29b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define COV_ATTR_NAME "aCoverage" 30b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define EDGE_ATTR_NAME "aEdge" 31b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 3206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruthnamespace { 3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruthinline void tex_attr_name(int coordIdx, SkString* s) { 3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth *s = "aTexCoord"; 3506cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth s->appendS32(coordIdx); 3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth} 3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth 38b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyinline const char* declared_color_output_name() { return "fsColorOut"; } 39b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyinline const char* dual_source_output_name() { return "dualSourceOut"; } 40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 42b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 43b1928704201034c785a26296a49f69355eb56a05Nick LewyckyGrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl, 44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const Desc& desc, 45b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const GrEffectStage* stages[]) { 46a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, stages)); 47bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!program->succeeded()) { 48bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky delete program; 49a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky program = NULL; 50a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 51bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return program; 52bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky} 53f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling 54bba40db07234cef7867b45c67f50632e684cbb15Nick LewyckyGrGLProgram::GrGLProgram(const GrGLContextInfo& gl, 55a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky const Desc& desc, 56b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const GrEffectStage* stages[]) 57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky: fContextInfo(gl) 58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky, fUniformManager(gl) { 59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fDesc = desc; 60b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fVShaderID = 0; 61b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fGShaderID = 0; 62269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky fFShaderID = 0; 63269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky fProgramID = 0; 64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 65f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel fViewMatrix = SkMatrix::InvalidMatrix(); 66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fViewportSize.set(-1, -1); 670c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky fColor = GrColor_ILLEGAL; 680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky fColorFilterColor = GrColor_ILLEGAL; 69f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel fRTHeight = -1; 700c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 71b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (int s = 0; s < GrDrawState::kNumStages; ++s) { 72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fEffects[s] = NULL; 7377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 74b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->genProgram(stages); 76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 781790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGrGLProgram::~GrGLProgram() { 791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fVShaderID) { 801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GL_CALL(DeleteShader(fVShaderID)); 811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fGShaderID) { 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GL_CALL(DeleteShader(fGShaderID)); 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fFShaderID) { 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GL_CALL(DeleteShader(fFShaderID)); 871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fProgramID) { 89b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GL_CALL(DeleteProgram(fProgramID)); 90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 9121b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling 9277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling for (int i = 0; i < GrDrawState::kNumStages; ++i) { 93253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling delete fEffects[i]; 94b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 9573996f44070df026e4d969b1b68461a70ebb3993Bill Wendling} 96269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 97a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewyckyvoid GrGLProgram::abandon() { 98a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky fVShaderID = 0; 99f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling fGShaderID = 0; 100bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky fFShaderID = 0; 101a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky fProgramID = 0; 1021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 103b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 104b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, 105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrBlendCoeff* dstCoeff) const { 106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (fDesc.fDualSrcOutput) { 107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case Desc::kNone_DualSrcOutput: 108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 109b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // the prog will write a coverage value to the secondary 110b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // output and the dst is blended by one minus that value. 111f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling case Desc::kCoverage_DualSrcOutput: 1127c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky case Desc::kCoverageISA_DualSrcOutput: 1137c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky case Desc::kCoverageISC_DualSrcOutput: 1147c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; 115a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky break; 116b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 117b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrCrash("Unexpected dual source blend output"); 118b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 119b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 1201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 1211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckynamespace { 1231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 124b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// given two blend coeffecients determine whether the src 125b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// and/or dst computation can be omitted. 126b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyinline void need_blend_inputs(SkXfermode::Coeff srcCoeff, 1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkXfermode::Coeff dstCoeff, 1281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky bool* needSrcValue, 129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky bool* needDstValue) { 130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (SkXfermode::kZero_Coeff == srcCoeff) { 1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (dstCoeff) { 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // these all read the src 133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kSC_Coeff: 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kISC_Coeff: 135b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kSA_Coeff: 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kISA_Coeff: 1371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *needSrcValue = true; 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 13917df2c3240837b4382898ead8c3ead407a338520Nick Lewycky default: 14017df2c3240837b4382898ead8c3ead407a338520Nick Lewycky *needSrcValue = false; 141d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky break; 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } else { 1441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *needSrcValue = true; 1451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 1461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (SkXfermode::kZero_Coeff == dstCoeff) { 1471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (srcCoeff) { 148b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // these all read the dst 149b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kDC_Coeff: 1507a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case SkXfermode::kIDC_Coeff: 1517a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case SkXfermode::kDA_Coeff: 1527a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case SkXfermode::kIDA_Coeff: 153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky *needDstValue = true; 154b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky *needDstValue = false; 1571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky break; 1581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 1591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } else { 1601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *needDstValue = true; 161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 164b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/** 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Create a blend_coeff * value string to be used in shader code. Sets empty 16616c19a155c65fd41865562fe4e678ef32728510bDevang Patel * string if result is trivially zero. 16716c19a155c65fd41865562fe4e678ef32728510bDevang Patel */ 168b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyinline void blend_term_string(SkString* str, SkXfermode::Coeff coeff, 169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const char* src, const char* dst, 1701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char* value) { 1711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (coeff) { 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kZero_Coeff: /** 0 */ 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky *str = ""; 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky break; 175bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case SkXfermode::kOne_Coeff: /** 1 */ 17616c19a155c65fd41865562fe4e678ef32728510bDevang Patel *str = value; 177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 178b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kSC_Coeff: 17916c19a155c65fd41865562fe4e678ef32728510bDevang Patel str->printf("(%s * %s)", src, value); 18016c19a155c65fd41865562fe4e678ef32728510bDevang Patel break; 18116c19a155c65fd41865562fe4e678ef32728510bDevang Patel case SkXfermode::kISC_Coeff: 18216c19a155c65fd41865562fe4e678ef32728510bDevang Patel str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), src, value); 18316c19a155c65fd41865562fe4e678ef32728510bDevang Patel break; 18416c19a155c65fd41865562fe4e678ef32728510bDevang Patel case SkXfermode::kDC_Coeff: 185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky str->printf("(%s * %s)", dst, value); 18616c19a155c65fd41865562fe4e678ef32728510bDevang Patel break; 18716c19a155c65fd41865562fe4e678ef32728510bDevang Patel case SkXfermode::kIDC_Coeff: 188b1928704201034c785a26296a49f69355eb56a05Nick Lewycky str->printf("((%s - %s) * %s)", GrGLSLOnesVecf(4), dst, value); 189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kSA_Coeff: /** src alpha */ 191680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel str->printf("(%s.a * %s)", src, value); 19216c19a155c65fd41865562fe4e678ef32728510bDevang Patel break; 1931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky str->printf("((1.0 - %s.a) * %s)", src, value); 195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kDA_Coeff: /** dst alpha */ 197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky str->printf("(%s.a * %s)", dst, value); 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky str->printf("((1.0 - %s.a) * %s)", dst, value); 20168155d31cd0175be89e26ee68387cb411fca537bDevang Patel break; 2021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 2031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrCrash("Unexpected xfer coeff."); 20416c19a155c65fd41865562fe4e678ef32728510bDevang Patel break; 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 207b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/** 208b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Adds a line to the fragment shader code which modifies the color by 2091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * the specified color filter. 2101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky */ 211b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid add_color_filter(SkString* fsCode, const char * outputVar, 212b1928704201034c785a26296a49f69355eb56a05Nick Lewycky SkXfermode::Coeff uniformCoeff, 2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkXfermode::Coeff colorCoeff, 2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char* filterColor, 2151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char* inColor) { 2161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkString colorStr, constStr; 21716c19a155c65fd41865562fe4e678ef32728510bDevang Patel blend_term_string(&colorStr, colorCoeff, filterColor, inColor, inColor); 218b1928704201034c785a26296a49f69355eb56a05Nick Lewycky blend_term_string(&constStr, uniformCoeff, filterColor, inColor, filterColor); 219b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fsCode->appendf("\t%s = ", outputVar); 2211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrGLSLAdd4f(fsCode, colorStr.c_str(), constStr.c_str()); 2221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fsCode->append(";\n"); 2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel} 22516c19a155c65fd41865562fe4e678ef32728510bDevang Patel 2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckybool GrGLProgram::genEdgeCoverage(SkString* coverageVar, 2271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrGLShaderBuilder* builder) const { 228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (fDesc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) { 229b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const char *vsName, *fsName; 230b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->addVarying(kVec4f_GrSLType, "Edge", &vsName, &fsName); 2311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fVSAttrs.push_back().set(kVec4f_GrSLType, 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrGLShaderVar::kAttribute_TypeModifier, 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky EDGE_ATTR_NAME); 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (fDesc.fVertexEdgeType) { 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GrDrawState::kHairLine_EdgeType: 2371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", builder->fragmentPosition(), fsName); 2381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GrDrawState::kQuad_EdgeType: 241b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.append("\tfloat edgeAlpha;\n"); 2421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // keep the derivative instructions outside the conditional 2431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 2441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.appendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); 246b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // today we know z and w are in device space. We could use derivatives 247b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.appendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, fsName); 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.append ("\t} else {\n"); 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.appendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky fsName, fsName); 252bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky builder->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); 253bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky builder->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n" 254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "\t}\n"); 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (kES2_GrGLBinding == fContextInfo.binding()) { 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); 257bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GrDrawState::kHairQuad_EdgeType: 2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 261b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 2621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fsName, fsName); 265f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling builder->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); 2661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); 267bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky builder->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 268bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (kES2_GrGLBinding == fContextInfo.binding()) { 2691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 2711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky break; 272bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GrDrawState::kCircle_EdgeType: 273bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky builder->fFSCode.append("\tfloat edgeAlpha;\n"); 274bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky builder->fFSCode.appendf("\tfloat d = distance(%s.xy, %s.xy);\n", builder->fragmentPosition(), fsName); 2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tfloat outerAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); 2761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tfloat innerAlpha = %s.w == 0.0 ? 1.0 : smoothstep(%s.w - 0.5, %s.w + 0.5, d);\n", fsName, fsName, fsName); 2771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.append("\tedgeAlpha = outerAlpha * innerAlpha;\n"); 278b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 279b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GrDrawState::kEllipse_EdgeType: 280b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.append("\tfloat edgeAlpha;\n"); 2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\tvec2 offset = (%s.xy - %s.xy);\n", builder->fragmentPosition(), fsName); 2821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fFSCode.appendf("\toffset.y *= %s.w;\n", fsName); 283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.append("\tfloat d = length(offset);\n"); 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder->fFSCode.appendf("\tedgeAlpha = smoothstep(d - 0.5, d + 0.5, %s.z);\n", fsName); 2851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky break; 2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrCrash("Unknown Edge Type!"); 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 2891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fDesc.fDiscardIfOutsideEdge) { 291a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky builder->fFSCode.appendf("\tif (edgeAlpha <= 0.0) {\n\t\tdiscard;\n\t}\n"); 292a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 2931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *coverageVar = "edgeAlpha"; 294b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return true; 2951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } else { 2961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky coverageVar->reset(); 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return false; 2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 299b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 300bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 301b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { 302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (fDesc.fColorInput) { 3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GrGLProgram::Desc::kAttribute_ColorInput: { 3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fVSAttrs.push_back().set(kVec4f_GrSLType, 3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrGLShaderVar::kAttribute_TypeModifier, 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky COL_ATTR_NAME); 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *vsName, *fsName; 3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); 3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName); 3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *inColor = fsName; 3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } break; 312bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GrGLProgram::Desc::kUniform_ColorInput: { 313bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const char* name; 3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fUniformHandles.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky kVec4f_GrSLType, "Color", &name); 316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky *inColor = name; 317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 318b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 319b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GrGLProgram::Desc::kTransBlack_ColorInput: 3201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrAssert(!"needComputedColor should be false."); 3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky break; 3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GrGLProgram::Desc::kSolidWhite_ColorInput: 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 325b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrCrash("Unknown color type."); 326b1928704201034c785a26296a49f69355eb56a05Nick Lewycky break; 3271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 3281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 330b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid GrGLProgram::genUniformCoverage(GrGLShaderBuilder* builder, SkString* inOutCoverage) { 331b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const char* covUniName; 33273996f44070df026e4d969b1b68461a70ebb3993Bill Wendling fUniformHandles.fCoverageUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 333269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky kVec4f_GrSLType, "Coverage", &covUniName); 334269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (inOutCoverage->size()) { 335269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky builder->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", 336269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky covUniName, inOutCoverage->c_str()); 337fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky *inOutCoverage = "uniCoverage"; 338269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } else { 339fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky *inOutCoverage = covUniName; 340fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 3416e5190c193f6267893daf6943af88e95039e739cBill Wendling} 3426e5190c193f6267893daf6943af88e95039e739cBill Wendling 3436e5190c193f6267893daf6943af88e95039e739cBill Wendlingnamespace { 344fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewyckyvoid gen_attribute_coverage(GrGLShaderBuilder* segments, 345269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky SkString* inOutCoverage) { 346269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky segments->fVSAttrs.push_back().set(kVec4f_GrSLType, 347fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky GrGLShaderVar::kAttribute_TypeModifier, 3486e5190c193f6267893daf6943af88e95039e739cBill Wendling COV_ATTR_NAME); 349fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky const char *vsName, *fsName; 3506e5190c193f6267893daf6943af88e95039e739cBill Wendling segments->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); 351269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName); 352269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (inOutCoverage->size()) { 3530c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n", 3541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fsName, inOutCoverage->c_str()); 3550c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky *inOutCoverage = "attrCoverage"; 3560c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky } else { 357f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel *inOutCoverage = fsName; 358f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 359a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 3600c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3610c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GrGLProgram::genGeometryShader(GrGLShaderBuilder* segments) const { 363f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel#if GR_GL_EXPERIMENTAL_GS 364bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (fDesc.fExperimentalGS) { 365bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrAssert(fContextInfo.glslGeneration() >= k150_GrGLSLGeneration); 366bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSHeader.append("layout(triangles) in;\n" 367bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky "layout(triangle_strip, max_vertices = 6) out;\n"); 368bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSCode.append("\tfor (int i = 0; i < 3; ++i) {\n" 369bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky "\t\tgl_Position = gl_in[i].gl_Position;\n"); 370bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (fDesc.fEmitsPointSize) { 371bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSCode.append("\t\tgl_PointSize = 1.0;\n"); 372bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrAssert(segments->fGSInputs.count() == segments->fGSOutputs.count()); 374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky int count = segments->fGSInputs.count(); 375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i < count; ++i) { 376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSCode.appendf("\t\t%s = %s[i];\n", 377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSOutputs[i].getName().c_str(), 378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSInputs[i].getName().c_str()); 379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky segments->fGSCode.append("\t\tEmitVertex();\n" 381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky "\t}\n" 382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky "\tEndPrimitive();\n"); 383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 384bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky#endif 385bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky} 386bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewyckyconst char* GrGLProgram::adjustInColor(const SkString& inColor) const { 388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (inColor.size()) { 389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return inColor.c_str(); 390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else { 391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Desc::kSolidWhite_ColorInput == fDesc.fColorInput) { 392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GrGLSLOnesVecf(4); 393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else { 394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GrGLSLZerosVecf(4); 395f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 396bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky} 398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 399bba40db07234cef7867b45c67f50632e684cbb15Nick Lewyckynamespace { 400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky// prints a shader using params similar to glShaderSource 401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewyckyvoid print_shader(GrGLint stringCnt, 402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const GrGLchar** strings, 403bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrGLint* stringLengths) { 404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i < stringCnt; ++i) { 405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (NULL == stringLengths || stringLengths[i] < 0) { 406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrPrintf(strings[i]); 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else { 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrPrintf("%.*s", stringLengths[i], strings[i]); 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 411b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 412b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky// Compiles a GL shader, returns shader ID or 0 if failed params have same meaning as glShaderSource 414b1928704201034c785a26296a49f69355eb56a05Nick LewyckyGrGLuint compile_shader(const GrGLContextInfo& gl, 415bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GrGLenum type, 416bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky int stringCnt, 417b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const char** strings, 418b1928704201034c785a26296a49f69355eb56a05Nick Lewycky int* stringLengths) { 419b1928704201034c785a26296a49f69355eb56a05Nick Lewycky SK_TRACE_EVENT1("GrGLProgram::CompileShader", 420f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel "stringCount", SkStringPrintf("%i", stringCnt).c_str()); 421f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 422f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLuint shader; 423f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL_RET(gl.interface(), shader, CreateShader(type)); 424f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (0 == shader) { 42577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return 0; 426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel const GrGLInterface* gli = gl.interface(); 429f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLint compiled = GR_GL_INIT_ZERO; 430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL(gli, ShaderSource(shader, stringCnt, strings, stringLengths)); 431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL(gli, CompileShader(shader)); 432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); 433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!compiled) { 435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLint infoLen = GR_GL_INIT_ZERO; 436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL(gli, GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (infoLen > 0) { 439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // retrieve length even though we don't need it to workaround bug in chrome cmd buffer 440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // param validation. 441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLsizei length = GR_GL_INIT_ZERO; 442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GR_GL_CALL(gli, GetShaderInfoLog(shader, infoLen+1, 443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel &length, (char*)log.get())); 444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel print_shader(stringCnt, strings, stringLengths); 445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf("\n%s", log.get()); 4461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrAssert(!"Shader compilation failed!"); 4481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GR_GL_CALL(gli, DeleteShader(shader)); 449b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return 0; 4501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 451ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg return shader; 452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 453f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 454f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel// helper version of above for when shader is already flattened into a single SkString 455f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang PatelGrGLuint compile_shader(const GrGLContextInfo& gl, GrGLenum type, const SkString& shader) { 456f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel const GrGLchar* str = shader.c_str(); 457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int length = shader.size(); 458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return compile_shader(gl, type, 1, &str, &length); 459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel// compiles all the shaders from builder and stores the shader IDs 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SkString shader; 467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel builder.getShader(GrGLShaderBuilder::kVertex_ShaderType, &shader); 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (c_PrintShaders) { 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf(shader.c_str()); 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf("\n"); 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 473b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 4741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!(fVShaderID = compile_shader(fContextInfo, GR_GL_VERTEX_SHADER, shader))) { 4751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return false; 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (builder.fUsesGS) { 479f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel builder.getShader(GrGLShaderBuilder::kGeometry_ShaderType, &shader); 480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (c_PrintShaders) { 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf(shader.c_str()); 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf("\n"); 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!(fGShaderID = compile_shader(fContextInfo, GR_GL_GEOMETRY_SHADER, shader))) { 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return false; 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel fGShaderID = 0; 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 490b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 491b1928704201034c785a26296a49f69355eb56a05Nick Lewycky builder.getShader(GrGLShaderBuilder::kFragment_ShaderType, &shader); 492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (c_PrintShaders) { 493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf(shader.c_str()); 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrPrintf("\n"); 4951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 4961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!(fFShaderID = compile_shader(fContextInfo, GR_GL_FRAGMENT_SHADER, shader))) { 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return false; 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 500f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return true; 501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GrGLProgram::genProgram(const GrEffectStage* stages[]) { 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrAssert(0 == fProgramID); 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 50677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GrGLShaderBuilder builder(fContextInfo, fUniformManager); 50777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling const uint32_t& layout = fDesc.fVertexLayout; 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel#if GR_GL_EXPERIMENTAL_GS 5101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.fUsesGS = fDesc.fExperimentalGS; 5111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky#endif 512c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 513c7a884040e4ec7795515978a94803894ad08c4caBill Wendling SkXfermode::Coeff colorCoeff, uniformCoeff; 51477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // The rest of transfer mode color filters have not been implemented 51577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { 51677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GR_DEBUGCODE(bool success =) 517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> 518b1928704201034c785a26296a49f69355eb56a05Nick Lewycky (fDesc.fColorFilterXfermode), 519b1928704201034c785a26296a49f69355eb56a05Nick Lewycky &uniformCoeff, &colorCoeff); 5204a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling GR_DEBUGASSERT(success); 521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 522253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling colorCoeff = SkXfermode::kOne_Coeff; 523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uniformCoeff = SkXfermode::kZero_Coeff; 52477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 52577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 52677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // no need to do the color filter if coverage is 0. The output color is scaled by the coverage. 52777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // All the dual source outputs are scaled by the coverage as well. 528f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) { 529b1928704201034c785a26296a49f69355eb56a05Nick Lewycky colorCoeff = SkXfermode::kZero_Coeff; 530b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uniformCoeff = SkXfermode::kZero_Coeff; 5311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // If we know the final color is going to be all zeros then we can 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // simplify the color filter coefficients. needComputedColor will then 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // come out false below. 5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) { 5371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky colorCoeff = SkXfermode::kZero_Coeff; 5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (SkXfermode::kDC_Coeff == uniformCoeff || 5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkXfermode::kDA_Coeff == uniformCoeff) { 5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uniformCoeff = SkXfermode::kZero_Coeff; 5411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } else if (SkXfermode::kIDC_Coeff == uniformCoeff || 5421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkXfermode::kIDA_Coeff == uniformCoeff) { 543db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner uniformCoeff = SkXfermode::kOne_Coeff; 544db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner } 5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky bool needColorFilterUniform; 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky bool needComputedColor; 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky need_blend_inputs(uniformCoeff, colorCoeff, 5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky &needColorFilterUniform, &needComputedColor); 5511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the dual source output has no canonical var name, have to 5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // declare an output, which is incompatible with gl_FragColor/gl_FragData. 5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky bool dualSourceOutputWritten = false; 5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.fHeader.append(GrGetGLSLVersionDecl(fContextInfo.binding(), 5567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky fContextInfo.glslGeneration())); 5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GrGLShaderVar colorOutput; 5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky bool isColorDeclared = GrGLSLSetupFSColorOuput(fContextInfo.glslGeneration(), 5601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky declared_color_output_name(), 5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky &colorOutput); 5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (isColorDeclared) { 5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.fFSOutputs.push_back(colorOutput); 5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char* viewMName; 5671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fUniformHandles.fViewMatrixUni = builder.addUniform(GrGLShaderBuilder::kVertex_ShaderType, 5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky kMat33f_GrSLType, "ViewM", &viewMName); 569267010864e139781ef5949939e081c41f954de0aJay Foad 5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.fVSCode.appendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" 5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", 573267010864e139781ef5949939e081c41f954de0aJay Foad viewMName, builder.positionAttribute().getName().c_str()); 5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // incoming color to current stage being processed. 5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SkString inColor; 5771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (needComputedColor) { 579b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->genInputColor(&builder, &inColor); 580db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner } 5815fdd6c8793462549e3593890ec61573da06e3346Jay Foad 5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // we output point size in the GS if present 5831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (fDesc.fEmitsPointSize && !builder.fUsesGS){ 5841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.fVSCode.append("\tgl_PointSize = 1.0;\n"); 58577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 58677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 587c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // add texture coordinates that are used to the list of vertex attr decls 58877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling SkString texCoordAttrs[GrDrawState::kMaxTexCoords]; 58977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 59077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) { 59177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling tex_attr_name(t, texCoordAttrs + t); 59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.fVSAttrs.push_back().set(kVec2f_GrSLType, 59377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GrGLShaderVar::kAttribute_TypeModifier, 594b1928704201034c785a26296a49f69355eb56a05Nick Lewycky texCoordAttrs[t].c_str()); 595b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 596b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 5975fdd6c8793462549e3593890ec61573da06e3346Jay Foad 5985409a188328d9de3755febc23558d4fc1797d04eNick Lewycky /////////////////////////////////////////////////////////////////////////// 5995409a188328d9de3755febc23558d4fc1797d04eNick Lewycky // compute the final color 6005409a188328d9de3755febc23558d4fc1797d04eNick Lewycky 601c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // if we have color stages string them together, feeding the output color 6021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // of each to the next and generating code for each stage. 603b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (needComputedColor) { 604b1928704201034c785a26296a49f69355eb56a05Nick Lewycky SkString outColor; 605b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (int s = 0; s < fDesc.fFirstCoverageStage; ++s) { 6065fdd6c8793462549e3593890ec61573da06e3346Jay Foad if (GrGLEffect::kNoEffectKey != fDesc.fEffectKeys[s]) { 607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // create var to hold stage result 608b1928704201034c785a26296a49f69355eb56a05Nick Lewycky outColor = "color"; 609b1928704201034c785a26296a49f69355eb56a05Nick Lewycky outColor.appendS32(s); 610db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner builder.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str()); 611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char* inCoords; 613b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // figure out what our input coords are 614b1928704201034c785a26296a49f69355eb56a05Nick Lewycky int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout); 615b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (tcIdx < 0) { 616db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner inCoords = builder.positionAttribute().c_str(); 6171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } else { 618b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // must have input tex coordinates if stage is enabled. 619b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GrAssert(texCoordAttrs[tcIdx].size()); 6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky inCoords = texCoordAttrs[tcIdx].c_str(); 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.setCurrentStage(s); 6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fEffects[s] = builder.createAndEmitGLEffect(*stages[s], 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky fDesc.fEffectKeys[s], 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky inColor.size() ? inColor.c_str() : NULL, 6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky outColor.c_str(), 6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky inCoords, 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky &fUniformHandles.fSamplerUnis[s]); 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky builder.setNonStage(); 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky inColor = outColor; 632b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 63421b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling } 635253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 636253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // if have all ones or zeros for the "dst" input to the color filter then we 637253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // may be able to make additional optimizations. 638253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (needColorFilterUniform && needComputedColor && !inColor.size()) { 639253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling GrAssert(Desc::kSolidWhite_ColorInput == fDesc.fColorInput); 640b1928704201034c785a26296a49f69355eb56a05Nick Lewycky bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff || 641253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling SkXfermode::kIDA_Coeff == uniformCoeff; 642253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (uniformCoeffIsZero) { 6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uniformCoeff = SkXfermode::kZero_Coeff; 644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky bool bogus; 645b1928704201034c785a26296a49f69355eb56a05Nick Lewycky need_blend_inputs(SkXfermode::kZero_Coeff, colorCoeff, 646b1928704201034c785a26296a49f69355eb56a05Nick Lewycky &needColorFilterUniform, &bogus); 647b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 648b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 649b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const char* colorFilterColorUniName = NULL; 650f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (needColorFilterUniform) { 651f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel fUniformHandles.fColorFilterUni = builder.addUniform( 652f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLShaderBuilder::kFragment_ShaderType, 653032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling kVec4f_GrSLType, "FilterColor", 654032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling &colorFilterColorUniName); 655f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 656f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool wroteFragColorZero = false; 65721b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling if (SkXfermode::kZero_Coeff == uniformCoeff && 6585409a188328d9de3755febc23558d4fc1797d04eNick Lewycky SkXfermode::kZero_Coeff == colorCoeff) { 659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel builder.fFSCode.appendf("\t%s = %s;\n", 660f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel colorOutput.getName().c_str(), 661f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GrGLSLZerosVecf(4)); 662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel wroteFragColorZero = true; 663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (SkXfermode::kDst_Mode != fDesc.fColorFilterXfermode) { 664f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel builder.fFSCode.append("\tvec4 filteredColor;\n"); 665f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel const char* color = adjustInColor(inColor); 666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel add_color_filter(&builder.fFSCode, "filteredColor", uniformCoeff, 667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel colorCoeff, colorFilterColorUniName, color); 668b1928704201034c785a26296a49f69355eb56a05Nick Lewycky inColor = "filteredColor"; 669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 671f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel /////////////////////////////////////////////////////////////////////////// 672f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // compute the partial coverage (coverage stages and edge aa) 673f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 674b1928704201034c785a26296a49f69355eb56a05Nick Lewycky SkString inCoverage; 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky bool coverageIsZero = Desc::kTransBlack_ColorInput == fDesc.fCoverageInput; 6761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // we don't need to compute coverage at all if we know the final shader 677b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // output will be zero and we don't have a dual src blend output. 6784a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { 6794a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6804a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling if (!coverageIsZero) { 6814a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling bool inCoverageIsScalar = this->genEdgeCoverage(&inCoverage, &builder); 6824a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6834a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling switch (fDesc.fCoverageInput) { 6844a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling case Desc::kSolidWhite_ColorInput: 6854a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // empty string implies solid white 6864a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling break; 6874a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling case Desc::kAttribute_ColorInput: 6884a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling gen_attribute_coverage(&builder, &inCoverage); 6894a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling inCoverageIsScalar = false; 6904a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling break; 6914a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling case Desc::kUniform_ColorInput: 692c1b6ea7b6ce3a738accbacddf52480bf94354d2fBill Wendling this->genUniformCoverage(&builder, &inCoverage); 6934a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling inCoverageIsScalar = false; 6944a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling break; 6954a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling default: 6964a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling GrCrash("Unexpected input coverage."); 697b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 69877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 69977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling SkString outCoverage; 70077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling const int& startStage = fDesc.fFirstCoverageStage; 70177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling for (int s = startStage; s < GrDrawState::kNumStages; ++s) { 70277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (fDesc.fEffectKeys[s]) { 70377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // create var to hold stage output 70477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling outCoverage = "coverage"; 70577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling outCoverage.appendS32(s); 70677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str()); 70777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 70877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling const char* inCoords; 70977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // figure out what our input coords are 71077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling int tcIdx = 71177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GrDrawTarget::VertexTexCoordsForStage(s, layout); 71277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (tcIdx < 0) { 71377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoords = builder.positionAttribute().c_str(); 71477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } else { 71577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // must have input tex coordinates if stage is 71677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // enabled. 71777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GrAssert(texCoordAttrs[tcIdx].size()); 71877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoords = texCoordAttrs[tcIdx].c_str(); 71977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 72077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // stages don't know how to deal with a scalar input. (Maybe they should. We 72277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // could pass a GrGLShaderVar) 72377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (inCoverageIsScalar) { 72477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.fFSCode.appendf("\tvec4 %s4 = vec4(%s);\n", 72577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoverage.c_str(), inCoverage.c_str()); 72677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoverage.append("4"); 72777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 72877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.setCurrentStage(s); 72977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling fEffects[s] = builder.createAndEmitGLEffect( 73077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling *stages[s], 73177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling fDesc.fEffectKeys[s], 73277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoverage.size() ? inCoverage.c_str() : NULL, 73377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling outCoverage.c_str(), 73477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoords, 73577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling &fUniformHandles.fSamplerUnis[s]); 73677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.setNonStage(); 73777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling inCoverage = outCoverage; 73877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 73977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 74077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 74177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 74277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) { 74377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling builder.fFSOutputs.push_back().set(kVec4f_GrSLType, 74477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GrGLShaderVar::kOut_TypeModifier, 74577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling dual_source_output_name()); 74677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling bool outputIsZero = coverageIsZero; 74777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling SkString coeff; 74877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (!outputIsZero && 74977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Desc::kCoverage_DualSrcOutput != fDesc.fDualSrcOutput && !wroteFragColorZero) { 750253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!inColor.size()) { 751253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling outputIsZero = true; 752253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } else { 753253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (Desc::kCoverageISA_DualSrcOutput == fDesc.fDualSrcOutput) { 754253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling coeff.printf("(1 - %s.a)", inColor.c_str()); 755253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } else { 756253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); 757253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 758253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 759253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 760253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (outputIsZero) { 761253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling builder.fFSCode.appendf("\t%s = %s;\n", 762253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling dual_source_output_name(), 763253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling GrGLSLZerosVecf(4)); 764253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } else { 765253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling builder.fFSCode.appendf("\t%s =", dual_source_output_name()); 766253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling GrGLSLModulate4f(&builder.fFSCode, coeff.c_str(), inCoverage.c_str()); 767253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling builder.fFSCode.append(";\n"); 768253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 769253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling dualSourceOutputWritten = true; 770253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 771032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling } 772032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling 773032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling /////////////////////////////////////////////////////////////////////////// 774032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling // combine color and coverage as frag color 775032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling 776032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling if (!wroteFragColorZero) { 777ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling if (coverageIsZero) { 778032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling builder.fFSCode.appendf("\t%s = %s;\n", 779253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling colorOutput.getName().c_str(), 780253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling GrGLSLZerosVecf(4)); 781253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } else { 782253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling builder.fFSCode.appendf("\t%s = ", colorOutput.getName().c_str()); 783253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling GrGLSLModulate4f(&builder.fFSCode, inColor.c_str(), inCoverage.c_str()); 784253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling builder.fFSCode.append(";\n"); 785253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 786253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 787253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 788253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling /////////////////////////////////////////////////////////////////////////// 789 // insert GS 790#if GR_DEBUG 791 this->genGeometryShader(&builder); 792#endif 793 794 /////////////////////////////////////////////////////////////////////////// 795 // compile and setup attribs and unis 796 797 if (!this->compileShaders(builder)) { 798 return false; 799 } 800 801 if (!this->bindOutputsAttribsAndLinkProgram(builder, 802 texCoordAttrs, 803 isColorDeclared, 804 dualSourceOutputWritten)) { 805 return false; 806 } 807 808 builder.finished(fProgramID); 809 this->initSamplerUniforms(); 810 fUniformHandles.fRTHeightUni = builder.getRTHeightUniform(); 811 812 return true; 813} 814 815bool GrGLProgram::bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder, 816 SkString texCoordAttrNames[], 817 bool bindColorOut, 818 bool bindDualSrcOut) { 819 GL_CALL_RET(fProgramID, CreateProgram()); 820 if (!fProgramID) { 821 return false; 822 } 823 824 GL_CALL(AttachShader(fProgramID, fVShaderID)); 825 if (fGShaderID) { 826 GL_CALL(AttachShader(fProgramID, fGShaderID)); 827 } 828 GL_CALL(AttachShader(fProgramID, fFShaderID)); 829 830 if (bindColorOut) { 831 GL_CALL(BindFragDataLocation(fProgramID, 0, declared_color_output_name())); 832 } 833 if (bindDualSrcOut) { 834 GL_CALL(BindFragDataLocationIndexed(fProgramID, 0, 1, dual_source_output_name())); 835 } 836 837 // Bind the attrib locations to same values for all shaders 838 GL_CALL(BindAttribLocation(fProgramID, 839 PositionAttributeIdx(), 840 builder.positionAttribute().c_str())); 841 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 842 if (texCoordAttrNames[t].size()) { 843 GL_CALL(BindAttribLocation(fProgramID, 844 TexCoordAttributeIdx(t), 845 texCoordAttrNames[t].c_str())); 846 } 847 } 848 849 GL_CALL(BindAttribLocation(fProgramID, ColorAttributeIdx(), COL_ATTR_NAME)); 850 GL_CALL(BindAttribLocation(fProgramID, CoverageAttributeIdx(), COV_ATTR_NAME)); 851 GL_CALL(BindAttribLocation(fProgramID, EdgeAttributeIdx(), EDGE_ATTR_NAME)); 852 853 GL_CALL(LinkProgram(fProgramID)); 854 855 GrGLint linked = GR_GL_INIT_ZERO; 856 GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked)); 857 if (!linked) { 858 GrGLint infoLen = GR_GL_INIT_ZERO; 859 GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); 860 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 861 if (infoLen > 0) { 862 // retrieve length even though we don't need it to workaround 863 // bug in chrome cmd buffer param validation. 864 GrGLsizei length = GR_GL_INIT_ZERO; 865 GL_CALL(GetProgramInfoLog(fProgramID, 866 infoLen+1, 867 &length, 868 (char*)log.get())); 869 GrPrintf((char*)log.get()); 870 } 871 GrAssert(!"Error linking program"); 872 GL_CALL(DeleteProgram(fProgramID)); 873 fProgramID = 0; 874 return false; 875 } 876 return true; 877} 878 879void GrGLProgram::initSamplerUniforms() { 880 GL_CALL(UseProgram(fProgramID)); 881 // We simply bind the uniforms to successive texture units beginning at 0. setData() assumes this 882 // behavior. 883 GrGLint texUnitIdx = 0; 884 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 885 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); 886 for (int u = 0; u < numSamplers; ++u) { 887 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; 888 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 889 fUniformManager.setSampler(handle, texUnitIdx); 890 ++texUnitIdx; 891 } 892 } 893 } 894} 895 896/////////////////////////////////////////////////////////////////////////////// 897 898void GrGLProgram::setData(GrGpuGL* gpu) { 899 const GrDrawState& drawState = gpu->getDrawState(); 900 901 int rtHeight = drawState.getRenderTarget()->height(); 902 if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni && 903 fRTHeight != rtHeight) { 904 fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(rtHeight)); 905 fRTHeight = rtHeight; 906 } 907 GrGLint texUnitIdx = 0; 908 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 909 if (NULL != fEffects[s]) { 910 const GrEffectStage& stage = drawState.getStage(s); 911 GrAssert(NULL != stage.getEffect()); 912 fEffects[s]->setData(fUniformManager, stage); 913 int numSamplers = fUniformHandles.fSamplerUnis[s].count(); 914 for (int u = 0; u < numSamplers; ++u) { 915 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u]; 916 if (GrGLUniformManager::kInvalidUniformHandle != handle) { 917 const GrTextureAccess& access = stage.getEffect()->textureAccess(u); 918 GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture()); 919 gpu->bindTexture(texUnitIdx, access.getParams(), texture); 920 ++texUnitIdx; 921 } 922 } 923 } 924 } 925} 926