Home | History | Annotate | Download | only in gl
      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