bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that, bool ignoreCoordTransforms) const { if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) { return false; } if (ignoreCoordTransforms) { if (this->numTransforms() != that.numTransforms()) { return false; } } else if (!this->hasSameTransforms(that)) { return false; } if (!this->onIsEqual(that)) { return false; } if (this->numChildProcessors() != that.numChildProcessors()) { return false; } for (int i = 0; i < this->numChildProcessors(); ++i) { if (!this->childProcessor(i).isEqual(that.childProcessor(i), ignoreCoordTransforms)) { return false; } } return true; }
void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, int index, const char* outColor, const char* inColor) { GrGLInstalledFragProc* ifp = new GrGLInstalledFragProc; ifp->fGLProc.reset(fp.createGLSLInstance()); SkSTArray<4, GrGLSLTextureSampler> samplers(fp.numTextures()); this->emitSamplers(fp, &samplers, ifp); GrGLSLFragmentProcessor::EmitArgs args(this, &fFS, this->glslCaps(), fp, outColor, inColor, fOutCoords[index], samplers); ifp->fGLProc->emitCode(args); // We have to check that effects and the code they emit are consistent, ie if an effect // asks for dst color, then the emit code needs to follow suit verify(fp); fFragmentProcessors->fProcs.push_back(ifp); }
void GrGLSLFragmentProcessor::setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor) { this->onSetData(pdman, processor); SkASSERT(fChildProcessors.count() == processor.numChildProcessors()); for (int i = 0; i < fChildProcessors.count(); ++i) { fChildProcessors[i]->setData(pdman, processor.childProcessor(i)); } }
bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { if (this->numTransforms() != that.numTransforms()) { return false; } int count = this->numTransforms(); for (int i = 0; i < count; ++i) { if (this->coordTransform(i) != that.coordTransform(i)) { return false; } } return true; }
bool SkModeColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*, SkTDArray<GrFragmentProcessor*>* array) const { if (SkXfermode::kDst_Mode != fMode) { GrFragmentProcessor* frag = ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); if (frag) { if (array) { *array->append() = frag; } else { frag->unref(); SkDEBUGCODE(frag = nullptr;) } return true; } }
static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, const GrFragmentProcessor& fp, const GrGLSLCaps& glslCaps, GrProcessorKeyBuilder* b) { for (int i = 0; i < fp.numChildProcessors(); ++i) { if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), glslCaps, b)) { return false; } } fp.getGLSLProcessorKey(glslCaps, b); return gen_meta_key(fp, glslCaps, primProc.getTransformKey(fp.coordTransforms(), fp.numTransformsExclChildren()), b); }
bool SkLumaColorFilter::asFragmentProcessors(GrContext*, GrProcessorDataManager*, SkTDArray<GrFragmentProcessor*>* array) const { GrFragmentProcessor* frag = LumaColorFilterEffect::Create(); if (frag) { if (array) { *array->append() = frag; } else { frag->unref(); SkDEBUGCODE(frag = nullptr;) } return true; } return false; }
void GrGLPathProgram::setTransformData(const GrPrimitiveProcessor& primProc, const GrFragmentProcessor& processor, int index, GrGLInstalledFragProc* ip) { GrGLPathProcessor* pathProc = static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get()); pathProc->setTransformData(primProc, fPathProgramDataManager, index, processor.coordTransforms()); }
void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor) { const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>(); GrSurfaceProxy* proxy = processor.textureSampler(0).proxy(); GrTexture* texture = proxy->peekTexture(); float imageIncrement[2]; imageIncrement[0] = 1.0f / texture->width(); imageIncrement[1] = 1.0f / texture->height(); pdman.set2fv(fImageIncrementUni, 1, imageIncrement); fDomain.setData(pdman, bicubicEffect.domain(), proxy); }
bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const { if (this->classID() != that.classID() || !this->hasSameSamplersAndAccesses(that)) { return false; } if (!this->hasSameTransforms(that)) { return false; } if (!this->onIsEqual(that)) { return false; } if (this->numChildProcessors() != that.numChildProcessors()) { return false; } for (int i = 0; i < this->numChildProcessors(); ++i) { if (!this->childProcessor(i).isEqual(that.childProcessor(i))) { return false; } } return true; }
void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor) { const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>(); GrTexture* texture = processor.textureSampler(0).peekTexture(); float imageIncrement[2]; imageIncrement[0] = 1.0f / texture->width(); imageIncrement[1] = 1.0f / texture->height(); pdman.set2fv(fImageIncrementUni, 1, imageIncrement); fDomain.setData(pdman, bicubicEffect.domain(), texture); if (SkToBool(bicubicEffect.colorSpaceXform())) { fColorSpaceHelper.setData(pdman, bicubicEffect.colorSpaceXform()); } }
bool SkColorCubeFilter::asFragmentProcessors(GrContext* context, GrProcessorDataManager*, SkTDArray<GrFragmentProcessor*>* array) const { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 2); builder[0] = fUniqueID; builder[1] = fCache.cubeDimension(); builder.finish(); GrSurfaceDesc desc; desc.fWidth = fCache.cubeDimension(); desc.fHeight = fCache.cubeDimension() * fCache.cubeDimension(); desc.fConfig = kRGBA_8888_GrPixelConfig; SkAutoTUnref<GrTexture> textureCube( context->textureProvider()->findAndRefTextureByUniqueKey(key)); if (!textureCube) { textureCube.reset(context->textureProvider()->createTexture( desc, true, fCubeData->data(), 0)); if (textureCube) { context->textureProvider()->assignUniqueKeyToTexture(key, textureCube); } } GrFragmentProcessor* frag = textureCube ? GrColorCubeEffect::Create(textureCube) : NULL; if (frag) { if (array) { *array->append() = frag; } else { frag->unref(); SkDEBUGCODE(frag = NULL;) } return true; } return false; }
// TODO Processors cannot output zeros because an empty string is all 1s // the fix is to allow effects to take the GrGLSLExpr4 directly void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, int index, const GrGLSLExpr4& input, GrGLSLExpr4* output) { // Program builders have a bit of state we need to clear with each effect AutoStageAdvance adv(this); this->nameExpression(output, "output"); // Enclose custom code in a block to avoid namespace conflicts SkString openBrace; openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); fFS.codeAppend(openBrace.c_str()); this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? nullptr : input.c_str()); fFS.codeAppend("}"); }
void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); }
void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc, const GrFragmentProcessor& processor, int index) { fGeometryProcessor->setTransformData(primProc, fProgramDataManager, index, processor.coordTransforms()); }