1 /* 2 * Copyright 2013 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 #include "gl/builders/GrGLProgramBuilder.h" 9 #include "GrGLProgramDesc.h" 10 #include "GrBackendProcessorFactory.h" 11 #include "GrProcessor.h" 12 #include "GrGpuGL.h" 13 #include "GrOptDrawState.h" 14 15 #include "SkChecksum.h" 16 17 /** 18 * The key for an individual coord transform is made up of a matrix type and a bit 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 which 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 modifications. 46 return false; 47 } 48 // check if the texture is alpha-only 49 if (kA_GrColorComponentFlag == configComponentMask) { 50 if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) { 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 read. 57 return true; 58 } 59 } 60 return false; 61 } 62 63 static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) { 64 uint32_t key = 0; 65 66 const GrGeometryProcessor::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 GrProcessorStage& effectStage, 77 bool useExplicitLocalCoords) { 78 uint32_t totalKey = 0; 79 int numTransforms = effectStage.getProcessor()->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.getProcessor()->coordTransform(t); 89 if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLocalCoords) { 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 GrProcessor* 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.getTexture()->config()); 105 if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) { 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 because 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 effect's class ID 117 * which must be different for every GrProcessor subclass. It can fail if an effect uses too many 118 * textures, transforms, etc, for the space allotted in the meta-key. 119 */ 120 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,useExplicitLocalCoords); 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 bool GrGLProgramDesc::GetProcessorKey(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); 151 size_t size = b->size(); 152 if (size > SK_MaxU16) { 153 *processorKeySize = 0; // suppresses a warning. 154 return false; 155 } 156 *processorKeySize = SkToU16(size); 157 if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) { 158 return false; 159 } 160 return true; 161 } 162 163 bool GrGLProgramDesc::GetGeometryProcessorKey(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.getGeometryProcessor()); 182 183 // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they 184 // don't fit. 185 static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16); 186 if ((attribKey) & kMetaKeyInvalidMask) { 187 return false; 188 } 189 190 key[1] |= attribKey; 191 return true; 192 } 193 194 195 bool GrGLProgramDesc::Build(const GrOptDrawState& optState, 196 GrGpu::DrawType drawType, 197 GrBlendCoeff srcCoeff, 198 GrBlendCoeff dstCoeff, 199 GrGpuGL* gpu, 200 const GrDeviceCoordTexture* dstCopy, 201 const GrGeometryStage** geometryProcessor, 202 SkTArray<const GrFragmentStage*, true>* colorStages, 203 SkTArray<const GrFragmentStage*, true>* coverageStages, 204 GrGLProgramDesc* desc) { 205 colorStages->reset(); 206 coverageStages->reset(); 207 208 bool inputColorIsUsed = optState.inputColorIsUsed(); 209 bool inputCoverageIsUsed = optState.inputCoverageIsUsed(); 210 211 // 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 213 // bindings in use or other descriptor field settings) it should be set 214 // to a canonical value to avoid duplicate programs with different keys. 215 216 bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib(); 217 218 int numStages = optState.numTotalStages(); 219 220 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); 221 // Make room for everything up to and including the array of offsets to effect keys. 222 desc->fKey.reset(); 223 desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages); 224 225 int offsetAndSizeIndex = 0; 226 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 232 if (optState.hasGeometryProcessor()) { 233 uint16_t* offsetAndSize = 234 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + 235 offsetAndSizeIndex * 2 * sizeof(uint16_t)); 236 237 GrProcessorKeyBuilder b(&desc->fKey); 238 uint16_t processorKeySize; 239 uint32_t processorOffset = desc->fKey.count(); 240 const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); 241 if (processorOffset > SK_MaxU16 || 242 !GetGeometryProcessorKey(gpStage, gpu->glCaps(), requiresLocalCoordAttrib, &b, 243 &processorKeySize)) { 244 desc->fKey.reset(); 245 return false; 246 } 247 248 offsetAndSize[0] = SkToU16(processorOffset); 249 offsetAndSize[1] = processorKeySize; 250 ++offsetAndSizeIndex; 251 *geometryProcessor = &gpStage; 252 header->fHasGeometryProcessor = true; 253 } 254 255 for (int s = 0; s < optState.numColorStages(); ++s) { 256 uint16_t* offsetAndSize = 257 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + 258 offsetAndSizeIndex * 2 * sizeof(uint16_t)); 259 260 GrProcessorKeyBuilder b(&desc->fKey); 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; 268 } 269 270 offsetAndSize[0] = SkToU16(processorOffset); 271 offsetAndSize[1] = processorKeySize; 272 ++offsetAndSizeIndex; 273 } 274 275 for (int s = 0; s < optState.numCoverageStages(); ++s) { 276 uint16_t* offsetAndSize = 277 reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + 278 offsetAndSizeIndex * 2 * sizeof(uint16_t)); 279 280 GrProcessorKeyBuilder b(&desc->fKey); 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; 288 } 289 290 offsetAndSize[0] = SkToU16(processorOffset); 291 offsetAndSize[1] = processorKeySize; 292 ++offsetAndSizeIndex; 293 } 294 295 // Because header is a pointer into the dynamic array, we can't push any new data into the key 296 // below here. 297 298 299 header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; 300 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() && 312 GrGpu::IsPathRenderingDrawType(drawType) && 313 gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) { 314 header->fUseFragShaderOnly = true; 315 SkASSERT(!optState.hasGeometryProcessor()); 316 } else { 317 header->fUseFragShaderOnly = false; 318 } 319 320 bool defaultToUniformInputs = GrGpu::IsPathRenderingDrawType(drawType) || 321 GR_GL_NO_CONSTANT_ATTRIBUTES; 322 323 if (!inputColorIsUsed) { 324 header->fColorInput = kAllOnes_ColorInput; 325 } else if (defaultToUniformInputs && !optState.hasColorVertexAttribute()) { 326 header->fColorInput = kUniform_ColorInput; 327 } else { 328 header->fColorInput = kAttribute_ColorInput; 329 SkASSERT(!header->fUseFragShaderOnly); 330 } 331 332 bool covIsSolidWhite = !optState.hasCoverageVertexAttribute() && 333 0xffffffff == optState.getCoverageColor(); 334 335 if (covIsSolidWhite || !inputCoverageIsUsed) { 336 header->fCoverageInput = kAllOnes_ColorInput; 337 } else if (defaultToUniformInputs && !optState.hasCoverageVertexAttribute()) { 338 header->fCoverageInput = kUniform_ColorInput; 339 } else { 340 header->fCoverageInput = kAttribute_ColorInput; 341 SkASSERT(!header->fUseFragShaderOnly); 342 } 343 344 if (optState.readsDst()) { 345 SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); 346 const GrTexture* dstCopyTexture = NULL; 347 if (dstCopy) { 348 dstCopyTexture = dstCopy->texture(); 349 } 350 header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture, 351 gpu->glCaps()); 352 SkASSERT(0 != header->fDstReadKey); 353 } else { 354 header->fDstReadKey = 0; 355 } 356 357 if (optState.readsFragPosition()) { 358 header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition( 359 optState.getRenderTarget(), gpu->glCaps()); 360 } else { 361 header->fFragPosKey = 0; 362 } 363 364 // Record attribute indices 365 header->fPositionAttributeIndex = optState.positionAttributeIndex(); 366 header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex(); 367 368 // For constant color and coverage we need an attribute with an index beyond those already set 369 int availableAttributeIndex = optState.getVertexAttribCount(); 370 if (optState.hasColorVertexAttribute()) { 371 header->fColorAttributeIndex = optState.colorVertexAttributeIndex(); 372 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) { 373 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); 374 header->fColorAttributeIndex = availableAttributeIndex; 375 availableAttributeIndex++; 376 } else { 377 header->fColorAttributeIndex = -1; 378 } 379 380 if (optState.hasCoverageVertexAttribute()) { 381 header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex(); 382 } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { 383 SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); 384 header->fCoverageAttributeIndex = availableAttributeIndex; 385 } else { 386 header->fCoverageAttributeIndex = -1; 387 } 388 389 header->fPrimaryOutputType = optState.getPrimaryOutputType(); 390 header->fSecondaryOutputType = optState.getSecondaryOutputType(); 391 392 for (int s = 0; s < optState.numColorStages(); ++s) { 393 colorStages->push_back(&optState.getColorStage(s)); 394 } 395 for (int s = 0; s < optState.numCoverageStages(); ++s) { 396 coverageStages->push_back(&optState.getCoverageStage(s)); 397 } 398 399 header->fColorEffectCnt = colorStages->count(); 400 header->fCoverageEffectCnt = coverageStages->count(); 401 402 desc->finalize(); 403 return true; 404 } 405 406 void GrGLProgramDesc::finalize() { 407 int keyLength = fKey.count(); 408 SkASSERT(0 == (keyLength % 4)); 409 *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength); 410 411 uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>(); 412 *checksum = 0; 413 *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength); 414 } 415 416 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { 417 size_t keyLength = other.keyLength(); 418 fKey.reset(keyLength); 419 memcpy(fKey.begin(), other.fKey.begin(), keyLength); 420 return *this; 421 } 422