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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 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 "glsl/GrGLSLProgramBuilder.h"
       9             : 
      10             : #include "GrCaps.h"
      11             : #include "GrPipeline.h"
      12             : #include "GrShaderCaps.h"
      13             : #include "GrTexturePriv.h"
      14             : #include "glsl/GrGLSLFragmentProcessor.h"
      15             : #include "glsl/GrGLSLGeometryProcessor.h"
      16             : #include "glsl/GrGLSLVarying.h"
      17             : #include "glsl/GrGLSLXferProcessor.h"
      18             : 
      19             : const int GrGLSLProgramBuilder::kVarsPerBlock = 8;
      20             : 
      21           0 : GrGLSLProgramBuilder::GrGLSLProgramBuilder(const GrPipeline& pipeline,
      22             :                                            const GrPrimitiveProcessor& primProc,
      23           0 :                                            GrProgramDesc* desc)
      24             :     : fVS(this)
      25             :     , fGS(this)
      26             :     , fFS(this)
      27             :     , fStageIndex(-1)
      28             :     , fPipeline(pipeline)
      29             :     , fPrimProc(primProc)
      30             :     , fDesc(desc)
      31             :     , fGeometryProcessor(nullptr)
      32             :     , fXferProcessor(nullptr)
      33             :     , fNumVertexSamplers(0)
      34             :     , fNumGeometrySamplers(0)
      35             :     , fNumFragmentSamplers(0)
      36             :     , fNumVertexImageStorages(0)
      37             :     , fNumGeometryImageStorages(0)
      38           0 :     , fNumFragmentImageStorages(0) {
      39           0 : }
      40             : 
      41           0 : void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders,
      42             :                                       uint32_t featureBit,
      43             :                                       const char* extensionName) {
      44           0 :     if (shaders & kVertex_GrShaderFlag) {
      45           0 :         fVS.addFeature(featureBit, extensionName);
      46             :     }
      47           0 :     if (shaders & kGeometry_GrShaderFlag) {
      48           0 :         SkASSERT(this->primitiveProcessor().willUseGeoShader());
      49           0 :         fGS.addFeature(featureBit, extensionName);
      50             :     }
      51           0 :     if (shaders & kFragment_GrShaderFlag) {
      52           0 :         fFS.addFeature(featureBit, extensionName);
      53             :     }
      54           0 : }
      55             : 
      56           0 : bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
      57             :                                                GrGLSLExpr4* inputCoverage) {
      58             :     // First we loop over all of the installed processors and collect coord transforms.  These will
      59             :     // be sent to the GrGLSLPrimitiveProcessor in its emitCode function
      60           0 :     const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
      61             : 
      62           0 :     this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage);
      63             : 
      64           0 :     this->emitAndInstallFragProcs(inputColor, inputCoverage);
      65           0 :     this->emitAndInstallXferProc(*inputColor, *inputCoverage);
      66           0 :     this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
      67             : 
      68           0 :     return this->checkSamplerCounts() && this->checkImageStorageCounts();
      69             : }
      70             : 
      71           0 : void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& proc,
      72             :                                                   GrGLSLExpr4* outputColor,
      73             :                                                   GrGLSLExpr4* outputCoverage) {
      74             :     // Program builders have a bit of state we need to clear with each effect
      75           0 :     AutoStageAdvance adv(this);
      76           0 :     this->nameExpression(outputColor, "outputColor");
      77           0 :     this->nameExpression(outputCoverage, "outputCoverage");
      78             : 
      79           0 :     const char* distanceVectorName = nullptr;
      80           0 :     if (this->fPipeline.usesDistanceVectorField() && proc.implementsDistanceVector()) {
      81             :         // Each individual user (FP) of the distance vector must be able to handle having this
      82             :         // variable be undeclared. There is no single default value that will yield a reasonable
      83             :         // result for all users.
      84           0 :         distanceVectorName = fFS.distanceVectorName();
      85           0 :         fFS.codeAppend( "// Normalized vector to the closest geometric edge (in device space)\n");
      86           0 :         fFS.codeAppend( "// Distance to the edge encoded in the z-component\n");
      87           0 :         fFS.codeAppendf("vec4 %s;", distanceVectorName);
      88             :     }
      89             : 
      90           0 :     SkASSERT(!fUniformHandles.fRTAdjustmentUni.isValid());
      91           0 :     GrShaderFlags rtAdjustVisibility = kVertex_GrShaderFlag;
      92           0 :     if (proc.willUseGeoShader()) {
      93           0 :         rtAdjustVisibility |= kGeometry_GrShaderFlag;
      94             :     }
      95           0 :     fUniformHandles.fRTAdjustmentUni = this->uniformHandler()->addUniform(rtAdjustVisibility,
      96             :                                                                           kVec4f_GrSLType,
      97             :                                                                           kHigh_GrSLPrecision,
      98           0 :                                                                           "rtAdjustment");
      99             :     const char* rtAdjustName =
     100           0 :         this->uniformHandler()->getUniformCStr(fUniformHandles.fRTAdjustmentUni);
     101             : 
     102             :     // Enclose custom code in a block to avoid namespace conflicts
     103           0 :     SkString openBrace;
     104           0 :     openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
     105           0 :     fFS.codeAppend(openBrace.c_str());
     106           0 :     fVS.codeAppendf("// Primitive Processor %s\n", proc.name());
     107             : 
     108           0 :     SkASSERT(!fGeometryProcessor);
     109           0 :     fGeometryProcessor = proc.createGLSLInstance(*this->shaderCaps());
     110             : 
     111           0 :     SkSTArray<4, SamplerHandle>      texSamplers(proc.numTextureSamplers());
     112           0 :     SkSTArray<2, SamplerHandle>      bufferSamplers(proc.numBuffers());
     113           0 :     SkSTArray<2, ImageStorageHandle> imageStorages(proc.numImageStorages());
     114           0 :     this->emitSamplersAndImageStorages(proc, &texSamplers, &bufferSamplers, &imageStorages);
     115             : 
     116             :     GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
     117           0 :                                                                        &fTransformedCoordVars);
     118             :     GrGLSLGeometryProcessor::EmitArgs args(&fVS,
     119           0 :                                            proc.willUseGeoShader() ? &fGS : nullptr,
     120             :                                            &fFS,
     121           0 :                                            this->varyingHandler(),
     122           0 :                                            this->uniformHandler(),
     123             :                                            this->shaderCaps(),
     124             :                                            proc,
     125             :                                            outputColor->c_str(),
     126             :                                            outputCoverage->c_str(),
     127             :                                            distanceVectorName,
     128             :                                            rtAdjustName,
     129           0 :                                            texSamplers.begin(),
     130           0 :                                            bufferSamplers.begin(),
     131           0 :                                            imageStorages.begin(),
     132           0 :                                            &transformHandler);
     133           0 :     fGeometryProcessor->emitCode(args);
     134             : 
     135             :     // We have to check that effects and the code they emit are consistent, ie if an effect
     136             :     // asks for dst color, then the emit code needs to follow suit
     137           0 :     SkDEBUGCODE(verify(proc);)
     138             : 
     139           0 :     fFS.codeAppend("}");
     140           0 : }
     141             : 
     142           0 : void GrGLSLProgramBuilder::emitAndInstallFragProcs(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
     143           0 :     int transformedCoordVarsIdx = 0;
     144           0 :     GrGLSLExpr4** inOut = &color;
     145           0 :     for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) {
     146           0 :         if (i == this->pipeline().numColorFragmentProcessors()) {
     147           0 :             inOut = &coverage;
     148             :         }
     149           0 :         GrGLSLExpr4 output;
     150           0 :         const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i);
     151           0 :         this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, &output);
     152           0 :         GrFragmentProcessor::Iter iter(&fp);
     153           0 :         while (const GrFragmentProcessor* fp = iter.next()) {
     154           0 :             transformedCoordVarsIdx += fp->numCoordTransforms();
     155           0 :         }
     156           0 :         **inOut = output;
     157             :     }
     158           0 : }
     159             : 
     160             : // TODO Processors cannot output zeros because an empty string is all 1s
     161             : // the fix is to allow effects to take the GrGLSLExpr4 directly
     162           0 : void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
     163             :                                                   int index,
     164             :                                                   int transformedCoordVarsIdx,
     165             :                                                   const GrGLSLExpr4& input,
     166             :                                                   GrGLSLExpr4* output) {
     167             :     // Program builders have a bit of state we need to clear with each effect
     168           0 :     AutoStageAdvance adv(this);
     169           0 :     this->nameExpression(output, "output");
     170             : 
     171             :     // Enclose custom code in a block to avoid namespace conflicts
     172           0 :     SkString openBrace;
     173           0 :     openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name());
     174           0 :     fFS.codeAppend(openBrace.c_str());
     175             : 
     176           0 :     GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
     177             : 
     178           0 :     SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers());
     179           0 :     SkSTArray<2, SamplerHandle> bufferSamplerArray(fp.numBuffers());
     180           0 :     SkSTArray<2, ImageStorageHandle> imageStorageArray(fp.numImageStorages());
     181           0 :     GrFragmentProcessor::Iter iter(&fp);
     182           0 :     while (const GrFragmentProcessor* subFP = iter.next()) {
     183           0 :         this->emitSamplersAndImageStorages(*subFP, &textureSamplerArray, &bufferSamplerArray,
     184           0 :                                            &imageStorageArray);
     185           0 :     }
     186             : 
     187           0 :     const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
     188           0 :     GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
     189           0 :     GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin());
     190           0 :     GrGLSLFragmentProcessor::BufferSamplers bufferSamplers(&fp, bufferSamplerArray.begin());
     191           0 :     GrGLSLFragmentProcessor::ImageStorages imageStorages(&fp, imageStorageArray.begin());
     192             :     GrGLSLFragmentProcessor::EmitArgs args(&fFS,
     193           0 :                                            this->uniformHandler(),
     194             :                                            this->shaderCaps(),
     195             :                                            fp,
     196             :                                            output->c_str(),
     197           0 :                                            input.isOnes() ? nullptr : input.c_str(),
     198             :                                            coords,
     199             :                                            textureSamplers,
     200             :                                            bufferSamplers,
     201             :                                            imageStorages,
     202           0 :                                            this->primitiveProcessor().implementsDistanceVector());
     203             : 
     204           0 :     fragProc->emitCode(args);
     205             : 
     206             :     // We have to check that effects and the code they emit are consistent, ie if an effect
     207             :     // asks for dst color, then the emit code needs to follow suit
     208           0 :     SkDEBUGCODE(verify(fp);)
     209           0 :     fFragmentProcessors.push_back(fragProc);
     210             : 
     211           0 :     fFS.codeAppend("}");
     212           0 : }
     213             : 
     214           0 : void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrGLSLExpr4& colorIn,
     215             :                                                   const GrGLSLExpr4& coverageIn) {
     216             :     // Program builders have a bit of state we need to clear with each effect
     217           0 :     AutoStageAdvance adv(this);
     218             : 
     219           0 :     SkASSERT(!fXferProcessor);
     220           0 :     const GrXferProcessor& xp = fPipeline.getXferProcessor();
     221           0 :     fXferProcessor = xp.createGLSLInstance();
     222             : 
     223             :     // Enable dual source secondary output if we have one
     224           0 :     if (xp.hasSecondaryOutput()) {
     225           0 :         fFS.enableSecondaryOutput();
     226             :     }
     227             : 
     228           0 :     if (this->shaderCaps()->mustDeclareFragmentShaderOutput()) {
     229           0 :         fFS.enableCustomOutput();
     230             :     }
     231             : 
     232           0 :     SkString openBrace;
     233           0 :     openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
     234           0 :     fFS.codeAppend(openBrace.c_str());
     235             : 
     236           0 :     SamplerHandle dstTextureSamplerHandle;
     237           0 :     GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin;
     238           0 :     if (GrTexture* dstTexture = fPipeline.dstTexture()) {
     239             :         // GrProcessor::TextureSampler sampler(dstTexture);
     240           0 :         SkString name("DstTextureSampler");
     241             :         dstTextureSamplerHandle =
     242           0 :                 this->emitSampler(dstTexture->texturePriv().samplerType(), dstTexture->config(),
     243           0 :                                   "DstTextureSampler", kFragment_GrShaderFlag);
     244           0 :         dstTextureOrigin = dstTexture->origin();
     245           0 :         SkASSERT(kTextureExternalSampler_GrSLType != dstTexture->texturePriv().samplerType());
     246             :     }
     247             : 
     248             :     GrGLSLXferProcessor::EmitArgs args(&fFS,
     249           0 :                                        this->uniformHandler(),
     250             :                                        this->shaderCaps(),
     251             :                                        xp,
     252             :                                        colorIn.c_str(),
     253             :                                        coverageIn.c_str(),
     254             :                                        fFS.getPrimaryColorOutputName(),
     255             :                                        fFS.getSecondaryColorOutputName(),
     256             :                                        dstTextureSamplerHandle,
     257           0 :                                        dstTextureOrigin);
     258           0 :     fXferProcessor->emitCode(args);
     259             : 
     260             :     // We have to check that effects and the code they emit are consistent, ie if an effect
     261             :     // asks for dst color, then the emit code needs to follow suit
     262           0 :     SkDEBUGCODE(verify(xp);)
     263           0 :     fFS.codeAppend("}");
     264           0 : }
     265             : 
     266           0 : void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
     267             :         const GrResourceIOProcessor& processor,
     268             :         SkTArray<SamplerHandle>* outTexSamplerHandles,
     269             :         SkTArray<SamplerHandle>* outBufferSamplerHandles,
     270             :         SkTArray<ImageStorageHandle>* outImageStorageHandles) {
     271           0 :     SkString name;
     272           0 :     int numTextureSamplers = processor.numTextureSamplers();
     273           0 :     for (int t = 0; t < numTextureSamplers; ++t) {
     274           0 :         const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(t);
     275           0 :         name.printf("TextureSampler_%d", outTexSamplerHandles->count());
     276           0 :         GrSLType samplerType = sampler.texture()->texturePriv().samplerType();
     277           0 :         if (kTextureExternalSampler_GrSLType == samplerType) {
     278             :             const char* externalFeatureString =
     279           0 :                     this->shaderCaps()->externalTextureExtensionString();
     280             :             // We shouldn't ever create a GrGLTexture that requires external sampler type
     281           0 :             SkASSERT(externalFeatureString);
     282           0 :             this->addFeature(sampler.visibility(),
     283             :                              1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
     284           0 :                              externalFeatureString);
     285             :         }
     286           0 :         outTexSamplerHandles->emplace_back(this->emitSampler(
     287           0 :                 samplerType, sampler.texture()->config(), name.c_str(), sampler.visibility()));
     288             :     }
     289           0 :     if (int numBuffers = processor.numBuffers()) {
     290           0 :         SkASSERT(this->shaderCaps()->texelBufferSupport());
     291           0 :         GrShaderFlags texelBufferVisibility = kNone_GrShaderFlags;
     292             : 
     293           0 :         for (int b = 0; b < numBuffers; ++b) {
     294           0 :             const GrResourceIOProcessor::BufferAccess& access = processor.bufferAccess(b);
     295           0 :             name.printf("BufferSampler_%d", outBufferSamplerHandles->count());
     296             :             outBufferSamplerHandles->emplace_back(
     297           0 :                     this->emitSampler(kBufferSampler_GrSLType, access.texelConfig(), name.c_str(),
     298           0 :                                       access.visibility()));
     299           0 :             texelBufferVisibility |= access.visibility();
     300             :         }
     301             : 
     302           0 :         if (const char* extension = this->shaderCaps()->texelBufferExtensionString()) {
     303             :             this->addFeature(texelBufferVisibility,
     304             :                              1 << GrGLSLShaderBuilder::kTexelBuffer_GLSLPrivateFeature,
     305           0 :                              extension);
     306             :         }
     307             :     }
     308           0 :     int numImageStorages = processor.numImageStorages();
     309           0 :     for (int i = 0; i < numImageStorages; ++i) {
     310             :         const GrResourceIOProcessor::ImageStorageAccess& imageStorageAccess =
     311           0 :                 processor.imageStorageAccess(i);
     312           0 :         name.printf("Image_%d", outImageStorageHandles->count());
     313             :         outImageStorageHandles->emplace_back(
     314           0 :                 this->emitImageStorage(imageStorageAccess, name.c_str()));
     315             :     }
     316           0 : }
     317             : 
     318           0 : GrGLSLProgramBuilder::SamplerHandle GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
     319             :                                                                       GrPixelConfig config,
     320             :                                                                       const char* name,
     321             :                                                                       GrShaderFlags visibility) {
     322           0 :     if (visibility & kVertex_GrShaderFlag) {
     323           0 :         ++fNumVertexSamplers;
     324             :     }
     325           0 :     if (visibility & kGeometry_GrShaderFlag) {
     326           0 :         SkASSERT(this->primitiveProcessor().willUseGeoShader());
     327           0 :         ++fNumGeometrySamplers;
     328             :     }
     329           0 :     if (visibility & kFragment_GrShaderFlag) {
     330           0 :         ++fNumFragmentSamplers;
     331             :     }
     332           0 :     GrSLPrecision precision = this->shaderCaps()->samplerPrecision(config, visibility);
     333           0 :     GrSwizzle swizzle = this->shaderCaps()->configTextureSwizzle(config);
     334           0 :     return this->uniformHandler()->addSampler(visibility, swizzle, samplerType, precision, name);
     335             : }
     336             : 
     337           0 : GrGLSLProgramBuilder::ImageStorageHandle GrGLSLProgramBuilder::emitImageStorage(
     338             :         const GrResourceIOProcessor::ImageStorageAccess& access, const char* name) {
     339           0 :     if (access.visibility() & kVertex_GrShaderFlag) {
     340           0 :         ++fNumVertexImageStorages;
     341             :     }
     342           0 :     if (access.visibility() & kGeometry_GrShaderFlag) {
     343           0 :         SkASSERT(this->primitiveProcessor().willUseGeoShader());
     344           0 :         ++fNumGeometryImageStorages;
     345             :     }
     346           0 :     if (access.visibility() & kFragment_GrShaderFlag) {
     347           0 :         ++fNumFragmentImageStorages;
     348             :     }
     349           0 :     GrSLType uniformType = access.texture()->texturePriv().imageStorageType();
     350           0 :     return this->uniformHandler()->addImageStorage(access.visibility(), uniformType,
     351             :                                                    access.format(), access.memoryModel(),
     352           0 :                                                    access.restrict(), access.ioType(), name);
     353             : }
     354             : 
     355           0 : void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
     356             :     // Swizzle the fragment shader outputs if necessary.
     357           0 :     GrSwizzle swizzle;
     358           0 :     swizzle.setFromKey(this->desc()->header().fOutputSwizzle);
     359           0 :     if (swizzle != GrSwizzle::RGBA()) {
     360           0 :         fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(),
     361             :                         fFS.getPrimaryColorOutputName(),
     362           0 :                         swizzle.c_str());
     363           0 :         if (hasSecondaryOutput) {
     364           0 :             fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(),
     365             :                             fFS.getSecondaryColorOutputName(),
     366           0 :                             swizzle.c_str());
     367             :         }
     368             :     }
     369           0 : }
     370             : 
     371           0 : bool GrGLSLProgramBuilder::checkSamplerCounts() {
     372           0 :     const GrShaderCaps& shaderCaps = *this->shaderCaps();
     373           0 :     if (fNumVertexSamplers > shaderCaps.maxVertexSamplers()) {
     374           0 :         GrCapsDebugf(this->caps(), "Program would use too many vertex samplers\n");
     375           0 :         return false;
     376             :     }
     377           0 :     if (fNumGeometrySamplers > shaderCaps.maxGeometrySamplers()) {
     378           0 :         GrCapsDebugf(this->caps(), "Program would use too many geometry samplers\n");
     379           0 :         return false;
     380             :     }
     381           0 :     if (fNumFragmentSamplers > shaderCaps.maxFragmentSamplers()) {
     382           0 :         GrCapsDebugf(this->caps(), "Program would use too many fragment samplers\n");
     383           0 :         return false;
     384             :     }
     385             :     // If the same sampler is used in two different shaders, it counts as two combined samplers.
     386           0 :     int numCombinedSamplers = fNumVertexSamplers + fNumGeometrySamplers + fNumFragmentSamplers;
     387           0 :     if (numCombinedSamplers > shaderCaps.maxCombinedSamplers()) {
     388           0 :         GrCapsDebugf(this->caps(), "Program would use too many combined samplers\n");
     389           0 :         return false;
     390             :     }
     391           0 :     return true;
     392             : }
     393             : 
     394           0 : bool GrGLSLProgramBuilder::checkImageStorageCounts() {
     395           0 :     const GrShaderCaps& shaderCaps = *this->shaderCaps();
     396           0 :     if (fNumVertexImageStorages > shaderCaps.maxVertexImageStorages()) {
     397           0 :         GrCapsDebugf(this->caps(), "Program would use too many vertex images\n");
     398           0 :         return false;
     399             :     }
     400           0 :     if (fNumGeometryImageStorages > shaderCaps.maxGeometryImageStorages()) {
     401           0 :         GrCapsDebugf(this->caps(), "Program would use too many geometry images\n");
     402           0 :         return false;
     403             :     }
     404           0 :     if (fNumFragmentImageStorages > shaderCaps.maxFragmentImageStorages()) {
     405           0 :         GrCapsDebugf(this->caps(), "Program would use too many fragment images\n");
     406           0 :         return false;
     407             :     }
     408             :     // If the same image is used in two different shaders, it counts as two combined images.
     409           0 :     int numCombinedImages = fNumVertexImageStorages + fNumGeometryImageStorages +
     410           0 :         fNumFragmentImageStorages;
     411           0 :     if (numCombinedImages > shaderCaps.maxCombinedImageStorages()) {
     412           0 :         GrCapsDebugf(this->caps(), "Program would use too many combined images\n");
     413           0 :         return false;
     414             :     }
     415           0 :     return true;
     416             : }
     417             : 
     418             : #ifdef SK_DEBUG
     419           0 : void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
     420           0 :     SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures());
     421           0 : }
     422             : 
     423           0 : void GrGLSLProgramBuilder::verify(const GrXferProcessor& xp) {
     424           0 :     SkASSERT(fFS.usedProcessorFeatures() == xp.requiredFeatures());
     425           0 :     SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor());
     426           0 : }
     427             : 
     428           0 : void GrGLSLProgramBuilder::verify(const GrFragmentProcessor& fp) {
     429           0 :     SkASSERT(fFS.usedProcessorFeatures() == fp.requiredFeatures());
     430           0 : }
     431             : #endif
     432             : 
     433           0 : void GrGLSLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) {
     434           0 :     if ('\0' == prefix) {
     435           0 :         *out = name;
     436             :     } else {
     437           0 :         out->printf("%c%s", prefix, name);
     438             :     }
     439           0 :     if (mangle) {
     440           0 :         if (out->endsWith('_')) {
     441             :             // Names containing "__" are reserved.
     442           0 :             out->append("x");
     443             :         }
     444           0 :         out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str());
     445             :     }
     446           0 : }
     447             : 
     448           0 : void GrGLSLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseName) {
     449             :     // create var to hold stage result.  If we already have a valid output name, just use that
     450             :     // otherwise create a new mangled one.  This name is only valid if we are reordering stages
     451             :     // and have to tell stage exactly where to put its output.
     452           0 :     SkString outName;
     453           0 :     if (output->isValid()) {
     454           0 :         outName = output->c_str();
     455             :     } else {
     456           0 :         this->nameVariable(&outName, '\0', baseName);
     457             :     }
     458           0 :     fFS.codeAppendf("vec4 %s;", outName.c_str());
     459           0 :     *output = outName;
     460           0 : }
     461             : 
     462           0 : void GrGLSLProgramBuilder::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
     463           0 :     this->uniformHandler()->appendUniformDecls(visibility, out);
     464           0 : }
     465             : 
     466           0 : void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) {
     467           0 :         SkASSERT(!fUniformHandles.fRTHeightUni.isValid());
     468           0 :         GrGLSLUniformHandler* uniformHandler = this->uniformHandler();
     469             :         fUniformHandles.fRTHeightUni =
     470             :             uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag,
     471             :                                                     kFloat_GrSLType, kDefault_GrSLPrecision,
     472           0 :                                                     name, false, 0, nullptr);
     473           0 : }
     474             : 
     475           0 : void GrGLSLProgramBuilder::cleanupFragmentProcessors() {
     476           0 :     for (int i = 0; i < fFragmentProcessors.count(); ++i) {
     477           0 :         delete fFragmentProcessors[i];
     478             :     }
     479           0 : }
     480             : 
     481           0 : void GrGLSLProgramBuilder::finalizeShaders() {
     482           0 :     this->varyingHandler()->finalize();
     483           0 :     fVS.finalize(kVertex_GrShaderFlag);
     484           0 :     if (this->primitiveProcessor().willUseGeoShader()) {
     485           0 :         SkASSERT(this->shaderCaps()->geometryShaderSupport());
     486           0 :         fGS.finalize(kGeometry_GrShaderFlag);
     487             :     }
     488           0 :     fFS.finalize(kFragment_GrShaderFlag);
     489           0 : }

Generated by: LCOV version 1.13