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; }
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); } } }
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"); }
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"); }
void GrGLProgram::doGLPost() const { for (int stage = 0; stage < GrDrawTarget::kNumStages; ++stage) { GrGLEffect* effect = fStageEffects[stage]; if (effect) { effect->doGLPost(); } } }
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; }