OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gl/builders/GrGLProgramBuilder.h" | 8 #include "gl/builders/GrGLProgramBuilder.h" |
9 #include "GrGLProgramDesc.h" | 9 #include "GrGLProgramDesc.h" |
10 #include "GrBackendEffectFactory.h" | 10 #include "GrBackendEffectFactory.h" |
11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
12 #include "GrGpuGL.h" | 12 #include "GrGpuGL.h" |
13 #include "GrOptDrawState.h" | 13 #include "GrOptDrawState.h" |
14 | 14 |
15 #include "SkChecksum.h" | 15 #include "SkChecksum.h" |
16 | 16 |
| 17 /** |
| 18 * The key for an individual coord transform is made up of a matrix type and a b
it that |
| 19 * indicates the source of the input coords. |
| 20 */ |
| 21 enum { |
| 22 kMatrixTypeKeyBits = 1, |
| 23 kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, |
| 24 kPositionCoords_Flag = (1 << kMatrixTypeKeyBits), |
| 25 kTransformKeyBits = kMatrixTypeKeyBits + 1, |
| 26 }; |
| 27 |
| 28 /** |
| 29 * We specialize the vertex code for each of these matrix types. |
| 30 */ |
| 31 enum MatrixType { |
| 32 kNoPersp_MatrixType = 0, |
| 33 kGeneral_MatrixType = 1, |
| 34 }; |
| 35 |
| 36 /** |
| 37 * Do we need to either map r,g,b->a or a->r. configComponentMask indicates whic
h channels are |
| 38 * present in the texture's config. swizzleComponentMask indicates the channels
present in the |
| 39 * shader swizzle. |
| 40 */ |
| 41 static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps, |
| 42 uint32_t configComponentMask, |
| 43 uint32_t swizzleComponentMask) { |
| 44 if (caps.textureSwizzleSupport()) { |
| 45 // Any remapping is handled using texture swizzling not shader modificat
ions. |
| 46 return false; |
| 47 } |
| 48 // check if the texture is alpha-only |
| 49 if (kA_GrColorComponentFlag == configComponentMask) { |
| 50 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleCompon
entMask)) { |
| 51 // we must map the swizzle 'a's to 'r'. |
| 52 return true; |
| 53 } |
| 54 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { |
| 55 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our
semantics that |
| 56 // alpha-only textures smear alpha across all four channels when rea
d. |
| 57 return true; |
| 58 } |
| 59 } |
| 60 return false; |
| 61 } |
| 62 |
| 63 static uint32_t gen_attrib_key(const GrEffect* effect) { |
| 64 uint32_t key = 0; |
| 65 |
| 66 const GrEffect::VertexAttribArray& vars = effect->getVertexAttribs(); |
| 67 int numAttributes = vars.count(); |
| 68 SkASSERT(numAttributes <= 2); |
| 69 for (int a = 0; a < numAttributes; ++a) { |
| 70 uint32_t value = 1 << a; |
| 71 key |= value; |
| 72 } |
| 73 return key; |
| 74 } |
| 75 |
| 76 static uint32_t gen_transform_key(const GrEffectStage& effectStage, |
| 77 bool useExplicitLocalCoords) { |
| 78 uint32_t totalKey = 0; |
| 79 int numTransforms = effectStage.getEffect()->numTransforms(); |
| 80 for (int t = 0; t < numTransforms; ++t) { |
| 81 uint32_t key = 0; |
| 82 if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords))
{ |
| 83 key |= kGeneral_MatrixType; |
| 84 } else { |
| 85 key |= kNoPersp_MatrixType; |
| 86 } |
| 87 |
| 88 const GrCoordTransform& coordTransform = effectStage.getEffect()->coordT
ransform(t); |
| 89 if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLoc
alCoords) { |
| 90 key |= kPositionCoords_Flag; |
| 91 } |
| 92 key <<= kTransformKeyBits * t; |
| 93 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to
overlap |
| 94 totalKey |= key; |
| 95 } |
| 96 return totalKey; |
| 97 } |
| 98 |
| 99 static uint32_t gen_texture_key(const GrEffect* effect, const GrGLCaps& caps) { |
| 100 uint32_t key = 0; |
| 101 int numTextures = effect->numTextures(); |
| 102 for (int t = 0; t < numTextures; ++t) { |
| 103 const GrTextureAccess& access = effect->textureAccess(t); |
| 104 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText
ure()->config()); |
| 105 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s
wizzleMask())) { |
| 106 key |= 1 << t; |
| 107 } |
| 108 } |
| 109 return key; |
| 110 } |
| 111 |
| 112 /** |
| 113 * A function which emits a meta key into the key builder. This is required bec
ause shader code may |
| 114 * be dependent on properties of the effect that the effect itself doesn't use |
| 115 * in its key (e.g. the pixel format of textures used). So we create a meta-key
for |
| 116 * every effect using this function. It is also responsible for inserting the ef
fect's class ID |
| 117 * which must be different for every GrEffect subclass. It can fail if an effect
uses too many |
| 118 * textures, attributes, etc for the space allotted in the meta-key. |
| 119 */ |
| 120 |
| 121 static bool gen_effect_meta_key(const GrEffectStage& effectStage, |
| 122 bool useExplicitLocalCoords, |
| 123 const GrGLCaps& caps, |
| 124 GrEffectKeyBuilder* b) { |
| 125 |
| 126 uint32_t textureKey = gen_texture_key(effectStage.getEffect(), caps); |
| 127 uint32_t transformKey = gen_transform_key(effectStage,useExplicitLocalCoords
); |
| 128 uint32_t attribKey = gen_attrib_key(effectStage.getEffect()); |
| 129 uint32_t classID = effectStage.getEffect()->getFactory().effectClassID(); |
| 130 |
| 131 // Currently we allow 16 bits for each of the above portions of the meta-key
. Fail if they |
| 132 // don't fit. |
| 133 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
| 134 if ((textureKey | transformKey | attribKey | classID) & kMetaKeyInvalidMask)
{ |
| 135 return false; |
| 136 } |
| 137 |
| 138 uint32_t* key = b->add32n(2); |
| 139 key[0] = (textureKey << 16 | transformKey); |
| 140 key[1] = (classID << 16 | attribKey); |
| 141 return true; |
| 142 } |
| 143 |
17 bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& c
aps, | 144 bool GrGLProgramDesc::GetEffectKey(const GrEffectStage& stage, const GrGLCaps& c
aps, |
18 bool useExplicitLocalCoords, GrEffectKeyBuild
er* b, | 145 bool useExplicitLocalCoords, GrEffectKeyBuild
er* b, |
19 uint16_t* effectKeySize) { | 146 uint16_t* effectKeySize) { |
20 const GrBackendEffectFactory& factory = stage.getEffect()->getFactory(); | 147 const GrBackendEffectFactory& factory = stage.getEffect()->getFactory(); |
21 const GrEffect& effect = *stage.getEffect(); | 148 const GrEffect& effect = *stage.getEffect(); |
22 factory.getGLEffectKey(effect, caps, b); | 149 factory.getGLEffectKey(effect, caps, b); |
23 size_t size = b->size(); | 150 size_t size = b->size(); |
24 if (size > SK_MaxU16) { | 151 if (size > SK_MaxU16) { |
25 *effectKeySize = 0; // suppresses a warning. | 152 *effectKeySize = 0; // suppresses a warning. |
26 return false; | 153 return false; |
27 } | 154 } |
28 *effectKeySize = SkToU16(size); | 155 *effectKeySize = SkToU16(size); |
29 if (!GrGLProgramEffects::GenEffectMetaKey(stage, | 156 if (!gen_effect_meta_key(stage, useExplicitLocalCoords, caps, b)) { |
30 useExplicitLocalCoords, | |
31 caps, | |
32 b)) { | |
33 return false; | 157 return false; |
34 } | 158 } |
35 return true; | 159 return true; |
36 } | 160 } |
37 | 161 |
38 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, | 162 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
39 GrGpu::DrawType drawType, | 163 GrGpu::DrawType drawType, |
40 GrBlendCoeff srcCoeff, | 164 GrBlendCoeff srcCoeff, |
41 GrBlendCoeff dstCoeff, | 165 GrBlendCoeff dstCoeff, |
42 const GrGpuGL* gpu, | 166 const GrGpuGL* gpu, |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 *checksum = 0; | 407 *checksum = 0; |
284 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); | 408 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); |
285 } | 409 } |
286 | 410 |
287 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 411 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
288 size_t keyLength = other.keyLength(); | 412 size_t keyLength = other.keyLength(); |
289 fKey.reset(keyLength); | 413 fKey.reset(keyLength); |
290 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 414 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
291 return *this; | 415 return *this; |
292 } | 416 } |
OLD | NEW |