Remove FP iterators.

No functional change, just code simplification.

Change-Id: Ie67d515195c462a57954256f045797c3a906d6a4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/435877
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Brian Salomon 2021-08-05 10:02:08 -04:00 committed by SkCQ
parent ded41aafb2
commit 9139803741
10 changed files with 48 additions and 190 deletions

View File

@ -61,6 +61,18 @@ void GrFragmentProcessor::visitTextureEffects(
}
}
void GrFragmentProcessor::visitWithImpls(
const std::function<void(const GrFragmentProcessor&, GrGLSLFragmentProcessor&)>& f,
GrGLSLFragmentProcessor& impl) const {
f(*this, impl);
SkASSERT(impl.numChildProcessors() == this->numChildProcessors());
for (int i = 0; i < this->numChildProcessors(); ++i) {
if (const auto* child = this->childProcessor(i)) {
child->visitWithImpls(f, *impl.childProcessor(i));
}
}
}
GrTextureEffect* GrFragmentProcessor::asTextureEffect() {
if (this->classID() == kGrTextureEffect_ClassID) {
return static_cast<GrTextureEffect*>(this);
@ -935,33 +947,3 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::HighPrecision(
return HighPrecisionFragmentProcessor::Make(std::move(fp));
}
//////////////////////////////////////////////////////////////////////////////
GrFragmentProcessor::CIter::CIter(const GrPaint& paint) {
if (paint.hasCoverageFragmentProcessor()) {
fFPStack.push_back(paint.getCoverageFragmentProcessor());
}
if (paint.hasColorFragmentProcessor()) {
fFPStack.push_back(paint.getColorFragmentProcessor());
}
}
GrFragmentProcessor::CIter::CIter(const GrPipeline& pipeline) {
for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
fFPStack.push_back(&pipeline.getFragmentProcessor(i));
}
}
GrFragmentProcessor::CIter& GrFragmentProcessor::CIter::operator++() {
SkASSERT(!fFPStack.empty());
const GrFragmentProcessor* back = fFPStack.back();
fFPStack.pop_back();
for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
if (auto child = back->childProcessor(i)) {
fFPStack.push_back(child);
}
}
return *this;
}

View File

@ -303,6 +303,10 @@ public:
void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
void visitWithImpls(
const std::function<void(const GrFragmentProcessor&, GrGLSLFragmentProcessor&)>&,
GrGLSLFragmentProcessor&) const;
GrTextureEffect* asTextureEffect();
const GrTextureEffect* asTextureEffect() const;
@ -507,51 +511,6 @@ private:
GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
//////////////////////////////////////////////////////////////////////////////
class GrFragmentProcessor::CIter {
public:
explicit CIter(const GrFragmentProcessor& fp) { fFPStack.push_back(&fp); }
explicit CIter(const GrPaint&);
explicit CIter(const GrPipeline&);
const GrFragmentProcessor& operator*() const { return *fFPStack.back(); }
const GrFragmentProcessor* operator->() const { return fFPStack.back(); }
CIter& operator++();
operator bool() const { return !fFPStack.empty(); }
bool operator!=(const EndCIter&) { return (bool)*this; }
// Hopefully this does not actually get called because of RVO.
CIter(const CIter&) = default;
CIter(CIter&&) = default;
// Because each iterator carries a stack we want to avoid copies.
CIter& operator=(const CIter&) = delete;
CIter& operator=(CIter&&) = default;
protected:
CIter() = delete;
SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
};
//////////////////////////////////////////////////////////////////////////////
template <typename Src> class GrFragmentProcessor::CIterRange {
public:
explicit CIterRange(const Src& t) : fT(t) {}
CIter begin() const { return CIter(fT); }
EndCIter end() const { return EndCIter(); }
private:
const Src& fT;
};
static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
return {false, std::move(fp)};
}

View File

@ -48,11 +48,12 @@ void GrD3DPipelineState::setAndBindConstants(GrD3DGpu* gpu,
this->setRenderTargetState(renderTarget, programInfo.origin());
fGeometryProcessor->setData(fDataManager, *gpu->caps()->shaderCaps(), programInfo.geomProc());
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
auto& fp = programInfo.pipeline().getFragmentProcessor(i);
for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
fp.visitWithImpls([&](const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& impl) {
impl.setData(fDataManager, fp);
}
}, *fFPImpls[i]);
}
programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles);

View File

