11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGLProgram.h" 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "../GrAllocator.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGLShaderVar.h" 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTrace.h" 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkXfermode.h" 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerenum { 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /// Used to mark a StageUniLocation field that should be bound 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /// to a uniform during getUniformLocationsAndInitCache(). 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kUseUniform = 2000 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} // namespace 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define PRINT_SHADERS 0 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrTAllocator<GrGLShaderVar> VarArray; 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// number of each input/output type in a single allocation block 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int gVarsPerBlock = 8; 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// except FS outputs where we expect 2 at most. 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int gMaxFSOutputs = 2; 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstruct ShaderCodeSegments { 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments() 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger : fVSUnis(gVarsPerBlock) 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fVSAttrs(gVarsPerBlock) 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fVSOutputs(gVarsPerBlock) 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fGSInputs(gVarsPerBlock) 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fGSOutputs(gVarsPerBlock) 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fFSInputs(gVarsPerBlock) 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fFSUnis(gVarsPerBlock) 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fFSOutputs(gMaxFSOutputs) 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger , fUsesGS(false) {} 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fHeader; // VS+FS, GLSL version, etc 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fVSUnis; 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fVSAttrs; 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fVSOutputs; 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fGSInputs; 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fGSOutputs; 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fFSInputs; 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fGSHeader; // layout qualifiers specific to GS 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fFSUnis; 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger VarArray fFSOutputs; 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fFSFunctions; 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fVSCode; 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fGSCode; 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fFSCode; 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool fUsesGS; 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrGLProgram::ProgramDesc::StageDesc StageDesc; 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_ATTRIBUTE_MATRICES 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define VIEW_MATRIX_NAME "aViewM" 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define VIEW_MATRIX_NAME "uViewM" 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define POS_ATTR_NAME "aPosition" 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COL_ATTR_NAME "aColor" 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COV_ATTR_NAME "aCoverage" 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define EDGE_ATTR_NAME "aEdge" 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COL_UNI_NAME "uColor" 784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define COV_UNI_NAME "uCoverage" 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define EDGES_UNI_NAME "uEdges" 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COL_FILTER_UNI_NAME "uColorFilter" 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COL_MATRIX_UNI_NAME "uColorMatrix" 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define COL_MATRIX_VEC_UNI_NAME "uColorMatrixVec" 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void tex_attr_name(int coordIdx, GrStringBuilder* s) { 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "aTexCoord"; 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(coordIdx); 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline GrGLShaderVar::Type float_vector_type(int count) { 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(GrGLShaderVar::kFloat_Type == 0); 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(GrGLShaderVar::kVec2f_Type == 1); 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(GrGLShaderVar::kVec3f_Type == 2); 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_STATIC_ASSERT(GrGLShaderVar::kVec4f_Type == 3); 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count > 0 && count <= 4); 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (GrGLShaderVar::Type)(count - 1); 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* float_vector_type_str(int count) { 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return GrGLShaderVar::TypeString(float_vector_type(count)); 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* vector_homog_coord(int count) { 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"}; 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS)); 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return HOMOGS[count]; 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* vector_nonhomog_coords(int count) { 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"}; 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS)); 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NONHOMOGS[count]; 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* vector_all_coords(int count) { 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"}; 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ALL)); 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return ALL[count]; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* all_ones_vec(int count) { 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)", 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "vec3(1,1,1)", "vec4(1,1,1,1)"}; 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ONESVEC)); 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return ONESVEC[count]; 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* all_zeros_vec(int count) { 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)", 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "vec3(0,0,0)", "vec4(0,0,0,0)"}; 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ZEROSVEC)); 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return ZEROSVEC[count]; 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* declared_color_output_name() { return "fsColorOut"; } 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline const char* dual_source_output_name() { return "dualSourceOut"; } 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void tex_matrix_name(int stage, GrStringBuilder* s) { 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_ATTRIBUTE_MATRICES 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "aTexM"; 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "uTexM"; 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(stage); 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void normalized_texel_size_name(int stage, GrStringBuilder* s) { 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "uTexelSize"; 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(stage); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void sampler_name(int stage, GrStringBuilder* s) { 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "uSampler"; 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(stage); 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void radial2_param_name(int stage, GrStringBuilder* s) { 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "uRadial2Params"; 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(stage); 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void convolve_param_names(int stage, GrStringBuilder* k, GrStringBuilder* i) { 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *k = "uKernel"; 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger k->appendS32(stage); 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *i = "uImageIncrement"; 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger i->appendS32(stage); 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerinline void image_increment_param_name(int stage, GrStringBuilder* i) { 1704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *i = "uImageIncrement"; 1714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger i->appendS32(stage); 1724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void tex_domain_name(int stage, GrStringBuilder* s) { 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *s = "uTexDom"; 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s->appendS32(stage); 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1801cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrGLProgram::GrGLProgram() { 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1831cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrGLProgram::~GrGLProgram() { 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrBlendCoeff* dstCoeff) const { 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (fProgramDesc.fDualSrcOutput) { 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case ProgramDesc::kNone_DualSrcOutput: 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the prog will write a coverage value to the secondary 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // output and the dst is blended by one minus that value. 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case ProgramDesc::kCoverage_DualSrcOutput: 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case ProgramDesc::kCoverageISA_DualSrcOutput: 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case ProgramDesc::kCoverageISC_DualSrcOutput: 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_BlendCoeff; 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrCrash("Unexpected dual source blend output"); 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// assigns modulation of two vars to an output var 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// vars can be vec4s or floats (or one of each) 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// result is always vec4 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// if either var is "" then assign to the other var 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// if both are "" then assign all ones 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline void modulate_helper(const char* outputVar, 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* var0, 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* var1, 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder* code) { 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != outputVar); 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != var0); 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != var1); 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != code); 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool has0 = '\0' != *var0; 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool has1 = '\0' != *var1; 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!has0 && !has1) { 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = %s;\n", outputVar, all_ones_vec(4)); 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!has0) { 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s);\n", outputVar, var1); 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!has1) { 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s);\n", outputVar, var0); 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s * %s);\n", outputVar, var0, var1); 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// assigns addition of two vars to an output var 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// vars can be vec4s or floats (or one of each) 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// result is always vec4 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// if either var is "" then assign to the other var 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// if both are "" then assign all zeros 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline void add_helper(const char* outputVar, 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* var0, 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* var1, 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder* code) { 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != outputVar); 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != var0); 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != var1); 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(NULL != code); 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool has0 = '\0' != *var0; 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool has1 = '\0' != *var1; 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!has0 && !has1) { 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = %s;\n", outputVar, all_zeros_vec(4)); 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!has0) { 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s);\n", outputVar, var1); 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (!has1) { 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s);\n", outputVar, var0); 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger code->appendf("\t%s = vec4(%s + %s);\n", outputVar, var0, var1); 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// given two blend coeffecients determine whether the src 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// and/or dst computation can be omitted. 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline void needBlendInputs(SkXfermode::Coeff srcCoeff, 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Coeff dstCoeff, 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool* needSrcValue, 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool* needDstValue) { 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::kZero_Coeff == srcCoeff) { 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (dstCoeff) { 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these all read the src 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSC_Coeff: 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kISC_Coeff: 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSA_Coeff: 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kISA_Coeff: 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needSrcValue = true; 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needSrcValue = false; 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needSrcValue = true; 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::kZero_Coeff == dstCoeff) { 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (srcCoeff) { 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these all read the dst 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDC_Coeff: 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kIDC_Coeff: 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDA_Coeff: 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kIDA_Coeff: 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needDstValue = true; 2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needDstValue = false; 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *needDstValue = true; 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/** 3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Create a blend_coeff * value string to be used in shader code. Sets empty 3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * string if result is trivially zero. 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void blendTermString(GrStringBuilder* str, SkXfermode::Coeff coeff, 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* src, const char* dst, 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* value) { 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (coeff) { 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kZero_Coeff: /** 0 */ 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *str = ""; 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kOne_Coeff: /** 1 */ 3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *str = value; 3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSC_Coeff: 3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("(%s * %s)", src, value); 3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kISC_Coeff: 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("((%s - %s) * %s)", all_ones_vec(4), src, value); 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDC_Coeff: 3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("(%s * %s)", dst, value); 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kIDC_Coeff: 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("((%s - %s) * %s)", all_ones_vec(4), dst, value); 3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSA_Coeff: /** src alpha */ 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("(%s.a * %s)", src, value); 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("((1.0 - %s.a) * %s)", src, value); 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDA_Coeff: /** dst alpha */ 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("(%s.a * %s)", dst, value); 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger str->printf("((1.0 - %s.a) * %s)", dst, value); 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrCrash("Unexpected xfer coeff."); 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/** 3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Adds a line to the fragment shader code which modifies the color by 3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the specified color filter. 3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void addColorFilter(GrStringBuilder* fsCode, const char * outputVar, 3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Coeff uniformCoeff, 3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Coeff colorCoeff, 3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* inColor) { 3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder colorStr, constStr; 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger blendTermString(&colorStr, colorCoeff, COL_FILTER_UNI_NAME, 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor, inColor); 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger blendTermString(&constStr, uniformCoeff, COL_FILTER_UNI_NAME, 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor, COL_FILTER_UNI_NAME); 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger add_helper(outputVar, colorStr.c_str(), constStr.c_str(), fsCode); 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/** 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Adds code to the fragment shader code which modifies the color by 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the specified color matrix. 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void addColorMatrix(GrStringBuilder* fsCode, const char * outputVar, 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* inColor) { 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCode->appendf("\t%s = %s * vec4(%s.rgb / %s.a, %s.a) + %s;\n", outputVar, COL_MATRIX_UNI_NAME, inColor, inColor, inColor, COL_MATRIX_VEC_UNI_NAME); 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCode->appendf("\t%s.rgb *= %s.a;\n", outputVar, outputVar); 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Adds a var that is computed in the VS and read in FS. 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// If there is a GS it will just pass it through. 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid append_varying(GrGLShaderVar::Type type, 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* name, 3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** vsOutName = NULL, 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** fsInName = NULL) { 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSOutputs.push_back(); 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSOutputs.back().setType(type); 3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSOutputs.back().setTypeModifier( 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kOut_TypeModifier); 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSOutputs.back().accessName()->printf("v%s", name); 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (vsOutName) { 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *vsOutName = segments->fVSOutputs.back().getName().c_str(); 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // input to FS comes either from VS or GS 3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrStringBuilder* fsName; 3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (segments->fUsesGS) { 3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we have a GS take each varying in as an array 3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // and output as non-array. 3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSInputs.push_back(); 3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSInputs.back().setType(type); 3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSInputs.back().setTypeModifier( 3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kIn_TypeModifier); 3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSInputs.back().setUnsizedArray(); 3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *segments->fGSInputs.back().accessName() = 3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSOutputs.back().getName(); 3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSOutputs.push_back(); 3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSOutputs.back().setType(type); 4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSOutputs.back().setTypeModifier( 4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kOut_TypeModifier); 4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSOutputs.back().accessName()->printf("g%s", name); 4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsName = segments->fGSOutputs.back().accessName(); 4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsName = segments->fVSOutputs.back().accessName(); 4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSInputs.push_back(); 4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSInputs.back().setType(type); 4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSInputs.back().setTypeModifier( 4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kIn_TypeModifier); 4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSInputs.back().setName(*fsName); 4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fsInName) { 4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *fsInName = fsName->c_str(); 4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// version of above that adds a stage number to the 4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// the var name (for uniqueness) 4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid append_varying(GrGLShaderVar::Type type, 4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* name, 4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int stageNum, 4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** vsOutName = NULL, 4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** fsInName = NULL) { 4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder nameWithStage(name); 4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger nameWithStage.appendS32(stageNum); 4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_varying(type, nameWithStage.c_str(), segments, vsOutName, fsInName); 4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrGLProgram::genEdgeCoverage(const GrGLContextInfo& gl, 4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrVertexLayout layout, 4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedData* programData, 4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder* coverageVar, 4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments) const { 4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fEdgeAANumEdges > 0) { 4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type, 4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger EDGES_UNI_NAME, 4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fProgramDesc.fEdgeAANumEdges); 4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fEdgesUni = kUseUniform; 4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int count = fProgramDesc.fEdgeAANumEdges; 4431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append( 4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\tvec3 pos = vec3(gl_FragCoord.xy, 1);\n"); 4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; i++) { 4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("\tfloat a"); 4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendS32(i); 4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append(" = clamp(dot(" EDGES_UNI_NAME "["); 4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendS32(i); 4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("], pos), 0.0, 1.0);\n"); 4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fEdgeAAConcave && (count & 0x01) == 0) { 4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // For concave polys, we consider the edges in pairs. 4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSFunctions.append("float cross2(vec2 a, vec2 b) {\n"); 4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSFunctions.append("\treturn dot(a, vec2(b.y, -b.x));\n"); 4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSFunctions.append("}\n"); 4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; i += 2) { 4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat eb%d;\n", i / 2); 4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tif (cross2(" EDGES_UNI_NAME "[%d].xy, " EDGES_UNI_NAME "[%d].xy) < 0.0) {\n", i, i + 1); 4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t\teb%d = a%d * a%d;\n", i / 2, i, i + 1); 4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("\t} else {\n"); 4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t\teb%d = a%d + a%d - a%d * a%d;\n", i / 2, i, i + 1, i, i + 1); 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("\t}\n"); 4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("\tfloat edgeAlpha = "); 4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count / 2 - 1; i++) { 4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("min(eb%d, ", i); 4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("eb%d", count / 2 - 1); 4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count / 2 - 1; i++) { 4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append(")"); 4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append(";\n"); 4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append("\tfloat edgeAlpha = "); 4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count - 1; i++) { 4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("min(a%d * a%d, ", i, i + 1); 4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("a%d * a0", count - 1); 4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count - 1; i++) { 4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append(")"); 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.append(";\n"); 4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *coverageVar = "edgeAlpha"; 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) { 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char *vsName, *fsName; 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments, 4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &vsName, &fsName); 4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, 4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME); 4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName); 4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) { 4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), %s.xyz));\n", fsName); 4954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 4964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else if (GrDrawState::kQuad_EdgeType == fProgramDesc.fVertexEdgeType) { 4974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\tfloat edgeAlpha;\n"); 4984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // keep the derivative instructions outside the conditional 4994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 5004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 5014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); 5024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // today we know z and w are in device space. We could use derivatives 5034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, fsName); 5044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append ("\t} else {\n"); 5054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 5064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 5074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsName, fsName); 5084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); 5094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\t\tedgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n" 5104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger "\t}\n"); 5114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (kES2_GrGLBinding == gl.binding()) { 5124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); 5134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(GrDrawState::kHairQuad_EdgeType == fProgramDesc.fVertexEdgeType); 5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tvec2 duvdx = dFdx(%s.xy);\n", fsName); 5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tvec2 duvdy = dFdy(%s.xy);\n", fsName); 5184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" 5194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger "\t 2.0*%s.x*duvdy.x - duvdy.y);\n", 5204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsName, fsName); 5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat edgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); 5224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); 5234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); 5244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (kES2_GrGLBinding == gl.binding()) { 5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fHeader.printf("#extension GL_OES_standard_derivatives: enable\n"); 5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *coverageVar = "edgeAlpha"; 5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coverageVar->reset(); 5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput, 5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::CachedData* programData, 5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder* inColor) { 5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (colorInput) { 5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GrGLProgram::ProgramDesc::kAttribute_ColorInput: { 5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, 5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, 5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COL_ATTR_NAME); 5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char *vsName, *fsName; 5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName); 5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName); 5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *inColor = fsName; 5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } break; 5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GrGLProgram::ProgramDesc::kUniform_ColorInput: 5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, 5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 5531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COL_UNI_NAME); 5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fColorUni = kUseUniform; 5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *inColor = COL_UNI_NAME; 5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 5571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GrGLProgram::ProgramDesc::kTransBlack_ColorInput: 5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(!"needComputedColor should be false."); 5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case GrGLProgram::ProgramDesc::kSolidWhite_ColorInput: 5611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrCrash("Unknown color type."); 5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 5684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid genAttributeCoverage(ShaderCodeSegments* segments, 5694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder* inOutCoverage) { 5704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, 5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, 5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COV_ATTR_NAME); 5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char *vsName, *fsName; 5744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_varying(GrGLShaderVar::kVec4f_Type, "Coverage", 5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments, &vsName, &fsName); 5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName); 5774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (inOutCoverage->size()) { 5784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec4 attrCoverage = %s * %s;\n", 5794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsName, inOutCoverage->c_str()); 5804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *inOutCoverage = "attrCoverage"; 5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 5824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *inOutCoverage = fsName; 5834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid genUniformCoverage(ShaderCodeSegments* segments, 5874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrGLProgram::CachedData* programData, 5884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder* inOutCoverage) { 5894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, 5904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 5914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger COV_UNI_NAME); 5924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger programData->fUniLocations.fCoverageUni = kUseUniform; 5934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (inOutCoverage->size()) { 5944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n", 5954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger COV_UNI_NAME, inOutCoverage->c_str()); 5964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *inOutCoverage = "uniCoverage"; 5974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 5984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *inOutCoverage = COV_UNI_NAME; 5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrGLProgram::genGeometryShader(const GrGLContextInfo& gl, 6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments) const { 6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_EXPERIMENTAL_GS 6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fExperimentalGS) { 6084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(gl.glslGeneration() >= k150_GrGLSLGeneration); 6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSHeader.append("layout(triangles) in;\n" 6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "layout(triangle_strip, max_vertices = 6) out;\n"); 6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSCode.append("void main() {\n" 6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\tfor (int i = 0; i < 3; ++i) {\n" 6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\t\tgl_Position = gl_in[i].gl_Position;\n"); 6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (this->fProgramDesc.fEmitsPointSize) { 6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSCode.append("\t\tgl_PointSize = 1.0;\n"); 6161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(segments->fGSInputs.count() == segments->fGSOutputs.count()); 6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int count = segments->fGSInputs.count(); 6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSCode.appendf("\t\t%s = %s[i];\n", 6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSOutputs[i].getName().c_str(), 6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSInputs[i].getName().c_str()); 6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fGSCode.append("\t\tEmitVertex();\n" 6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\t}\n" 6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\tEndPrimitive();\n" 6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "}\n"); 6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst char* GrGLProgram::adjustInColor(const GrStringBuilder& inColor) const { 6331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (inColor.size()) { 6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return inColor.c_str(); 6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ProgramDesc::kSolidWhite_ColorInput == fProgramDesc.fColorInput) { 6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return all_ones_vec(4); 6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 6391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return all_zeros_vec(4); 6401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 6431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 6454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool GrGLProgram::genProgram(const GrGLContextInfo& gl, 6461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::CachedData* programData) const { 6471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments segments; 6491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const uint32_t& layout = fProgramDesc.fVertexLayout; 6501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.reset(); 6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_EXPERIMENTAL_GS 6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fUsesGS = fProgramDesc.fExperimentalGS; 6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Coeff colorCoeff, uniformCoeff; 6584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool applyColorMatrix = SkToBool(fProgramDesc.fColorMatrixEnabled); 6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // The rest of transfer mode color filters have not been implemented 6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) { 6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_DEBUGCODE(bool success =) 6621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode> 6631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (fProgramDesc.fColorFilterXfermode), 6641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &uniformCoeff, &colorCoeff); 6651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GR_DEBUGASSERT(success); 6661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 6671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger colorCoeff = SkXfermode::kOne_Coeff; 6681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uniformCoeff = SkXfermode::kZero_Coeff; 6691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // no need to do the color filter / matrix at all if coverage is 0. The 6724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // output color is scaled by the coverage. All the dual source outputs are 6734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // scaled by the coverage as well. 6744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (ProgramDesc::kTransBlack_ColorInput == fProgramDesc.fCoverageInput) { 6754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorCoeff = SkXfermode::kZero_Coeff; 6764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger uniformCoeff = SkXfermode::kZero_Coeff; 6774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger applyColorMatrix = false; 6784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 6794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 6801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // If we know the final color is going to be all zeros then we can 6811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // simplify the color filter coeffecients. needComputedColor will then 6821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // come out false below. 6831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ProgramDesc::kTransBlack_ColorInput == fProgramDesc.fColorInput) { 6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger colorCoeff = SkXfermode::kZero_Coeff; 6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::kDC_Coeff == uniformCoeff || 6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::kDA_Coeff == uniformCoeff) { 6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uniformCoeff = SkXfermode::kZero_Coeff; 6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (SkXfermode::kIDC_Coeff == uniformCoeff || 6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::kIDA_Coeff == uniformCoeff) { 6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uniformCoeff = SkXfermode::kOne_Coeff; 6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool needColorFilterUniform; 6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool needComputedColor; 6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger needBlendInputs(uniformCoeff, colorCoeff, 6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &needColorFilterUniform, &needComputedColor); 6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 6991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // the dual source output has no canonical var name, have to 7001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // declare an output, which is incompatible with gl_FragColor/gl_FragData. 7011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool dualSourceOutputWritten = false; 7024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fHeader.printf(GrGetGLSLVersionDecl(gl.binding(), 7034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger gl.glslGeneration())); 7044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 7054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrGLShaderVar colorOutput; 7064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool isColorDeclared = GrGLSLSetupFSColorOuput(gl.glslGeneration(), 7074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger declared_color_output_name(), 7084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &colorOutput); 7094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (isColorDeclared) { 7104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSOutputs.push_back(colorOutput); 7114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 7121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_GL_ATTRIBUTE_MATRICES 7141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, 7151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME); 7161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fViewMatrixUni = kSetAsAttribute; 7171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 7181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, 7191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME); 7201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fViewMatrixUni = kUseUniform; 7211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 7221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, 7231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME); 7241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSCode.append( 7261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "void main() {\n" 7271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3("POS_ATTR_NAME", 1);\n" 7281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n"); 7291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // incoming color to current stage being processed. 7311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder inColor; 7321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (needComputedColor) { 7341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger genInputColor((ProgramDesc::ColorInput) fProgramDesc.fColorInput, 7351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData, &segments, &inColor); 7361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we output point size in the GS if present 7391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fEmitsPointSize && !segments.fUsesGS){ 7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSCode.append("\tgl_PointSize = 1.0;\n"); 7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSCode.append("void main() {\n"); 7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // add texture coordinates that are used to the list of vertex attr decls 7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texCoordAttrs[GrDrawState::kMaxTexCoords]; 7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) { 7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_attr_name(t, texCoordAttrs + t); 7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, 7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kAttribute_TypeModifier, 7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texCoordAttrs[t].c_str()); 7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compute the final color 7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we have color stages string them together, feeding the output color 7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // of each to the next and generating code for each stage. 7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (needComputedColor) { 7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder outColor; 7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int s = 0; s < fProgramDesc.fFirstCoverageStage; ++s) { 7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fStages[s].isEnabled()) { 7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // create var to hold stage result 7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger outColor = "color"; 7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger outColor.appendS32(s); 7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str()); 7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* inCoords; 7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // figure out what our input coords are 7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & 7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger layout) { 7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inCoords = POS_ATTR_NAME; 7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout); 7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we better have input tex coordinates if stage is enabled. 7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(tcIdx >= 0); 7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(texCoordAttrs[tcIdx].size()); 7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inCoords = texCoordAttrs[tcIdx].c_str(); 7811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->genStageCode(gl, 7841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger s, 7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fProgramDesc.fStages[s], 7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor.size() ? inColor.c_str() : NULL, 7871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger outColor.c_str(), 7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inCoords, 7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &segments, 7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &programData->fUniLocations.fStages[s]); 7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor = outColor; 7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if have all ones or zeros for the "dst" input to the color filter then we 7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // may be able to make additional optimizations. 7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (needColorFilterUniform && needComputedColor && !inColor.size()) { 7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(ProgramDesc::kSolidWhite_ColorInput == fProgramDesc.fColorInput); 8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool uniformCoeffIsZero = SkXfermode::kIDC_Coeff == uniformCoeff || 8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::kIDA_Coeff == uniformCoeff; 8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (uniformCoeffIsZero) { 8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uniformCoeff = SkXfermode::kZero_Coeff; 8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool bogus; 8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger needBlendInputs(SkXfermode::kZero_Coeff, colorCoeff, 8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &needColorFilterUniform, &bogus); 8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (needColorFilterUniform) { 8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, 8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COL_FILTER_UNI_NAME); 8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fColorFilterUni = kUseUniform; 8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool wroteFragColorZero = false; 8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::kZero_Coeff == uniformCoeff && 8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::kZero_Coeff == colorCoeff && 8184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger !applyColorMatrix) { 8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSCode.appendf("\t%s = %s;\n", 8204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger all_zeros_vec(4)); 8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger wroteFragColorZero = true; 8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) { 8244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.append("\tvec4 filteredColor;\n"); 8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* color = adjustInColor(inColor); 8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger addColorFilter(&segments.fFSCode, "filteredColor", uniformCoeff, 8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger colorCoeff, color); 8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor = "filteredColor"; 8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (applyColorMatrix) { 8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSUnis.push_back().set(GrGLShaderVar::kMat44f_Type, 8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COL_MATRIX_UNI_NAME); 8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, 8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, 8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger COL_MATRIX_VEC_UNI_NAME); 8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fColorMatrixUni = kUseUniform; 8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fColorMatrixVecUni = kUseUniform; 8394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.append("\tvec4 matrixedColor;\n"); 8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* color = adjustInColor(inColor); 8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger addColorMatrix(&segments.fFSCode, "matrixedColor", color); 8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inColor = "matrixedColor"; 8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compute the partial coverage (coverage stages and edge aa) 8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder inCoverage; 8494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool coverageIsZero = ProgramDesc::kTransBlack_ColorInput == 8504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fProgramDesc.fCoverageInput; 8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we don't need to compute coverage at all if we know the final shader 8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // output will be zero and we don't have a dual src blend output. 8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!wroteFragColorZero || 8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) { 8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!coverageIsZero) { 8574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->genEdgeCoverage(gl, 8584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger layout, 8594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger programData, 8604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &inCoverage, 8614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &segments); 8624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 8634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (fProgramDesc.fCoverageInput) { 8644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case ProgramDesc::kSolidWhite_ColorInput: 8654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // empty string implies solid white 8664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 8674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case ProgramDesc::kAttribute_ColorInput: 8684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger genAttributeCoverage(&segments, &inCoverage); 8694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 8704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case ProgramDesc::kUniform_ColorInput: 8714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger genUniformCoverage(&segments, programData, &inCoverage); 8724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 8734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger default: 8744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrCrash("Unexpected input coverage."); 8754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder outCoverage; 8784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const int& startStage = fProgramDesc.fFirstCoverageStage; 8794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger for (int s = startStage; s < GrDrawState::kNumStages; ++s) { 8804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fProgramDesc.fStages[s].isEnabled()) { 8814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // create var to hold stage output 8824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger outCoverage = "coverage"; 8834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger outCoverage.appendS32(s); 8844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.appendf("\tvec4 %s;\n", 8854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger outCoverage.c_str()); 8864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 8874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* inCoords; 8884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // figure out what our input coords are 8894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & 8904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger layout) { 8914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoords = POS_ATTR_NAME; 8924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 8934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int tcIdx = 8944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrDrawTarget::VertexTexCoordsForStage(s, layout); 8954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // we better have input tex coordinates if stage is 8964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // enabled. 8974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(tcIdx >= 0); 8984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(texCoordAttrs[tcIdx].size()); 8994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoords = texCoordAttrs[tcIdx].c_str(); 9004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger genStageCode(gl, s, 9034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fProgramDesc.fStages[s], 9044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoverage.size() ? inCoverage.c_str() : NULL, 9054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger outCoverage.c_str(), 9064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoords, 9074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &segments, 9084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &programData->fUniLocations.fStages[s]); 9094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoverage = outCoverage; 9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) { 9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type, 9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kOut_TypeModifier, 9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dual_source_output_name()); 9174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool outputIsZero = coverageIsZero; 9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder coeff; 9194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!outputIsZero && 9204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ProgramDesc::kCoverage_DualSrcOutput != 9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fProgramDesc.fDualSrcOutput && !wroteFragColorZero) { 9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!inColor.size()) { 9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger outputIsZero = true; 9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fDualSrcOutput == 9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ProgramDesc::kCoverageISA_DualSrcOutput) { 9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coeff.printf("(1 - %s.a)", inColor.c_str()); 9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str()); 9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (outputIsZero) { 9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSCode.appendf("\t%s = %s;\n", 9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dual_source_output_name(), 9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger all_zeros_vec(4)); 9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger modulate_helper(dual_source_output_name(), 9391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coeff.c_str(), 9401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inCoverage.c_str(), 9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &segments.fFSCode); 9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dualSourceOutputWritten = true; 9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // combine color and coverage as frag color 9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!wroteFragColorZero) { 9514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (coverageIsZero) { 9524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.appendf("\t%s = %s;\n", 9534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger all_zeros_vec(4)); 9554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 9564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger modulate_helper(colorOutput.getName().c_str(), 9574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inColor.c_str(), 9584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger inCoverage.c_str(), 9594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &segments.fFSCode); 9604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 9614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig == 9624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fProgramDesc.fOutputConfig) { 9634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0)/255.0, %s.a);\n", 9644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str()); 9694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else if (ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig == 9704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fProgramDesc.fOutputConfig) { 9714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0)/255.0, %s.a);\n", 9724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str(), 9764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colorOutput.getName().c_str()); 9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fVSCode.append("}\n"); 9811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSCode.append("}\n"); 9821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 9841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // insert GS 9851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG 9864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->genGeometryShader(gl, &segments); 9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 9901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compile and setup attribs and unis 9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!CompileShaders(gl, segments, programData)) { 9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!this->bindOutputsAttribsAndLinkProgram(gl, texCoordAttrs, 9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger isColorDeclared, 9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dualSourceOutputWritten, 9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData)) { 10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->getUniformLocationsAndInitCache(gl, programData); 10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 10091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void expand_decls(const VarArray& vars, 10114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrGLContextInfo& gl, 10124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder* string) { 10131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int count = vars.count(); 10141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < count; ++i) { 10154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger vars[i].appendDecl(gl, string); 10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void print_shader(int stringCnt, 10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** strings, 10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int* stringLengths) { 10221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < stringCnt; ++i) { 10231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == stringLengths || stringLengths[i] < 0) { 10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf(strings[i]); 10251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("%.*s", stringLengths[i], strings[i]); 10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef SkTArray<const char*, true> StrArray; 10321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define PREALLOC_STR_ARRAY(N) SkSTArray<(N), const char*, true> 10331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef SkTArray<int, true> LengthArray; 10351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define PREALLOC_LENGTH_ARRAY(N) SkSTArray<(N), int, true> 10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// these shouldn't relocate 10381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef GrTAllocator<GrStringBuilder> TempArray; 10391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define PREALLOC_TEMP_ARRAY(N) GrSTAllocator<(N), GrStringBuilder> 10401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void append_string(const GrStringBuilder& str, 10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StrArray* strings, 10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger LengthArray* lengths) { 10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int length = (int) str.size(); 10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (length) { 10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strings->push_back(str.c_str()); 10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger lengths->push_back(length); 10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(strings->count() == lengths->count()); 10501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void append_decls(const VarArray& vars, 10534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrGLContextInfo& gl, 10541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StrArray* strings, 10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger LengthArray* lengths, 10564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger TempArray* temp) { 10574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger expand_decls(vars, gl, &temp->push_back()); 10581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(temp->back(), strings, lengths); 10591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool GrGLProgram::CompileShaders(const GrGLContextInfo& gl, 10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const ShaderCodeSegments& segments, 10651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedData* programData) { 10661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger enum { kPreAllocStringCnt = 8 }; 10671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger PREALLOC_STR_ARRAY(kPreAllocStringCnt) strs; 10691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger PREALLOC_LENGTH_ARRAY(kPreAllocStringCnt) lengths; 10701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger PREALLOC_TEMP_ARRAY(kPreAllocStringCnt) temps; 10711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder unis; 10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder inputs; 10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder outputs; 10751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fHeader, &strs, &lengths); 10774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fVSUnis, gl, &strs, &lengths, &temps); 10784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fVSAttrs, gl, &strs, &lengths, &temps); 10794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fVSOutputs, gl, &strs, &lengths, &temps); 10801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fVSCode, &strs, &lengths); 10811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if PRINT_SHADERS 10831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger print_shader(strs.count(), &strs[0], &lengths[0]); 10841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("\n"); 10851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 10861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fVShaderID = 10881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CompileShader(gl, GR_GL_VERTEX_SHADER, strs.count(), 10891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &strs[0], &lengths[0]); 10901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!programData->fVShaderID) { 10921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (segments.fUsesGS) { 10951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strs.reset(); 10961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger lengths.reset(); 10971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger temps.reset(); 10981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fHeader, &strs, &lengths); 10991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fGSHeader, &strs, &lengths); 11004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fGSInputs, gl, &strs, &lengths, &temps); 11014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fGSOutputs, gl, &strs, &lengths, &temps); 11021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fGSCode, &strs, &lengths); 11031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if PRINT_SHADERS 11041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger print_shader(strs.count(), &strs[0], &lengths[0]); 11051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("\n"); 11061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 11071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fGShaderID = 11081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CompileShader(gl, GR_GL_GEOMETRY_SHADER, strs.count(), 11091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &strs[0], &lengths[0]); 11101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 11111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fGShaderID = 0; 11121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger strs.reset(); 11151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger lengths.reset(); 11161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger temps.reset(); 11171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fHeader, &strs, &lengths); 11194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder precisionStr(GrGetGLSLShaderPrecisionDecl(gl.binding())); 11201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(precisionStr, &strs, &lengths); 11214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fFSUnis, gl, &strs, &lengths, &temps); 11224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fFSInputs, gl, &strs, &lengths, &temps); 11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // We shouldn't have declared outputs on 1.10 11244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(k110_GrGLSLGeneration != gl.glslGeneration() || 11251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments.fFSOutputs.empty()); 11264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger append_decls(segments.fFSOutputs, gl, &strs, &lengths, &temps); 11271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fFSFunctions, &strs, &lengths); 11281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_string(segments.fFSCode, &strs, &lengths); 11291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if PRINT_SHADERS 11311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger print_shader(strs.count(), &strs[0], &lengths[0]); 11321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("\n"); 11331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 11341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fFShaderID = 11361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CompileShader(gl, GR_GL_FRAGMENT_SHADER, strs.count(), 11371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &strs[0], &lengths[0]); 11381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!programData->fFShaderID) { 11401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 11411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 11441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 11451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define GL_CALL(X) GR_GL_CALL(gl.interface(), X) 11474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gl.interface(), R, X) 11484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 11494f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerGrGLuint GrGLProgram::CompileShader(const GrGLContextInfo& gl, 11501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLenum type, 11511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int stringCnt, 11521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** strings, 11531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int* stringLengths) { 11541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_TRACE_EVENT1("GrGLProgram::CompileShader", 11551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "stringCount", SkStringPrintf("%i", stringCnt).c_str()); 11561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLuint shader; 11584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(shader, CreateShader(type)); 11591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == shader) { 11601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0; 11611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLint compiled = GR_GL_INIT_ZERO; 11644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(ShaderSource(shader, stringCnt, strings, stringLengths)); 11654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(CompileShader(shader)); 11664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled)); 11671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!compiled) { 11691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLint infoLen = GR_GL_INIT_ZERO; 11704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen)); 11711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 11721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (infoLen > 0) { 11731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // retrieve length even though we don't need it to workaround 11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // bug in chrome cmd buffer param validation. 11751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLsizei length = GR_GL_INIT_ZERO; 11764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetShaderInfoLog(shader, infoLen+1, 11774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &length, (char*)log.get())); 11781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger print_shader(stringCnt, strings, stringLengths); 11791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf("\n%s", log.get()); 11801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(!"Shader compilation failed!"); 11824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(DeleteShader(shader)); 11831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0; 11841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return shader; 11861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 11871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 11881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrGLProgram::bindOutputsAttribsAndLinkProgram( 11894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const GrGLContextInfo& gl, 11901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texCoordAttrNames[], 11911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool bindColorOut, 11921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool bindDualSrcOut, 11931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedData* programData) const { 11944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fProgramID, CreateProgram()); 11951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!programData->fProgramID) { 11961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 11971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 11981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrGLint& progID = programData->fProgramID; 11991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(AttachShader(progID, programData->fVShaderID)); 12011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (programData->fGShaderID) { 12024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(AttachShader(progID, programData->fGShaderID)); 12031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(AttachShader(progID, programData->fFShaderID)); 12051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (bindColorOut) { 12074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindFragDataLocation(programData->fProgramID, 12084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0, declared_color_output_name())); 12091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (bindDualSrcOut) { 12114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindFragDataLocationIndexed(programData->fProgramID, 12124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0, 1, dual_source_output_name())); 12131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Bind the attrib locations to same values for all shaders 12164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, PositionAttributeIdx(), POS_ATTR_NAME)); 12171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { 12181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (texCoordAttrNames[t].size()) { 12194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, 12204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger TexCoordAttributeIdx(t), 12214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger texCoordAttrNames[t].c_str())); 12221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kSetAsAttribute == programData->fUniLocations.fViewMatrixUni) { 12264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, 12274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ViewMatrixAttributeIdx(), 12284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger VIEW_MATRIX_NAME)); 12291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int s = 0; s < GrDrawState::kNumStages; ++s) { 12321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const StageUniLocations& unis = programData->fUniLocations.fStages[s]; 12331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kSetAsAttribute == unis.fTextureMatrixUni) { 12341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder matName; 12351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_matrix_name(s, &matName); 12364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, 12374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger TextureMatrixAttributeIdx(s), 12384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger matName.c_str())); 12391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, ColorAttributeIdx(), COL_ATTR_NAME)); 12434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, CoverageAttributeIdx(), COV_ATTR_NAME)); 12444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(BindAttribLocation(progID, EdgeAttributeIdx(), EDGE_ATTR_NAME)); 12451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(LinkProgram(progID)); 12471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLint linked = GR_GL_INIT_ZERO; 12494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked)); 12501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!linked) { 12511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLint infoLen = GR_GL_INIT_ZERO; 12524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen)); 12531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 12541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (infoLen > 0) { 12551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // retrieve length even though we don't need it to workaround 12561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // bug in chrome cmd buffer param validation. 12571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLsizei length = GR_GL_INIT_ZERO; 12584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(GetProgramInfoLog(progID, 12594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger infoLen+1, 12604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &length, 12614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger (char*)log.get())); 12621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrPrintf((char*)log.get()); 12631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(!"Error linking program"); 12654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(DeleteProgram(progID)); 12661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fProgramID = 0; 12671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 12681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 12701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 12711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl, 12731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger CachedData* programData) const { 12741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrGLint& progID = programData->fProgramID; 12751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fViewMatrixUni) { 12774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fViewMatrixUni, 12784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, VIEW_MATRIX_NAME)); 12791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != programData->fUniLocations.fViewMatrixUni); 12801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fColorUni) { 12824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fColorUni, 12834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, COL_UNI_NAME)); 12841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != programData->fUniLocations.fColorUni); 12851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fColorFilterUni) { 12874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fColorFilterUni, 12884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, COL_FILTER_UNI_NAME)); 12891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != programData->fUniLocations.fColorFilterUni); 12901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fColorMatrixUni) { 12934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fColorMatrixUni, 12944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, COL_MATRIX_UNI_NAME)); 12951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 12961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 12971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fColorMatrixVecUni) { 12984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fColorMatrixVecUni, 12994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, COL_MATRIX_VEC_UNI_NAME)); 13004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (kUseUniform == programData->fUniLocations.fCoverageUni) { 13024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fCoverageUni, 13034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, COV_UNI_NAME)); 13044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(kUnusedUniform != programData->fUniLocations.fCoverageUni); 13051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == programData->fUniLocations.fEdgesUni) { 13084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(programData->fUniLocations.fEdgesUni, 13094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, EDGES_UNI_NAME)); 13101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != programData->fUniLocations.fEdgesUni); 13111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 13121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fUniLocations.fEdgesUni = kUnusedUniform; 13131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int s = 0; s < GrDrawState::kNumStages; ++s) { 13161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageUniLocations& locations = programData->fUniLocations.fStages[s]; 13171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fProgramDesc.fStages[s].isEnabled()) { 13181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fTextureMatrixUni) { 13191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texMName; 13201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_matrix_name(s, &texMName); 13214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fTextureMatrixUni, 13224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, texMName.c_str())); 13231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fTextureMatrixUni); 13241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fSamplerUni) { 13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder samplerName; 13281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampler_name(s, &samplerName); 13294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fSamplerUni, 13304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID,samplerName.c_str())); 13311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fSamplerUni); 13321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fNormalizedTexelSizeUni) { 13351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texelSizeName; 13361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger normalized_texel_size_name(s, &texelSizeName); 13374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fNormalizedTexelSizeUni, 13384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, texelSizeName.c_str())); 13391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni); 13401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fRadial2Uni) { 13431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2ParamName; 13441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2_param_name(s, &radial2ParamName); 13454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fRadial2Uni, 13464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, radial2ParamName.c_str())); 13471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fRadial2Uni); 13481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fTexDomUni) { 13511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texDomName; 13521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_domain_name(s, &texDomName); 13534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fTexDomUni, 13544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, texDomName.c_str())); 13551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fTexDomUni); 13561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder kernelName, imageIncrementName; 13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger convolve_param_names(s, &kernelName, &imageIncrementName); 13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fKernelUni) { 13614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fKernelUni, 13624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, kernelName.c_str())); 13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fKernelUni); 13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUseUniform == locations.fImageIncrementUni) { 13674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL_RET(locations.fImageIncrementUni, 13684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GetUniformLocation(progID, 13694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger imageIncrementName.c_str())); 13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(kUnusedUniform != locations.fImageIncrementUni); 13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(UseProgram(progID)); 13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // init sampler unis and set bogus values for state tracking 13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int s = 0; s < GrDrawState::kNumStages; ++s) { 13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (kUnusedUniform != programData->fUniLocations.fStages[s].fSamplerUni) { 13794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GL_CALL(Uniform1i(programData->fUniLocations.fStages[s].fSamplerUni, s)); 13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix(); 13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fRadial2CenterX1[s] = GR_ScalarMax; 13831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fRadial2Radius0[s] = -GR_ScalarMax; 13841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fTextureWidth[s] = -1; 13851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fTextureHeight[s] = -1; 13861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fViewMatrix = GrMatrix::InvalidMatrix(); 13881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fColor = GrColor_ILLEGAL; 13891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger programData->fColorFilterColor = GrColor_ILLEGAL; 13901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//============================================================================ 13931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Stage code generation 13941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//============================================================================ 13951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace { 13971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool isRadialMapping(GrGLProgram::StageDesc::CoordMapping mapping) { 13991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 14001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (GrGLProgram::StageDesc::kRadial2Gradient_CoordMapping == mapping || 14011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::StageDesc::kRadial2GradientDegenerate_CoordMapping == mapping); 14021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14041cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrGLShaderVar* genRadialVS(int stageNum, 14051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 14061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::StageUniLocations* locations, 14071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** radial2VaryingVSName, 14081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** radial2VaryingFSName, 14091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* varyingVSName, 14101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int varyingDims, int coordDims) { 14111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back(); 14131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2FSParams->setType(GrGLShaderVar::kFloat_Type); 14141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 14151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2FSParams->setArrayCount(6); 14161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2_param_name(stageNum, radial2FSParams->accessName()); 14171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true); 14181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fRadial2Uni = kUseUniform; 14201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // for radial grads without perspective we can pass the linear 14221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // part of the quadratic as a varying. 14231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (varyingDims == coordDims) { 14241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(2 == coordDims); 14251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_varying(GrGLShaderVar::kFloat_Type, 14261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "Radial2BCoeff", 14271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stageNum, 14281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments, 14291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2VaryingVSName, 14301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2VaryingFSName); 14311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p2; 14331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p3; 14341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2FSParams->appendArrayAccess(2, &radial2p2); 14351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2FSParams->appendArrayAccess(3, &radial2p3); 14361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) 14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* r2ParamName = radial2FSParams->getName().c_str(); 14391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = 2.0 *(%s * %s.x - %s);\n", 14401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *radial2VaryingVSName, radial2p2.c_str(), 14411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingVSName, radial2p3.c_str()); 14421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return radial2FSParams; 14451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool genRadial2GradientCoordMapping(int stageNum, 14481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 14491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* radial2VaryingFSName, 14501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* radial2Params, 14511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& sampleCoords, 14521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& fsCoordName, 14531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int varyingDims, 14541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int coordDims) { 14551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder cName("c"); 14561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder ac4Name("ac4"); 14571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder rootName("root"); 14581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger cName.appendS32(stageNum); 14601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ac4Name.appendS32(stageNum); 14611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rootName.appendS32(stageNum); 14621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p0; 14641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p1; 14651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p2; 14661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p3; 14671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p4; 14681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p5; 14691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(0, &radial2p0); 14701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(1, &radial2p1); 14711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(2, &radial2p2); 14721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(3, &radial2p3); 14731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(4, &radial2p4); 14741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(5, &radial2p5); 14751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we were able to interpolate the linear component bVar is the varying 14771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // otherwise compute it 14781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder bVar; 14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (coordDims == varyingDims) { 14801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar = radial2VaryingFSName; 14811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(2 == varyingDims); 14821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 14831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(3 == varyingDims); 14841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar = "b"; 14851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar.appendS32(stageNum); 14861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", 14871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar.c_str(), radial2p2.c_str(), 14881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.c_str(), radial2p3.c_str()); 14891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // c = (x^2)+(y^2) - params[4] 14921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n", 14931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger cName.c_str(), fsCoordName.c_str(), 14941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.c_str(), 14951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2p4.c_str()); 14961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // ac4 = 4.0 * params[0] * c 14971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = %s * 4.0 * %s;\n", 14981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ac4Name.c_str(), radial2p0.c_str(), 14991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger cName.c_str()); 15001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // root = sqrt(b^2-4ac) 15021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // (abs to avoid exception due to fp precision) 15031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n", 15041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rootName.c_str(), bVar.c_str(), bVar.c_str(), 15051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ac4Name.c_str()); 15061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] 15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // y coord is 0.5 (texture is effectively 1D) 15091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)", 15101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar.c_str(), radial2p5.c_str(), 15111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rootName.c_str(), radial2p1.c_str()); 15121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 15131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 15141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool genRadial2GradientDegenerateCoordMapping(int stageNum, 15161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 15171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* radial2VaryingFSName, 15181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* radial2Params, 15191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& sampleCoords, 15201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& fsCoordName, 15211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int varyingDims, 15221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int coordDims) { 15231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder cName("c"); 15241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger cName.appendS32(stageNum); 15261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p2; 15281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p3; 15291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder radial2p4; 15301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(2, &radial2p2); 15311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(3, &radial2p3); 15321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params->appendArrayAccess(4, &radial2p4); 15331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we were able to interpolate the linear component bVar is the varying 15351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // otherwise compute it 15361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder bVar; 15371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (coordDims == varyingDims) { 15381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar = radial2VaryingFSName; 15391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(2 == varyingDims); 15401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 15411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(3 == varyingDims); 15421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar = "b"; 15431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar.appendS32(stageNum); 15441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", 15451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bVar.c_str(), radial2p2.c_str(), 15461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.c_str(), radial2p3.c_str()); 15471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // c = (x^2)+(y^2) - params[4] 15501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n", 15511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger cName.c_str(), fsCoordName.c_str(), 15521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.c_str(), 15531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2p4.c_str()); 15541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // x coord is: -c/b 15561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // y coord is 0.5 (texture is effectively 1D) 15571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.printf("vec2((-%s / %s), 0.5)", cName.c_str(), bVar.c_str()); 15581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 15591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 15601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid gen2x2FS(int stageNum, 15621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 15631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::StageUniLocations* locations, 15641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder* sampleCoords, 15651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* samplerName, 15661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* texelSizeName, 15671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* swizzle, 15681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* fsOutColor, 15691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& texFunc, 15701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& modulate, 15711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool complexCoord, 15721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int coordDims) { 15731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fNormalizedTexelSizeUni = kUseUniform; 15741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (complexCoord) { 15751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // assign the coord to a var rather than compute 4x. 15761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder coordVar("tCoord"); 15771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.appendS32(stageNum); 15781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s %s = %s;\n", 15791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float_vector_type_str(coordDims), 15801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.c_str(), sampleCoords->c_str()); 15811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *sampleCoords = coordVar; 15821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(2 == coordDims); 15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder accumVar("accum"); 15851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger accumVar.appendS32(stageNum); 15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle); 15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle); 15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle); 15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle); 15901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str()); 15911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 15931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid genConvolutionVS(int stageNum, 15951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const StageDesc& desc, 15961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 15971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLProgram::StageUniLocations* locations, 15981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar** kernel, 15991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char** imageIncrementName, 16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* varyingVSName) { 16011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger //GrGLShaderVar* kernel = &segments->fFSUnis.push_back(); 16021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *kernel = &segments->fFSUnis.push_back(); 16031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (*kernel)->setType(GrGLShaderVar::kFloat_Type); 16041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 16051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (*kernel)->setArrayCount(desc.fKernelWidth); 16061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* imgInc = &segments->fFSUnis.push_back(); 16071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger imgInc->setType(GrGLShaderVar::kVec2f_Type); 16081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 16091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger convolve_param_names(stageNum, 16111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (*kernel)->accessName(), 16121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger imgInc->accessName()); 16131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *imageIncrementName = imgInc->getName().c_str(); 16141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // need image increment in both VS and FS 16161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true); 16171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fKernelUni = kUseUniform; 16191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fImageIncrementUni = kUseUniform; 16201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float scale = (desc.fKernelWidth - 1) * 0.5f; 16211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n", 16221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingVSName, scale, scale, 16231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *imageIncrementName); 16241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 16251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid genConvolutionFS(int stageNum, 16271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const StageDesc& desc, 16281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 16291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* samplerName, 16301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* kernel, 16311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* swizzle, 16321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* imageIncrementName, 16331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* fsOutColor, 16341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& sampleCoords, 16351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& texFunc, 16361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder& modulate) { 16371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder sumVar("sum"); 16381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sumVar.appendS32(stageNum); 16391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder coordVar("coord"); 16401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.appendS32(stageNum); 16411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder kernelIndex; 16431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kernel->appendArrayAccess("i", &kernelIndex); 16441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 16451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n", 16461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sumVar.c_str()); 16471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tvec2 %s = %s;\n", 16481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.c_str(), 16491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.c_str()); 16501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n", 16511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fKernelWidth); 16521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s;\n", 16531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sumVar.c_str(), texFunc.c_str(), 16541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger samplerName, coordVar.c_str(), swizzle, 16551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger kernelIndex.c_str()); 16561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t\t%s += %s;\n", 16571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.c_str(), 16581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger imageIncrementName); 16594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.append("\t}\n"); 16601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor, 16611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sumVar.c_str(), modulate.c_str()); 16621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 16634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid genMorphologyVS(int stageNum, 16654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const StageDesc& desc, 16664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ShaderCodeSegments* segments, 16674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrGLProgram::StageUniLocations* locations, 16684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char** imageIncrementName, 16694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* varyingVSName) { 16704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrGLShaderVar* imgInc = &segments->fFSUnis.push_back(); 16714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger imgInc->setType(GrGLShaderVar::kVec2f_Type); 16724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 16734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger image_increment_param_name(stageNum, imgInc->accessName()); 16754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *imageIncrementName = imgInc->getName().c_str(); 16764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // need image increment in both VS and FS 16784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true); 16794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger locations->fImageIncrementUni = kUseUniform; 16814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fVSCode.appendf("\t%s -= vec2(%d, %d) * %s;\n", 16824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger varyingVSName, desc.fKernelWidth, 16834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger desc.fKernelWidth, *imageIncrementName); 16844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 16854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid genMorphologyFS(int stageNum, 16874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const StageDesc& desc, 16884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ShaderCodeSegments* segments, 16894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* samplerName, 16904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* swizzle, 16914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* imageIncrementName, 16924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const char* fsOutColor, 16934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder& sampleCoords, 16944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder& texFunc, 16954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder& modulate) { 16964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder valueVar("value"); 16974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.appendS32(stageNum); 16984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrStringBuilder coordVar("coord"); 16994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger coordVar.appendS32(stageNum); 17004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool isDilate = StageDesc::kDilate_FetchMode == desc.fFetchMode; 17014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 17024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (isDilate) { 17034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n", 17044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.c_str()); 17054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 17064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec4 %s = vec4(1, 1, 1, 1);\n", 17074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.c_str()); 17084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 17094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tvec2 %s = %s;\n", 17104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger coordVar.c_str(), 17114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sampleCoords.c_str()); 17124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n", 17134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger desc.fKernelWidth * 2 + 1); 17144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t\t%s = %s(%s, %s(%s, %s)%s);\n", 17154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.c_str(), isDilate ? "max" : "min", 17164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.c_str(), texFunc.c_str(), 17174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger samplerName, coordVar.c_str(), swizzle); 17184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t\t%s += %s;\n", 17194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger coordVar.c_str(), 17204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger imageIncrementName); 17214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t}\n"); 17224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor, 17234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger valueVar.c_str(), modulate.c_str()); 17244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 17251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 17271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid GrGLProgram::genStageCode(const GrGLContextInfo& gl, 17291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int stageNum, 17301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const GrGLProgram::StageDesc& desc, 17311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* fsInColor, // NULL means no incoming color 17321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* fsOutColor, 17331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* vsInCoord, 17341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ShaderCodeSegments* segments, 17351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageUniLocations* locations) const { 17361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(stageNum >= 0 && stageNum <= GrDrawState::kNumStages); 17381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == 17391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger desc.fInConfigFlags); 17401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // First decide how many coords are needed to access the texture 17421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Right now it's always 2 but we could start using 1D textures for 17431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // gradients. 17441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const int coordDims = 2; 17451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int varyingDims; 17461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /// Vertex Shader Stuff 17471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // decide whether we need a matrix to transform texture coords 17491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // and whether the varying needs a perspective coord. 17501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* matName = NULL; 17511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) { 17521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims = coordDims; 17531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 17541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* mat; 17551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if GR_GL_ATTRIBUTE_MATRICES 17561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat = &segments->fVSAttrs.push_back(); 17571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat->setTypeModifier(GrGLShaderVar::kAttribute_TypeModifier); 17581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fTextureMatrixUni = kSetAsAttribute; 17591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #else 17601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat = &segments->fVSUnis.push_back(); 17611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); 17621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fTextureMatrixUni = kUseUniform; 17631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 17641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_matrix_name(stageNum, mat->accessName()); 17651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat->setType(GrGLShaderVar::kMat33f_Type); 17661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger matName = mat->getName().c_str(); 17671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) { 17691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims = coordDims; 17701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 17711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims = coordDims + 1; 17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type, 17761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, ""); 17771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampler_name(stageNum, segments->fFSUnis.back().accessName()); 17781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fSamplerUni = kUseUniform; 17791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* samplerName = segments->fFSUnis.back().getName().c_str(); 17801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* texelSizeName = NULL; 17821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (StageDesc::k2x2_FetchMode == desc.fFetchMode) { 17831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type, 17841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, ""); 17851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName()); 17861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texelSizeName = segments->fFSUnis.back().getName().c_str(); 17871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 17881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char *varyingVSName, *varyingFSName; 17901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger append_varying(float_vector_type(varyingDims), 17911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "Stage", 17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stageNum, 17931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments, 17941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &varyingVSName, 17951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &varyingFSName); 17961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!matName) { 17981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(varyingDims == coordDims); 17991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = %s;\n", varyingVSName, vsInCoord); 18001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // varying = texMatrix * texCoord 18021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n", 18031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingVSName, matName, vsInCoord, 18041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vector_all_coords(varyingDims)); 18051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* radial2Params = NULL; 18081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* radial2VaryingVSName = NULL; 18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* radial2VaryingFSName = NULL; 18101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (isRadialMapping((StageDesc::CoordMapping) desc.fCoordMapping)) { 18121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2Params = genRadialVS(stageNum, segments, 18131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations, 18141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &radial2VaryingVSName, 18151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &radial2VaryingFSName, 18161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingVSName, 18171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims, coordDims); 18181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar* kernel = NULL; 18211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* imageIncrementName = NULL; 18221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (StageDesc::kConvolution_FetchMode == desc.fFetchMode) { 18231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger genConvolutionVS(stageNum, desc, segments, locations, 18241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger &kernel, &imageIncrementName, varyingVSName); 18254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else if (StageDesc::kDilate_FetchMode == desc.fFetchMode || 18264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger StageDesc::kErode_FetchMode == desc.fFetchMode) { 18274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger genMorphologyVS(stageNum, desc, segments, locations, 18284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger &imageIncrementName, varyingVSName); 18291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /// Fragment Shader Stuff 18321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder fsCoordName; 18331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // function used to access the shader, may be made projective 18341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texFunc("texture2D"); 18351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit | 18361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageDesc::kNoPerspective_OptFlagBit)) { 18371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(varyingDims == coordDims); 18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName = varyingFSName; 18391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we have to do some special op on the varyings to get 18411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // our final tex coords then when in perspective we have to 18421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // do an explicit divide. Otherwise, we can use a Proj func. 18431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping && 18441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageDesc::kSingle_FetchMode == desc.fFetchMode) { 18451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texFunc.append("Proj"); 18461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName = varyingFSName; 18471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 18481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName = "inCoord"; 18491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.appendS32(stageNum); 18501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n", 18511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::TypeString(float_vector_type(coordDims)), 18521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsCoordName.c_str(), 18531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingFSName, 18541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vector_nonhomog_coords(varyingDims), 18551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingFSName, 18561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vector_homog_coord(varyingDims)); 18571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 18591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder sampleCoords; 18611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool complexCoord = false; 18621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (desc.fCoordMapping) { 18631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kIdentity_CoordMapping: 18641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords = fsCoordName; 18651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kSweepGradient_CoordMapping: 18671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", fsCoordName.c_str(), fsCoordName.c_str()); 18681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger complexCoord = true; 18691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kRadialGradient_CoordMapping: 18711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.printf("vec2(length(%s.xy), 0.5)", fsCoordName.c_str()); 18721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger complexCoord = true; 18731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kRadial2Gradient_CoordMapping: 18751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger complexCoord = genRadial2GradientCoordMapping( 18761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stageNum, segments, 18771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2VaryingFSName, radial2Params, 18781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords, fsCoordName, 18791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims, coordDims); 18801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kRadial2GradientDegenerate_CoordMapping: 18831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger complexCoord = genRadial2GradientDegenerateCoordMapping( 18841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger stageNum, segments, 18851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger radial2VaryingFSName, radial2Params, 18861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords, fsCoordName, 18871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger varyingDims, coordDims); 18881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 18891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 18911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger static const uint32_t kMulByAlphaMask = 18934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger (StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag | 18944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag); 18954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 18961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const char* swizzle = ""; 18971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (desc.fInConfigFlags & StageDesc::kSwapRAndB_InConfigFlag) { 18981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag)); 18991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger swizzle = ".bgra"; 19001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) { 19014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); 19021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger swizzle = ".aaaa"; 19031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder modulate; 19061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != fsInColor) { 19071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger modulate.printf(" * %s", fsInColor); 19081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (desc.fOptFlags & 19111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageDesc::kCustomTextureDomain_OptFlagBit) { 19121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder texDomainName; 19131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tex_domain_name(stageNum, &texDomainName); 19141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, 19151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrGLShaderVar::kUniform_TypeModifier, texDomainName); 19161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrStringBuilder coordVar("clampCoord"); 19171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n", 19181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger float_vector_type_str(coordDims), 19191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger coordVar.c_str(), 19201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords.c_str(), 19211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texDomainName.c_str(), 19221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texDomainName.c_str()); 19231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords = coordVar; 19241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger locations->fTexDomUni = kUseUniform; 19251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (desc.fFetchMode) { 19281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::k2x2_FetchMode: 19294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); 19301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger gen2x2FS(stageNum, segments, locations, &sampleCoords, 19311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger samplerName, texelSizeName, swizzle, fsOutColor, 19321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger texFunc, modulate, complexCoord, coordDims); 19331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 19341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case StageDesc::kConvolution_FetchMode: 19354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); 19361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger genConvolutionFS(stageNum, desc, segments, 19371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger samplerName, kernel, swizzle, imageIncrementName, fsOutColor, 19381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sampleCoords, texFunc, modulate); 19391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 19404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case StageDesc::kDilate_FetchMode: 19414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case StageDesc::kErode_FetchMode: 19424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); 19434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger genMorphologyFS(stageNum, desc, segments, 19444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger samplerName, swizzle, imageIncrementName, fsOutColor, 19454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger sampleCoords, texFunc, modulate); 19464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 19471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 19484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (desc.fInConfigFlags & kMulByAlphaMask) { 19494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // only one of the mul by alpha flags should be set 19504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger GrAssert(GrIsPow2(kMulByAlphaMask & desc.fInConfigFlags)); 19511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GrAssert(!(desc.fInConfigFlags & 19521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger StageDesc::kSmearAlpha_InConfigFlag)); 19531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n", 19541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsOutColor, texFunc.c_str(), 19551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger samplerName, sampleCoords.c_str(), 19561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger swizzle); 19574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (desc.fInConfigFlags & 19584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) { 19594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t%s = vec4(ceil(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", 19604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsOutColor, fsOutColor, fsOutColor, 19614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsOutColor, modulate.c_str()); 19624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 19634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger segments->fFSCode.appendf("\t%s = vec4(floor(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", 19644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsOutColor, fsOutColor, fsOutColor, 19654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fsOutColor, modulate.c_str()); 19664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 19671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 19681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n", 19691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fsOutColor, texFunc.c_str(), 19701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger samplerName, sampleCoords.c_str(), 19711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger swizzle, modulate.c_str()); 19721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 19741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 19751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1977