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:
parent
ded41aafb2
commit
9139803741
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user