@ -505,10 +505,10 @@ wgpu::BindGroup GrDawnProgram::setUniformData(GrDawnGpu* gpu, const GrRenderTarg
fGeometryProcessor->setData(fDataManager, *gpu->caps()->shaderCaps(), geomProc);
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
auto& fp = programInfo.pipeline().getFragmentProcessor(i);
for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
fp.visitWithImpls([&](const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& impl) {
impl.setData(fDataManager, fp);
}
}, *fFPImpls[i]);
}
programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles);

View File

@ -113,10 +113,10 @@ void GrGLProgram::updateUniforms(const GrRenderTarget* renderTarget,
programInfo.geomProc());
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
auto& fp = programInfo.pipeline().getFragmentProcessor(i);
for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
fp.visitWithImpls([&](const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& impl) {
impl.setData(fProgramDataManager, fp);
}
}, *fFPImpls[i]);
}
programInfo.pipeline().setDstTextureUniforms(fProgramDataManager, &fBuiltinUniformHandles);

View File

@ -134,56 +134,3 @@ SkString GrGLSLFragmentProcessor::invokeChildWithMatrix(int childIndex, const ch
invocation.append(")");
return invocation;
}
//////////////////////////////////////////////////////////////////////////////
GrGLSLFragmentProcessor::Iter::Iter(std::unique_ptr<GrGLSLFragmentProcessor> fps[], int cnt) {
for (int i = cnt - 1; i >= 0; --i) {
fFPStack.push_back(fps[i].get());
}
}
GrGLSLFragmentProcessor::ParallelIter::ParallelIter(const GrFragmentProcessor& fp,
GrGLSLFragmentProcessor& glslFP)
: fpIter(fp), glslIter(glslFP) {}
GrGLSLFragmentProcessor::ParallelIter& GrGLSLFragmentProcessor::ParallelIter::operator++() {
++fpIter;
++glslIter;
SkASSERT(static_cast<bool>(fpIter) == static_cast<bool>(glslIter));
return *this;
}
std::tuple<const GrFragmentProcessor&, GrGLSLFragmentProcessor&>
GrGLSLFragmentProcessor::ParallelIter::operator*() const {
return {*fpIter, *glslIter};
}
bool GrGLSLFragmentProcessor::ParallelIter::operator==(const ParallelIterEnd& end) const {
SkASSERT(static_cast<bool>(fpIter) == static_cast<bool>(glslIter));
return !fpIter;
}
GrGLSLFragmentProcessor& GrGLSLFragmentProcessor::Iter::operator*() const {
return *fFPStack.back();
}
GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::operator->() const {
return fFPStack.back();
}
GrGLSLFragmentProcessor::Iter& GrGLSLFragmentProcessor::Iter::operator++() {
SkASSERT(!fFPStack.empty());
const GrGLSLFragmentProcessor* back = fFPStack.back();
fFPStack.pop_back();
for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
if (auto child = back->childProcessor(i)) {
fFPStack.push_back(child);
}
}
return *this;
}
GrGLSLFragmentProcessor::ParallelRange::ParallelRange(const GrFragmentProcessor& fp,
GrGLSLFragmentProcessor& glslFP)
: fInitialFP(fp), fInitialGLSLFP(glslFP) {}

View File

