Make fragment processor iterators work with range for loops.
When iterating over the coord transforms or texture samplers of a
FP also have access to the owning FP.
Pass a coord transform range to GPs rather than a pointer to an
iterator.
Change-Id: If7c829a67dce6600d7f49e12d6f49f685dcace3a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/256216
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 5ce72ff..1000bd1 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -181,7 +181,7 @@
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
if (!dgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dgp.viewMatrix())) {
@@ -200,7 +200,7 @@
pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage()));
fCoverage = dgp.coverage();
}
- this->setTransformDataHelper(dgp.fLocalMatrix, pdman, &transformIter);
+ this->setTransformDataHelper(dgp.fLocalMatrix, pdman, transformRange);
fColorSpaceHelper.setData(pdman, dgp.fColorSpaceXform.get());
}
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 933bc01..88acf1e 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -48,10 +48,9 @@
}
void GrFragmentProcessor::visitProxies(const GrOp::VisitProxyFunc& func) {
- GrFragmentProcessor::TextureAccessIter iter(this);
- while (const TextureSampler* sampler = iter.next()) {
- bool mipped = (GrSamplerState::Filter::kMipMap == sampler->samplerState().filter());
- func(sampler->proxy(), GrMipMapped(mipped));
+ for (auto [sampler, fp] : FPTextureSamplerRange(*this)) {
+ bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
+ func(sampler.proxy(), GrMipMapped(mipped));
}
}
@@ -389,12 +388,6 @@
//////////////////////////////////////////////////////////////////////////////
-GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
- for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
- fFPStack.push_back(&pipeline.getFragmentProcessor(i));
- }
-}
-
GrFragmentProcessor::Iter::Iter(const GrPaint& paint) {
for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
fFPStack.push_back(paint.getCoverageFragmentProcessor(i));
@@ -404,16 +397,32 @@
}
}
-const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
- if (fFPStack.empty()) {
- return nullptr;
+GrFragmentProcessor::Iter::Iter(const GrProcessorSet& set) {
+ for (int i = set.numCoverageFragmentProcessors() - 1; i >= 0; --i) {
+ fFPStack.push_back(set.coverageFragmentProcessor(i));
}
+ for (int i = set.numColorFragmentProcessors() - 1; i >= 0; --i) {
+ fFPStack.push_back(set.colorFragmentProcessor(i));
+ }
+}
+
+GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
+ for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
+ fFPStack.push_back(&pipeline.getFragmentProcessor(i));
+ }
+}
+
+const GrFragmentProcessor& GrFragmentProcessor::Iter::operator*() const { return *fFPStack.back(); }
+const GrFragmentProcessor* GrFragmentProcessor::Iter::operator->() const { return fFPStack.back(); }
+
+GrFragmentProcessor::Iter& GrFragmentProcessor::Iter::operator++() {
+ SkASSERT(!fFPStack.empty());
const GrFragmentProcessor* back = fFPStack.back();
fFPStack.pop_back();
for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
fFPStack.push_back(&back->childProcessor(i));
}
- return back;
+ return *this;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 9188081..c5e7b96 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -193,72 +193,88 @@
*/
bool isEqual(const GrFragmentProcessor& that) const;
- /**
- * Pre-order traversal of a FP hierarchy, or of the forest of FPs in a GrPipeline. In the latter
- * case the tree rooted at each FP in the GrPipeline is visited successively.
- */
- class Iter : public SkNoncopyable {
- public:
- explicit Iter(const GrFragmentProcessor* fp) { fFPStack.push_back(fp); }
- explicit Iter(const GrPipeline& pipeline);
- explicit Iter(const GrPaint&);
- const GrFragmentProcessor* next();
+ void visitProxies(const GrOp::VisitProxyFunc& func);
- private:
- SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
- };
+ // A pre-order traversal iterator over a hierarchy of FPs. It can also iterate over all the FP
+ // hierarchies rooted in a GrPaint, GrProcessorSet, or GrPipeline. For these collections it
+ // iterates the tree rooted at each color FP and then each coverage FP.
+ //
+ // An iterator is constructed from one of the srcs and used like this:
+ // for (GrFragmentProcessor::Iter iter(pipeline); iter; ++iter) {
+ // const GrFragmentProcessor& fp = *iter;
+ // }
+ // The exit test for the loop is using Iter's operator bool().
+ // To use a range-for loop instead see IterRange below.
+ class Iter;
- /**
- * Iterates over all the Ts owned by a GrFragmentProcessor and its children or over all the Ts
- * owned by the forest of GrFragmentProcessors in a GrPipeline. FPs are visited in the same
- * order as Iter and each of an FP's Ts are visited in order.
- */
- template <typename T, int (GrFragmentProcessor::*COUNT)() const,
- const T& (GrFragmentProcessor::*GET)(int)const>
- class FPItemIter : public SkNoncopyable {
- public:
- explicit FPItemIter(const GrFragmentProcessor* fp)
- : fCurrFP(nullptr)
- , fCTIdx(0)
- , fFPIter(fp) {
- fCurrFP = fFPIter.next();
- }
- explicit FPItemIter(const GrPipeline& pipeline)
- : fCurrFP(nullptr)
- , fCTIdx(0)
- , fFPIter(pipeline) {
- fCurrFP = fFPIter.next();
- }
+ // Used to implement a range-for loop using Iter. Src is one of GrFragmentProcessor, GrPaint,
+ // GrProcessorSet, or GrPipeline. Type aliases for these defined below.
+ // Example usage:
+ // for (const auto& fp : GrFragmentProcessor::PaintRange(paint)) {
+ // if (fp.usesLocalCoords()) {
+ // ...
+ // }
+ // }
+ template <typename Src> class IterRange;
- const T* next() {
- if (!fCurrFP) {
- return nullptr;
- }
- while (fCTIdx == (fCurrFP->*COUNT)()) {
- fCTIdx = 0;
- fCurrFP = fFPIter.next();
- if (!fCurrFP) {
- return nullptr;
- }
- }
- return &(fCurrFP->*GET)(fCTIdx++);
- }
+ // We would use template deduction guides for Iter but for:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79501
+ // Instead we use these specialized type aliases to make it prettier
+ // to construct Iters for particular sources of FPs.
+ using FPRange = IterRange<GrFragmentProcessor>;
+ using PaintRange = IterRange<GrPaint>;
- private:
- const GrFragmentProcessor* fCurrFP;
- int fCTIdx;
- GrFragmentProcessor::Iter fFPIter;
- };
+ using CountFn = int (GrFragmentProcessor::*)() const;
+ template <typename Item> using GetFn = const Item& (GrFragmentProcessor::*)(int) const;
+ // Implementation detail for iterators that walk an array of things owned by a set of FPs.
+ template <typename Item, CountFn Count, GetFn<Item> Get> class FPItemIter;
+
+ // Loops over all the GrCoordTransforms owned by GrFragmentProcessors. The possible sources for
+ // the iteration are the same as those for Iter and the FPs are walked in the same order as
+ // Iter. This provides access to the coord transform and the FP that owns it. Example usage:
+ // for (GrFragmentProcessor::CoordTransformIter iter(pipeline); iter; ++iter) {
+ // // transform is const GrCoordTransform& and owningFP is const GrFragmentProcessor&.
+ // auto [transform, owningFP] = *iter;
+ // ...
+ // }
+ // See the ranges below to make this simpler a la range-for loops.
using CoordTransformIter = FPItemIter<GrCoordTransform,
&GrFragmentProcessor::numCoordTransforms,
&GrFragmentProcessor::coordTransform>;
+ // Same as CoordTransformIter but for TextureSamplers:
+ // for (GrFragmentProcessor::TextureSamplerIter iter(pipeline); iter; ++iter) {
+ // // TextureSamplerIter is const GrFragmentProcessor::TextureSampler& and
+ // // owningFP is const GrFragmentProcessor&.
+ // auto [sampler, owningFP] = *iter;
+ // ...
+ // }
+ // See the ranges below to make this simpler a la range-for loops.
+ using TextureSamplerIter = FPItemIter<TextureSampler,
+ &GrFragmentProcessor::numTextureSamplers,
+ &GrFragmentProcessor::textureSampler>;
- using TextureAccessIter = FPItemIter<TextureSampler,
- &GrFragmentProcessor::numTextureSamplers,
- &GrFragmentProcessor::textureSampler>;
+ // Implementation detail for using CoordTransformIter and TextureSamplerIter in range-for loops.
+ template <typename Src, typename ItemIter> class FPItemRange;
- void visitProxies(const GrOp::VisitProxyFunc& func);
+ // These allow iteration over coord transforms/texture samplers for various FP sources via
+ // range-for loops. An example usage for looping over the coord transforms in a pipeline:
+ // for (auto [transform, fp] : GrFragmentProcessor::PipelineCoordTransformRange(pipeline)) {
+ // ...
+ // }
+ // Only the combinations of FP sources and iterable things have been defined but it is easy
+ // to add more as they become useful. Maybe someday we'll have template argument deduction
+ // with guides for type aliases and the sources can be removed from the type aliases:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1021r5.html
+ using PipelineCoordTransformRange = FPItemRange<GrPipeline, CoordTransformIter>;
+ using PipelineTextureSamplerRange = FPItemRange<GrPipeline, TextureSamplerIter>;
+ using FPTextureSamplerRange = FPItemRange<GrFragmentProcessor, TextureSamplerIter>;
+ using ProcessorSetTextureSamplerRange = FPItemRange<GrProcessorSet, TextureSamplerIter>;
+
+ // Sentinel type for range-for using Iter.
+ class EndIter {};
+ // Sentinel type for range-for using FPItemIter.
+ class FPItemEndIter {};
protected:
enum OptimizationFlags : uint32_t {
@@ -472,4 +488,96 @@
GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
+//////////////////////////////////////////////////////////////////////////////
+
+class GrFragmentProcessor::Iter {
+public:
+ explicit Iter(const GrFragmentProcessor& fp) { fFPStack.push_back(&fp); }
+ explicit Iter(const GrPaint&);
+ explicit Iter(const GrProcessorSet&);
+ explicit Iter(const GrPipeline&);
+
+ const GrFragmentProcessor& operator*() const;
+ const GrFragmentProcessor* operator->() const;
+ Iter& operator++();
+ operator bool() const { return !fFPStack.empty(); }
+ bool operator!=(const EndIter&) { return (bool)*this; }
+
+ // Because each iterator carries a stack we want to avoid copies.
+ Iter(const Iter&) = delete;
+ Iter& operator=(const Iter&) = delete;
+
+private:
+ SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Src> class GrFragmentProcessor::IterRange {
+public:
+ explicit IterRange(const Src& t) : fT(t) {}
+ Iter begin() const { return Iter(fT); }
+ EndIter end() const { return EndIter(); }
+
+private:
+ const Src& fT;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Item, GrFragmentProcessor::CountFn Count, GrFragmentProcessor::GetFn<Item> Get>
+class GrFragmentProcessor::FPItemIter {
+public:
+ template <typename Src> explicit FPItemIter(const Src& s);
+
+ std::pair<const Item&, const GrFragmentProcessor&> operator*() const {
+ return {(*fFPIter.*Get)(fIndex), *fFPIter};
+ }
+ FPItemIter& operator++();
+ operator bool() const { return fFPIter; }
+ bool operator!=(const FPItemEndIter&) { return (bool)*this; }
+
+ FPItemIter(const FPItemIter&) = delete;
+ FPItemIter& operator=(const FPItemIter&) = delete;
+
+private:
+ Iter fFPIter;
+ int fIndex;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Src, typename ItemIter> class GrFragmentProcessor::FPItemRange {
+public:
+ FPItemRange(const Src& src) : fSrc(src) {}
+ ItemIter begin() const { return ItemIter(fSrc); }
+ FPItemEndIter end() const { return FPItemEndIter(); }
+
+private:
+ const Src& fSrc;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename Item, GrFragmentProcessor::CountFn Count, GrFragmentProcessor::GetFn<Item> Get>
+template <typename Src>
+GrFragmentProcessor::FPItemIter<Item, Count, Get>::FPItemIter(const Src& s)
+ : fFPIter(s), fIndex(-1) {
+ if (fFPIter) {
+ ++*this;
+ }
+}
+
+template <typename Item, GrFragmentProcessor::CountFn Count, GrFragmentProcessor::GetFn<Item> Get>
+GrFragmentProcessor::FPItemIter<Item, Count, Get>&
+GrFragmentProcessor::FPItemIter<Item, Count, Get>::operator++() {
+ ++fIndex;
+ if (fIndex < ((*fFPIter).*Count)()) {
+ return *this;
+ }
+ fIndex = 0;
+ do {} while (++fFPIter && !((*fFPIter).*Count)());
+ return *this;
+}
+
#endif
diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp
index 8524b72..571ad1c 100644
--- a/src/gpu/GrPathProcessor.cpp
+++ b/src/gpu/GrPathProcessor.cpp
@@ -85,7 +85,7 @@
void setData(const GrGLSLProgramDataManager& pd,
const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
if (pathProc.color() != fColor) {
pd.set4fv(fColorUniform, 1, pathProc.color().vec());
@@ -93,9 +93,9 @@
}
int t = 0;
- while (const GrCoordTransform* coordTransform = transformIter.next()) {
+ for (auto [transform, fp] : transformRange) {
SkASSERT(fInstalledTransforms[t].fHandle.isValid());
- const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
+ const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), transform);
if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
continue;
}
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index e75ac06..f653542 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -111,3 +111,14 @@
b->add32(blendKey);
}
+
+void GrPipeline::visitProxies(const GrOp::VisitProxyFunc& func) const {
+ // This iteration includes any clip coverage FPs
+ for (auto [sampler, fp] : GrFragmentProcessor::PipelineTextureSamplerRange(*this)) {
+ bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
+ func(sampler.proxy(), GrMipMapped(mipped));
+ }
+ if (fDstProxyView.asTextureProxy()) {
+ func(fDstProxyView.asTextureProxy(), GrMipMapped::kNo);
+ }
+}
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index f2a7f81..5921062 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -213,19 +213,7 @@
const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; }
- void visitProxies(const GrOp::VisitProxyFunc& func) const {
- // This iteration includes any clip coverage FPs
- for (int i = 0; i < this->numFragmentProcessors(); ++i) {
- GrFragmentProcessor::TextureAccessIter iter(fFragmentProcessors[i].get());
- while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
- bool mipped = (GrSamplerState::Filter::kMipMap == sampler->samplerState().filter());
- func(sampler->proxy(), GrMipMapped(mipped));
- }
- }
- if (fDstProxyView.asTextureProxy()) {
- func(fDstProxyView.asTextureProxy(), GrMipMapped::kNo);
- }
- }
+ void visitProxies(const GrOp::VisitProxyFunc&) const;
private:
static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp
index cd30a88..cf75415 100644
--- a/src/gpu/GrProcessorSet.cpp
+++ b/src/gpu/GrProcessorSet.cpp
@@ -251,3 +251,10 @@
#endif
return analysis;
}
+
+void GrProcessorSet::visitProxies(const GrOp::VisitProxyFunc& func) const {
+ for (auto [sampler, fp] : GrFragmentProcessor::ProcessorSetTextureSamplerRange(*this)) {
+ bool mipped = (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter());
+ func(sampler.proxy(), GrMipMapped(mipped));
+ }
+}
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 9583864..e155c67 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -153,15 +153,7 @@
SkString dumpProcessors() const;
#endif
- void visitProxies(const GrOp::VisitProxyFunc& func) const {
- for (int i = 0; i < this->numFragmentProcessors(); ++i) {
- GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
- while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
- bool mipped = (GrSamplerState::Filter::kMipMap == sampler->samplerState().filter());
- func(sampler->proxy(), GrMipMapped(mipped));
- }
- }
- }
+ void visitProxies(const GrOp::VisitProxyFunc& func) const;
private:
GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
diff --git a/src/gpu/GrProgramInfo.cpp b/src/gpu/GrProgramInfo.cpp
index e61fff0..2b0fb84 100644
--- a/src/gpu/GrProgramInfo.cpp
+++ b/src/gpu/GrProgramInfo.cpp
@@ -116,12 +116,8 @@
}
}
- GrFragmentProcessor::Iter iter(this->pipeline());
- while (const GrFragmentProcessor* fp = iter.next()) {
- for (int s = 0; s < fp->numTextureSamplers(); ++s) {
- const auto& textureSampler = fp->textureSampler(s);
- assertResolved(textureSampler.peekTexture(), textureSampler.samplerState());
- }
+ for (auto [sampler, fp] : GrFragmentProcessor::PipelineTextureSamplerRange(this->pipeline())) {
+ assertResolved(sampler.peekTexture(), sampler.samplerState());
}
}
diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
index c4f7472..aa99e35 100644
--- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp
+++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp
@@ -17,9 +17,8 @@
#include "src/gpu/ccpr/GrOctoBounds.h"
static bool has_coord_transforms(const GrPaint& paint) {
- GrFragmentProcessor::Iter iter(paint);
- while (const GrFragmentProcessor* fp = iter.next()) {
- if (!fp->coordTransforms().empty()) {
+ for (const auto& fp : GrFragmentProcessor::PaintRange(paint)) {
+ if (!fp.coordTransforms().empty()) {
return true;
}
}
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index 0c97eaf..4c4b300 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -105,12 +105,12 @@
private:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const auto& proc = primProc.cast<GrCCPathProcessor>();
pdman.set2f(fAtlasAdjustUniform,
1.0f / proc.fAtlasDimensions.fWidth,
1.0f / proc.fAtlasDimensions.fHeight);
- this->setTransformDataHelper(proc.fLocalMatrix, pdman, &transformIter);
+ this->setTransformDataHelper(proc.fLocalMatrix, pdman, transformRange);
}
GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform;
diff --git a/src/gpu/ccpr/GrCCStroker.cpp b/src/gpu/ccpr/GrCCStroker.cpp
index ccb687b..000e530 100644
--- a/src/gpu/ccpr/GrCCStroker.cpp
+++ b/src/gpu/ccpr/GrCCStroker.cpp
@@ -89,7 +89,7 @@
class Impl : public GrGLSLGeometryProcessor {
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&&) override {}
+ const CoordTransformRange&) override {}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;
};
@@ -182,7 +182,7 @@
class Impl : public GrGLSLGeometryProcessor {
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&&) override {}
+ const CoordTransformRange&) override {}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override;
};
diff --git a/src/gpu/ccpr/GrGSCoverageProcessor.cpp b/src/gpu/ccpr/GrGSCoverageProcessor.cpp
index b8b8888..320cd0c 100644
--- a/src/gpu/ccpr/GrGSCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrGSCoverageProcessor.cpp
@@ -24,8 +24,8 @@
virtual bool hasCoverage(const GrGSCoverageProcessor& proc) const { return false; }
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& transformIter) final {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ const CoordTransformRange& transformRange) final {
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
diff --git a/src/gpu/ccpr/GrSampleMaskProcessor.cpp b/src/gpu/ccpr/GrSampleMaskProcessor.cpp
index 78c05c3..7c8e9a9 100644
--- a/src/gpu/ccpr/GrSampleMaskProcessor.cpp
+++ b/src/gpu/ccpr/GrSampleMaskProcessor.cpp
@@ -16,7 +16,7 @@
private:
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&&) override {}
+ const CoordTransformRange&) override {}
void onEmitCode(EmitArgs&, GrGPArgs*) override;
diff --git a/src/gpu/ccpr/GrStencilAtlasOp.cpp b/src/gpu/ccpr/GrStencilAtlasOp.cpp
index 0c38f07..2fed59e 100644
--- a/src/gpu/ccpr/GrStencilAtlasOp.cpp
+++ b/src/gpu/ccpr/GrStencilAtlasOp.cpp
@@ -59,7 +59,7 @@
}
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&&) override {}
+ const CoordTransformRange&) override {}
};
GrGLSLPrimitiveProcessor* StencilResolveProcessor::createGLSLInstance(const GrShaderCaps&) const {
diff --git a/src/gpu/ccpr/GrVSCoverageProcessor.cpp b/src/gpu/ccpr/GrVSCoverageProcessor.cpp
index e61c76e..231c046 100644
--- a/src/gpu/ccpr/GrVSCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrVSCoverageProcessor.cpp
@@ -19,8 +19,8 @@
private:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& transformIter) final {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ const CoordTransformRange& transformRange) final {
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
void onEmitCode(EmitArgs&, GrGPArgs*) override;
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index 8ac8fbd..86ea295 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -517,16 +517,12 @@
this->setRenderTargetState(renderTarget, programInfo.origin());
const GrPipeline& pipeline = programInfo.pipeline();
const GrPrimitiveProcessor& primProc = programInfo.primProc();
- fGeometryProcessor->setData(fDataManager, primProc,
- GrFragmentProcessor::CoordTransformIter(pipeline));
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::PipelineCoordTransformRange transformRange(pipeline);
+ fGeometryProcessor->setData(fDataManager, primProc, transformRange);
+ GrFragmentProcessor::Iter fpIter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fDataManager, *fp);
- fp = iter.next();
- glslFP = glslIter.next();
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ glslIter->setData(fDataManager, *fpIter);
}
SkIPoint offset;
GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
@@ -554,17 +550,13 @@
&binding);
}
}
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::Iter fpIter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- auto& s = fp->textureSampler(i);
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
+ auto& s = fpIter->textureSampler(i);
set_texture(gpu, s.samplerState(), s.peekTexture(), &bindings, &binding);
}
- fp = iter.next();
- glslFP = glslIter.next();
}
SkIPoint offset;
if (GrTexture* dstTexture = pipeline.peekDstTexture(&offset)) {
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 37bdae8..9066c40 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -26,7 +26,7 @@
GrProcessorKeyBuilder*);
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const GrConicEffect& ce = primProc.cast<GrConicEffect>();
if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
@@ -45,7 +45,7 @@
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
fCoverageScale = ce.coverageScale();
}
- this->setTransformDataHelper(ce.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(ce.localMatrix(), pdman, transformRange);
}
private:
@@ -278,7 +278,7 @@
GrProcessorKeyBuilder*);
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) {
@@ -297,7 +297,7 @@
pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
fCoverageScale = qe.coverageScale();
}
- this->setTransformDataHelper(qe.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(qe.localMatrix(), pdman, transformRange);
}
private:
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 1cec0a1..5c710cc 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -76,7 +76,7 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
if (btgp.color() != fColor && !btgp.hasVertexColor()) {
pdman.set4fv(fColorUniform, 1, btgp.color().vec());
@@ -92,7 +92,7 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(btgp.localMatrix(), pdman, transformRange);
}
static inline void GenKey(const GrGeometryProcessor& proc,
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 9196449..1122d0e 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -163,7 +163,7 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>();
#ifdef SK_GAMMA_APPLY_TO_A8
@@ -183,7 +183,7 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(dfa8gp.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(dfa8gp.localMatrix(), pdman, transformRange);
}
static inline void GenKey(const GrGeometryProcessor& gp,
@@ -463,8 +463,7 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
- FPCoordTransformIter&& transformIter) override {
-
+ const CoordTransformRange& transformRange) override {
const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
if (dfpgp.matrix().hasPerspective() && !fMatrix.cheapEqualTo(dfpgp.matrix())) {
@@ -484,9 +483,9 @@
}
if (dfpgp.matrix().hasPerspective()) {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
} else {
- this->setTransformDataHelper(dfpgp.matrix(), pdman, &transformIter);
+ this->setTransformDataHelper(dfpgp.matrix(), pdman, transformRange);
}
}
@@ -791,7 +790,7 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& processor,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
SkASSERT(fDistanceAdjustUni.isValid());
const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFieldLCDTextGeoProc>();
@@ -812,7 +811,7 @@
1.0f / atlasDimensions.fHeight);
fAtlasDimensions = atlasDimensions;
}
- this->setTransformDataHelper(dflcd.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(dflcd.localMatrix(), pdman, transformRange);
}
static inline void GenKey(const GrGeometryProcessor& gp,
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index decae06..a1c4c54 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -51,8 +51,8 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
- FPCoordTransformIter&& transformIter) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ const CoordTransformRange& transformRange) override {
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
private:
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index a626f80..7914d77 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -84,8 +84,8 @@
// We must bind to texture units in the same order in which we set the uniforms in
// GrGLProgramDataManager. That is, we bind textures for processors in this order:
// primProc, fragProcs, XP.
- fPrimitiveProcessor->setData(fProgramDataManager, programInfo.primProc(),
- GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
+ GrFragmentProcessor::PipelineCoordTransformRange range(programInfo.pipeline());
+ fPrimitiveProcessor->setData(fProgramDataManager, programInfo.primProc(), range);
if (programInfo.hasFixedPrimProcTextures()) {
this->updatePrimitiveProcessorTextureBindings(programInfo.primProc(),
programInfo.fixedPrimProcTextures());
@@ -118,21 +118,17 @@
}
void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSamplerIdx) {
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::Iter fpIter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fProgramDataManager, *fp);
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ glslIter->setData(fProgramDataManager, *fpIter);
+ for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
+ const GrFragmentProcessor::TextureSampler& sampler = fpIter->textureSampler(i);
fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(), sampler.swizzle(),
static_cast<GrGLTexture*>(sampler.peekTexture()));
}
- fp = iter.next();
- glslFP = glslIter.next();
}
- SkASSERT(!fp && !glslFP);
+ SkASSERT(!fpIter && !glslIter);
}
void GrGLProgram::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin,
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index e5e97de..706e892 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -117,14 +117,26 @@
//////////////////////////////////////////////////////////////////////////////
-GrGLSLFragmentProcessor* GrGLSLFragmentProcessor::Iter::next() {
- if (fFPStack.empty()) {
- return nullptr;
+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* back = fFPStack.back();
+}
+
+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) {
fFPStack.push_back(back->childProcessor(i));
}
- return back;
+ return *this;
}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index ad441d8..df501c2 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -35,7 +35,7 @@
private:
/**
- * This class allows the shader builder to provide each GrGLSLFragmentProcesor with an array of
+ * This class allows the shader builder to provide each GrGLSLFragmentProcessor with an array of
* generated variables where each generated variable corresponds to an element of an array on
* the GrFragmentProcessor that generated the GLSLFP. For example, this is used to provide a
* variable holding transformed coords for each GrCoordTransform owned by the FP.
@@ -54,15 +54,15 @@
BuilderInputProvider childInputs(int childIdx) const {
const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
- GrFragmentProcessor::Iter iter(fFP);
int numToSkip = 0;
- while (true) {
- const GrFragmentProcessor* fp = iter.next();
- if (fp == child) {
+ for (const auto& fp : GrFragmentProcessor::FPRange(*fFP)) {
+ if (&fp == child) {
return BuilderInputProvider(child, fTs + numToSkip);
}
- numToSkip += (fp->*COUNT)();
+ numToSkip += (fp.*COUNT)();
}
+ SK_ABORT("Didn't find the child.");
+ return {nullptr, nullptr};
}
private:
@@ -134,9 +134,7 @@
int numChildProcessors() const { return fChildProcessors.count(); }
- GrGLSLFragmentProcessor* childProcessor(int index) {
- return fChildProcessors[index];
- }
+ GrGLSLFragmentProcessor* childProcessor(int index) const { return fChildProcessors[index]; }
// Invoke the child with the default input color (solid white)
inline void invokeChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs,
@@ -168,17 +166,22 @@
/**
* Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
- * GLSLFPS. This agrees with the traversal order of GrFragmentProcessor::Iter
+ * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
+ * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
+ * a GrPipeline that produces the same program key.
*/
- class Iter : public SkNoncopyable {
+ class Iter {
public:
- explicit Iter(GrGLSLFragmentProcessor* fp) { fFPStack.push_back(fp); }
- explicit Iter(std::unique_ptr<GrGLSLFragmentProcessor> fps[], int cnt) {
- for (int i = cnt - 1; i >= 0; --i) {
- fFPStack.push_back(fps[i].get());
- }
- }
- GrGLSLFragmentProcessor* next();
+ Iter(std::unique_ptr<GrGLSLFragmentProcessor> fps[], int cnt);
+
+ GrGLSLFragmentProcessor& operator*() const;
+ GrGLSLFragmentProcessor* operator->() const;
+ Iter& operator++();
+ operator bool() const { return !fFPStack.empty(); }
+
+ // Because each iterator carries a stack we want to avoid copies.
+ Iter(const Iter&) = delete;
+ Iter& operator=(const Iter&) = delete;
private:
SkSTArray<4, GrGLSLFragmentProcessor*, true> fFPStack;
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index d99239e..adb20fa 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -102,10 +102,10 @@
void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix,
const GrGLSLProgramDataManager& pdman,
- FPCoordTransformIter* transformIter) {
+ const CoordTransformRange& transformRange) {
int i = 0;
- while (const GrCoordTransform* coordTransform = transformIter->next()) {
- const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform);
+ for (auto [transform, fp] : transformRange) {
+ const SkMatrix& m = GetTransformMatrix(localMatrix, transform);
if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) {
pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m);
fInstalledTransforms[i].fCurrentValue = m;
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h
index eb34412..c8f7895 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.h
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h
@@ -26,7 +26,7 @@
// A helper which subclasses can use to upload coord transform matrices in setData().
void setTransformDataHelper(const SkMatrix& localMatrix,
const GrGLSLProgramDataManager& pdman,
- FPCoordTransformIter*);
+ const CoordTransformRange&);
// Emit transformed local coords from the vertex shader as a uniform matrix and varying per
// coord-transform. localCoordsVar must be a 2- or 3-component vector. If it is 3 then it is
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
index 9d35c44..cccbeed 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
@@ -67,12 +67,15 @@
//////////////////////////////////////////////////////////////////////////////
const GrCoordTransform* GrGLSLPrimitiveProcessor::FPCoordTransformHandler::nextCoordTransform() {
-#ifdef SK_DEBUG
SkASSERT(nullptr == fCurr || fAddedCoord);
+ if (!fIter) {
+ return nullptr;
+ }
+ auto [transform, fp] = *fIter;
+ ++fIter;
+#ifdef SK_DEBUG
fAddedCoord = false;
- fCurr = fIter.next();
- return fCurr;
-#else
- return fIter.next();
+ fCurr = &transform;
#endif
+ return &transform;
}
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index 12fb74f..9327d15 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -23,9 +23,9 @@
class GrGLSLPrimitiveProcessor {
public:
- using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
- using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using CoordTransformRange = GrFragmentProcessor::PipelineCoordTransformRange;
struct TransformVar {
TransformVar() = default;
@@ -132,12 +132,13 @@
* GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
* identical processor key as the GrPrimitiveProcessor that created this
* GrGLSLPrimitiveProcessor.
- * The subclass may use the transform iterator to perform any setup required for the particular
- * set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over
- * the transforms in the same order as the TransformHandler passed to emitCode.
+ * The subclass should use the transform range to perform any setup required for the coord
+ * transforms of the FPs that are part of the same program, such as updating matrix uniforms.
+ * The range will iterate over the transforms in the same order as the TransformHandler passed
+ * to emitCode.
*/
virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&&) = 0;
+ const CoordTransformRange&) = 0;
static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&);
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index cb6a6bd..3474380 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -150,9 +150,8 @@
const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i);
output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output,
&glslFragmentProcessors);
- GrFragmentProcessor::Iter iter(&fp);
- while (const GrFragmentProcessor* fp = iter.next()) {
- transformedCoordVarsIdx += fp->numCoordTransforms();
+ for (const auto& subFP : GrFragmentProcessor::FPRange(fp)) {
+ transformedCoordVarsIdx += subFP.numCoordTransforms();
}
**inOut = output;
}
@@ -185,20 +184,18 @@
GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
SkSTArray<4, SamplerHandle> texSamplers;
- GrFragmentProcessor::Iter fpIter(&fp);
int samplerIdx = 0;
- while (const auto* subFP = fpIter.next()) {
- for (int i = 0; i < subFP->numTextureSamplers(); ++i) {
+ for (const auto& subFP : GrFragmentProcessor::FPRange(fp)) {
+ for (int i = 0; i < subFP.numTextureSamplers(); ++i) {
SkString name;
name.printf("TextureSampler_%d", samplerIdx++);
- const auto& sampler = subFP->textureSampler(i);
+ const auto& sampler = subFP.textureSampler(i);
texSamplers.emplace_back(this->emitSampler(sampler.proxy(),
sampler.samplerState(),
sampler.swizzle(),
name.c_str()));
}
}
-
const GrGLSLPrimitiveProcessor::TransformVar* coordVars = fTransformedCoordVars.begin() +
transformedCoordVarsIdx;
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
diff --git a/src/gpu/mtl/GrMtlPipelineState.mm b/src/gpu/mtl/GrMtlPipelineState.mm
index 6f4ae8a..ecc6366 100644
--- a/src/gpu/mtl/GrMtlPipelineState.mm
+++ b/src/gpu/mtl/GrMtlPipelineState.mm
@@ -59,8 +59,8 @@
void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo) {
this->setRenderTargetState(renderTarget, programInfo.origin());
- fGeometryProcessor->setData(fDataManager, programInfo.primProc(),
- GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
+ GrFragmentProcessor::PipelineCoordTransformRange transformRange(programInfo.pipeline());
+ fGeometryProcessor->setData(fDataManager, programInfo.primProc(), transformRange);
if (!programInfo.hasDynamicPrimProcTextures()) {
auto proxies = programInfo.hasFixedPrimProcTextures() ? programInfo.fixedPrimProcTextures()
@@ -89,20 +89,16 @@
fSamplerBindings.emplace_back(sampler.samplerState(), texture, fGpu);
}
- GrFragmentProcessor::Iter iter(programInfo.pipeline());
+ GrFragmentProcessor::Iter fpIter(programInfo.pipeline());
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fDataManager, *fp);
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const auto& sampler = fp->textureSampler(i);
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ glslIter->setData(fDataManager, *fpIter);
+ for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
+ const auto& sampler = fpIter->textureSampler(i);
fSamplerBindings.emplace_back(sampler.samplerState(), sampler.peekTexture(), fGpu);
}
- fp = iter.next();
- glslFP = glslIter.next();
}
- SkASSERT(!fp && !glslFP);
+ SkASSERT(!fpIter && !glslIter);
{
SkIPoint offset;
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index aa48aff..9efdd3a 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -611,9 +611,9 @@
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const QuadEdgeEffect& qe = gp.cast<QuadEdgeEffect>();
- this->setTransformDataHelper(qe.fLocalMatrix, pdman, &transformIter);
+ this->setTransformDataHelper(qe.fLocalMatrix, pdman, transformRange);
}
private:
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index f68a474..ecd5b16 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -820,7 +820,8 @@
GrProcessorKeyBuilder*);
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& transformIter) override;
+ const CoordTransformRange& transformRange) override;
+
private:
UniformHandle fParamUniform;
UniformHandle fColorUniform;
@@ -893,13 +894,13 @@
void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& processor,
- FPCoordTransformIter&& transformIter) {
+ const CoordTransformRange& transformRange) {
const DashingCircleEffect& dce = processor.cast<DashingCircleEffect>();
if (dce.color() != fColor) {
pdman.set4fv(fColorUniform, 1, dce.color().vec());
fColor = dce.color();
}
- this->setTransformDataHelper(dce.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(dce.localMatrix(), pdman, transformRange);
}
void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp,
@@ -1029,7 +1030,7 @@
GrProcessorKeyBuilder*);
void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& iter) override;
+ const CoordTransformRange&) override;
private:
SkPMColor4f fColor;
@@ -1120,13 +1121,13 @@
void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& processor,
- FPCoordTransformIter&& transformIter) {
+ const CoordTransformRange& transformRange) {
const DashingLineEffect& de = processor.cast<DashingLineEffect>();
if (de.color() != fColor) {
pdman.set4fv(fColorUniform, 1, de.color().vec());
fColor = de.color();
}
- this->setTransformDataHelper(de.localMatrix(), pdman, &transformIter);
+ this->setTransformDataHelper(de.localMatrix(), pdman, transformRange);
}
void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp,
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index 5858dc2..e0d3167 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -632,8 +632,8 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& transformIter) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ const CoordTransformRange& transformRange) override {
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
};
@@ -738,8 +738,8 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
- FPCoordTransformIter&& transformIter) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ const CoordTransformRange& transformRange) override {
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
};
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index aac4dd6..b9c11ff 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -47,9 +47,9 @@
class GLSLProcessor : public GrGLSLGeometryProcessor {
public:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const auto& latticeGP = proc.cast<LatticeGP>();
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
fColorSpaceXformHelper.setData(pdman, latticeGP.fColorSpaceXform.get());
}
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 65bd63a..6adb970 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -221,9 +221,9 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
this->setTransformDataHelper(primProc.cast<CircleGeometryProcessor>().fLocalMatrix,
- pdman, &transformIter);
+ pdman, transformRange);
}
private:
@@ -481,10 +481,10 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
this->setTransformDataHelper(
primProc.cast<ButtCapDashedCircleGeometryProcessor>().fLocalMatrix, pdman,
- &transformIter);
+ transformRange);
}
private:
@@ -672,9 +672,9 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const EllipseGeometryProcessor& egp = primProc.cast<EllipseGeometryProcessor>();
- this->setTransformDataHelper(egp.fLocalMatrix, pdman, &transformIter);
+ this->setTransformDataHelper(egp.fLocalMatrix, pdman, transformRange);
}
private:
@@ -868,7 +868,7 @@
}
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>();
if (!diegp.fViewMatrix.isIdentity() && !fViewMatrix.cheapEqualTo(diegp.fViewMatrix)) {
@@ -877,7 +877,7 @@
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
}
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
private:
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index 2726c24..da70bf6 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -575,10 +575,10 @@
class GLSLProcessor : public GrGLSLGeometryProcessor {
public:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
- FPCoordTransformIter&& transformIter) override {
+ const CoordTransformRange& transformRange) override {
const auto& gp = proc.cast<QuadPerEdgeAAGeometryProcessor>();
if (gp.fLocalCoord.isInitialized()) {
- this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ this->setTransformDataHelper(SkMatrix::I(), pdman, transformRange);
}
fTextureColorSpaceXformHelper.setData(pdman, gp.fTextureColorSpaceXform.get());
}
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index 5bbeb6e..6a9ead7 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -575,12 +575,9 @@
}
}
- GrFragmentProcessor::Iter iter(programInfo.pipeline());
- while (const GrFragmentProcessor* fp = iter.next()) {
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
- check_sampled_texture(sampler.peekTexture(), fRenderTarget, fGpu);
- }
+ GrFragmentProcessor::PipelineTextureSamplerRange textureSamplerRange(programInfo.pipeline());
+ for (auto [sampler, fp] : textureSamplerRange) {
+ check_sampled_texture(sampler.peekTexture(), fRenderTarget, fGpu);
}
if (GrTexture* dstTexture = programInfo.pipeline().peekDstTexture()) {
check_sampled_texture(dstTexture, fRenderTarget, fGpu);
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index f41c53d..e2a6fe5 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -103,18 +103,14 @@
GrVkCommandBuffer* commandBuffer) {
this->setRenderTargetState(renderTarget, programInfo.origin());
- fGeometryProcessor->setData(fDataManager, programInfo.primProc(),
- GrFragmentProcessor::CoordTransformIter(programInfo.pipeline()));
- GrFragmentProcessor::Iter iter(programInfo.pipeline());
+ GrFragmentProcessor::PipelineCoordTransformRange transformRange(programInfo.pipeline());
+ fGeometryProcessor->setData(fDataManager, programInfo.primProc(), transformRange);
+ GrFragmentProcessor::Iter fpIter(programInfo.pipeline());
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- glslFP->setData(fDataManager, *fp);
- fp = iter.next();
- glslFP = glslIter.next();
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ glslIter->setData(fDataManager, *fpIter);
}
- SkASSERT(!fp && !glslFP);
+ SkASSERT(!fpIter && !glslIter);
{
SkIPoint offset;
@@ -168,20 +164,16 @@
samplerBindings[currTextureBinding++] = {sampler.samplerState(), texture};
}
- GrFragmentProcessor::Iter iter(pipeline);
+ GrFragmentProcessor::Iter fpIter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
- const GrFragmentProcessor* fp = iter.next();
- GrGLSLFragmentProcessor* glslFP = glslIter.next();
- while (fp && glslFP) {
- for (int i = 0; i < fp->numTextureSamplers(); ++i) {
- const auto& sampler = fp->textureSampler(i);
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ for (int i = 0; i < fpIter->numTextureSamplers(); ++i) {
+ const auto& sampler = fpIter->textureSampler(i);
samplerBindings[currTextureBinding++] =
{sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
}
- fp = iter.next();
- glslFP = glslIter.next();
}
- SkASSERT(!fp && !glslFP);
+ SkASSERT(!fpIter && !glslIter);
if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
samplerBindings[currTextureBinding++] = {