bool GrPipeline::isEqual(const GrPipeline& that) const { if (this->getRenderTarget() != that.getRenderTarget() || this->fFragmentStages.count() != that.fFragmentStages.count() || this->fNumColorStages != that.fNumColorStages || this->fScissorState != that.fScissorState || this->fFlags != that.fFlags || this->fStencilSettings != that.fStencilSettings || this->fDrawFace != that.fDrawFace) { return false; } if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) { return false; } // The program desc comparison should have already assured that the stage counts match. SkASSERT(this->numFragmentStages() == that.numFragmentStages()); for (int i = 0; i < this->numFragmentStages(); i++) { if (this->getFragmentStage(i) != that.getFragmentStage(i)) { return false; } } return true; }
void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { int numProcessors = fFragmentProcessors->fProcs.count(); for (int e = 0; e < numProcessors; ++e) { const GrPendingFragmentStage& stage = pipeline.getFragmentStage(e); const GrProcessor& processor = *stage.processor(); fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor); this->setTransformData(primProc, stage, e, fFragmentProcessors->fProcs[e]); this->bindTextures(fFragmentProcessors->fProcs[e], processor); } }
bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc, const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, const GrGLGpu* gpu, const GrBatchTracker& batchTracker) { // The descriptor is used as a cache key. Thus when a field of the // descriptor will not affect program generation (because of the attribute // bindings in use or other descriptor field settings) it should be set // to a canonical value to avoid duplicate programs with different keys. GrGLProgramDesc* glDesc = (GrGLProgramDesc*) desc; GR_STATIC_ASSERT(0 == kProcessorKeysOffset % sizeof(uint32_t)); // Make room for everything up to the effect keys. glDesc->key().reset(); glDesc->key().push_back_n(kProcessorKeysOffset); GrProcessorKeyBuilder b(&glDesc->key()); primProc.getGLProcessorKey(batchTracker, gpu->glCaps(), &b); if (!get_meta_key(primProc, gpu->glCaps(), 0, &b)) { glDesc->key().reset(); return false; } for (int s = 0; s < pipeline.numFragmentStages(); ++s) { const GrPendingFragmentStage& fps = pipeline.getFragmentStage(s); const GrFragmentProcessor& fp = *fps.processor(); fp.getGLProcessorKey(gpu->glCaps(), &b); if (!get_meta_key(fp, gpu->glCaps(), primProc.getTransformKey(fp.coordTransforms()), &b)) { glDesc->key().reset(); return false; } } const GrXferProcessor& xp = *pipeline.getXferProcessor(); xp.getGLProcessorKey(gpu->glCaps(), &b); if (!get_meta_key(xp, gpu->glCaps(), 0, &b)) { glDesc->key().reset(); return false; } // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------------------------- // Because header is a pointer into the dynamic array, we can't push any new data into the key // below here. KeyHeader* header = glDesc->atOffset<KeyHeader, kHeaderOffset>(); // make sure any padding in the header is zeroed. memset(header, 0, kHeaderSize); if (pipeline.readsFragPosition()) { header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(pipeline.getRenderTarget(), gpu->glCaps()); } else { header->fFragPosKey = 0; } header->fColorEffectCnt = pipeline.numColorFragmentStages(); header->fCoverageEffectCnt = pipeline.numCoverageFragmentStages(); glDesc->finalize(); return true; }