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/GrGLFragmentShaderBuilder.h" | 8 #include "gl/builders/GrGLFragmentShaderBuilder.h" |
9 #include "GrGLProgramDesc.h" | 9 #include "GrGLProgramDesc.h" |
10 #include "GrBackendProcessorFactory.h" | 10 #include "GrBackendProcessorFactory.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 } | 53 } |
54 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { | 54 if (kRGB_GrColorComponentFlags & swizzleComponentMask) { |
55 // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our
semantics that | 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. | 56 // alpha-only textures smear alpha across all four channels when rea
d. |
57 return true; | 57 return true; |
58 } | 58 } |
59 } | 59 } |
60 return false; | 60 return false; |
61 } | 61 } |
62 | 62 |
63 static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) { | 63 static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) { |
64 uint32_t key = 0; | 64 uint32_t key = 0; |
65 | 65 |
66 const GrGeometryProcessor::VertexAttribArray& vars = proc.getVertexAttribs()
; | 66 const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttrib
s(); |
67 int numAttributes = vars.count(); | 67 int numAttributes = vars.count(); |
68 SkASSERT(numAttributes <= 2); | 68 SkASSERT(numAttributes <= 2); |
69 for (int a = 0; a < numAttributes; ++a) { | 69 for (int a = 0; a < numAttributes; ++a) { |
70 uint32_t value = 1 << a; | 70 uint32_t value = 1 << a; |
71 key |= value; | 71 key |= value; |
72 } | 72 } |
73 return key; | 73 return key; |
74 } | 74 } |
75 | 75 |
76 static uint32_t gen_transform_key(const GrFragmentStage& effectStage, | 76 static uint32_t gen_transform_key(const GrProcessorStage& effectStage, |
77 bool useExplicitLocalCoords) { | 77 bool useExplicitLocalCoords) { |
78 uint32_t totalKey = 0; | 78 uint32_t totalKey = 0; |
79 int numTransforms = effectStage.getProcessor()->numTransforms(); | 79 int numTransforms = effectStage.getProcessor()->numTransforms(); |
80 for (int t = 0; t < numTransforms; ++t) { | 80 for (int t = 0; t < numTransforms; ++t) { |
81 uint32_t key = 0; | 81 uint32_t key = 0; |
82 if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords))
{ | 82 if (effectStage.isPerspectiveCoordTransform(t, useExplicitLocalCoords))
{ |
83 key |= kGeneral_MatrixType; | 83 key |= kGeneral_MatrixType; |
84 } else { | 84 } else { |
85 key |= kNoPersp_MatrixType; | 85 key |= kNoPersp_MatrixType; |
86 } | 86 } |
87 | 87 |
88 const GrCoordTransform& coordTransform = effectStage.getProcessor()->coo
rdTransform(t); | 88 const GrCoordTransform& coordTransform = effectStage.getProcessor()->coo
rdTransform(t); |
89 if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLoc
alCoords) { | 89 if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLoc
alCoords) { |
90 key |= kPositionCoords_Flag; | 90 key |= kPositionCoords_Flag; |
91 } | 91 } |
92 key <<= kTransformKeyBits * t; | 92 key <<= kTransformKeyBits * t; |
93 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to
overlap | 93 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to
overlap |
94 totalKey |= key; | 94 totalKey |= key; |
95 } | 95 } |
96 return totalKey; | 96 return totalKey; |
97 } | 97 } |
98 | 98 |
99 static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) { | 99 static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps)
{ |
100 uint32_t key = 0; | 100 uint32_t key = 0; |
101 int numTextures = proc.numTextures(); | 101 int numTextures = effect->numTextures(); |
102 for (int t = 0; t < numTextures; ++t) { | 102 for (int t = 0; t < numTextures; ++t) { |
103 const GrTextureAccess& access = proc.textureAccess(t); | 103 const GrTextureAccess& access = effect->textureAccess(t); |
104 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText
ure()->config()); | 104 uint32_t configComponentMask = GrPixelConfigComponentMask(access.getText
ure()->config()); |
105 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s
wizzleMask())) { | 105 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.s
wizzleMask())) { |
106 key |= 1 << t; | 106 key |= 1 << t; |
107 } | 107 } |
108 } | 108 } |
109 return key; | 109 return key; |
110 } | 110 } |
111 | 111 |
112 /** | 112 /** |
113 * A function which emits a meta key into the key builder. This is required bec
ause shader code may | 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 | 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 | 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 | 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 GrProcessor subclass. It can fail if an eff
ect uses too many | 117 * which must be different for every GrProcessor subclass. It can fail if an eff
ect uses too many |
118 * textures, transforms, etc, for the space allotted in the meta-key. NOTE, bot
h FPs and GPs share | 118 * textures, transforms, etc, for the space allotted in the meta-key. |
119 * this function because it is hairy, though FPs do not have attribs, and GPs do
not have transforms | |
120 */ | 119 */ |
121 static bool get_meta_key(const GrProcessor& proc, | 120 |
122 const GrGLCaps& caps, | 121 static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage, |
123 uint32_t transformKey, | 122 bool useExplicitLocalCoords, |
124 uint32_t attribKey, | 123 const GrGLCaps& caps, |
125 GrProcessorKeyBuilder* b, | 124 GrProcessorKeyBuilder* b) { |
126 uint16_t* processorKeySize) { | 125 |
127 const GrBackendProcessorFactory& factory = proc.getFactory(); | 126 uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps); |
128 factory.getGLProcessorKey(proc, caps, b); | 127 uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoo
rds); |
| 128 uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID
(); |
| 129 |
| 130 // Currently we allow 16 bits for each of the above portions of the meta-key
. Fail if they |
| 131 // don't fit. |
| 132 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
| 133 if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) { |
| 134 return NULL; |
| 135 } |
| 136 |
| 137 uint32_t* key = b->add32n(2); |
| 138 key[0] = (textureKey << 16 | transformKey); |
| 139 key[1] = (classID << 16); |
| 140 return key; |
| 141 } |
| 142 |
| 143 static bool get_fp_key(const GrProcessorStage& stage, |
| 144 const GrGLCaps& caps, |
| 145 bool useExplicitLocalCoords, |
| 146 GrProcessorKeyBuilder* b, |
| 147 uint16_t* processorKeySize) { |
| 148 const GrProcessor& effect = *stage.getProcessor(); |
| 149 const GrBackendProcessorFactory& factory = effect.getFactory(); |
| 150 factory.getGLProcessorKey(effect, caps, b); |
129 size_t size = b->size(); | 151 size_t size = b->size(); |
130 if (size > SK_MaxU16) { | 152 if (size > SK_MaxU16) { |
131 *processorKeySize = 0; // suppresses a warning. | 153 *processorKeySize = 0; // suppresses a warning. |
132 return false; | 154 return false; |
133 } | 155 } |
134 *processorKeySize = SkToU16(size); | 156 *processorKeySize = SkToU16(size); |
135 uint32_t textureKey = gen_texture_key(proc, caps); | 157 if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b))
{ |
136 uint32_t classID = proc.getFactory().effectClassID(); | 158 return false; |
| 159 } |
| 160 return true; |
| 161 } |
| 162 |
| 163 static bool get_gp_key(const GrGeometryStage& stage, |
| 164 const GrGLCaps& caps, |
| 165 bool useExplicitLocalCoords, |
| 166 GrProcessorKeyBuilder* b, |
| 167 uint16_t* processorKeySize) { |
| 168 const GrProcessor& effect = *stage.getProcessor(); |
| 169 const GrBackendProcessorFactory& factory = effect.getFactory(); |
| 170 factory.getGLProcessorKey(effect, caps, b); |
| 171 size_t size = b->size(); |
| 172 if (size > SK_MaxU16) { |
| 173 *processorKeySize = 0; // suppresses a warning. |
| 174 return false; |
| 175 } |
| 176 *processorKeySize = SkToU16(size); |
| 177 uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps,
b); |
| 178 if (NULL == key) { |
| 179 return false; |
| 180 } |
| 181 uint32_t attribKey = gen_attrib_key(stage.getProcessor()); |
137 | 182 |
138 // Currently we allow 16 bits for each of the above portions of the meta-key
. Fail if they | 183 // Currently we allow 16 bits for each of the above portions of the meta-key
. Fail if they |
139 // don't fit. | 184 // don't fit. |
140 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); | 185 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
141 if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) { | 186 if ((attribKey) & kMetaKeyInvalidMask) { |
142 return false; | 187 return false; |
143 } | 188 } |
144 | 189 |
145 uint32_t* key = b->add32n(2); | 190 key[1] |= attribKey; |
146 key[0] = (textureKey << 16 | transformKey); | |
147 key[1] = (classID << 16); | |
148 return true; | 191 return true; |
149 } | 192 } |
150 | 193 |
151 struct GeometryProcessorKeyBuilder { | 194 struct GeometryProcessorKeyBuilder { |
152 typedef GrGeometryProcessor StagedProcessor; | 195 typedef GrGeometryStage StagedProcessor; |
153 static bool GetProcessorKey(const GrGeometryProcessor& gp, | 196 static bool GetProcessorKey(const GrGeometryStage& gpStage, |
154 const GrGLCaps& caps, | 197 const GrGLCaps& caps, |
155 bool, | 198 bool requiresLocalCoordAttrib, |
156 GrProcessorKeyBuilder* b, | 199 GrProcessorKeyBuilder* b, |
157 uint16_t* keySize) { | 200 uint16_t* processorKeySize) { |
158 /* 0 because no transforms on a GP */ | 201 return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorK
eySize); |
159 return get_meta_key(gp, caps, 0, gen_attrib_key(gp), b, keySize); | |
160 } | 202 } |
161 }; | 203 }; |
162 | 204 |
163 struct FragmentProcessorKeyBuilder { | 205 struct FragmentProcessorKeyBuilder { |
164 typedef GrFragmentStage StagedProcessor; | 206 typedef GrFragmentStage StagedProcessor; |
165 static bool GetProcessorKey(const GrFragmentStage& fps, | 207 static bool GetProcessorKey(const GrFragmentStage& fpStage, |
166 const GrGLCaps& caps, | 208 const GrGLCaps& caps, |
167 bool useLocalCoords, | 209 bool requiresLocalCoordAttrib, |
168 GrProcessorKeyBuilder* b, | 210 GrProcessorKeyBuilder* b, |
169 uint16_t* keySize) { | 211 uint16_t* processorKeySize) { |
170 /* 0 because no attribs on a fP */ | 212 return get_fp_key(fpStage, caps, requiresLocalCoordAttrib, b, processorK
eySize); |
171 return get_meta_key(*fps.getProcessor(), caps, gen_transform_key(fps, us
eLocalCoords), 0, | |
172 b, keySize); | |
173 } | 213 } |
174 }; | 214 }; |
175 | 215 |
176 | 216 |
177 template <class ProcessorKeyBuilder> | 217 template <class ProcessorKeyBuilder> |
178 bool | 218 bool |
179 GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
gedProcessor& stage, | 219 GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
gedProcessor& stage, |
180 const GrGLCaps& caps, | 220 const GrGLCaps& caps, |
181 bool requiresLocalCoordAttrib, | 221 bool requiresLocalCoordAttrib, |
182 GrGLProgramDesc* desc, | 222 GrGLProgramDesc* desc, |
(...skipping 12 matching lines...) Expand all Loading... |
195 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + | 235 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + |
196 *offsetAndSizeIndex * 2 * sizeof(uint16_
t)); | 236 *offsetAndSizeIndex * 2 * sizeof(uint16_
t)); |
197 offsetAndSize[0] = SkToU16(processorOffset); | 237 offsetAndSize[0] = SkToU16(processorOffset); |
198 offsetAndSize[1] = processorKeySize; | 238 offsetAndSize[1] = processorKeySize; |
199 ++(*offsetAndSizeIndex); | 239 ++(*offsetAndSizeIndex); |
200 return true; | 240 return true; |
201 } | 241 } |
202 | 242 |
203 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, | 243 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
204 GrGpu::DrawType drawType, | 244 GrGpu::DrawType drawType, |
| 245 GrBlendCoeff srcCoeff, |
| 246 GrBlendCoeff dstCoeff, |
205 GrGpuGL* gpu, | 247 GrGpuGL* gpu, |
206 const GrDeviceCoordTexture* dstCopy, | 248 const GrDeviceCoordTexture* dstCopy, |
| 249 const GrGeometryStage** geometryProcessor, |
| 250 SkTArray<const GrFragmentStage*, true>* colorStages, |
| 251 SkTArray<const GrFragmentStage*, true>* coverageStag
es, |
207 GrGLProgramDesc* desc) { | 252 GrGLProgramDesc* desc) { |
| 253 colorStages->reset(); |
| 254 coverageStages->reset(); |
| 255 |
208 bool inputColorIsUsed = optState.inputColorIsUsed(); | 256 bool inputColorIsUsed = optState.inputColorIsUsed(); |
209 bool inputCoverageIsUsed = optState.inputCoverageIsUsed(); | 257 bool inputCoverageIsUsed = optState.inputCoverageIsUsed(); |
210 | 258 |
211 // The descriptor is used as a cache key. Thus when a field of the | 259 // The descriptor is used as a cache key. Thus when a field of the |
212 // descriptor will not affect program generation (because of the attribute | 260 // descriptor will not affect program generation (because of the attribute |
213 // bindings in use or other descriptor field settings) it should be set | 261 // bindings in use or other descriptor field settings) it should be set |
214 // to a canonical value to avoid duplicate programs with different keys. | 262 // to a canonical value to avoid duplicate programs with different keys. |
215 | 263 |
216 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); | 264 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); |
217 | 265 |
218 int numStages = optState.numTotalStages(); | 266 int numStages = optState.numTotalStages(); |
219 | 267 |
220 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); | 268 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); |
221 // Make room for everything up to and including the array of offsets to effe
ct keys. | 269 // Make room for everything up to and including the array of offsets to effe
ct keys. |
222 desc->fKey.reset(); | 270 desc->fKey.reset(); |
223 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_
t) * numStages); | 271 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_
t) * numStages); |
224 | 272 |
225 int offsetAndSizeIndex = 0; | 273 int offsetAndSizeIndex = 0; |
226 | 274 |
227 // We can only have one effect which touches the vertex shader | 275 // We can only have one effect which touches the vertex shader |
228 if (optState.hasGeometryProcessor()) { | 276 if (optState.hasGeometryProcessor()) { |
229 if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getG
eometryProcessor(), | 277 const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); |
| 278 if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage, |
230 gpu->glCaps(), | 279 gpu->glCaps(), |
231 false, | 280 requiresLocalC
oordAttrib, |
| 281 desc, |
| 282 &offsetAndSize
Index)) { |
| 283 return false; |
| 284 } |
| 285 *geometryProcessor = &gpStage; |
| 286 } |
| 287 |
| 288 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 289 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo
lorStage(s), |
| 290 gpu->glCaps(), |
| 291 requiresLocalC
oordAttrib, |
232 desc, | 292 desc, |
233 &offsetAndSize
Index)) { | 293 &offsetAndSize
Index)) { |
234 return false; | 294 return false; |
235 } | 295 } |
236 } | 296 } |
237 | 297 |
238 for (int s = 0; s < optState.numFragmentStages(); ++s) { | 298 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
239 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getFr
agmentStage(s), | 299 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo
verageStage(s), |
240 gpu->glCaps(), | 300 gpu->glCaps(), |
241 requiresLocalC
oordAttrib, | 301 requiresLocalC
oordAttrib, |
242 desc, | 302 desc, |
243 &offsetAndSize
Index)) { | 303 &offsetAndSize
Index)) { |
244 return false; | 304 return false; |
245 } | 305 } |
246 } | 306 } |
247 | 307 |
248 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- | 308 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- |
249 // Because header is a pointer into the dynamic array, we can't push any new
data into the key | 309 // Because header is a pointer into the dynamic array, we can't push any new
data into the key |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput)
{ | 392 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput)
{ |
333 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); | 393 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
334 header->fCoverageAttributeIndex = availableAttributeIndex; | 394 header->fCoverageAttributeIndex = availableAttributeIndex; |
335 } else { | 395 } else { |
336 header->fCoverageAttributeIndex = -1; | 396 header->fCoverageAttributeIndex = -1; |
337 } | 397 } |
338 | 398 |
339 header->fPrimaryOutputType = optState.getPrimaryOutputType(); | 399 header->fPrimaryOutputType = optState.getPrimaryOutputType(); |
340 header->fSecondaryOutputType = optState.getSecondaryOutputType(); | 400 header->fSecondaryOutputType = optState.getSecondaryOutputType(); |
341 | 401 |
342 header->fColorEffectCnt = optState.numColorStages(); | 402 for (int s = 0; s < optState.numColorStages(); ++s) { |
343 header->fCoverageEffectCnt = optState.numCoverageStages(); | 403 colorStages->push_back(&optState.getColorStage(s)); |
| 404 } |
| 405 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
| 406 coverageStages->push_back(&optState.getCoverageStage(s)); |
| 407 } |
| 408 |
| 409 header->fColorEffectCnt = colorStages->count(); |
| 410 header->fCoverageEffectCnt = coverageStages->count(); |
344 desc->finalize(); | 411 desc->finalize(); |
345 return true; | 412 return true; |
346 } | 413 } |
347 | 414 |
348 void GrGLProgramDesc::finalize() { | 415 void GrGLProgramDesc::finalize() { |
349 int keyLength = fKey.count(); | 416 int keyLength = fKey.count(); |
350 SkASSERT(0 == (keyLength % 4)); | 417 SkASSERT(0 == (keyLength % 4)); |
351 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); | 418 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); |
352 | 419 |
353 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); | 420 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); |
354 *checksum = 0; | 421 *checksum = 0; |
355 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); | 422 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); |
356 } | 423 } |
357 | 424 |
358 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 425 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
359 size_t keyLength = other.keyLength(); | 426 size_t keyLength = other.keyLength(); |
360 fKey.reset(keyLength); | 427 fKey.reset(keyLength); |
361 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 428 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
362 return *this; | 429 return *this; |
363 } | 430 } |
OLD | NEW |