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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttrib s(); | 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 GrProcessorStage& effectStage, | 76 static uint32_t gen_transform_key(const GrFragmentStage& 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 } |
(...skipping 16 matching lines...) Expand all Loading... | |
103 const GrTextureAccess& access = effect->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 |
bsalomon
2014/10/09 18:35:45
This comment needs some rework with this change. M
| |
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. | 118 * textures, transforms, etc, for the space allotted in the meta-key. |
119 */ | 119 */ |
120 | 120 static bool get_fp_key(const GrFragmentStage& stage, |
121 static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage, | |
122 bool useExplicitLocalCoords, | |
123 const GrGLCaps& caps, | |
124 GrProcessorKeyBuilder* b) { | |
125 | |
126 uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps); | |
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, | 121 const GrGLCaps& caps, |
145 bool useExplicitLocalCoords, | 122 bool useExplicitLocalCoords, |
146 GrProcessorKeyBuilder* b, | 123 GrProcessorKeyBuilder* b, |
147 uint16_t* processorKeySize) { | 124 uint16_t* processorKeySize) { |
148 const GrProcessor& effect = *stage.getProcessor(); | 125 const GrProcessor& effect = *stage.getProcessor(); |
149 const GrBackendProcessorFactory& factory = effect.getFactory(); | 126 const GrBackendProcessorFactory& factory = effect.getFactory(); |
150 factory.getGLProcessorKey(effect, caps, b); | 127 factory.getGLProcessorKey(effect, caps, b); |
151 size_t size = b->size(); | 128 size_t size = b->size(); |
152 if (size > SK_MaxU16) { | 129 if (size > SK_MaxU16) { |
153 *processorKeySize = 0; // suppresses a warning. | 130 *processorKeySize = 0; // suppresses a warning. |
154 return false; | 131 return false; |
155 } | 132 } |
156 *processorKeySize = SkToU16(size); | 133 *processorKeySize = SkToU16(size); |
157 if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) { | 134 uint32_t textureKey = gen_texture_key(stage.getProcessor(), caps); |
135 uint32_t transformKey = gen_transform_key(stage, useExplicitLocalCoords); | |
136 uint32_t classID = stage.getProcessor()->getFactory().effectClassID(); | |
137 | |
138 // Currently we allow 16 bits for each of the above portions of the meta-key . Fail if they | |
139 // don't fit. | |
140 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); | |
141 if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) { | |
158 return false; | 142 return false; |
159 } | 143 } |
144 | |
145 uint32_t* key = b->add32n(2); | |
146 key[0] = (textureKey << 16 | transformKey); | |
147 key[1] = (classID << 16); | |
160 return true; | 148 return true; |
161 } | 149 } |
162 | 150 |
163 static bool get_gp_key(const GrGeometryStage& stage, | 151 static bool get_gp_key(const GrGeometryProcessor& gp, |
164 const GrGLCaps& caps, | 152 const GrGLCaps& caps, |
165 bool useExplicitLocalCoords, | 153 bool useExplicitLocalCoords, |
166 GrProcessorKeyBuilder* b, | 154 GrProcessorKeyBuilder* b, |
167 uint16_t* processorKeySize) { | 155 uint16_t* processorKeySize) { |
168 const GrProcessor& effect = *stage.getProcessor(); | 156 const GrBackendProcessorFactory& factory = gp.getFactory(); |
169 const GrBackendProcessorFactory& factory = effect.getFactory(); | 157 factory.getGLProcessorKey(gp, caps, b); |
170 factory.getGLProcessorKey(effect, caps, b); | |
171 size_t size = b->size(); | 158 size_t size = b->size(); |
172 if (size > SK_MaxU16) { | 159 if (size > SK_MaxU16) { |
173 *processorKeySize = 0; // suppresses a warning. | 160 *processorKeySize = 0; // suppresses a warning. |
174 return false; | 161 return false; |
175 } | 162 } |
176 *processorKeySize = SkToU16(size); | 163 *processorKeySize = SkToU16(size); |
177 uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b); | 164 uint32_t textureKey = gen_texture_key(&gp, caps); |
178 if (NULL == key) { | 165 uint32_t attribKey = gen_attrib_key(&gp); |
179 return false; | 166 uint32_t classID = gp.getFactory().effectClassID(); |
180 } | |
181 uint32_t attribKey = gen_attrib_key(stage.getProcessor()); | |
182 | 167 |
183 // Currently we allow 16 bits for each of the above portions of the meta-key . Fail if they | 168 // Currently we allow 16 bits for each of the above portions of the meta-key . Fail if they |
184 // don't fit. | 169 // don't fit. |
185 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); | 170 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
186 if ((attribKey) & kMetaKeyInvalidMask) { | 171 if ((textureKey | attribKey | classID) & kMetaKeyInvalidMask) { |
187 return false; | 172 return false; |
188 } | 173 } |
189 | 174 |
190 key[1] |= attribKey; | 175 uint32_t* key = b->add32n(2); |
176 key[0] = (textureKey << 16); | |
177 key[1] = (classID << 16 | attribKey); | |
191 return true; | 178 return true; |
192 } | 179 } |
193 | 180 |
194 struct GeometryProcessorKeyBuilder { | 181 struct GeometryProcessorKeyBuilder { |
195 typedef GrGeometryStage StagedProcessor; | 182 typedef GrGeometryProcessor StagedProcessor; |
196 static bool GetProcessorKey(const GrGeometryStage& gpStage, | 183 static bool GetProcessorKey(const GrGeometryProcessor& gpStage, |
197 const GrGLCaps& caps, | 184 const GrGLCaps& caps, |
198 bool requiresLocalCoordAttrib, | 185 bool requiresLocalCoordAttrib, |
199 GrProcessorKeyBuilder* b, | 186 GrProcessorKeyBuilder* b, |
200 uint16_t* processorKeySize) { | 187 uint16_t* processorKeySize) { |
201 return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorK eySize); | 188 return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorK eySize); |
202 } | 189 } |
203 }; | 190 }; |
204 | 191 |
205 struct FragmentProcessorKeyBuilder { | 192 struct FragmentProcessorKeyBuilder { |
206 typedef GrFragmentStage StagedProcessor; | 193 typedef GrFragmentStage StagedProcessor; |
(...skipping 28 matching lines...) Expand all Loading... | |
235 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + | 222 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn dLengthOffset + |
236 *offsetAndSizeIndex * 2 * sizeof(uint16_ t)); | 223 *offsetAndSizeIndex * 2 * sizeof(uint16_ t)); |
237 offsetAndSize[0] = SkToU16(processorOffset); | 224 offsetAndSize[0] = SkToU16(processorOffset); |
238 offsetAndSize[1] = processorKeySize; | 225 offsetAndSize[1] = processorKeySize; |
239 ++(*offsetAndSizeIndex); | 226 ++(*offsetAndSizeIndex); |
240 return true; | 227 return true; |
241 } | 228 } |
242 | 229 |
243 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, | 230 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
244 GrGpu::DrawType drawType, | 231 GrGpu::DrawType drawType, |
245 GrBlendCoeff srcCoeff, | |
246 GrBlendCoeff dstCoeff, | |
247 GrGpuGL* gpu, | 232 GrGpuGL* gpu, |
248 const GrDeviceCoordTexture* dstCopy, | 233 const GrDeviceCoordTexture* dstCopy, |
249 const GrGeometryStage** geometryProcessor, | |
250 SkTArray<const GrFragmentStage*, true>* colorStages, | |
251 SkTArray<const GrFragmentStage*, true>* coverageStag es, | |
252 GrGLProgramDesc* desc) { | 234 GrGLProgramDesc* desc) { |
253 colorStages->reset(); | |
254 coverageStages->reset(); | |
255 | |
256 bool inputColorIsUsed = optState.inputColorIsUsed(); | 235 bool inputColorIsUsed = optState.inputColorIsUsed(); |
257 bool inputCoverageIsUsed = optState.inputCoverageIsUsed(); | 236 bool inputCoverageIsUsed = optState.inputCoverageIsUsed(); |
258 | 237 |
259 // The descriptor is used as a cache key. Thus when a field of the | 238 // The descriptor is used as a cache key. Thus when a field of the |
260 // descriptor will not affect program generation (because of the attribute | 239 // descriptor will not affect program generation (because of the attribute |
261 // bindings in use or other descriptor field settings) it should be set | 240 // bindings in use or other descriptor field settings) it should be set |
262 // to a canonical value to avoid duplicate programs with different keys. | 241 // to a canonical value to avoid duplicate programs with different keys. |
263 | 242 |
264 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); | 243 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); |
265 | 244 |
266 int numStages = optState.numTotalStages(); | 245 int numStages = optState.numTotalStages(); |
267 | 246 |
268 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); | 247 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); |
269 // Make room for everything up to and including the array of offsets to effe ct keys. | 248 // Make room for everything up to and including the array of offsets to effe ct keys. |
270 desc->fKey.reset(); | 249 desc->fKey.reset(); |
271 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); | 250 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_ t) * numStages); |
272 | 251 |
273 int offsetAndSizeIndex = 0; | 252 int offsetAndSizeIndex = 0; |
274 | 253 |
275 // We can only have one effect which touches the vertex shader | 254 // We can only have one effect which touches the vertex shader |
276 if (optState.hasGeometryProcessor()) { | 255 if (optState.hasGeometryProcessor()) { |
277 const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); | 256 if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getG eometryProcessor(), |
278 if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage, | |
279 gpu->glCaps(), | 257 gpu->glCaps(), |
280 requiresLocalC oordAttrib, | 258 requiresLocalC oordAttrib, |
281 desc, | 259 desc, |
282 &offsetAndSize Index)) { | 260 &offsetAndSize Index)) { |
283 return false; | 261 return false; |
284 } | 262 } |
285 *geometryProcessor = &gpStage; | |
286 } | 263 } |
287 | 264 |
288 for (int s = 0; s < optState.numColorStages(); ++s) { | 265 for (int s = 0; s < optState.numColorStages(); ++s) { |
289 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo lorStage(s), | 266 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo lorStage(s), |
290 gpu->glCaps(), | 267 gpu->glCaps(), |
291 requiresLocalC oordAttrib, | 268 requiresLocalC oordAttrib, |
292 desc, | 269 desc, |
293 &offsetAndSize Index)) { | 270 &offsetAndSize Index)) { |
294 return false; | 271 return false; |
295 } | 272 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { | 369 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { |
393 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); | 370 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); |
394 header->fCoverageAttributeIndex = availableAttributeIndex; | 371 header->fCoverageAttributeIndex = availableAttributeIndex; |
395 } else { | 372 } else { |
396 header->fCoverageAttributeIndex = -1; | 373 header->fCoverageAttributeIndex = -1; |
397 } | 374 } |
398 | 375 |
399 header->fPrimaryOutputType = optState.getPrimaryOutputType(); | 376 header->fPrimaryOutputType = optState.getPrimaryOutputType(); |
400 header->fSecondaryOutputType = optState.getSecondaryOutputType(); | 377 header->fSecondaryOutputType = optState.getSecondaryOutputType(); |
401 | 378 |
402 for (int s = 0; s < optState.numColorStages(); ++s) { | 379 header->fColorEffectCnt = optState.numColorStages(); |
403 colorStages->push_back(&optState.getColorStage(s)); | 380 header->fCoverageEffectCnt = optState.numCoverageStages(); |
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(); | |
411 desc->finalize(); | 381 desc->finalize(); |
412 return true; | 382 return true; |
413 } | 383 } |
414 | 384 |
415 void GrGLProgramDesc::finalize() { | 385 void GrGLProgramDesc::finalize() { |
416 int keyLength = fKey.count(); | 386 int keyLength = fKey.count(); |
417 SkASSERT(0 == (keyLength % 4)); | 387 SkASSERT(0 == (keyLength % 4)); |
418 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); | 388 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); |
419 | 389 |
420 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); | 390 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); |
421 *checksum = 0; | 391 *checksum = 0; |
422 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); | 392 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k eyLength); |
423 } | 393 } |
424 | 394 |
425 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 395 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
426 size_t keyLength = other.keyLength(); | 396 size_t keyLength = other.keyLength(); |
427 fKey.reset(keyLength); | 397 fKey.reset(keyLength); |
428 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 398 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
429 return *this; | 399 return *this; |
430 } | 400 } |
OLD | NEW |