| 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) { | 133 if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) { |
| 134 return NULL; | 134 return NULL; |
| 135 } | 135 } |
| 136 | 136 |
| 137 uint32_t* key = b->add32n(2); | 137 uint32_t* key = b->add32n(2); |
| 138 key[0] = (textureKey << 16 | transformKey); | 138 key[0] = (textureKey << 16 | transformKey); |
| 139 key[1] = (classID << 16); | 139 key[1] = (classID << 16); |
| 140 return key; | 140 return key; |
| 141 } | 141 } |
| 142 | 142 |
| 143 bool GrGLProgramDesc::GetProcessorKey(const GrProcessorStage& stage, | 143 static bool get_fp_key(const GrProcessorStage& stage, |
| 144 const GrGLCaps& caps, | 144 const GrGLCaps& caps, |
| 145 bool useExplicitLocalCoords, | 145 bool useExplicitLocalCoords, |
| 146 GrProcessorKeyBuilder* b, | 146 GrProcessorKeyBuilder* b, |
| 147 uint16_t* processorKeySize) { | 147 uint16_t* processorKeySize) { |
| 148 const GrProcessor& effect = *stage.getProcessor(); | 148 const GrProcessor& effect = *stage.getProcessor(); |
| 149 const GrBackendProcessorFactory& factory = effect.getFactory(); | 149 const GrBackendProcessorFactory& factory = effect.getFactory(); |
| 150 factory.getGLProcessorKey(effect, caps, b); | 150 factory.getGLProcessorKey(effect, caps, b); |
| 151 size_t size = b->size(); | 151 size_t size = b->size(); |
| 152 if (size > SK_MaxU16) { | 152 if (size > SK_MaxU16) { |
| 153 *processorKeySize = 0; // suppresses a warning. | 153 *processorKeySize = 0; // suppresses a warning. |
| 154 return false; | 154 return false; |
| 155 } | 155 } |
| 156 *processorKeySize = SkToU16(size); | 156 *processorKeySize = SkToU16(size); |
| 157 if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b))
{ | 157 if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b))
{ |
| 158 return false; | 158 return false; |
| 159 } | 159 } |
| 160 return true; | 160 return true; |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool GrGLProgramDesc::GetGeometryProcessorKey(const GrGeometryStage& stage, | 163 static bool get_gp_key(const GrGeometryStage& stage, |
| 164 const GrGLCaps& caps, | 164 const GrGLCaps& caps, |
| 165 bool useExplicitLocalCoords, | 165 bool useExplicitLocalCoords, |
| 166 GrProcessorKeyBuilder* b, | 166 GrProcessorKeyBuilder* b, |
| 167 uint16_t* processorKeySize) { | 167 uint16_t* processorKeySize) { |
| 168 const GrProcessor& effect = *stage.getProcessor(); | 168 const GrProcessor& effect = *stage.getProcessor(); |
| 169 const GrBackendProcessorFactory& factory = effect.getFactory(); | 169 const GrBackendProcessorFactory& factory = effect.getFactory(); |
| 170 factory.getGLProcessorKey(effect, caps, b); | 170 factory.getGLProcessorKey(effect, caps, b); |
| 171 size_t size = b->size(); | 171 size_t size = b->size(); |
| 172 if (size > SK_MaxU16) { | 172 if (size > SK_MaxU16) { |
| 173 *processorKeySize = 0; // suppresses a warning. | 173 *processorKeySize = 0; // suppresses a warning. |
| 174 return false; | 174 return false; |
| 175 } | 175 } |
| 176 *processorKeySize = SkToU16(size); | 176 *processorKeySize = SkToU16(size); |
| 177 uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps,
b); | 177 uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps,
b); |
| 178 if (NULL == key) { | 178 if (NULL == key) { |
| 179 return false; | 179 return false; |
| 180 } | 180 } |
| 181 uint32_t attribKey = gen_attrib_key(stage.getProcessor()); | 181 uint32_t attribKey = gen_attrib_key(stage.getProcessor()); |
| 182 | 182 |
| 183 // 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 |
| 184 // don't fit. | 184 // don't fit. |
| 185 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); | 185 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); |
| 186 if ((attribKey) & kMetaKeyInvalidMask) { | 186 if ((attribKey) & kMetaKeyInvalidMask) { |
| 187 return false; | 187 return false; |
| 188 } | 188 } |
| 189 | 189 |
| 190 key[1] |= attribKey; | 190 key[1] |= attribKey; |
| 191 return true; | 191 return true; |
| 192 } | 192 } |
| 193 | 193 |
| 194 struct GeometryProcessorKeyBuilder { |
| 195 typedef GrGeometryStage StagedProcessor; |
| 196 static bool GetProcessorKey(const GrGeometryStage& gpStage, |
| 197 const GrGLCaps& caps, |
| 198 bool requiresLocalCoordAttrib, |
| 199 GrProcessorKeyBuilder* b, |
| 200 uint16_t* processorKeySize) { |
| 201 return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorK
eySize); |
| 202 } |
| 203 }; |
| 204 |
| 205 struct FragmentProcessorKeyBuilder { |
| 206 typedef GrFragmentStage StagedProcessor; |
| 207 static bool GetProcessorKey(const GrFragmentStage& fpStage, |
| 208 const GrGLCaps& caps, |
| 209 bool requiresLocalCoordAttrib, |
| 210 GrProcessorKeyBuilder* b, |
| 211 uint16_t* processorKeySize) { |
| 212 return get_fp_key(fpStage, caps, requiresLocalCoordAttrib, b, processorK
eySize); |
| 213 } |
| 214 }; |
| 215 |
| 216 |
| 217 template <class ProcessorKeyBuilder> |
| 218 bool |
| 219 GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
gedProcessor& stage, |
| 220 const GrGLCaps& caps, |
| 221 bool requiresLocalCoordAttrib, |
| 222 GrGLProgramDesc* desc, |
| 223 int* offsetAndSizeIndex) { |
| 224 GrProcessorKeyBuilder b(&desc->fKey); |
| 225 uint16_t processorKeySize; |
| 226 uint32_t processorOffset = desc->fKey.count(); |
| 227 if (processorOffset > SK_MaxU16 || |
| 228 !ProcessorKeyBuilder::GetProcessorKey(stage, caps, requiresLocalCoor
dAttrib, &b, |
| 229 &processorKeySize)){ |
| 230 desc->fKey.reset(); |
| 231 return false; |
| 232 } |
| 233 |
| 234 uint16_t* offsetAndSize = |
| 235 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + |
| 236 *offsetAndSizeIndex * 2 * sizeof(uint16_
t)); |
| 237 offsetAndSize[0] = SkToU16(processorOffset); |
| 238 offsetAndSize[1] = processorKeySize; |
| 239 ++(*offsetAndSizeIndex); |
| 240 return true; |
| 241 } |
| 194 | 242 |
| 195 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, | 243 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, |
| 196 GrGpu::DrawType drawType, | 244 GrGpu::DrawType drawType, |
| 197 GrBlendCoeff srcCoeff, | 245 GrBlendCoeff srcCoeff, |
| 198 GrBlendCoeff dstCoeff, | 246 GrBlendCoeff dstCoeff, |
| 199 GrGpuGL* gpu, | 247 GrGpuGL* gpu, |
| 200 const GrDeviceCoordTexture* dstCopy, | 248 const GrDeviceCoordTexture* dstCopy, |
| 201 const GrGeometryStage** geometryProcessor, | 249 const GrGeometryStage** geometryProcessor, |
| 202 SkTArray<const GrFragmentStage*, true>* colorStages, | 250 SkTArray<const GrFragmentStage*, true>* colorStages, |
| 203 SkTArray<const GrFragmentStage*, true>* coverageStag
es, | 251 SkTArray<const GrFragmentStage*, true>* coverageStag
es, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 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 KeyHeader* header = desc->header(); | |
| 228 // make sure any padding in the header is zeroed. | |
| 229 memset(desc->header(), 0, kHeaderSize); | |
| 230 | |
| 231 // We can only have one effect which touches the vertex shader | 275 // We can only have one effect which touches the vertex shader |
| 232 if (optState.hasGeometryProcessor()) { | 276 if (optState.hasGeometryProcessor()) { |
| 233 uint16_t* offsetAndSize = | |
| 234 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffse
tsAndLengthOffset + | |
| 235 offsetAndSizeIndex * 2 * sizeof(uint
16_t)); | |
| 236 | |
| 237 GrProcessorKeyBuilder b(&desc->fKey); | |
| 238 uint16_t processorKeySize; | |
| 239 uint32_t processorOffset = desc->fKey.count(); | |
| 240 const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); | 277 const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); |
| 241 if (processorOffset > SK_MaxU16 || | 278 if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage, |
| 242 !GetGeometryProcessorKey(gpStage, gpu->glCaps(), requiresLocalCo
ordAttrib, &b, | 279 gpu->glCaps(), |
| 243 &processorKeySize)) { | 280 requiresLocalC
oordAttrib, |
| 244 desc->fKey.reset(); | 281 desc, |
| 282 &offsetAndSize
Index)) { |
| 245 return false; | 283 return false; |
| 246 } | 284 } |
| 247 | |
| 248 offsetAndSize[0] = SkToU16(processorOffset); | |
| 249 offsetAndSize[1] = processorKeySize; | |
| 250 ++offsetAndSizeIndex; | |
| 251 *geometryProcessor = &gpStage; | 285 *geometryProcessor = &gpStage; |
| 252 header->fHasGeometryProcessor = true; | |
| 253 } | 286 } |
| 254 | 287 |
| 255 for (int s = 0; s < optState.numColorStages(); ++s) { | 288 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 256 uint16_t* offsetAndSize = | 289 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo
lorStage(s), |
| 257 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + | 290 gpu->glCaps(), |
| 258 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); | 291 requiresLocalC
oordAttrib, |
| 259 | 292 desc, |
| 260 GrProcessorKeyBuilder b(&desc->fKey); | 293 &offsetAndSize
Index)) { |
| 261 uint16_t processorKeySize; | |
| 262 uint32_t processorOffset = desc->fKey.count(); | |
| 263 if (processorOffset > SK_MaxU16 || | |
| 264 !GetProcessorKey(optState.getColorStage(s), gpu->glCaps(), | |
| 265 requiresLocalCoordAttrib, &b, &processorKeySize
)) { | |
| 266 desc->fKey.reset(); | |
| 267 return false; | 294 return false; |
| 268 } | 295 } |
| 269 | |
| 270 offsetAndSize[0] = SkToU16(processorOffset); | |
| 271 offsetAndSize[1] = processorKeySize; | |
| 272 ++offsetAndSizeIndex; | |
| 273 } | 296 } |
| 274 | 297 |
| 275 for (int s = 0; s < optState.numCoverageStages(); ++s) { | 298 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
| 276 uint16_t* offsetAndSize = | 299 if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCo
verageStage(s), |
| 277 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAn
dLengthOffset + | 300 gpu->glCaps(), |
| 278 offsetAndSizeIndex * 2 * sizeof(uint16_t
)); | 301 requiresLocalC
oordAttrib, |
| 279 | 302 desc, |
| 280 GrProcessorKeyBuilder b(&desc->fKey); | 303 &offsetAndSize
Index)) { |
| 281 uint16_t processorKeySize; | |
| 282 uint32_t processorOffset = desc->fKey.count(); | |
| 283 if (processorOffset > SK_MaxU16 || | |
| 284 !GetProcessorKey(optState.getCoverageStage(s), gpu->glCaps(), | |
| 285 requiresLocalCoordAttrib, &b, &processorKeySize
)) { | |
| 286 desc->fKey.reset(); | |
| 287 return false; | 304 return false; |
| 288 } | 305 } |
| 289 | |
| 290 offsetAndSize[0] = SkToU16(processorOffset); | |
| 291 offsetAndSize[1] = processorKeySize; | |
| 292 ++offsetAndSizeIndex; | |
| 293 } | 306 } |
| 294 | 307 |
| 308 // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------
------------------- |
| 295 // 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 |
| 296 // below here. | 310 // below here. |
| 311 KeyHeader* header = desc->header(); |
| 297 | 312 |
| 313 // make sure any padding in the header is zeroed. |
| 314 memset(header, 0, kHeaderSize); |
| 315 |
| 316 header->fHasGeometryProcessor = optState.hasGeometryProcessor(); |
| 298 | 317 |
| 299 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; | 318 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; |
| 300 | 319 |
| 301 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | |
| 302 // other than pass through values from the VS to the FS anyway). | |
| 303 #if GR_GL_EXPERIMENTAL_GS | |
| 304 #if 0 | |
| 305 header->fExperimentalGS = gpu->caps().geometryShaderSupport(); | |
| 306 #else | |
| 307 header->fExperimentalGS = false; | |
| 308 #endif | |
| 309 #endif | |
| 310 | |
| 311 if (gpu->caps()->pathRenderingSupport() && | 320 if (gpu->caps()->pathRenderingSupport() && |
| 312 GrGpu::IsPathRenderingDrawType(drawType) && | 321 GrGpu::IsPathRenderingDrawType(drawType) && |
| 313 gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunct
ion_TexturingMode) { | 322 gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunct
ion_TexturingMode) { |
| 314 header->fUseFragShaderOnly = true; | 323 header->fUseFragShaderOnly = true; |
| 315 SkASSERT(!optState.hasGeometryProcessor()); | 324 SkASSERT(!optState.hasGeometryProcessor()); |
| 316 } else { | 325 } else { |
| 317 header->fUseFragShaderOnly = false; | 326 header->fUseFragShaderOnly = false; |
| 318 } | 327 } |
| 319 | 328 |
| 320 bool defaultToUniformInputs = GrGpu::IsPathRenderingDrawType(drawType) || | 329 bool defaultToUniformInputs = GrGpu::IsPathRenderingDrawType(drawType) || |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 401 |
| 393 for (int s = 0; s < optState.numColorStages(); ++s) { | 402 for (int s = 0; s < optState.numColorStages(); ++s) { |
| 394 colorStages->push_back(&optState.getColorStage(s)); | 403 colorStages->push_back(&optState.getColorStage(s)); |
| 395 } | 404 } |
| 396 for (int s = 0; s < optState.numCoverageStages(); ++s) { | 405 for (int s = 0; s < optState.numCoverageStages(); ++s) { |
| 397 coverageStages->push_back(&optState.getCoverageStage(s)); | 406 coverageStages->push_back(&optState.getCoverageStage(s)); |
| 398 } | 407 } |
| 399 | 408 |
| 400 header->fColorEffectCnt = colorStages->count(); | 409 header->fColorEffectCnt = colorStages->count(); |
| 401 header->fCoverageEffectCnt = coverageStages->count(); | 410 header->fCoverageEffectCnt = coverageStages->count(); |
| 402 | |
| 403 desc->finalize(); | 411 desc->finalize(); |
| 404 return true; | 412 return true; |
| 405 } | 413 } |
| 406 | 414 |
| 407 void GrGLProgramDesc::finalize() { | 415 void GrGLProgramDesc::finalize() { |
| 408 int keyLength = fKey.count(); | 416 int keyLength = fKey.count(); |
| 409 SkASSERT(0 == (keyLength % 4)); | 417 SkASSERT(0 == (keyLength % 4)); |
| 410 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); | 418 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); |
| 411 | 419 |
| 412 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); | 420 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); |
| 413 *checksum = 0; | 421 *checksum = 0; |
| 414 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); | 422 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), k
eyLength); |
| 415 } | 423 } |
| 416 | 424 |
| 417 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 425 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
| 418 size_t keyLength = other.keyLength(); | 426 size_t keyLength = other.keyLength(); |
| 419 fKey.reset(keyLength); | 427 fKey.reset(keyLength); |
| 420 memcpy(fKey.begin(), other.fKey.begin(), keyLength); | 428 memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
| 421 return *this; | 429 return *this; |
| 422 } | 430 } |
| OLD | NEW |