Home | History | Annotate | Download | only in builders
      1 /*
      2  * Copyright 2014 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 "GrGLFullProgramBuilder.h"
      9 #include "../GrGLGeometryProcessor.h"
     10 #include "../GrGpuGL.h"
     11 
     12 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu,
     13                                                const GrGLProgramDesc& desc)
     14     : INHERITED(gpu, desc)
     15     , fGLGeometryProcessorEmitter(this)
     16     , fGS(this)
     17     , fVS(this) {
     18 }
     19 
     20 void
     21 GrGLFullProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor,
     22                                              const GrFragmentStage* colorStages[],
     23                                              const GrFragmentStage* coverageStages[],
     24                                              GrGLSLExpr4* inputColor,
     25                                              GrGLSLExpr4* inputCoverage) {
     26     fVS.emitCodeBeforeEffects(inputColor, inputCoverage);
     27 
     28     ///////////////////////////////////////////////////////////////////////////
     29     // emit the per-effect code for both color and coverage effects
     30 
     31     EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
     32     fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
     33                                                      this->desc().numColorEffects(),
     34                                                      colorKeyProvider,
     35                                                      inputColor));
     36 
     37     if (geometryProcessor) {
     38         const GrGeometryProcessor& gp = *geometryProcessor->getGeometryProcessor();
     39         fGLGeometryProcessorEmitter.set(&gp);
     40         fEffectEmitter = &fGLGeometryProcessorEmitter;
     41         fVS.emitAttributes(gp);
     42         GrGLSLExpr4 gpInputCoverage = *inputCoverage;
     43         GrGLSLExpr4 gpOutputCoverage;
     44         EffectKeyProvider gpKeyProvider(&this->desc(),
     45                 EffectKeyProvider::kGeometryProcessor_EffectType);
     46         bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords();
     47         fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalCoords)));
     48         this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInputCoverage,
     49                                     &gpOutputCoverage);
     50         fGeometryProcessor.reset(fProgramEffects.detach());
     51         *inputCoverage = gpOutputCoverage;
     52     }
     53 
     54     EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
     55     fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
     56                                                         this->desc().numCoverageEffects(),
     57                                                         coverageKeyProvider,
     58                                                         inputCoverage));
     59 
     60      fVS.emitCodeAfterEffects();
     61 }
     62 
     63 void GrGLFullProgramBuilder::addVarying(GrSLType type,
     64                                         const char* name,
     65                                         const char** vsOutName,
     66                                         const char** fsInName,
     67                                         GrGLShaderVar::Precision fsPrecision) {
     68     fVS.addVarying(type, name, vsOutName);
     69 
     70     SkString* fsInputName = fVS.fOutputs.back().accessName();
     71 
     72 #if GR_GL_EXPERIMENTAL_GS
     73     if (desc().getHeader().fExperimentalGS) {
     74        // TODO let the caller use these names
     75        fGS.addVarying(type, fsInputName->c_str(), NULL);
     76        fsInputName = fGS.fOutputs.back().accessName();
     77     }
     78 #endif
     79     fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
     80 }
     81 
     82 GrGLFullProgramBuilder::VaryingHandle
     83 GrGLFullProgramBuilder::addSeparableVarying(GrSLType type,
     84                                             const char* name,
     85                                             const char** vsOutName,
     86                                             const char** fsInName) {
     87     addVarying(type, name, vsOutName, fsInName);
     88     SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
     89     varying.fVariable = fFS.fInputs.back();
     90     return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos.count() - 1);
     91 }
     92 
     93 GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects(
     94         const GrFragmentStage* effectStages[],
     95         int effectCnt,
     96         const GrGLProgramDesc::EffectKeyProvider& keyProvider,
     97         GrGLSLExpr4* inOutFSColor) {
     98     fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects,
     99                                  (effectCnt,
    100                                   this->getVertexShaderBuilder()->hasExplicitLocalCoords())));
    101     this->INHERITED::createAndEmitEffects(effectStages,
    102                                           effectCnt,
    103                                           keyProvider,
    104                                           inOutFSColor);
    105     return fProgramEffects.detach();
    106 }
    107 
    108 void GrGLFullProgramBuilder::emitEffect(const GrProcessorStage& stage,
    109                                         const GrProcessorKey& key,
    110                                         const char* outColor,
    111                                         const char* inColor,
    112                                         int stageIndex) {
    113     SkASSERT(fProgramEffects.get());
    114     const GrProcessor& effect = *stage.getProcessor();
    115     SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms());
    116     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures());
    117 
    118     this->emitTransforms(stage, &coords);
    119     this->emitSamplers(effect, &samplers);
    120 
    121     SkASSERT(fEffectEmitter);
    122     GrGLProcessor* glEffect = fEffectEmitter->createGLInstance();
    123     fProgramEffects->addEffect(glEffect);
    124 
    125     // Enclose custom code in a block to avoid namespace conflicts
    126     SkString openBrace;
    127     openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name());
    128     fFS.codeAppend(openBrace.c_str());
    129     fVS.codeAppend(openBrace.c_str());
    130 
    131     fEffectEmitter->emit(key, outColor, inColor, coords, samplers);
    132 
    133     fVS.codeAppend("\t}\n");
    134     fFS.codeAppend("\t}\n");
    135 }
    136 
    137 void GrGLFullProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
    138                                             GrGLProcessor::TransformedCoordsArray* outCoords) {
    139     SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms =
    140             fProgramEffects->addTransforms();
    141     const GrProcessor* effect = effectStage.getProcessor();
    142     int numTransforms = effect->numTransforms();
    143     transforms.push_back_n(numTransforms);
    144 
    145     SkTArray<GrGLVertexProgramEffects::PathTransform, true>* pathTransforms = NULL;
    146     const GrGLCaps* glCaps = this->ctxInfo().caps();
    147     if (glCaps->pathRenderingSupport() &&
    148         this->gpu()->glPathRendering()->texturingMode() ==
    149            GrGLPathRendering::SeparableShaders_TexturingMode) {
    150         pathTransforms = &fProgramEffects->addPathTransforms();
    151         pathTransforms->push_back_n(numTransforms);
    152     }
    153 
    154     for (int t = 0; t < numTransforms; t++) {
    155         const char* uniName = "StageMatrix";
    156         GrSLType varyingType =
    157                 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
    158                         kVec3f_GrSLType :
    159                         kVec2f_GrSLType;
    160 
    161         SkString suffixedUniName;
    162         if (0 != t) {
    163             suffixedUniName.append(uniName);
    164             suffixedUniName.appendf("_%i", t);
    165             uniName = suffixedUniName.c_str();
    166         }
    167         transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
    168                                                  kMat33f_GrSLType,
    169                                                  uniName,
    170                                                  &uniName);
    171 
    172         const char* varyingName = "MatrixCoord";
    173         SkString suffixedVaryingName;
    174         if (0 != t) {
    175             suffixedVaryingName.append(varyingName);
    176             suffixedVaryingName.appendf("_%i", t);
    177             varyingName = suffixedVaryingName.c_str();
    178         }
    179         const char* vsVaryingName;
    180         const char* fsVaryingName;
    181         if (pathTransforms) {
    182             (*pathTransforms)[t].fHandle =
    183                 this->addSeparableVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
    184             (*pathTransforms)[t].fType = varyingType;
    185         } else {
    186             this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
    187         }
    188 
    189         const GrGLShaderVar& coords =
    190                 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
    191                                           fVS.positionAttribute() :
    192                                           fVS.localCoordsAttribute();
    193         // varying = matrix * coords (logically)
    194         SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
    195         if (kVec2f_GrSLType == varyingType) {
    196             fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
    197                             vsVaryingName, uniName, coords.c_str());
    198         } else {
    199             fVS.codeAppendf("%s = %s * vec3(%s, 1);",
    200                             vsVaryingName, uniName, coords.c_str());
    201         }
    202         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
    203                                (SkString(fsVaryingName), varyingType));
    204     }
    205 }
    206 
    207 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId,
    208                                                      SkTDArray<GrGLuint>* shaderIds) const {
    209     return INHERITED::compileAndAttachShaders(programId, shaderIds)
    210          && fVS.compileAndAttachShaders(programId, shaderIds)
    211 #if GR_GL_EXPERIMENTAL_GS
    212          && (!desc().getHeader().fExperimentalGS
    213                  || fGS.compileAndAttachShaders(programId, shaderIds))
    214 #endif
    215          ;
    216 }
    217 
    218 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) {
    219     fVS.bindProgramLocations(programId);
    220     INHERITED::bindProgramLocations(programId);
    221 }
    222