Example #1
0
GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
                                const GrEffectStage& stage,
                                GrGLEffect::EffectKey key,
                                const char* fsInColor,
                                const char* fsOutColor,
                                const char* vsInCoord,
                                SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
    GrAssert(NULL != stage.getEffect());

    const GrEffect& effect = *stage.getEffect();
    int numTextures = effect.numTextures();
    SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
    textureSamplers.push_back_n(numTextures);
    for (int i = 0; i < numTextures; ++i) {
        textureSamplers[i].init(this, &effect.textureAccess(i), i);
        samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
    }

    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);

    // Enclose custom code in a block to avoid namespace conflicts
    this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
    this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
    glEffect->emitCode(this,
                       stage,
                       key,
                       vsInCoord,
                       fsOutColor,
                       fsInColor,
                       textureSamplers);
    this->fVSCode.appendf("\t}\n");
    this->fFSCode.appendf("\t}\n");

    return glEffect;
}
Example #2
0
void GrGLProgram::buildKey(GrBinHashKeyBuilder& key) const {
    // Add stage configuration to the key
    key.keyData(reinterpret_cast<const uint8_t*>(&fProgramDesc), sizeof(ProgramDesc));

    for(int stage = 0; stage < GrDrawTarget::kNumStages; ++stage) {
        // First pass: count effects and write the count to the key.
        // This may seem like  we are adding redundant data to the
        // key, but in ensures the one key cannot be a prefix of
        // another key, or identical to the key of a different program.
        GrGLEffect* currentEffect = fStageEffects[stage];
        uint8_t effectCount = 0;
        while (currentEffect) {
            GrAssert(effectCount < 255); // overflow detection
            ++effectCount;
            currentEffect = currentEffect->nextEffect();
        }
        key.keyData(reinterpret_cast<const uint8_t*>(&effectCount), sizeof(uint8_t));

        // Second pass: continue building key using the effects
        currentEffect = fStageEffects[stage];
        while (currentEffect) {
            fStageEffects[stage]->buildKey(key);
        }
    }
}
Example #3
0
void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder,
                                          const GrEffectStage& stage,
                                          const GrEffectKey& key,
                                          const char* outColor,
                                          const char* inColor,
                                          int stageIndex) {
    GrDrawEffect drawEffect(stage, false);
    const GrEffect* effect = stage.getEffect();
    SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
    SkSTArray<4, TextureSampler> samplers(effect->numTextures());

    SkASSERT(0 == stage.getVertexAttribIndexCount());
    this->setupPathTexGen(builder, drawEffect, &coords);
    this->emitSamplers(builder, effect, &samplers);

    GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
    fGLEffects.push_back(glEffect);

    // Enclose custom code in a block to avoid namespace conflicts
    SkString openBrace;
    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
    builder->fsCodeAppend(openBrace.c_str());

    SkASSERT(!glEffect->isVertexEffect());
    glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);

    builder->fsCodeAppend("\t}\n");
}
Example #4
0
void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
                                          const GrEffectStage& stage,
                                          const GrEffectKey& key,
                                          const char* outColor,
                                          const char* inColor,
                                          int stageIndex) {
    GrDrawEffect drawEffect(stage, fHasExplicitLocalCoords);
    const GrEffect* effect = stage.getEffect();
    SkSTArray<2, TransformedCoords> coords(effect->numTransforms());
    SkSTArray<4, TextureSampler> samplers(effect->numTextures());

    this->emitAttributes(builder, stage);
    this->emitTransforms(builder, drawEffect, &coords);
    this->emitSamplers(builder, effect, &samplers);

    GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
    fGLEffects.push_back(glEffect);

    // Enclose custom code in a block to avoid namespace conflicts
    SkString openBrace;
    openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
    builder->vsCodeAppend(openBrace.c_str());
    builder->fsCodeAppend(openBrace.c_str());

    if (glEffect->isVertexEffect()) {
        GrGLVertexEffect* vertexEffect = static_cast<GrGLVertexEffect*>(glEffect);
        vertexEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
    } else {
        glEffect->emitCode(builder, drawEffect, key, outColor, inColor, coords, samplers);
    }

    builder->vsCodeAppend("\t}\n");
    builder->fsCodeAppend("\t}\n");
}
Example #5
0
void GrGLProgram::doGLPost() const {
    for (int stage = 0; stage < GrDrawTarget::kNumStages; ++stage) {
        GrGLEffect* effect = fStageEffects[stage];
        if (effect) {
            effect->doGLPost(); 
        }    
    }
}
Example #6
0
bool GrGLProgram::doGLSetup(GrPrimitiveType type, 
                            GrGLProgram::CachedData* programData) const {
    for (int stage = 0; stage < GrDrawTarget::kNumStages; ++stage) {
        GrGLEffect* effect = fStageEffects[stage];
        if (effect) {
            if (!effect->doGLSetup(type, programData->fProgramID)) {
                return false;
            }
        }
    }

    return true;
}