1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrProgramDesc_DEFINED 9 #define GrProgramDesc_DEFINED 10 11 #include "GrColor.h" 12 #include "GrTypesPriv.h" 13 #include "SkOpts.h" 14 #include "SkTArray.h" 15 #include "SkTo.h" 16 #include "glsl/GrGLSLFragmentShaderBuilder.h" 17 18 class GrShaderCaps; 19 class GrPipeline; 20 class GrPrimitiveProcessor; 21 22 /** This class describes a program to generate. It also serves as a program cache key */ 23 class GrProgramDesc { 24 public: 25 // Creates an uninitialized key that must be populated by GrGpu::buildProgramDesc() GrProgramDesc()26 GrProgramDesc() {} 27 28 /** 29 * Builds a program descriptor. Before the descriptor can be used, the client must call finalize 30 * on the returned GrProgramDesc. 31 * 32 * @param GrPrimitiveProcessor The geometry 33 * @param hasPointSize Controls whether the shader will output a point size. 34 * @param GrPipeline The optimized drawstate. The descriptor will represent a program 35 * which this optstate can use to draw with. The optstate contains 36 * general draw information, as well as the specific color, geometry, 37 * and coverage stages which will be used to generate the GL Program for 38 * this optstate. 39 * @param GrGpu Ptr to the GrGpu object the program will be used with. 40 * @param GrProgramDesc The built and finalized descriptor 41 **/ 42 static bool Build(GrProgramDesc*, const GrRenderTarget*, const GrPrimitiveProcessor&, 43 bool hasPointSize, const GrPipeline&, GrGpu*); 44 45 // Returns this as a uint32_t array to be used as a key in the program cache. asKey()46 const uint32_t* asKey() const { 47 return reinterpret_cast<const uint32_t*>(fKey.begin()); 48 } 49 50 // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. keyLength()51 uint32_t keyLength() const { 52 SkASSERT(0 == (fKey.count() % 4)); 53 return fKey.count(); 54 } 55 56 GrProgramDesc& operator= (const GrProgramDesc& other) { 57 uint32_t keyLength = other.keyLength(); 58 fKey.reset(SkToInt(keyLength)); 59 memcpy(fKey.begin(), other.fKey.begin(), keyLength); 60 return *this; 61 } 62 63 bool operator== (const GrProgramDesc& that) const { 64 if (this->keyLength() != that.keyLength()) { 65 return false; 66 } 67 68 SkASSERT(SkIsAlign4(this->keyLength())); 69 int l = this->keyLength() >> 2; 70 const uint32_t* aKey = this->asKey(); 71 const uint32_t* bKey = that.asKey(); 72 for (int i = 0; i < l; ++i) { 73 if (aKey[i] != bKey[i]) { 74 return false; 75 } 76 } 77 return true; 78 } 79 80 bool operator!= (const GrProgramDesc& other) const { 81 return !(*this == other); 82 } 83 setSurfaceOriginKey(int key)84 void setSurfaceOriginKey(int key) { 85 KeyHeader* header = this->atOffset<KeyHeader, kHeaderOffset>(); 86 header->fSurfaceOriginKey = key; 87 } 88 89 struct KeyHeader { hasSurfaceOriginKeyKeyHeader90 bool hasSurfaceOriginKey() const { 91 return SkToBool(fSurfaceOriginKey); 92 } processorFeaturesKeyHeader93 GrProcessor::CustomFeatures processorFeatures() const { 94 return (GrProcessor::CustomFeatures)fProcessorFeatures; 95 } 96 97 // Set to uniquely idenitify any swizzling of the shader's output color(s). 98 uint16_t fOutputSwizzle; 99 uint8_t fColorFragmentProcessorCnt; // Can be packed into 4 bits if required. 100 uint8_t fCoverageFragmentProcessorCnt; 101 // Set to uniquely identify the rt's origin, or 0 if the shader does not require this info. 102 uint8_t fSurfaceOriginKey : 2; 103 uint8_t fProcessorFeatures : 1; 104 bool fSnapVerticesToPixelCenters : 1; 105 bool fHasPointSize : 1; 106 bool fClampBlendInput : 1; 107 uint8_t fPad : 2; 108 }; 109 GR_STATIC_ASSERT(sizeof(KeyHeader) == 6); 110 111 // This should really only be used internally, base classes should return their own headers header()112 const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); } 113 114 protected: atOffset()115 template<typename T, size_t OFFSET> T* atOffset() { 116 return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); 117 } 118 atOffset()119 template<typename T, size_t OFFSET> const T* atOffset() const { 120 return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); 121 } 122 123 // The key, stored in fKey, is composed of two parts: 124 // 1. Header struct defined above. 125 // 2. A Backend specific payload which includes the per-processor keys. 126 enum KeyOffsets { 127 kHeaderOffset = 0, 128 kHeaderSize = SkAlign4(sizeof(KeyHeader)), 129 // Part 4. 130 // This is the offset into the backenend specific part of the key, which includes 131 // per-processor keys. 132 kProcessorKeysOffset = kHeaderOffset + kHeaderSize, 133 }; 134 135 enum { 136 kMaxPreallocProcessors = 8, 137 kIntsPerProcessor = 4, // This is an overestimate of the average effect key size. 138 kPreAllocSize = kHeaderOffset + kHeaderSize + 139 kMaxPreallocProcessors * sizeof(uint32_t) * kIntsPerProcessor, 140 }; 141 key()142 SkSTArray<kPreAllocSize, uint8_t, true>& key() { return fKey; } key()143 const SkSTArray<kPreAllocSize, uint8_t, true>& key() const { return fKey; } 144 145 private: 146 SkSTArray<kPreAllocSize, uint8_t, true> fKey; 147 }; 148 149 #endif 150