LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrProgramDesc.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 114 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 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             : #include "GrProgramDesc.h"
       8             : #include "GrPipeline.h"
       9             : #include "GrPrimitiveProcessor.h"
      10             : #include "GrProcessor.h"
      11             : #include "GrRenderTargetPriv.h"
      12             : #include "GrShaderCaps.h"
      13             : #include "GrTexturePriv.h"
      14             : #include "SkChecksum.h"
      15             : #include "glsl/GrGLSLFragmentProcessor.h"
      16             : #include "glsl/GrGLSLFragmentShaderBuilder.h"
      17             : 
      18             : enum {
      19             :     kSamplerOrImageTypeKeyBits = 4
      20             : };
      21             : 
      22           0 : static inline uint16_t image_storage_or_sampler_uniform_type_key(GrSLType type ) {
      23           0 :     int value = UINT16_MAX;
      24           0 :     switch (type) {
      25             :         case kTexture2DSampler_GrSLType:
      26           0 :             value = 0;
      27           0 :             break;
      28             :         case kITexture2DSampler_GrSLType:
      29           0 :             value = 1;
      30           0 :             break;
      31             :         case kTextureExternalSampler_GrSLType:
      32           0 :             value = 2;
      33           0 :             break;
      34             :         case kTexture2DRectSampler_GrSLType:
      35           0 :             value = 3;
      36           0 :             break;
      37             :         case kBufferSampler_GrSLType:
      38           0 :             value = 4;
      39           0 :             break;
      40             :         case kImageStorage2D_GrSLType:
      41           0 :             value = 5;
      42           0 :             break;
      43             :         case kIImageStorage2D_GrSLType:
      44           0 :             value = 6;
      45           0 :             break;
      46             : 
      47             :         default:
      48           0 :             break;
      49             :     }
      50           0 :     SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value);
      51           0 :     return value;
      52             : }
      53             : 
      54           0 : static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility,
      55             :                             const GrShaderCaps& caps) {
      56           0 :     int samplerTypeKey = image_storage_or_sampler_uniform_type_key(samplerType);
      57             : 
      58             :     GR_STATIC_ASSERT(1 == sizeof(caps.configTextureSwizzle(config).asKey()));
      59           0 :     return SkToU16(samplerTypeKey |
      60             :                    caps.configTextureSwizzle(config).asKey() << kSamplerOrImageTypeKeyBits |
      61             :                    (caps.samplerPrecision(config, visibility) << (8 + kSamplerOrImageTypeKeyBits)));
      62             : }
      63             : 
      64           0 : static uint16_t storage_image_key(const GrResourceIOProcessor::ImageStorageAccess& imageAccess) {
      65           0 :     GrSLType type = imageAccess.texture()->texturePriv().imageStorageType();
      66           0 :     return image_storage_or_sampler_uniform_type_key(type) |
      67           0 :            (int)imageAccess.format() << kSamplerOrImageTypeKeyBits;
      68             : }
      69             : 
      70           0 : static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourceIOProcessor& proc,
      71             :                                        const GrShaderCaps& caps) {
      72           0 :     int numTextureSamplers = proc.numTextureSamplers();
      73           0 :     int numBuffers = proc.numBuffers();
      74           0 :     int numImageStorages = proc.numImageStorages();
      75           0 :     int numUniforms = numTextureSamplers + numBuffers + numImageStorages;
      76             :     // Need two bytes per key.
      77           0 :     int word32Count = (numUniforms + 1) / 2;
      78           0 :     if (0 == word32Count) {
      79           0 :         return;
      80             :     }
      81           0 :     uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
      82           0 :     int j = 0;
      83           0 :     for (int i = 0; i < numTextureSamplers; ++i, ++j) {
      84           0 :         const GrResourceIOProcessor::TextureSampler& sampler = proc.textureSampler(i);
      85           0 :         const GrTexture* tex = sampler.texture();
      86           0 :         k16[j] = sampler_key(tex->texturePriv().samplerType(), tex->config(), sampler.visibility(),
      87             :                              caps);
      88             :     }
      89           0 :     for (int i = 0; i < numBuffers; ++i, ++j) {
      90           0 :         const GrResourceIOProcessor::BufferAccess& access = proc.bufferAccess(i);
      91           0 :         k16[j] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(), access.visibility(),
      92             :                              caps);
      93             :     }
      94           0 :     for (int i = 0; i < numImageStorages; ++i, ++j) {
      95           0 :         k16[j] = storage_image_key(proc.imageStorageAccess(i));
      96             :     }
      97             :     // zero the last 16 bits if the number of uniforms for samplers and image storages is odd.
      98           0 :     if (numUniforms & 0x1) {
      99           0 :         k16[numUniforms] = 0;
     100             :     }
     101             : }
     102             : 
     103             : /**
     104             :  * A function which emits a meta key into the key builder.  This is required because shader code may
     105             :  * be dependent on properties of the effect that the effect itself doesn't use
     106             :  * in its key (e.g. the pixel format of textures used). So we create a meta-key for
     107             :  * every effect using this function. It is also responsible for inserting the effect's class ID
     108             :  * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
     109             :  * transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share this
     110             :  * function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
     111             :  */
     112           0 : static bool gen_meta_key(const GrResourceIOProcessor& proc,
     113             :                          const GrShaderCaps& shaderCaps,
     114             :                          uint32_t transformKey,
     115             :                          GrProcessorKeyBuilder* b) {
     116           0 :     size_t processorKeySize = b->size();
     117           0 :     uint32_t classID = proc.classID();
     118             : 
     119             :     // Currently we allow 16 bits for the class id and the overall processor key size.
     120             :     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)SK_MaxU16);
     121           0 :     if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
     122           0 :         return false;
     123             :     }
     124             : 
     125           0 :     add_sampler_and_image_keys(b, proc, shaderCaps);
     126             : 
     127           0 :     uint32_t* key = b->add32n(2);
     128           0 :     key[0] = (classID << 16) | SkToU32(processorKeySize);
     129           0 :     key[1] = transformKey;
     130           0 :     return true;
     131             : }
     132             : 
     133           0 : static bool gen_meta_key(const GrXferProcessor& xp,
     134             :                          const GrShaderCaps& shaderCaps,
     135             :                          GrProcessorKeyBuilder* b) {
     136           0 :     size_t processorKeySize = b->size();
     137           0 :     uint32_t classID = xp.classID();
     138             : 
     139             :     // Currently we allow 16 bits for the class id and the overall processor key size.
     140             :     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)SK_MaxU16);
     141           0 :     if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
     142           0 :         return false;
     143             :     }
     144             : 
     145           0 :     b->add32((classID << 16) | SkToU32(processorKeySize));
     146           0 :     return true;
     147             : }
     148             : 
     149           0 : static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
     150             :                                         const GrFragmentProcessor& fp,
     151             :                                         const GrShaderCaps& shaderCaps,
     152             :                                         GrProcessorKeyBuilder* b) {
     153           0 :     for (int i = 0; i < fp.numChildProcessors(); ++i) {
     154           0 :         if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), shaderCaps, b)) {
     155           0 :             return false;
     156             :         }
     157             :     }
     158             : 
     159           0 :     fp.getGLSLProcessorKey(shaderCaps, b);
     160             : 
     161           0 :     return gen_meta_key(fp, shaderCaps, primProc.getTransformKey(fp.coordTransforms(),
     162           0 :                                                                  fp.numCoordTransforms()), b);
     163             : }
     164             : 
     165           0 : bool GrProgramDesc::Build(GrProgramDesc* desc,
     166             :                           const GrPrimitiveProcessor& primProc,
     167             :                           bool hasPointSize,
     168             :                           const GrPipeline& pipeline,
     169             :                           const GrShaderCaps& shaderCaps) {
     170             :     // The descriptor is used as a cache key. Thus when a field of the
     171             :     // descriptor will not affect program generation (because of the attribute
     172             :     // bindings in use or other descriptor field settings) it should be set
     173             :     // to a canonical value to avoid duplicate programs with different keys.
     174             : 
     175             :     GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t));
     176             :     // Make room for everything up to the effect keys.
     177           0 :     desc->key().reset();
     178           0 :     desc->key().push_back_n(kProcessorKeysOffset);
     179             : 
     180           0 :     GrProcessorKeyBuilder b(&desc->key());
     181             : 
     182           0 :     primProc.getGLSLProcessorKey(shaderCaps, &b);
     183           0 :     if (!gen_meta_key(primProc, shaderCaps, 0, &b)) {
     184           0 :         desc->key().reset();
     185           0 :         return false;
     186             :     }
     187           0 :     GrProcessor::RequiredFeatures requiredFeatures = primProc.requiredFeatures();
     188             : 
     189           0 :     for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
     190           0 :         const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i);
     191           0 :         if (!gen_frag_proc_and_meta_keys(primProc, fp, shaderCaps, &b)) {
     192           0 :             desc->key().reset();
     193           0 :             return false;
     194             :         }
     195           0 :         requiredFeatures |= fp.requiredFeatures();
     196             :     }
     197             : 
     198           0 :     const GrXferProcessor& xp = pipeline.getXferProcessor();
     199           0 :     const GrSurfaceOrigin* originIfDstTexture = nullptr;
     200             :     GrSurfaceOrigin origin;
     201           0 :     if (pipeline.dstTexture()) {
     202           0 :         origin = pipeline.dstTexture()->origin();
     203           0 :         originIfDstTexture = &origin;
     204             :     }
     205           0 :     xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture);
     206           0 :     if (!gen_meta_key(xp, shaderCaps, &b)) {
     207           0 :         desc->key().reset();
     208           0 :         return false;
     209             :     }
     210           0 :     requiredFeatures |= xp.requiredFeatures();
     211             : 
     212             :     // --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
     213             :     // Because header is a pointer into the dynamic array, we can't push any new data into the key
     214             :     // below here.
     215           0 :     KeyHeader* header = desc->atOffset<KeyHeader, kHeaderOffset>();
     216             : 
     217             :     // make sure any padding in the header is zeroed.
     218           0 :     memset(header, 0, kHeaderSize);
     219             : 
     220           0 :     GrRenderTarget* rt = pipeline.getRenderTarget();
     221             : 
     222           0 :     if (requiredFeatures & GrProcessor::kSampleLocations_RequiredFeature) {
     223           0 :         SkASSERT(pipeline.isHWAntialiasState());
     224           0 :         header->fSamplePatternKey =
     225           0 :             rt->renderTargetPriv().getMultisampleSpecs(pipeline).fUniqueID;
     226             :     } else {
     227           0 :         header->fSamplePatternKey = 0;
     228             :     }
     229             : 
     230           0 :     header->fOutputSwizzle = shaderCaps.configOutputSwizzle(rt->config()).asKey();
     231             : 
     232           0 :     header->fSnapVerticesToPixelCenters = pipeline.snapVerticesToPixelCenters();
     233           0 :     header->fColorFragmentProcessorCnt = pipeline.numColorFragmentProcessors();
     234           0 :     header->fCoverageFragmentProcessorCnt = pipeline.numCoverageFragmentProcessors();
     235             :     // Fail if the client requested more processors than the key can fit.
     236           0 :     if (header->fColorFragmentProcessorCnt != pipeline.numColorFragmentProcessors() ||
     237           0 :         header->fCoverageFragmentProcessorCnt != pipeline.numCoverageFragmentProcessors()) {
     238           0 :         return false;
     239             :     }
     240           0 :     header->fHasPointSize = hasPointSize ? 1 : 0;
     241           0 :     return true;
     242             : }

Generated by: LCOV version 1.13