GrGLProgram.h revision d8f856c32b679d9f5a9926feac005e2c0186f83f
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 9f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#ifndef GrGLProgram_DEFINED 10f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#define GrGLProgram_DEFINED 11f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 12d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#include "GrDrawState.h" 1396399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com#include "GrGLContextInfo.h" 14086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com#include "GrGLSL.h" 15d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#include "GrStringBuilder.h" 16d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#include "GrGpu.h" 17f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 1897c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo#include "SkXfermode.h" 1997c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo 20f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comclass GrBinHashKeyBuilder; 2107eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.comclass GrGLProgramStage; 22d31cbc465088a253b5574b0305e09f9301b2bf81junov@google.com 234fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.comstruct ShaderCodeSegments; 24f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 25edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com// optionally compile the experimental GS code. Set to GR_DEBUG 26edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com// so that debug build bots will execute the code. 27edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#define GR_GL_EXPERIMENTAL_GS GR_DEBUG 28edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com 29f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com/** 30f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * This class manages a GPU program and records per-program information. 31f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * We can specify the attribute locations so that they are constant 32f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * across our shaders. But the driver determines the uniform locations 33f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * at link time. We don't need to remember the sampler uniform location 34f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * because we will bind a texture slot to it and never change it 35f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * Uniforms are program-local so we can't rely on fHWState to hold the 36f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * previous uniform state after a program change. 37f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 38f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comclass GrGLProgram { 39f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.compublic: 404fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 41f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com class CachedData; 42f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 43f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLProgram(); 44f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com ~GrGLProgram(); 45f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 46f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com /** 47f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * This is the heavy initilization routine for building a GLProgram. 48f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * The result of heavy init is not stored in datamembers of GrGLProgam, 49f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * but in a separate cacheable container. 50f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 5196399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com bool genProgram(const GrGLContextInfo& gl, 5207eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com GrCustomStage** customStages, 530b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com CachedData* programData) const; 54f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 55271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com /** 56271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com * The shader may modify the blend coeffecients. Params are in/out 57271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com */ 58271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 59271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com 60271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com /** 61b5b5eaff4774d74fda1980963d77b41c4bb8d687bsalomon@google.com * Attribute indices. These should not overlap. Matrices consume 3 slots. 62271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com */ 639196130af83782fcac4334117142475a837dd74dbsalomon@google.com static int PositionAttributeIdx() { return 0; } 649196130af83782fcac4334117142475a837dd74dbsalomon@google.com static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; } 659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com static int ColorAttributeIdx() { return 1 + GrDrawState::kMaxTexCoords; } 66a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com static int CoverageAttributeIdx() { 679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com return 2 + GrDrawState::kMaxTexCoords; 68a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com static int EdgeAttributeIdx() { return 3 + GrDrawState::kMaxTexCoords; } 70aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com 710d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com static int ViewMatrixAttributeIdx() { 729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com return 4 + GrDrawState::kMaxTexCoords; 739196130af83782fcac4334117142475a837dd74dbsalomon@google.com } 740d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com static int TextureMatrixAttributeIdx(int stage) { 759381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com return 7 + GrDrawState::kMaxTexCoords + 3 * stage; 769196130af83782fcac4334117142475a837dd74dbsalomon@google.com } 779196130af83782fcac4334117142475a837dd74dbsalomon@google.com 782a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.compublic: 79f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 800d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com // Parameters that affect code generation 810d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com // These structs should be kept compact; they are the input to an 820d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com // expensive hash key generator. 83f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com struct ProgramDesc { 844be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com ProgramDesc() { 854be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com // since we use this as part of a key we can't have any unitialized 864be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com // padding 874be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com memset(this, 0, sizeof(ProgramDesc)); 884be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com } 894be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com 90a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com enum OutputConfig { 91c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // PM-color OR color with no alpha channel 92a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kPremultiplied_OutputConfig, 93a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // nonPM-color with alpha channel. Round components up after 94a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // dividing by alpha. Assumes output is 8 bits for r, g, and b 95a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kUnpremultiplied_RoundUp_OutputConfig, 96a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // nonPM-color with alpha channel. Round components down after 97a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // dividing by alpha. Assumes output is 8 bits for r, g, and b 98a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kUnpremultiplied_RoundDown_OutputConfig, 99a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 100a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kOutputConfigCnt 101c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com }; 102c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1030d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com struct StageDesc { 1040d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com enum OptFlagBits { 1050d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kNoPerspective_OptFlagBit = 1 << 0, 1060d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kIdentityMatrix_OptFlagBit = 1 << 1, 1070d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kCustomTextureDomain_OptFlagBit = 1 << 2, 1080d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kIsEnabled_OptFlagBit = 1 << 7 1090d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 110d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com // Convolution is obsolete; left in for testing only 1110d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com enum FetchMode { 1120d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kSingle_FetchMode, 1131e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com k2x2_FetchMode, 114027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org kConvolution_FetchMode, 11505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org kErode_FetchMode, 11605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org kDilate_FetchMode, 1171e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com 1181e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com kFetchModeCnt, 1190d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 1200a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com /** 12174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com Flags set based on a src texture's pixel config. The operations 12274b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com described are performed after reading a texel. 1230a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com */ 12474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com enum InConfigFlags { 125443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kNone_InConfigFlag = 0x00, 12674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 12785b505bedc35369283ca3aa4449962622842b720bsalomon@google.com /** 12874b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com Swap the R and B channels. This is incompatible with 12974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com kSmearAlpha. It is prefereable to perform the swizzle outside 13074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com the shader using GL_ARB_texture_swizzle if possible rather 13174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com than setting this flag. 1320a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com */ 133443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kSwapRAndB_InConfigFlag = 0x01, 13474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 1350a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com /** 13674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com Smear alpha across all four channels. This is incompatible with 137443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kSwapRAndB, kMulRGBByAlpha* and kSmearRed. It is prefereable 138443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com to perform the smear outside the shader using 139443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com GL_ARB_texture_swizzle if possible rather than setting this 140443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com flag. 14185b505bedc35369283ca3aa4449962622842b720bsalomon@google.com */ 142443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kSmearAlpha_InConfigFlag = 0x02, 143443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com 144443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com /** 145443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com Smear the red channel across all four channels. This flag is 146443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com incompatible with kSwapRAndB, kMulRGBByAlpha*and kSmearAlpha. 147443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com It is preferable to use GL_ARB_texture_swizzle instead of this 148443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com flag. 149443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com */ 150443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kSmearRed_InConfigFlag = 0x04, 15174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 15274b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com /** 15374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com Multiply r,g,b by a after texture reads. This flag incompatible 15474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com with kSmearAlpha and may only be used with FetchMode kSingle. 155a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 156a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com It is assumed the src texture has 8bit color components. After 157a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com reading the texture one version rounds up to the next multiple 158a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com of 1/255.0 and the other rounds down. At most one of these 159a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com flags may be set. 16074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com */ 161443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kMulRGBByAlpha_RoundUp_InConfigFlag = 0x08, 162443e5a52b7e85070c26a068cd3b0aad126502395robertphillips@google.com kMulRGBByAlpha_RoundDown_InConfigFlag = 0x10, 16374b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 16474b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com kDummyInConfigFlag, 16574b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com kInConfigBitMask = (kDummyInConfigFlag-1) | 16674b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com (kDummyInConfigFlag-2) 16785b505bedc35369283ca3aa4449962622842b720bsalomon@google.com }; 1680d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com enum CoordMapping { 1690d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kIdentity_CoordMapping, 1700d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kRadialGradient_CoordMapping, 1710d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com kSweepGradient_CoordMapping, 1721e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com kRadial2Gradient_CoordMapping, 17322c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com // need different shader computation when quadratic 17422c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com // eq describing the gradient degenerates to a linear eq. 17522c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com kRadial2GradientDegenerate_CoordMapping, 1761e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com kCoordMappingCnt 1770d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 178f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 1790d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com uint8_t fOptFlags; 18074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com uint8_t fInConfigFlags; // bitfield of InConfigFlags values 18185b505bedc35369283ca3aa4449962622842b720bsalomon@google.com uint8_t fFetchMode; // casts to enum FetchMode 1820d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com uint8_t fCoordMapping; // casts to enum CoordMapping 183027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org uint8_t fKernelWidth; 1840d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com 18507eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com /** Non-zero if user-supplied code will write the stage's 18607eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com contribution to the fragment shader. */ 18707eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com uint16_t fCustomStageKey; 18807eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com 18974b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask == 19074b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com kInConfigBitMask); 19174b98715a375e5e4863115d681386c9f5ec194f5bsalomon@google.com 1920d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com inline bool isEnabled() const { 193c2c9b97e603fbccf04d29a550bf73709340ffe7dbsalomon@google.com return SkToBool(fOptFlags & kIsEnabled_OptFlagBit); 1940d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com } 1950d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com inline void setEnabled(bool newValue) { 1960d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com if (newValue) { 1970d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com fOptFlags |= kIsEnabled_OptFlagBit; 1980d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com } else { 1990d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com fOptFlags &= ~kIsEnabled_OptFlagBit; 2000d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com } 2010d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com } 2020d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 2030d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com 20486c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com // Specifies where the intitial color comes from before the stages are 20586c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com // applied. 20685b505bedc35369283ca3aa4449962622842b720bsalomon@google.com enum ColorInput { 20785b505bedc35369283ca3aa4449962622842b720bsalomon@google.com kSolidWhite_ColorInput, 20885b505bedc35369283ca3aa4449962622842b720bsalomon@google.com kTransBlack_ColorInput, 20985b505bedc35369283ca3aa4449962622842b720bsalomon@google.com kAttribute_ColorInput, 21085b505bedc35369283ca3aa4449962622842b720bsalomon@google.com kUniform_ColorInput, 21186c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com 21285b505bedc35369283ca3aa4449962622842b720bsalomon@google.com kColorInputCnt 2130d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 2140d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com // Dual-src blending makes use of a secondary output color that can be 215271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com // used as a per-pixel blend coeffecient. This controls whether a 216271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com // secondary source is output and what value it holds. 217271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com enum DualSrcOutput { 218271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com kNone_DualSrcOutput, 219271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com kCoverage_DualSrcOutput, 220271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com kCoverageISA_DualSrcOutput, 221271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com kCoverageISC_DualSrcOutput, 2221e257a5db32e1c9e3b0dba80f43470816ef948afbsalomon@google.com 223271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com kDualSrcOutputCnt 2240d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com }; 225f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 2269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrDrawState::VertexEdgeType fVertexEdgeType; 227aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com 2280d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com // stripped of bits that don't affect prog generation 2290d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com GrVertexLayout fVertexLayout; 23097c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo 2319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com StageDesc fStages[GrDrawState::kNumStages]; 232f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 233edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com // To enable experimental geometry shader code (not for use in 234edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com // production) 235edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#if GR_GL_EXPERIMENTAL_GS 236edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com bool fExperimentalGS; 237edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com#endif 238edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com 23985b505bedc35369283ca3aa4449962622842b720bsalomon@google.com uint8_t fColorInput; // casts to enum ColorInput 2402401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com uint8_t fCoverageInput; // casts to enum CoverageInput 241a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com uint8_t fOutputConfig; // casts to enum OutputConfig 24285b505bedc35369283ca3aa4449962622842b720bsalomon@google.com uint8_t fDualSrcOutput; // casts to enum DualSrcOutput 2430d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com int8_t fFirstCoverageStage; 2440d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com SkBool8 fEmitsPointSize; 245129b8e3237b80b9d258a8f48e8f54c0073cafbdcsenorblanco@chromium.org SkBool8 fEdgeAAConcave; 24650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org SkBool8 fColorMatrixEnabled; 247f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 2480d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com int8_t fEdgeAANumEdges; 2490d831725f6d3e68650c8d3cbcafd7f4986b4b2cctomhudson@google.com uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode 25050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org int8_t fPadding[3]; 2516aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com 252f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } fProgramDesc; 253edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com GR_STATIC_ASSERT(!(sizeof(ProgramDesc) % 4)); 254f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 25522c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com // for code readability 25622c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com typedef ProgramDesc::StageDesc StageDesc; 25722c5deaf755223111cb055462ac5bbce623f3a08bsalomon@google.com 2582a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.comprivate: 2592a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com 2602a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com const ProgramDesc& getDesc() { return fProgramDesc; } 261b3a39b5b017eeb8a37ce5cb29c6e9b00d649d11bsenorblanco@chromium.org const char* adjustInColor(const GrStringBuilder& inColor) const; 2622a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com 263f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.compublic: 2649196130af83782fcac4334117142475a837dd74dbsalomon@google.com enum { 2659196130af83782fcac4334117142475a837dd74dbsalomon@google.com kUnusedUniform = -1, 2669196130af83782fcac4334117142475a837dd74dbsalomon@google.com kSetAsAttribute = 1000, 2679196130af83782fcac4334117142475a837dd74dbsalomon@google.com }; 2689196130af83782fcac4334117142475a837dd74dbsalomon@google.com 269f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com struct StageUniLocations { 270f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLint fTextureMatrixUni; 2716aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrGLint fNormalizedTexelSizeUni; 272f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLint fSamplerUni; 273f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLint fRadial2Uni; 2746acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.com GrGLint fTexDomUni; 275027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrGLint fKernelUni; 276027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrGLint fImageIncrementUni; 2779196130af83782fcac4334117142475a837dd74dbsalomon@google.com void reset() { 2789196130af83782fcac4334117142475a837dd74dbsalomon@google.com fTextureMatrixUni = kUnusedUniform; 2799196130af83782fcac4334117142475a837dd74dbsalomon@google.com fNormalizedTexelSizeUni = kUnusedUniform; 2809196130af83782fcac4334117142475a837dd74dbsalomon@google.com fSamplerUni = kUnusedUniform; 2819196130af83782fcac4334117142475a837dd74dbsalomon@google.com fRadial2Uni = kUnusedUniform; 2826acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.com fTexDomUni = kUnusedUniform; 283027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org fKernelUni = kUnusedUniform; 284027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org fImageIncrementUni = kUnusedUniform; 2859196130af83782fcac4334117142475a837dd74dbsalomon@google.com } 286f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com }; 287f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 288f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com struct UniLocations { 289f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLint fViewMatrixUni; 2904be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com GrGLint fColorUni; 2912401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com GrGLint fCoverageUni; 29292e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org GrGLint fEdgesUni; 29397c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo GrGLint fColorFilterUni; 29450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org GrGLint fColorMatrixUni; 29550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org GrGLint fColorMatrixVecUni; 2969381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com StageUniLocations fStages[GrDrawState::kNumStages]; 2979196130af83782fcac4334117142475a837dd74dbsalomon@google.com void reset() { 2989196130af83782fcac4334117142475a837dd74dbsalomon@google.com fViewMatrixUni = kUnusedUniform; 2999196130af83782fcac4334117142475a837dd74dbsalomon@google.com fColorUni = kUnusedUniform; 3002401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com fCoverageUni = kUnusedUniform; 30192e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org fEdgesUni = kUnusedUniform; 30297c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo fColorFilterUni = kUnusedUniform; 30350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org fColorMatrixUni = kUnusedUniform; 30450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org fColorMatrixVecUni = kUnusedUniform; 3059381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com for (int s = 0; s < GrDrawState::kNumStages; ++s) { 3069196130af83782fcac4334117142475a837dd74dbsalomon@google.com fStages[s].reset(); 3079196130af83782fcac4334117142475a837dd74dbsalomon@google.com } 3089196130af83782fcac4334117142475a837dd74dbsalomon@google.com } 309f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com }; 310f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 311f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com class CachedData : public ::GrNoncopyable { 312f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com public: 313f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com CachedData() { 31407eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com for (int i = 0; i < GrDrawState::kNumStages; ++i) { 31507eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com fCustomStage[i] = NULL; 31607eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com } 317f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 318f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 31907eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com ~CachedData(); 320f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 321f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com void copyAndTakeOwnership(CachedData& other) { 3222d9ddf9df12b900b7dbe9b9c627757595f8ed289bsalomon@google.com memcpy(this, &other, sizeof(*this)); 323d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com for (int i = 0; i < GrDrawState::kNumStages; ++i) { 324d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com other.fCustomStage[i] = NULL; 325d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com } 326f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com } 327f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 328f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com public: 329f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 330f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // IDs 331f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLuint fVShaderID; 332edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com GrGLuint fGShaderID; 333f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLuint fFShaderID; 334f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrGLuint fProgramID; 335f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // shader uniform locations (-1 if shader doesn't use them) 336f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com UniLocations fUniLocations; 337f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 338f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com GrMatrix fViewMatrix; 339f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 340f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // these reflect the current values of uniforms 341f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // (GL uniform values travel with program) 3424be283f3a82895530d1b70372cd48ddb1c663fd8bsalomon@google.com GrColor fColor; 3432401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com GrColor fCoverage; 34497c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo GrColor fColorFilterColor; 3459381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrMatrix fTextureMatrices[GrDrawState::kNumStages]; 3466aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // width and height used for normalized texel size 3479381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int fTextureWidth[GrDrawState::kNumStages]; 3489381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int fTextureHeight[GrDrawState::kNumStages]; 3499381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrScalar fRadial2CenterX1[GrDrawState::kNumStages]; 3509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrScalar fRadial2Radius0[GrDrawState::kNumStages]; 3519381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com bool fRadial2PosRoot[GrDrawState::kNumStages]; 3529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrRect fTextureDomain[GrDrawState::kNumStages]; 353f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 35407eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com GrGLProgramStage* fCustomStage[GrDrawState::kNumStages]; 35507eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com 356f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com private: 357f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com enum Constants { 358f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com kUniLocationPreAllocSize = 8 359f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com }; 360f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 361f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com }; // CachedData 362f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 363f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com enum Constants { 364f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com kProgramKeySize = sizeof(ProgramDesc) 365f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com }; 366f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com 367f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com // Provide an opaque ProgramDesc 368f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com const uint32_t* keyData() const{ 369f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com return reinterpret_cast<const uint32_t*>(&fProgramDesc); 370f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com } 371f7c00f6be1542a7175b6987d61e9bd5e52f4901ejunov@google.com 372f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comprivate: 3739196130af83782fcac4334117142475a837dd74dbsalomon@google.com 3742a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com // Determines which uniforms will need to be bound. 37596399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com void genStageCode(const GrGLContextInfo& gl, 3760b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com int stageNum, 377f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com const ProgramDesc::StageDesc& desc, 378f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com const char* fsInColor, // NULL means no incoming color 379f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com const char* fsOutColor, 380f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com const char* vsInCoord, 381f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com ShaderCodeSegments* segments, 38207eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com StageUniLocations* locations, 38307eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com GrGLProgramStage* override) const; 3844fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 38596399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com void genGeometryShader(const GrGLContextInfo& gl, 386edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com ShaderCodeSegments* segments) const; 387edfe1aac5c6f3a3f3830e86ddea8dbceeb0e6df4bsalomon@google.com 388661056739ce2eb9aaa18d2bc82566038dc4a0089bsalomon@google.com // generates code to compute coverage based on edge AA. 38996399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com void genEdgeCoverage(const GrGLContextInfo& gl, 390661056739ce2eb9aaa18d2bc82566038dc4a0089bsalomon@google.com GrVertexLayout layout, 391661056739ce2eb9aaa18d2bc82566038dc4a0089bsalomon@google.com CachedData* programData, 392661056739ce2eb9aaa18d2bc82566038dc4a0089bsalomon@google.com GrStringBuilder* coverageVar, 393661056739ce2eb9aaa18d2bc82566038dc4a0089bsalomon@google.com ShaderCodeSegments* segments) const; 394f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 39596399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com static bool CompileShaders(const GrGLContextInfo& gl, 3960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com const ShaderCodeSegments& segments, 3979196130af83782fcac4334117142475a837dd74dbsalomon@google.com CachedData* programData); 3989196130af83782fcac4334117142475a837dd74dbsalomon@google.com 399f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // Compiles a GL shader, returns shader ID or 0 if failed 400f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com // params have same meaning as glShaderSource 40196399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com static GrGLuint CompileShader(const GrGLContextInfo& gl, 4020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com GrGLenum type, int stringCnt, 403f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com const char** strings, 404f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com int* stringLengths); 405f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 4069196130af83782fcac4334117142475a837dd74dbsalomon@google.com // Creates a GL program ID, binds shader attributes to GL vertex attrs, and 4079196130af83782fcac4334117142475a837dd74dbsalomon@google.com // links the program 408271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com bool bindOutputsAttribsAndLinkProgram( 40996399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com const GrGLContextInfo& gl, 4109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com GrStringBuilder texCoordAttrNames[GrDrawState::kMaxTexCoords], 411271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com bool bindColorOut, 412271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com bool bindDualSrcOut, 413271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com CachedData* programData) const; 4149196130af83782fcac4334117142475a837dd74dbsalomon@google.com 4152a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.com // Binds uniforms; initializes cache to invalid values. 41696399948dc2f1afd2e9d9e5be7d646c01d17f82bbsalomon@google.com void getUniformLocationsAndInitCache(const GrGLContextInfo& gl, 4170b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com CachedData* programData) const; 4189196130af83782fcac4334117142475a837dd74dbsalomon@google.com 419f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com friend class GrGpuGLShaders; 420f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com}; 421f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 422f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#endif 423