@ -168,43 +168,6 @@ public:
SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
};
class ParallelIterEnd {};
/**
* Walks parallel trees of GrFragmentProcessor and associated GrGLSLFragmentProcessors. The
* GrGLSLFragmentProcessor used to initialize the iterator must have been created by calling
* GrFragmentProcessor::createGLSLInstance() on the passed GrFragmentProcessor.
*/
class ParallelIter {
public:
ParallelIter(const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& glslFP);
ParallelIter& operator++();
std::tuple<const GrFragmentProcessor&, GrGLSLFragmentProcessor&> operator*() const;
bool operator==(const ParallelIterEnd& end) const;
bool operator!=(const ParallelIterEnd& end) const { return !(*this == end); }
private:
GrFragmentProcessor::CIter fpIter;
GrGLSLFragmentProcessor::Iter glslIter;
};
class ParallelRange {
public:
ParallelRange(const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& glslFP);
ParallelIter begin() { return {fInitialFP, fInitialGLSLFP}; }
ParallelIterEnd end() { return {}; }
private:
const GrFragmentProcessor& fInitialFP;
GrGLSLFragmentProcessor& fInitialGLSLFP;
};
protected:
/** A GrGLSLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
the same stage key; this function reads data from a GrFragmentProcessor and uploads any

View File

@ -155,7 +155,7 @@ bool GrGLSLProgramBuilder::emitAndInstallFragProcs(SkString* color, SkString* co
}
SkString GrGLSLProgramBuilder::emitFragProc(const GrFragmentProcessor& fp,
GrGLSLFragmentProcessor& glslFP,
GrGLSLFragmentProcessor& impl,
const SkString& input,
SkString output) {
SkASSERT(input.size());
@ -164,10 +164,10 @@ SkString GrGLSLProgramBuilder::emitFragProc(const GrFragmentProcessor& fp,
AutoStageAdvance adv(this);
this->nameExpression(&output, "output");
fFS.codeAppendf("half4 %s;", output.c_str());
int samplerIdx = 0;
for (auto [subFP, subGLSLFP] : GrGLSLFragmentProcessor::ParallelRange(fp, glslFP)) {
if (auto* te = subFP.asTextureEffect()) {
bool ok = true;
fp.visitWithImpls([&, samplerIdx = 0](const GrFragmentProcessor& fp,
GrGLSLFragmentProcessor& impl) mutable {
if (auto* te = fp.asTextureEffect()) {
SkString name;
name.printf("TextureSampler_%d", samplerIdx++);
@ -176,11 +176,16 @@ SkString GrGLSLProgramBuilder::emitFragProc(const GrFragmentProcessor& fp,
GrSwizzle swizzle = te->view().swizzle();
SamplerHandle handle = this->emitSampler(format, samplerState, swizzle, name.c_str());
if (!handle.isValid()) {
return {};
ok = false;
return;
}
static_cast<GrTextureEffect::Impl&>(subGLSLFP).setSamplerHandle(handle);
static_cast<GrTextureEffect::Impl&>(impl).setSamplerHandle(handle);
}
}, impl);
if (!ok) {
return {};
}
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->shaderCaps(),
@ -188,12 +193,12 @@ SkString GrGLSLProgramBuilder::emitFragProc(const GrFragmentProcessor& fp,
fp.isBlendFunction() ? "_src" : "_input",
"_dst",
"_coords");
fFS.writeProcessorFunction(&glslFP, args);
fFS.writeProcessorFunction(&impl, args);
if (fp.isBlendFunction()) {
fFS.codeAppendf(
"%s = %s(%s, half4(1));", output.c_str(), glslFP.functionName(), input.c_str());
"%s = %s(%s, half4(1));", output.c_str(), impl.functionName(), input.c_str());
} else {
fFS.codeAppendf("%s = %s(%s);", output.c_str(), glslFP.functionName(), input.c_str());
fFS.codeAppendf("%s = %s(%s);", output.c_str(), impl.functionName(), input.c_str());
}
// We have to check that effects and the code they emit are consistent, ie if an effect asks

View File

@ -65,10 +65,10 @@ void GrMtlPipelineState::setData(GrMtlFramebuffer* framebuffer,
fGeometryProcessor->setData(fDataManager, *fGpu->caps()->shaderCaps(), programInfo.geomProc());
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
auto& fp = programInfo.pipeline().getFragmentProcessor(i);
for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
fp.visitWithImpls([&](const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& impl) {
impl.setData(fDataManager, fp);
}
}, *fFPImpls[i]);
}
programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles);

View File

@ -80,11 +80,12 @@ bool GrVkPipelineState::setAndBindUniforms(GrVkGpu* gpu,
this->setRenderTargetState(colorAttachmentDimensions, programInfo.origin());
fGeometryProcessor->setData(fDataManager, *gpu->caps()->shaderCaps(), programInfo.geomProc());
for (int i = 0; i < programInfo.pipeline().numFragmentProcessors(); ++i) {
auto& fp = programInfo.pipeline().getFragmentProcessor(i);
for (auto [fp, impl] : GrGLSLFragmentProcessor::ParallelRange(fp, *fFPImpls[i])) {
const auto& fp = programInfo.pipeline().getFragmentProcessor(i);
fp.visitWithImpls([&](const GrFragmentProcessor& fp, GrGLSLFragmentProcessor& impl) {
impl.setData(fDataManager, fp);
}
}, *fFPImpls[i]);
}
programInfo.pipeline().setDstTextureUniforms(fDataManager, &fBuiltinUniformHandles);