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 "GrGLFragmentOnlyProgramBuilder.h"
      9 #include "../GrGpuGL.h"
     10 
     11 GrGLFragmentOnlyProgramBuilder::GrGLFragmentOnlyProgramBuilder(GrGpuGL* gpu,
     12                                                                const GrGLProgramDesc& desc)
     13     : INHERITED(gpu, desc) {
     14     SkASSERT(desc.getHeader().fUseFragShaderOnly);
     15     SkASSERT(gpu->glCaps().pathRenderingSupport());
     16     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
     17     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
     18 }
     19 
     20 int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) {
     21     int firstFreeCoordSet = fTexCoordSetCnt;
     22     fTexCoordSetCnt += count;
     23     SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt);
     24     return firstFreeCoordSet;
     25 }
     26 
     27 void
     28 GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor,
     29                                                      const GrFragmentStage* colorStages[],
     30                                                      const GrFragmentStage* coverageStages[],
     31                                                      GrGLSLExpr4* inputColor,
     32                                                      GrGLSLExpr4* inputCoverage) {
     33     ///////////////////////////////////////////////////////////////////////////
     34     // emit the per-effect code for both color and coverage effects
     35 
     36     EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
     37     fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
     38                                                      this->desc().numColorEffects(),
     39                                                      colorKeyProvider,
     40                                                      inputColor));
     41 
     42     EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
     43     fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
     44                                                         this->desc().numCoverageEffects(),
     45                                                         coverageKeyProvider,
     46                                                         inputCoverage));
     47 }
     48 
     49 GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects(
     50         const GrFragmentStage* effectStages[], int effectCnt,
     51         const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) {
     52     fProgramEffects.reset(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (effectCnt)));
     53     this->INHERITED::createAndEmitEffects(effectStages,
     54                                           effectCnt,
     55                                           keyProvider,
     56                                           inOutFSColor);
     57     return fProgramEffects.detach();
     58 }
     59 
     60 void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrProcessorStage& stage,
     61                                                 const GrProcessorKey& key,
     62                                                 const char* outColor,
     63                                                 const char* inColor,
     64                                                 int stageIndex) {
     65     SkASSERT(fProgramEffects.get());
     66     const GrProcessor& effect = *stage.getProcessor();
     67 
     68     SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms());
     69     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures());
     70 
     71     this->setupPathTexGen(stage, &coords);
     72     this->emitSamplers(effect, &samplers);
     73 
     74     SkASSERT(fEffectEmitter);
     75     GrGLProcessor* glEffect = fEffectEmitter->createGLInstance();
     76     fProgramEffects->addEffect(glEffect);
     77 
     78     GrGLFragmentShaderBuilder* fsBuilder = this->getFragmentShaderBuilder();
     79     // Enclose custom code in a block to avoid namespace conflicts
     80     SkString openBrace;
     81     openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
     82     fsBuilder->codeAppend(openBrace.c_str());
     83 
     84     fEffectEmitter->emit(key, outColor, inColor, coords, samplers);
     85 
     86     fsBuilder->codeAppend("\t}\n");
     87 }
     88 
     89 void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(
     90         const GrProcessorStage& effectStage, GrGLProcessor::TransformedCoordsArray* outCoords) {
     91     int numTransforms = effectStage.getProcessor()->numTransforms();
     92     int texCoordIndex = this->addTexCoordSets(numTransforms);
     93 
     94     fProgramEffects->addTransforms(texCoordIndex);
     95 
     96     SkString name;
     97     for (int t = 0; t < numTransforms; ++t) {
     98         GrSLType type =
     99                 effectStage.isPerspectiveCoordTransform(t, false) ?
    100                         kVec3f_GrSLType :
    101                         kVec2f_GrSLType;
    102 
    103         name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
    104         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (name, type));
    105     }
    106 }
    107