aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrFragmentProcessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrFragmentProcessor.h')
-rw-r--r--src/gpu/GrFragmentProcessor.h120
1 files changed, 104 insertions, 16 deletions
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index b875c7919f..8a35c57da9 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -24,8 +24,10 @@ class GrSwizzle;
GrCoordTransforms to receive a transformation of the local coordinates that map from local space
to the fragment being processed.
*/
-class GrFragmentProcessor : public GrResourceIOProcessor {
+class GrFragmentProcessor : public GrProcessor {
public:
+ class TextureSampler;
+
/**
* In many instances (e.g. SkShader::asFragmentProcessor() implementations) it is desirable to
* only consider the input color's alpha. However, there is a competing desire to have reusable
@@ -115,6 +117,9 @@ public:
}
}
+ int numTextureSamplers() const { return fTextureSamplerCnt; }
+ const TextureSampler& textureSampler(int i) const;
+
int numCoordTransforms() const { return fCoordTransforms.count(); }
/** Returns the coordinate transformation at index. index must be valid according to
@@ -204,9 +209,8 @@ public:
* 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, typename BASE,
- int (BASE::*COUNT)() const,
- const T& (BASE::*GET)(int) const>
+ template <typename T, int (GrFragmentProcessor::*COUNT)() const,
+ const T& (GrFragmentProcessor::*GET)(int)const>
class FPItemIter : public SkNoncopyable {
public:
explicit FPItemIter(const GrFragmentProcessor* fp)
@@ -243,21 +247,14 @@ public:
};
using CoordTransformIter = FPItemIter<GrCoordTransform,
- GrFragmentProcessor,
&GrFragmentProcessor::numCoordTransforms,
&GrFragmentProcessor::coordTransform>;
using TextureAccessIter = FPItemIter<TextureSampler,
- GrResourceIOProcessor,
- &GrResourceIOProcessor::numTextureSamplers,
- &GrResourceIOProcessor::textureSampler>;
-
- void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) {
- GrFragmentProcessor::TextureAccessIter iter(this);
- while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
- func(sampler->proxy());
- }
- }
+ &GrFragmentProcessor::numTextureSamplers,
+ &GrFragmentProcessor::textureSampler>;
+
+ void visitProxies(const std::function<void(GrSurfaceProxy*)>& func);
protected:
enum OptimizationFlags : uint32_t {
@@ -337,6 +334,22 @@ protected:
*/
int registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child);
+ void setTextureSamplerCnt(int cnt) {
+ SkASSERT(cnt >= 0);
+ fTextureSamplerCnt = cnt;
+ }
+
+ /**
+ * Helper for implementing onTextureSampler(). E.g.:
+ * return IthTexureSampler(i, fMyFirstSampler, fMySecondSampler, fMyThirdSampler);
+ */
+ template <typename... Args>
+ static const TextureSampler& IthTextureSampler(int i, const TextureSampler& samp0,
+ const Args&... samps) {
+ return (0 == i) ? samp0 : IthTextureSampler(i - 1, samps...);
+ }
+ inline static const TextureSampler& IthTextureSampler(int i);
+
private:
virtual GrColor4f constantOutputForConstantInput(GrColor4f /* inputColor */) const {
SK_ABORT("Subclass must override this if advertising this optimization.");
@@ -359,6 +372,8 @@ private:
*/
virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
+ virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
+
bool hasSameTransforms(const GrFragmentProcessor&) const;
enum PrivateFlags {
@@ -368,13 +383,86 @@ private:
mutable uint32_t fFlags = 0;
+ int fTextureSamplerCnt = 0;
+
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
SkSTArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
- typedef GrResourceIOProcessor INHERITED;
+ typedef GrProcessor INHERITED;
};
+/**
+ * Used to represent a texture that is required by a GrFragmentProcessor. It holds a GrTextureProxy
+ * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
+ * account for texture origin.
+ */
+class GrFragmentProcessor::TextureSampler {
+public:
+ TextureSampler() = default;
+
+ /**
+ * This copy constructor is used by GrFragmentProcessor::clone() implementations. The copy
+ * always takes a new ref on the texture proxy as the new fragment processor will not yet be
+ * in pending execution state.
+ */
+ explicit TextureSampler(const TextureSampler& that)
+ : fProxyRef(sk_ref_sp(that.fProxyRef.get()), that.fProxyRef.ioType())
+ , fSamplerState(that.fSamplerState) {}
+
+ TextureSampler(sk_sp<GrTextureProxy>, const GrSamplerState&);
+
+ explicit TextureSampler(sk_sp<GrTextureProxy>,
+ GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
+ GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp);
+
+ TextureSampler& operator=(const TextureSampler&) = delete;
+
+ void reset(sk_sp<GrTextureProxy>, const GrSamplerState&);
+ void reset(sk_sp<GrTextureProxy>,
+ GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
+ GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp);
+
+ bool operator==(const TextureSampler& that) const {
+ return this->proxy()->underlyingUniqueID() == that.proxy()->underlyingUniqueID() &&
+ fSamplerState == that.fSamplerState;
+ }
+
+ bool operator!=(const TextureSampler& other) const { return !(*this == other); }
+
+ // 'instantiate' should only ever be called at flush time.
+ bool instantiate(GrResourceProvider* resourceProvider) const {
+ return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
+ }
+
+ // 'peekTexture' should only ever be called after a successful 'instantiate' call
+ GrTexture* peekTexture() const {
+ SkASSERT(fProxyRef.get()->priv().peekTexture());
+ return fProxyRef.get()->priv().peekTexture();
+ }
+
+ GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); }
+ const GrSamplerState& samplerState() const { return fSamplerState; }
+
+ bool isInitialized() const { return SkToBool(fProxyRef.get()); }
+ /**
+ * For internal use by GrFragmentProcessor.
+ */
+ const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; }
+
+private:
+ GrSurfaceProxyRef fProxyRef;
+ GrSamplerState fSamplerState;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::IthTextureSampler(int i) {
+ SK_ABORT("Illegal texture sampler index");
+ static const TextureSampler kBogus;
+ return kBogus;
+}
+
GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
#endif