17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifndef GrGLProgramDesc_DEFINED 97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define GrGLProgramDesc_DEFINED 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrGLEffect.h" 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrDrawState.h" 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrGLShaderBuilder.h" 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGpuGL; 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_DEBUG 180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // Optionally compile the experimental GS code. Set to SK_DEBUG so that debug build bots will 190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // execute the code. 200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger #define GR_GL_EXPERIMENTAL_GS 1 210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#else 220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger #define GR_GL_EXPERIMENTAL_GS 0 230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/** This class describes a program to generate. It also serves as a program cache key. Very little 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger of this is GL-specific. There is the generation of GrGLEffect::EffectKeys and the dst-read part 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger of the key set by GrGLShaderBuilder. If the interfaces that set those portions were abstracted 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger to be API-neutral then so could this class. */ 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass GrGLProgramDesc { 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic: 32779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrGLProgramDesc() : fInitialized(false) {} 33779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; } 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 35779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // Returns this as a uint32_t array to be used as a key in the program cache. 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const uint32_t* asKey() const { 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fInitialized); 38779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return reinterpret_cast<const uint32_t*>(fKey.get()); 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 41779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two 42779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // keys the size of either key can be used with memcmp() since the lengths themselves begin the 43779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // keys and thus the memcmp will exit early if the keys are of different lengths. 44779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>(); } 45779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 46779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache. 47779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); } 48779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // For unit testing. 500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger void setRandom(SkRandom*, 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrGpuGL* gpu, 52779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrRenderTarget* dummyDstRenderTarget, 53779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrTexture* dummyDstCopyTexture, 54779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrEffectStage* stages[], 55779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numColorStages, 56779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numCoverageStages, 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int currAttribIndex); 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger /** 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the 61779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also 6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * outputs the color and coverage stages referenced by the generated descriptor. This may 6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * not contain all stages from the draw state and coverage stages from the drawState may 6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * be treated as color stages in the output. 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static void Build(const GrDrawState&, 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool isPoints, 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrDrawState::BlendOptFlags, 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrBlendCoeff srcCoeff, 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrBlendCoeff dstCoeff, 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrGpuGL* gpu, 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrDeviceCoordTexture* dstCopy, 7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkTArray<const GrEffectStage*, true>* outColorStages, 7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkTArray<const GrEffectStage*, true>* outCoverageStages, 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrGLProgramDesc* outDesc); 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 77779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numColorEffects() const { 780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fInitialized); 79779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return this->getHeader().fColorEffectCnt; 80779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 81779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 82779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numCoverageEffects() const { 830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fInitialized); 84779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return this->getHeader().fCoverageEffectCnt; 85779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 86779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 87779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); } 88779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 89779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrGLProgramDesc& operator= (const GrGLProgramDesc& other); 90779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 91779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger bool operator== (const GrGLProgramDesc& other) const { 920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fInitialized && other.fInitialized); 93779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // The length is masked as a hint to the compiler that the address will be 4 byte aligned. 94779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3); 95779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 96779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 97779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger bool operator!= (const GrGLProgramDesc& other) const { 98779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return !(*this == other); 99779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 100779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 101779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) { 102779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0; 103779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 104779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate: 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Specifies where the initial color comes from before the stages are applied. 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger enum ColorInput { 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kSolidWhite_ColorInput, 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kTransBlack_ColorInput, 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kAttribute_ColorInput, 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kUniform_ColorInput, 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kColorInputCnt 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger }; 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger enum CoverageOutput { 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // modulate color and coverage, write result as the color output. 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kModulate_CoverageOutput, 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Writes color*coverage as the primary color output and also writes coverage as the 1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // secondary output. Only set if dual source blending is supported. 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kSecondaryCoverage_CoverageOutput, 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Writes color*coverage as the primary color output and also writes coverage * (1 - colorA) 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // as the secondary output. Only set if dual source blending is supported. 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kSecondaryCoverageISA_CoverageOutput, 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Writes color*coverage as the primary color output and also writes coverage * 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // (1 - colorRGB) as the secondary output. Only set if dual source blending is supported. 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kSecondaryCoverageISC_CoverageOutput, 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This 1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // can only be set if fDstReadKey is non-zero. 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kCombineWithDst_CoverageOutput, 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger kCoverageOutputCnt 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger }; 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static bool CoverageOutputUsesSecondaryOutput(CoverageOutput co) { 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger switch (co) { 1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case kSecondaryCoverage_CoverageOutput: // fallthru 1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case kSecondaryCoverageISA_CoverageOutput: 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger case kSecondaryCoverageISC_CoverageOutput: 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return true; 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger default: 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 146779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger struct KeyHeader { 147779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuilder if there 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // are effects that must read the dst. 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Otherwise, 0. 150779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuilder if there are 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // effects that read the fragment position. 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Otherwise, 0. 1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 154779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // should the FS discard if the coverage is zero (to avoid stencil manipulation) 155779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkBool8 fDiscardIfZeroCoverage; 1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ColorInput fColorInput : 8; 1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ColorInput fCoverageInput : 8; 1590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger CoverageOutput fCoverageOutput : 8; 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBool8 fHasVertexCode; 162779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkBool8 fEmitsPointSize; 163779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 164779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // To enable experimental geometry shader code (not for use in 165779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // production) 166779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#if GR_GL_EXPERIMENTAL_GS 167779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkBool8 fExperimentalGS; 168779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#endif 169779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 170779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fPositionAttributeIndex; 171779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fLocalCoordAttributeIndex; 172779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fColorAttributeIndex; 173779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fCoverageAttributeIndex; 174779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 175779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fColorEffectCnt; 176779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int8_t fCoverageEffectCnt; 177779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger }; 178779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 179779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then 180779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // the effect keys. Everything is fixed length except the effect key array. 181779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger enum { 182779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kLengthOffset = 0, 183779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kChecksumOffset = kLengthOffset + sizeof(uint32_t), 184779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kHeaderOffset = kChecksumOffset + sizeof(uint32_t), 185779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kHeaderSize = SkAlign4(sizeof(KeyHeader)), 186779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kEffectKeyOffset = kHeaderOffset + kHeaderSize, 187779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger }; 188779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 189779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger template<typename T, size_t OFFSET> T* atOffset() { 190779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET); 191779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 192779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 193779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger template<typename T, size_t OFFSET> const T* atOffset() const { 194779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET); 195779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 196779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 197779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger typedef GrGLEffect::EffectKey EffectKey; 198779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 199779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); } 200779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); } 201779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset>(); } 202779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 203779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); } 204779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kEffectKeyOffset>(); } 205779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 206779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger static size_t KeyLength(int effectCnt) { 207779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3)); 208779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger return kEffectKeyOffset + effectCnt * sizeof(EffectKey); 209779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 210779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 211779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger enum { 212779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kMaxPreallocEffects = 16, 213779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectKey), 214779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger }; 2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 216779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkAutoSMalloc<kPreAllocSize> fKey; 217779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger bool fInitialized; 2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Move all 2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // code generation to GrGLShaderBuilder (and maybe add getters rather than friending). 2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger friend class GrGLProgram; 2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger friend class GrGLShaderBuilder; 2230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger friend class GrGLFullShaderBuilder; 2240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger friend class GrGLFragmentOnlyShaderBuilder; 2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 228