aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/private/GrSurfaceProxyRef.h28
-rw-r--r--src/effects/imagefilters/SkDisplacementMapEffect.cpp2
-rw-r--r--src/gpu/GrFragmentProcessor.cpp63
-rw-r--r--src/gpu/GrFragmentProcessor.h120
-rw-r--r--src/gpu/GrPipeline.cpp2
-rw-r--r--src/gpu/GrPrimitiveProcessor.cpp68
-rw-r--r--src/gpu/GrPrimitiveProcessor.h101
-rw-r--r--src/gpu/GrProcessor.cpp77
-rw-r--r--src/gpu/GrProcessor.h122
-rw-r--r--src/gpu/GrProcessorSet.h2
-rw-r--r--src/gpu/GrProgramDesc.cpp59
-rw-r--r--src/gpu/ccpr/GrCCClipProcessor.cpp2
-rw-r--r--src/gpu/gl/GrGLProgram.cpp60
-rw-r--r--src/gpu/gl/GrGLProgram.h9
-rw-r--r--src/gpu/glsl/GrGLSLFragmentProcessor.h10
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp45
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h2
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp54
-rw-r--r--src/gpu/vk/GrVkPipelineState.cpp53
-rw-r--r--src/gpu/vk/GrVkPipelineState.h9
-rw-r--r--tests/LazyProxyTest.cpp2
21 files changed, 501 insertions, 389 deletions
diff --git a/include/private/GrSurfaceProxyRef.h b/include/private/GrSurfaceProxyRef.h
index 38d5827614..fb2ed3746a 100644
--- a/include/private/GrSurfaceProxyRef.h
+++ b/include/private/GrSurfaceProxyRef.h
@@ -15,7 +15,17 @@ class GrSurfaceProxy;
class GrSurfaceProxyRef : SkNoncopyable {
public:
- virtual ~GrSurfaceProxyRef();
+ GrSurfaceProxyRef();
+
+ /** ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ GrSurfaceProxyRef(sk_sp<GrSurfaceProxy>, GrIOType);
+
+ ~GrSurfaceProxyRef();
+
+ /** ioType expresses what type of IO operations will be marked as
+ pending on the resource when markPendingIO is called. */
+ void setProxy(sk_sp<GrSurfaceProxy>, GrIOType);
GrSurfaceProxy* get() const { return fProxy; }
@@ -30,18 +40,6 @@ public:
is called. */
void reset();
-protected:
- GrSurfaceProxyRef();
-
- /** ioType expresses what type of IO operations will be marked as
- pending on the resource when markPendingIO is called. */
- GrSurfaceProxyRef(sk_sp<GrSurfaceProxy>, GrIOType);
-
- /** ioType expresses what type of IO operations will be marked as
- pending on the resource when markPendingIO is called. */
- void setProxy(sk_sp<GrSurfaceProxy>, GrIOType);
-
-private:
/** Called by owning GrProgramElement when the program element is first scheduled for
execution. It can only be called once. */
void markPendingIO() const;
@@ -58,9 +56,7 @@ private:
called. */
void pendingIOComplete() const;
- friend class GrResourceIOProcessor;
- friend class GrOpList; // for setProxy
-
+private:
GrSurfaceProxy* fProxy;
mutable bool fOwnRef;
mutable bool fPendingIO;
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index 2ab8c5e051..356e82ed09 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -546,7 +546,7 @@ void GrGLDisplacementMapEffect::emitCode(EmitArgs& args) {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("\t\thalf4 %s = ", dColor);
fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fTransformedCoords[0].c_str(),
- args.fTransformedCoords[0].getType());
+ args.fTransformedCoords[0].getType());
fragBuilder->codeAppend(";\n");
// Unpremultiply the displacement
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 63dc39c36b..081aff31f8 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -19,10 +19,17 @@
#include "glsl/GrGLSLUniformHandler.h"
bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
- if (this->classID() != that.classID() ||
- !this->hasSameSamplers(that)) {
+ if (this->classID() != that.classID()) {
return false;
}
+ if (this->numTextureSamplers() != that.numTextureSamplers()) {
+ return false;
+ }
+ for (int i = 0; i < this->numTextureSamplers(); ++i) {
+ if (this->textureSampler(i) != that.textureSampler(i)) {
+ return false;
+ }
+ }
if (!this->hasSameTransforms(that)) {
return false;
}
@@ -40,6 +47,13 @@ bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
return true;
}
+void GrFragmentProcessor::visitProxies(const std::function<void(GrSurfaceProxy*)>& func) {
+ GrFragmentProcessor::TextureAccessIter iter(this);
+ while (const TextureSampler* sampler = iter.next()) {
+ func(sampler->proxy());
+ }
+}
+
GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
@@ -49,6 +63,11 @@ GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
return glFragProc;
}
+const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::textureSampler(int i) const {
+ SkASSERT(i >= 0 && i < fTextureSamplerCnt);
+ return this->onTextureSampler(i);
+}
+
void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
fCoordTransforms.push_back(transform);
fFlags |= kUsesLocalCoords_Flag;
@@ -56,8 +75,10 @@ void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
}
bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const {
- if (!INHERITED::instantiate(resourceProvider)) {
- return false;
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ if (!this->textureSampler(i).instantiate(resourceProvider)) {
+ return false;
+ }
}
for (int i = 0; i < this->numChildProcessors(); ++i) {
@@ -70,8 +91,11 @@ bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) cons
}
void GrFragmentProcessor::markPendingExecution() const {
- INHERITED::addPendingIOs();
- INHERITED::removeRefs();
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ auto* proxy = this->textureSampler(i).programProxy();
+ proxy->markPendingIO();
+ proxy->removeRef();
+ }
for (int i = 0; i < this->numChildProcessors(); ++i) {
this->childProcessor(i).markPendingExecution();
}
@@ -499,3 +523,30 @@ const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
return back;
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
+ const GrSamplerState& samplerState) {
+ this->reset(std::move(proxy), samplerState);
+}
+
+GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
+ GrSamplerState::Filter filterMode,
+ GrSamplerState::WrapMode wrapXAndY) {
+ this->reset(std::move(proxy), filterMode, wrapXAndY);
+}
+
+void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
+ const GrSamplerState& samplerState) {
+ fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
+ fSamplerState = samplerState;
+ fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode()));
+}
+
+void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
+ GrSamplerState::Filter filterMode,
+ GrSamplerState::WrapMode wrapXAndY) {
+ fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
+ filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
+ fSamplerState = GrSamplerState(wrapXAndY, filterMode);
+}
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
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 6608d7c7d2..50545644a4 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -80,7 +80,7 @@ GrPipeline::GrPipeline(const InitArgs& args,
void GrPipeline::addDependenciesTo(GrOpList* opList, const GrCaps& caps) const {
for (int i = 0; i < fFragmentProcessors.count(); ++i) {
GrFragmentProcessor::TextureAccessIter iter(fFragmentProcessors[i].get());
- while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
+ while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
opList->addDependency(sampler->proxy(), caps);
}
}
diff --git a/src/gpu/GrPrimitiveProcessor.cpp b/src/gpu/GrPrimitiveProcessor.cpp
index db79fb1052..10b13370f4 100644
--- a/src/gpu/GrPrimitiveProcessor.cpp
+++ b/src/gpu/GrPrimitiveProcessor.cpp
@@ -17,7 +17,12 @@ enum MatrixType {
kGeneral_MatrixType = 1,
};
-GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrResourceIOProcessor(classID) {}
+GrPrimitiveProcessor::GrPrimitiveProcessor(ClassID classID) : GrProcessor(classID) {}
+
+const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::textureSampler(int i) const {
+ SkASSERT(i >= 0 && i < this->numTextureSamplers());
+ return this->onTextureSampler(i);
+}
const GrPrimitiveProcessor::Attribute& GrPrimitiveProcessor::vertexAttribute(int i) const {
SkASSERT(i >= 0 && i < this->numVertexAttributes());
@@ -69,6 +74,33 @@ size_t GrPrimitiveProcessor::debugOnly_instanceAttributeOffset(int i) const {
}
#endif
+void GrPrimitiveProcessor::addPendingIOs() const {
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ this->textureSampler(i).programProxy()->markPendingIO();
+ }
+}
+
+void GrPrimitiveProcessor::removeRefs() const {
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ this->textureSampler(i).programProxy()->removeRef();
+ }
+}
+
+void GrPrimitiveProcessor::pendingIOComplete() const {
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ this->textureSampler(i).programProxy()->pendingIOComplete();
+ }
+}
+
+bool GrPrimitiveProcessor::instantiate(GrResourceProvider* resourceProvider) const {
+ for (int i = 0; i < fTextureSamplerCnt; ++i) {
+ if (!this->textureSampler(i).instantiate(resourceProvider)) {
+ return false;
+ }
+ }
+ return true;
+}
+
uint32_t
GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
int numCoords) const {
@@ -87,3 +119,37 @@ GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, tr
}
return totalKey;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+GrPrimitiveProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
+ const GrSamplerState& samplerState,
+ GrShaderFlags visibility) {
+ this->reset(std::move(proxy), samplerState, visibility);
+}
+
+GrPrimitiveProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
+ GrSamplerState::Filter filterMode,
+ GrSamplerState::WrapMode wrapXAndY,
+ GrShaderFlags visibility) {
+ this->reset(std::move(proxy), filterMode, wrapXAndY, visibility);
+}
+
+void GrPrimitiveProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
+ const GrSamplerState& samplerState,
+ GrShaderFlags visibility) {
+ fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
+ fSamplerState = samplerState;
+ fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode()));
+ fVisibility = visibility;
+}
+
+void GrPrimitiveProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
+ GrSamplerState::Filter filterMode,
+ GrSamplerState::WrapMode wrapXAndY,
+ GrShaderFlags visibility) {
+ fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
+ filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
+ fSamplerState = GrSamplerState(wrapXAndY, filterMode);
+ fVisibility = visibility;
+}
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index cc24b64a87..d5d5d5f747 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -40,8 +40,10 @@ class GrGLSLPrimitiveProcessor;
* GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
* pipelines, and they must provide some notion of equality
*/
-class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
+class GrPrimitiveProcessor : public GrProcessor, public GrProgramElement {
public:
+ class TextureSampler;
+
/** Describes a vertex or instance attribute. */
class Attribute {
public:
@@ -70,6 +72,8 @@ public:
GrPrimitiveProcessor(ClassID);
+ int numTextureSamplers() const { return fTextureSamplerCnt; }
+ const TextureSampler& textureSampler(int index) const;
int numVertexAttributes() const { return fVertexAttributeCnt; }
const Attribute& vertexAttribute(int i) const;
int numInstanceAttributes() const { return fInstanceAttributeCnt; }
@@ -131,27 +135,112 @@ public:
virtual float getSampleShading() const { return 0.0; }
+ bool instantiate(GrResourceProvider*) const;
+
protected:
- void setVertexAttributeCnt(int cnt) { fVertexAttributeCnt = cnt; }
- void setInstanceAttributeCnt(int cnt) { fInstanceAttributeCnt = cnt; }
+ void setVertexAttributeCnt(int cnt) {
+ SkASSERT(cnt >= 0);
+ fVertexAttributeCnt = cnt;
+ }
+ void setInstanceAttributeCnt(int cnt) {
+ SkASSERT(cnt >= 0);
+ fInstanceAttributeCnt = cnt;
+ }
+ 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:
- void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
- void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
- void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
+ void addPendingIOs() const final;
+ void removeRefs() const final;
+ void pendingIOComplete() const final;
void notifyRefCntIsZero() const final {}
virtual const Attribute& onVertexAttribute(int) const = 0;
virtual const Attribute& onInstanceAttribute(int) const = 0;
+ virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
int fVertexAttributeCnt = 0;
int fInstanceAttributeCnt = 0;
+ int fTextureSamplerCnt = 0;
typedef GrProcessor INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
/**
+ * Used to represent a texture that is required by a GrPrimitiveProcessor. It holds a GrTextureProxy
+ * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
+ * account for texture origin.
+ */
+class GrPrimitiveProcessor::TextureSampler {
+public:
+ TextureSampler() = default;
+
+ TextureSampler(sk_sp<GrTextureProxy>, const GrSamplerState&, GrShaderFlags visibility);
+
+ explicit TextureSampler(sk_sp<GrTextureProxy>,
+ GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
+ GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
+ GrShaderFlags visibility = kFragment_GrShaderFlag);
+
+ TextureSampler(const TextureSampler&) = delete;
+ TextureSampler& operator=(const TextureSampler&) = delete;
+
+ void reset(sk_sp<GrTextureProxy>, const GrSamplerState&,
+ GrShaderFlags visibility = kFragment_GrShaderFlag);
+ void reset(sk_sp<GrTextureProxy>,
+ GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
+ GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
+ GrShaderFlags visibility = kFragment_GrShaderFlag);
+
+ 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(); }
+ GrShaderFlags visibility() const { return fVisibility; }
+ const GrSamplerState& samplerState() const { return fSamplerState; }
+
+ bool isInitialized() const { return SkToBool(fProxyRef.get()); }
+ /**
+ * For internal use by GrPrimitiveProcessor.
+ */
+ const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; }
+
+private:
+ GrSurfaceProxyRef fProxyRef;
+ GrSamplerState fSamplerState;
+ GrShaderFlags fVisibility = kNone_GrShaderFlags;
+};
+
+const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::IthTextureSampler(int i) {
+ SK_ABORT("Illegal texture sampler index");
+ static const TextureSampler kBogus;
+ return kBogus;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
* Returns the size of the attrib type in bytes.
* This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
* with C++11.
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 43b4213dc1..aba8d9b4ae 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -125,80 +125,3 @@ void* GrProcessor::operator new(size_t size) { return MemoryPoolAccessor().pool(
void GrProcessor::operator delete(void* target) {
return MemoryPoolAccessor().pool()->release(target);
}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrResourceIOProcessor::addPendingIOs() const {
- for (int i = 0; i < fNumTextureSamplers; ++i) {
- this->textureSampler(i).programProxy()->markPendingIO();
- }
-}
-
-void GrResourceIOProcessor::removeRefs() const {
- for (int i = 0; i < fNumTextureSamplers; ++i) {
- this->textureSampler(i).programProxy()->removeRef();
- }
-}
-
-void GrResourceIOProcessor::pendingIOComplete() const {
- for (int i = 0; i < fNumTextureSamplers; ++i) {
- this->textureSampler(i).programProxy()->pendingIOComplete();
- }
-}
-
-bool GrResourceIOProcessor::instantiate(GrResourceProvider* resourceProvider) const {
- for (int i = 0; i < fNumTextureSamplers; ++i) {
- if (!this->textureSampler(i).instantiate(resourceProvider)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool GrResourceIOProcessor::hasSameSamplers(const GrResourceIOProcessor& that) const {
- if (this->numTextureSamplers() != that.numTextureSamplers()) {
- return false;
- }
- for (int i = 0; i < this->numTextureSamplers(); ++i) {
- if (this->textureSampler(i) != that.textureSampler(i)) {
- return false;
- }
- }
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-GrResourceIOProcessor::TextureSampler::TextureSampler() {}
-
-GrResourceIOProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
- const GrSamplerState& samplerState) {
- this->reset(std::move(proxy), samplerState);
-}
-
-GrResourceIOProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
- GrSamplerState::Filter filterMode,
- GrSamplerState::WrapMode wrapXAndY,
- GrShaderFlags visibility) {
- this->reset(std::move(proxy), filterMode, wrapXAndY, visibility);
-}
-
-void GrResourceIOProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
- const GrSamplerState& samplerState,
- GrShaderFlags visibility) {
- fSamplerState = samplerState;
- fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
- fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode()));
- fVisibility = visibility;
-}
-
-void GrResourceIOProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
- GrSamplerState::Filter filterMode,
- GrSamplerState::WrapMode wrapXAndY,
- GrShaderFlags visibility) {
- fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
- filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
- fSamplerState = GrSamplerState(wrapXAndY, filterMode);
- fVisibility = visibility;
-}
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index f4a1e1682b..1c0161a811 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -196,126 +196,4 @@ private:
ClassID fClassID;
};
-/** A GrProcessor with the ability to access textures, buffers, and image storages. */
-class GrResourceIOProcessor : public GrProcessor {
-public:
- class TextureSampler;
-
- int numTextureSamplers() const { return fNumTextureSamplers; }
-
- /** Gets a TextureSampler which is a combination of a GrTextureProxy and how it is sampled.
- * index must be valid according to numTextureSamplers(). */
- const TextureSampler& textureSampler(int index) const {
- SkASSERT(index >= 0 && index < fNumTextureSamplers);
- return this->onTextureSampler(index);
- }
-
- bool instantiate(GrResourceProvider* resourceProvider) const;
-
-protected:
- 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);
-
- GrResourceIOProcessor(ClassID classID) : INHERITED(classID) {}
-
- void setTextureSamplerCnt(int numTextureSamplers) {
- SkASSERT(numTextureSamplers >= 0);
- fNumTextureSamplers = numTextureSamplers;
- }
-
- bool hasSameSamplers(const GrResourceIOProcessor&) const;
-
- // These methods can be used by derived classes that also derive from GrProgramElement.
- void addPendingIOs() const;
- void removeRefs() const;
- void pendingIOComplete() const;
-
-private:
- virtual const TextureSampler& onTextureSampler(int index) const { return IthTextureSampler(0); }
-
- int fNumTextureSamplers = 0;
- typedef GrProcessor INHERITED;
-};
-
-/**
- * Used to represent a texture that is required by a GrResourceIOProcessor. It holds a GrTexture
- * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
- * account for texture origin.
- */
-class GrResourceIOProcessor::TextureSampler {
-public:
- /**
- * Must be initialized before adding to a GrProcessor's texture access list.
- */
- TextureSampler();
- /**
- * 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)
- , fVisibility(that.fVisibility) {}
-
- TextureSampler(sk_sp<GrTextureProxy>, const GrSamplerState&);
-
- explicit TextureSampler(sk_sp<GrTextureProxy>,
- GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
- GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
- GrShaderFlags visibility = kFragment_GrShaderFlag);
-
- TextureSampler& operator=(const TextureSampler&) = delete;
-
- void reset(sk_sp<GrTextureProxy>, const GrSamplerState&,
- GrShaderFlags visibility = kFragment_GrShaderFlag);
- void reset(sk_sp<GrTextureProxy>,
- GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
- GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
- GrShaderFlags visibility = kFragment_GrShaderFlag);
-
- bool operator==(const TextureSampler& that) const {
- return this->proxy()->underlyingUniqueID() == that.proxy()->underlyingUniqueID() &&
- fSamplerState == that.fSamplerState && fVisibility == that.fVisibility;
- }
-
- 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(); }
- GrShaderFlags visibility() const { return fVisibility; }
- const GrSamplerState& samplerState() const { return fSamplerState; }
-
- bool isInitialized() const { return SkToBool(fProxyRef.get()); }
- /**
- * For internal use by GrProcessor.
- */
- const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; }
-
-private:
- GrSurfaceProxyRef fProxyRef;
- GrSamplerState fSamplerState;
- GrShaderFlags fVisibility;
-};
-
-const GrResourceIOProcessor::TextureSampler& GrResourceIOProcessor::IthTextureSampler(int i) {
- SK_ABORT("Illegal texture sampler index");
- static const TextureSampler kBogus;
- return kBogus;
-}
-
#endif
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 05d0a59ab2..5dd1c4876e 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -155,7 +155,7 @@ public:
void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) const {
for (int i = 0; i < this->numFragmentProcessors(); ++i) {
GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
- while (const GrResourceIOProcessor::TextureSampler* sampler = iter.next()) {
+ while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
func(sampler->proxy());
}
}
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index b0396f9c37..e99a947d80 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -49,21 +49,39 @@ static uint16_t sampler_key(GrTextureType textureType, GrPixelConfig config,
(GrSLSamplerPrecision(config) << (8 + kSamplerOrImageTypeKeyBits)));
}
-static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourceIOProcessor& proc,
- const GrShaderCaps& caps) {
- int numTextureSamplers = proc.numTextureSamplers();
+static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrFragmentProcessor& fp,
+ const GrShaderCaps& caps) {
+ int numTextureSamplers = fp.numTextureSamplers();
// Need two bytes per key.
int word32Count = (numTextureSamplers + 1) / 2;
if (0 == word32Count) {
return;
}
uint16_t* k16 = reinterpret_cast<uint16_t*>(b->add32n(word32Count));
- int j = 0;
- for (int i = 0; i < numTextureSamplers; ++i, ++j) {
- const GrResourceIOProcessor::TextureSampler& sampler = proc.textureSampler(i);
+ for (int i = 0; i < numTextureSamplers; ++i) {
+ const GrFragmentProcessor::TextureSampler& sampler = fp.textureSampler(i);
const GrTexture* tex = sampler.peekTexture();
+ k16[i] = sampler_key(tex->texturePriv().textureType(), tex->config(), caps);
+ }
+ // zero the last 16 bits if the number of uniforms for samplers is odd.
+ if (numTextureSamplers & 0x1) {
+ k16[numTextureSamplers] = 0;
+ }
+}
- k16[j] = sampler_key(tex->texturePriv().textureType(), tex->config(), caps);
+static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrPrimitiveProcessor& pp,
+ const GrShaderCaps& caps) {
+ int numTextureSamplers = pp.numTextureSamplers();
+ // Need two bytes per key.
+ int word32Count = (numTextureSamplers + 1) / 2;
+ if (0 == word32Count) {
+ return;
+ }
+ uint16_t* k16 = reinterpret_cast<uint16_t*>(b->add32n(word32Count));
+ for (int i = 0; i < numTextureSamplers; ++i) {
+ const GrPrimitiveProcessor::TextureSampler& sampler = pp.textureSampler(i);
+ const GrTexture* tex = sampler.peekTexture();
+ k16[i] = sampler_key(tex->texturePriv().textureType(), tex->config(), caps);
}
// zero the last 16 bits if the number of uniforms for samplers is odd.
if (numTextureSamplers & 0x1) {
@@ -80,12 +98,33 @@ static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrResourc
* transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share this
* function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
*/
-static bool gen_meta_key(const GrResourceIOProcessor& proc,
+static bool gen_meta_key(const GrFragmentProcessor& fp,
+ const GrShaderCaps& shaderCaps,
+ uint32_t transformKey,
+ GrProcessorKeyBuilder* b) {
+ size_t processorKeySize = b->size();
+ uint32_t classID = fp.classID();
+
+ // Currently we allow 16 bits for the class id and the overall processor key size.
+ static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)UINT16_MAX);
+ if ((processorKeySize | classID) & kMetaKeyInvalidMask) {
+ return false;
+ }
+
+ add_sampler_keys(b, fp, shaderCaps);
+
+ uint32_t* key = b->add32n(2);
+ key[0] = (classID << 16) | SkToU32(processorKeySize);
+ key[1] = transformKey;
+ return true;
+}
+
+static bool gen_meta_key(const GrPrimitiveProcessor& pp,
const GrShaderCaps& shaderCaps,
uint32_t transformKey,
GrProcessorKeyBuilder* b) {
size_t processorKeySize = b->size();
- uint32_t classID = proc.classID();
+ uint32_t classID = pp.classID();
// Currently we allow 16 bits for the class id and the overall processor key size.
static const uint32_t kMetaKeyInvalidMask = ~((uint32_t)UINT16_MAX);
@@ -93,7 +132,7 @@ static bool gen_meta_key(const GrResourceIOProcessor& proc,
return false;
}
- add_sampler_and_image_keys(b, proc, shaderCaps);
+ add_sampler_keys(b, pp, shaderCaps);
uint32_t* key = b->add32n(2);
key[0] = (classID << 16) | SkToU32(processorKeySize);
diff --git a/src/gpu/ccpr/GrCCClipProcessor.cpp b/src/gpu/ccpr/GrCCClipProcessor.cpp
index 0c1f0e8459..864ac58596 100644
--- a/src/gpu/ccpr/GrCCClipProcessor.cpp
+++ b/src/gpu/ccpr/GrCCClipProcessor.cpp
@@ -21,7 +21,7 @@ GrCCClipProcessor::GrCCClipProcessor(const GrCCClipPath* clipPath, MustCheckBoun
, fMustCheckBounds((bool)mustCheckBounds)
, fOverrideFillType(overrideFillType)
, fAtlasAccess(sk_ref_sp(fClipPath->atlasLazyProxy()), GrSamplerState::Filter::kNearest,
- GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag) {
+ GrSamplerState::WrapMode::kClamp) {
this->setTextureSamplerCnt(1);
}
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 52d53bde95..a392bc26f0 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -84,9 +84,13 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
int nextTexSamplerIdx = 0;
fPrimitiveProcessor->setData(fProgramDataManager, primProc,
GrFragmentProcessor::CoordTransformIter(pipeline));
- this->bindTextures(primProc, &nextTexSamplerIdx);
+ for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+ const GrPrimitiveProcessor::TextureSampler& sampler = primProc.textureSampler(i);
+ fGpu->bindTexture(nextTexSamplerIdx++, sampler.samplerState(),
+ static_cast<GrGLTexture*>(sampler.peekTexture()));
+ }
- this->setFragmentData(primProc, pipeline, &nextTexSamplerIdx);
+ this->setFragmentData(pipeline, &nextTexSamplerIdx);
const GrXferProcessor& xp = pipeline.getXferProcessor();
SkIPoint offset;
@@ -102,31 +106,47 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline) {
- this->generateMipmaps(primProc);
+ auto genLevelsIfNeeded = [this](GrTexture* tex, const GrSamplerState& sampler) {
+ if (sampler.filter() == GrSamplerState::Filter::kMipMap &&
+ tex->texturePriv().mipMapped() == GrMipMapped::kYes &&
+ tex->texturePriv().mipMapsAreDirty()) {
+ SkASSERT(fGpu->caps()->mipMapSupport());
+ fGpu->regenerateMipMapLevels(static_cast<GrGLTexture*>(tex));
+ }
+ };
+
+ for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+ const auto& textureSampler = primProc.textureSampler(i);
+ genLevelsIfNeeded(textureSampler.peekTexture(), textureSampler.samplerState());
+ }
GrFragmentProcessor::Iter iter(pipeline);
while (const GrFragmentProcessor* fp = iter.next()) {
- this->generateMipmaps(*fp);
+ for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+ const auto& textureSampler = fp->textureSampler(i);
+ genLevelsIfNeeded(textureSampler.peekTexture(), textureSampler.samplerState());
+ }
}
}
-void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc,
- const GrPipeline& pipeline,
- int* nextTexSamplerIdx) {
+void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSamplerIdx) {
GrFragmentProcessor::Iter iter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
const GrFragmentProcessor* fp = iter.next();
GrGLSLFragmentProcessor* glslFP = glslIter.next();
while (fp && glslFP) {
glslFP->setData(fProgramDataManager, *fp);
- this->bindTextures(*fp, nextTexSamplerIdx);
+ for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+ const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
+ fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(),
+ static_cast<GrGLTexture*>(sampler.peekTexture()));
+ }
fp = iter.next();
glslFP = glslIter.next();
}
SkASSERT(!fp && !glslFP);
}
-
void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
const GrRenderTargetProxy* proxy) {
GrRenderTarget* rt = proxy->priv().peekRenderTarget();
@@ -156,25 +176,3 @@ void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
size, proxy->origin());
}
}
-
-void GrGLProgram::bindTextures(const GrResourceIOProcessor& processor,
- int* nextTexSamplerIdx) {
- for (int i = 0; i < processor.numTextureSamplers(); ++i) {
- const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
- fGpu->bindTexture((*nextTexSamplerIdx)++, sampler.samplerState(),
- static_cast<GrGLTexture*>(sampler.peekTexture()));
- }
-}
-
-void GrGLProgram::generateMipmaps(const GrResourceIOProcessor& processor) {
- for (int i = 0; i < processor.numTextureSamplers(); ++i) {
- const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
- auto* tex = sampler.peekTexture();
- if (sampler.samplerState().filter() == GrSamplerState::Filter::kMipMap &&
- tex->texturePriv().mipMapped() == GrMipMapped::kYes &&
- tex->texturePriv().mipMapsAreDirty()) {
- SkASSERT(fGpu->caps()->mipMapSupport());
- fGpu->regenerateMipMapLevels(static_cast<GrGLTexture*>(sampler.peekTexture()));
- }
- }
-}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index a8a3391adc..25b6e9a84e 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -19,7 +19,6 @@ class GrGLSLXferProcessor;
class GrPipeline;
class GrPrimitiveProcessor;
class GrRenderTargetProxy;
-class GrResourceIOProcessor;
/**
* This class manages a GPU program and records per-program information. It also records the vertex
@@ -140,17 +139,11 @@ public:
private:
// A helper to loop over effects, set the transforms (via subclass) and bind textures
- void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextTexSamplerIdx);
+ void setFragmentData(const GrPipeline&, int* nextTexSamplerIdx);
// Helper for setData() that sets the view matrix and loads the render target height uniform
void setRenderTargetState(const GrPrimitiveProcessor&, const GrRenderTargetProxy*);
- // Helper for setData() that binds textures to the appropriate texture units
- void bindTextures(const GrResourceIOProcessor&, int* nextSamplerIdx);
-
- // Helper for generateMipmaps() that ensures mipmaps are up to date
- void generateMipmaps(const GrResourceIOProcessor&);
-
// these reflect the current values of uniforms (GL uniform values travel with program)
RenderTargetState fRenderTargetState;
GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index 8f903755ea..591146e925 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -38,7 +38,7 @@ private:
* 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.
*/
- template <typename T, typename FPBASE, int (FPBASE::*COUNT)() const>
+ template <typename T, int (GrFragmentProcessor::*COUNT)() const>
class BuilderInputProvider {
public:
BuilderInputProvider(const GrFragmentProcessor* fp, const T* ts) : fFP(fp) , fTs(ts) {}
@@ -67,10 +67,10 @@ private:
};
public:
- using TransformedCoordVars = BuilderInputProvider<GrShaderVar, GrFragmentProcessor,
- &GrFragmentProcessor::numCoordTransforms>;
- using TextureSamplers = BuilderInputProvider<SamplerHandle, GrResourceIOProcessor,
- &GrResourceIOProcessor::numTextureSamplers>;
+ using TransformedCoordVars =
+ BuilderInputProvider<GrShaderVar, &GrFragmentProcessor::numCoordTransforms>;
+ using TextureSamplers =
+ BuilderInputProvider<SamplerHandle, &GrFragmentProcessor::numTextureSamplers>;
/** Called when the program stage should insert its code into the shaders. The code in each
shader will be in its own block ({}) and so locally scoped names will not collide across
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 05b78eef0c..b0cf8169d4 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -96,8 +96,15 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
SkASSERT(!fGeometryProcessor);
fGeometryProcessor.reset(proc.createGLSLInstance(*this->shaderCaps()));
- SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
- this->emitSamplers(proc, &texSamplers);
+ SkAutoSTMalloc<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
+ for (int i = 0; i < proc.numTextureSamplers(); ++i) {
+ SkString name;
+ name.printf("TextureSampler_%d", i);
+ const auto& sampler = proc.textureSampler(i);
+ GrTextureType textureType = sampler.peekTexture()->texturePriv().textureType();
+ texSamplers[i] = this->emitSampler(textureType, sampler.peekTexture()->config(),
+ name.c_str(), sampler.visibility());
+ }
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
&fTransformedCoordVars);
@@ -111,7 +118,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
outputColor->c_str(),
outputCoverage->c_str(),
rtAdjustName,
- texSamplers.begin(),
+ texSamplers.get(),
&transformHandler);
fGeometryProcessor->emitCode(args);
@@ -168,15 +175,23 @@ SkString GrGLSLProgramBuilder::emitAndInstallFragProc(
GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
- SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers());
- GrFragmentProcessor::Iter iter(&fp);
- while (const GrFragmentProcessor* subFP = iter.next()) {
- this->emitSamplers(*subFP, &textureSamplerArray);
+ 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) {
+ SkString name;
+ name.printf("TextureSampler_%d", samplerIdx++);
+ const auto& sampler = subFP->textureSampler(i);
+ GrTextureType textureType = sampler.peekTexture()->texturePriv().textureType();
+ texSamplers.emplace_back(this->emitSampler(textureType, sampler.peekTexture()->config(),
+ name.c_str(), kFragment_GrShaderFlag));
+ }
}
const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
- GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin());
+ GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, texSamplers.begin());
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->shaderCaps(),
@@ -250,20 +265,6 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
fFS.codeAppend("}");
}
-void GrGLSLProgramBuilder::emitSamplers(
- const GrResourceIOProcessor& processor,
- SkTArray<SamplerHandle>* outTexSamplerHandles) {
- SkString name;
- int numTextureSamplers = processor.numTextureSamplers();
- for (int t = 0; t < numTextureSamplers; ++t) {
- const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(t);
- name.printf("TextureSampler_%d", outTexSamplerHandles->count());
- GrTextureType textureType = sampler.peekTexture()->texturePriv().textureType();
- outTexSamplerHandles->emplace_back(this->emitSampler(
- textureType, sampler.peekTexture()->config(), name.c_str(), sampler.visibility()));
- }
-}
-
void GrGLSLProgramBuilder::updateSamplerCounts(GrShaderFlags visibility) {
if (visibility & kVertex_GrShaderFlag) {
++fNumVertexSamplers;
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index bdc39c00dd..8d263b8e00 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -135,8 +135,6 @@ private:
SkString output,
SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>*);
void emitAndInstallXferProc(const SkString& colorIn, const SkString& coverageIn);
- void emitSamplers(const GrResourceIOProcessor& processor,
- SkTArray<SamplerHandle>* outTexSamplerHandles);
SamplerHandle emitSampler(GrTextureType, GrPixelConfig, const char* name,
GrShaderFlags visibility);
void emitFSOutputSwizzle(bool hasSecondaryOutput);
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index d58a8b5ff7..013c1d7815 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -608,31 +608,6 @@ GrVkPipelineState* GrVkGpuRTCommandBuffer::prepareDrawState(
return pipelineState;
}
-static void prepare_sampled_images(const GrResourceIOProcessor& processor,
- SkTArray<GrVkImage*>* sampledImages,
- GrVkGpu* gpu) {
- for (int i = 0; i < processor.numTextureSamplers(); ++i) {
- const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(i);
- GrVkTexture* vkTexture = static_cast<GrVkTexture*>(sampler.peekTexture());
-
- // We may need to resolve the texture first if it is also a render target
- GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
- if (texRT) {
- gpu->onResolveRenderTarget(texRT);
- }
-
- // Check if we need to regenerate any mip maps
- if (GrSamplerState::Filter::kMipMap == sampler.samplerState().filter() &&
- (vkTexture->width() != 1 || vkTexture->height() != 1)) {
- SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes);
- if (vkTexture->texturePriv().mipMapsAreDirty()) {
- gpu->regenerateMipMapLevels(vkTexture);
- }
- }
- sampledImages->push_back(vkTexture);
- }
-}
-
void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState,
@@ -648,10 +623,35 @@ void GrVkGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
- prepare_sampled_images(primProc, &cbInfo.fSampledImages, fGpu);
+ auto prepareSampledImage = [&](GrTexture* texture, GrSamplerState::Filter filter) {
+ GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture);
+ // We may need to resolve the texture first if it is also a render target
+ GrVkRenderTarget* texRT = static_cast<GrVkRenderTarget*>(vkTexture->asRenderTarget());
+ if (texRT) {
+ fGpu->onResolveRenderTarget(texRT);
+ }
+
+ // Check if we need to regenerate any mip maps
+ if (GrSamplerState::Filter::kMipMap == filter &&
+ (vkTexture->width() != 1 || vkTexture->height() != 1)) {
+ SkASSERT(vkTexture->texturePriv().mipMapped() == GrMipMapped::kYes);
+ if (vkTexture->texturePriv().mipMapsAreDirty()) {
+ fGpu->regenerateMipMapLevels(vkTexture);
+ }
+ }
+ cbInfo.fSampledImages.push_back(vkTexture);
+ };
+
+ for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+ const GrPrimitiveProcessor::TextureSampler& sampler = primProc.textureSampler(i);
+ prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter());
+ }
GrFragmentProcessor::Iter iter(pipeline);
while (const GrFragmentProcessor* fp = iter.next()) {
- prepare_sampled_images(*fp, &cbInfo.fSampledImages, fGpu);
+ for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+ const GrFragmentProcessor::TextureSampler& sampler = fp->textureSampler(i);
+ prepareSampledImage(sampler.peekTexture(), sampler.samplerState().filter());
+ }
}
if (GrTexture* dstTexture = pipeline.peekDstTexture()) {
cbInfo.fSampledImages.push_back(static_cast<GrVkTexture*>(dstTexture));
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 9080128bef..8870f41e86 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -165,19 +165,6 @@ void GrVkPipelineState::abandonGPUResources() {
}
}
-static void append_texture_bindings(
- const GrResourceIOProcessor& processor,
- SkTArray<const GrResourceIOProcessor::TextureSampler*>* textureBindings) {
- if (int numTextureSamplers = processor.numTextureSamplers()) {
- const GrResourceIOProcessor::TextureSampler** bindings =
- textureBindings->push_back_n(numTextureSamplers);
- int i = 0;
- do {
- bindings[i] = &processor.textureSampler(i);
- } while (++i < numTextureSamplers);
- }
-}
-
void GrVkPipelineState::setData(GrVkGpu* gpu,
const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline) {
@@ -187,11 +174,16 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
this->setRenderTargetState(pipeline.proxy());
- SkSTArray<8, const GrResourceIOProcessor::TextureSampler*> textureBindings;
+ SkAutoSTMalloc<8, SamplerBindings> samplerBindings(fNumSamplers);
+ int currTextureBinding = 0;
fGeometryProcessor->setData(fDataManager, primProc,
GrFragmentProcessor::CoordTransformIter(pipeline));
- append_texture_bindings(primProc, &textureBindings);
+ for (int i = 0; i < primProc.numTextureSamplers(); ++i) {
+ const auto& sampler = primProc.textureSampler(i);
+ samplerBindings[currTextureBinding++] = {sampler.samplerState(),
+ static_cast<GrVkTexture*>(sampler.peekTexture())};
+ }
GrFragmentProcessor::Iter iter(pipeline);
GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
@@ -199,7 +191,11 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
GrGLSLFragmentProcessor* glslFP = glslIter.next();
while (fp && glslFP) {
glslFP->setData(fDataManager, *fp);
- append_texture_bindings(*fp, &textureBindings);
+ for (int i = 0; i < fp->numTextureSamplers(); ++i) {
+ const auto& sampler = fp->textureSampler(i);
+ samplerBindings[currTextureBinding++] =
+ {sampler.samplerState(), static_cast<GrVkTexture*>(sampler.peekTexture())};
+ }
fp = iter.next();
glslFP = glslIter.next();
}
@@ -212,16 +208,14 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
}
- GrResourceProvider* resourceProvider = gpu->getContext()->contextPriv().resourceProvider();
-
- GrResourceIOProcessor::TextureSampler dstTextureSampler;
if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
- dstTextureSampler.reset(sk_ref_sp(dstTextureProxy));
- SkAssertResult(dstTextureSampler.instantiate(resourceProvider));
- textureBindings.push_back(&dstTextureSampler);
+ samplerBindings[currTextureBinding++] =
+ {GrSamplerState::ClampNearest(),
+ static_cast<GrVkTexture*>(dstTextureProxy->priv().peekTexture())};
}
// Get new descriptor sets
+ SkASSERT(fNumSamplers == currTextureBinding);
if (fNumSamplers) {
if (fSamplerDescriptorSet) {
fSamplerDescriptorSet->recycle(gpu);
@@ -229,7 +223,7 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
- this->writeSamplers(gpu, textureBindings);
+ this->writeSamplers(gpu, samplerBindings.get());
}
if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
@@ -307,15 +301,10 @@ void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
}
}
-void GrVkPipelineState::writeSamplers(
- GrVkGpu* gpu,
- const SkTArray<const GrResourceIOProcessor::TextureSampler*>& textureBindings) {
- SkASSERT(fNumSamplers == textureBindings.count());
-
- for (int i = 0; i < textureBindings.count(); ++i) {
- GrSamplerState state = textureBindings[i]->samplerState();
-
- GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->peekTexture());
+void GrVkPipelineState::writeSamplers(GrVkGpu* gpu, const SamplerBindings bindings[]) {
+ for (int i = 0; i < fNumSamplers; ++i) {
+ const GrSamplerState& state = bindings[i].fState;
+ GrVkTexture* texture = bindings[i].fTexture;
fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(
state, texture->texturePriv().maxMipMapLevel()));
diff --git a/src/gpu/vk/GrVkPipelineState.h b/src/gpu/vk/GrVkPipelineState.h
index a3320e5550..1df4bb5348 100644
--- a/src/gpu/vk/GrVkPipelineState.h
+++ b/src/gpu/vk/GrVkPipelineState.h
@@ -25,6 +25,7 @@ class GrVkImageView;
class GrVkPipeline;
class GrVkPipelineLayout;
class GrVkSampler;
+class GrVkTexture;
class GrVkUniformBuffer;
/**
@@ -72,9 +73,11 @@ public:
private:
void writeUniformBuffers(const GrVkGpu* gpu);
- void writeSamplers(
- GrVkGpu* gpu,
- const SkTArray<const GrResourceIOProcessor::TextureSampler*>& textureBindings);
+ struct SamplerBindings {
+ GrSamplerState fState;
+ GrVkTexture* fTexture;
+ };
+ void writeSamplers(GrVkGpu* gpu, const SamplerBindings[]);
/**
* We use the RT's size and origin to adjust from Skia device space to vulkan normalized device
diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp
index 4a82d10760..3881251f6c 100644
--- a/tests/LazyProxyTest.cpp
+++ b/tests/LazyProxyTest.cpp
@@ -137,7 +137,7 @@ public:
kBottomLeft_GrSurfaceOrigin,
kAlpha_half_GrPixelConfig, *proxyProvider->caps());
fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
- GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag);
+ GrSamplerState::WrapMode::kClamp);
this->setTextureSamplerCnt(1);
}