aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/GrPipeline.cpp19
-rw-r--r--src/gpu/GrPipeline.h46
-rw-r--r--src/gpu/GrProgramDesc.cpp8
-rw-r--r--src/gpu/GrXferProcessor.cpp44
-rw-r--r--src/gpu/GrXferProcessor.h54
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.cpp3
-rw-r--r--src/gpu/effects/GrCoverageSetOpXP.h4
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp24
-rw-r--r--src/gpu/effects/GrDisableColorXP.cpp3
-rw-r--r--src/gpu/effects/GrDisableColorXP.h4
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp23
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.h7
-rw-r--r--src/gpu/gl/GrGLProgram.cpp9
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp70
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h12
-rw-r--r--src/gpu/glsl/GrGLSLXferProcessor.cpp21
-rw-r--r--src/gpu/glsl/GrGLSLXferProcessor.h25
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp25
-rw-r--r--src/gpu/vk/GrVkPipelineState.cpp10
-rw-r--r--tests/GrPorterDuffTest.cpp10
20 files changed, 191 insertions, 230 deletions
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 2917dcbe27..960cd8adb3 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -61,18 +61,20 @@ void GrPipeline::init(const InitArgs& args) {
sk_sp<GrXferProcessor> xferProcessor;
const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
if (xpFactory) {
- xferProcessor.reset(xpFactory->createXferProcessor(args.fInputColor,
- args.fInputCoverage, hasMixedSamples,
- &args.fDstTexture, *args.fCaps));
+ xferProcessor.reset(xpFactory->createXferProcessor(
+ args.fInputColor, args.fInputCoverage, hasMixedSamples, *args.fCaps));
SkASSERT(xferProcessor);
} else {
// This may return nullptr in the common case of src-over implemented using hw blending.
xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
- *args.fCaps, args.fInputColor, args.fInputCoverage, hasMixedSamples,
- &args.fDstTexture));
+ *args.fCaps, args.fInputColor, args.fInputCoverage, hasMixedSamples));
}
fXferProcessor.reset(xferProcessor.get());
}
+ if (args.fDstTexture.texture()) {
+ fDstTexture.reset(args.fDstTexture.texture());
+ fDstTextureOffset = args.fDstTexture.offset();
+ }
// This is for the legacy GrPipeline creation in GrLegacyMeshDrawOp where analysis does not
// eliminate fragment processors from GrProcessorSet.
@@ -130,12 +132,9 @@ void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
}
- const GrXferProcessor& xfer = this->getXferProcessor();
-
- for (int i = 0; i < xfer.numTextureSamplers(); ++i) {
- GrTexture* texture = xfer.textureSampler(i).texture();
+ if (fDstTexture) {
SkASSERT(rt->getLastOpList());
- rt->getLastOpList()->addDependency(texture);
+ rt->getLastOpList()->addDependency(fDstTexture.get());
}
}
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index 91cd16456c..d7a4f4ebed 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -144,6 +144,17 @@ public:
}
}
+ /**
+ * If the GrXferProcessor uses a texture to access the dst color, then this returns that
+ * texture and the offset to the dst contents within that texture.
+ */
+ GrTexture* dstTexture(SkIPoint* offset = nullptr) const {
+ if (offset) {
+ *offset = fDstTextureOffset;
+ }
+ return fDstTexture.get();
+ }
+
const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
SkASSERT(idx < this->numColorFragmentProcessors());
return *fFragmentProcessors[idx].get();
@@ -194,7 +205,10 @@ public:
}
GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
- return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
+ if (fDstTexture.get() && fDstTexture.get() == fRenderTarget.get()->asTexture()) {
+ return kTexture_GrXferBarrierType;
+ }
+ return this->getXferProcessor().xferBarrierType(caps);
}
/**
@@ -214,21 +228,25 @@ private:
kStencilEnabled_Flag = 0x40,
};
- typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
- typedef GrPendingProgramElement<const GrFragmentProcessor> PendingFragmentProcessor;
- typedef SkAutoSTArray<8, PendingFragmentProcessor> FragmentProcessorArray;
- typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
- RenderTarget fRenderTarget;
- GrScissorState fScissorState;
- GrWindowRectsState fWindowRectsState;
- const GrUserStencilSettings* fUserStencilSettings;
- uint16_t fDrawFace;
- uint16_t fFlags;
- ProgramXferProcessor fXferProcessor;
- FragmentProcessorArray fFragmentProcessors;
+ using RenderTarget = GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>;
+ using DstTexture = GrPendingIOResource<GrTexture, kRead_GrIOType>;
+ using PendingFragmentProcessor = GrPendingProgramElement<const GrFragmentProcessor>;
+ using FragmentProcessorArray = SkAutoSTArray<8, PendingFragmentProcessor>;
+ using ProgramXferProcessor = GrPendingProgramElement<const GrXferProcessor>;
+
+ DstTexture fDstTexture;
+ SkIPoint fDstTextureOffset;
+ RenderTarget fRenderTarget;
+ GrScissorState fScissorState;
+ GrWindowRectsState fWindowRectsState;
+ const GrUserStencilSettings* fUserStencilSettings;
+ uint16_t fDrawFace;
+ uint16_t fFlags;
+ ProgramXferProcessor fXferProcessor;
+ FragmentProcessorArray fFragmentProcessors;
// This value is also the index in fFragmentProcessors where coverage processors begin.
- int fNumColorProcessors;
+ int fNumColorProcessors;
typedef SkRefCnt INHERITED;
};
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index 0e40a852c4..0b7d2c3d77 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -180,7 +180,13 @@ bool GrProgramDesc::Build(GrProgramDesc* desc,
}
const GrXferProcessor& xp = pipeline.getXferProcessor();
- xp.getGLSLProcessorKey(shaderCaps, &b);
+ const GrSurfaceOrigin* originIfDstTexture = nullptr;
+ GrSurfaceOrigin origin;
+ if (pipeline.dstTexture()) {
+ origin = pipeline.dstTexture()->origin();
+ originIfDstTexture = &origin;
+ }
+ xp.getGLSLProcessorKey(shaderCaps, &b, originIfDstTexture);
if (!gen_meta_key(xp, shaderCaps, 0, &b)) {
desc->key().reset();
return false;
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 839fea621c..b04a5cca06 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -9,25 +9,11 @@
#include "GrPipeline.h"
#include "gl/GrGLCaps.h"
-GrXferProcessor::GrXferProcessor()
- : fWillReadDstColor(false)
- , fDstReadUsesMixedSamples(false)
- , fDstTextureOffset() {
-}
+GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstReadUsesMixedSamples(false) {}
-GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
- bool willReadDstColor,
- bool hasMixedSamples)
- : fWillReadDstColor(willReadDstColor)
- , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
- , fDstTextureOffset() {
- if (dstTexture && dstTexture->texture()) {
- SkASSERT(willReadDstColor);
- fDstTexture.reset(dstTexture->texture());
- fDstTextureOffset = dstTexture->offset();
- this->addTextureSampler(&fDstTexture);
- }
-}
+GrXferProcessor::GrXferProcessor(bool willReadDstColor, bool hasMixedSamples)
+ : fWillReadDstColor(willReadDstColor)
+ , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples) {}
bool GrXferProcessor::hasSecondaryOutput() const {
if (!this->willReadDstColor()) {
@@ -45,13 +31,13 @@ void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
}
}
-void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
+void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b,
+ const GrSurfaceOrigin* originIfDstTexture) const {
uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
if (key) {
- if (const GrTexture* dstTexture = this->getDstTexture()) {
+ if (originIfDstTexture) {
key |= 0x2;
- if (kTopLeft_GrSurfaceOrigin == dstTexture->origin()) {
+ if (kTopLeft_GrSurfaceOrigin == *originIfDstTexture) {
key |= 0x4;
}
}
@@ -63,17 +49,6 @@ void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
this->onGetGLSLProcessorKey(caps, b);
}
-GrXferBarrierType GrXferProcessor::xferBarrierType(const GrRenderTarget* rt,
- const GrCaps& caps) const {
- SkASSERT(rt);
- if (static_cast<const GrSurface*>(rt) == this->getDstTexture()) {
- // Texture barriers are required when a shader reads and renders to the same texture.
- SkASSERT(caps.textureBarrierSupport());
- return kTexture_GrXferBarrierType;
- }
- return this->onXferBarrier(caps);
-}
-
#ifdef SK_DEBUG
static const char* equation_string(GrBlendEquation eq) {
switch (eq) {
@@ -195,8 +170,7 @@ GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties(
GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcessorAnalysisColor& color,
GrProcessorAnalysisCoverage coverage,
bool hasMixedSamples,
- const DstTexture* dstTexture,
const GrCaps& caps) const {
SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
- return this->onCreateXferProcessor(caps, color, coverage, hasMixedSamples, dstTexture);
+ return this->onCreateXferProcessor(caps, color, coverage, hasMixedSamples);
}
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index 596e849826..b65a125ca3 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -97,8 +97,10 @@ public:
/**
* Sets a unique key on the GrProcessorKeyBuilder calls onGetGLSLProcessorKey(...) to get the
* specific subclass's key.
- */
- void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const;
+ */
+ void getGLSLProcessorKey(const GrShaderCaps&,
+ GrProcessorKeyBuilder*,
+ const GrSurfaceOrigin* originIfDstTexture) const;
/** Returns a new instance of the appropriate *GL* implementation class
for the given GrXferProcessor; caller is responsible for deleting
@@ -106,10 +108,13 @@ public:
virtual GrGLSLXferProcessor* createGLSLInstance() const = 0;
/**
- * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType
- * is updated to contain the type of barrier needed.
+ * Returns the barrier type, if any, that this XP will require. Note that the possibility
+ * that a kTexture type barrier is required is handled by the GrPipeline and need not be
+ * considered by subclass overrides of this function.
*/
- GrXferBarrierType xferBarrierType(const GrRenderTarget* rt, const GrCaps& caps) const;
+ virtual GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
+ return kNone_GrXferBarrierType;
+ }
struct BlendInfo {
void reset() {
@@ -134,22 +139,6 @@ public:
bool willReadDstColor() const { return fWillReadDstColor; }
/**
- * Returns the texture to be used as the destination when reading the dst in the fragment
- * shader. If the returned texture is NULL then the XP is either not reading the dst or we have
- * extentions that support framebuffer fetching and thus don't need a copy of the dst texture.
- */
- const GrTexture* getDstTexture() const { return fDstTexture.texture(); }
-
- /**
- * Returns the offset in device coords to use when accessing the dst texture to get the dst
- * pixel color in the shader. This value is only valid if getDstTexture() != NULL.
- */
- const SkIPoint& dstTextureOffset() const {
- SkASSERT(this->getDstTexture());
- return fDstTextureOffset;
- }
-
- /**
* If we are performing a dst read, returns whether the base class will use mixed samples to
* antialias the shader's final output. If not doing a dst read, the subclass is responsible
* for antialiasing and this returns false.
@@ -177,12 +166,6 @@ public:
if (this->fWillReadDstColor != that.fWillReadDstColor) {
return false;
}
- if (this->fDstTexture.texture() != that.fDstTexture.texture()) {
- return false;
- }
- if (this->fDstTextureOffset != that.fDstTextureOffset) {
- return false;
- }
if (this->fDstReadUsesMixedSamples != that.fDstReadUsesMixedSamples) {
return false;
}
@@ -191,7 +174,7 @@ public:
protected:
GrXferProcessor();
- GrXferProcessor(const DstTexture*, bool willReadDstColor, bool hasMixedSamples);
+ GrXferProcessor(bool willReadDstColor, bool hasMixedSamples);
private:
void notifyRefCntIsZero() const final {}
@@ -203,15 +186,6 @@ private:
virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
/**
- * Determines the type of barrier (if any) required by the subclass. Note that the possibility
- * that a kTexture type barrier is required is handled by the base class and need not be
- * considered by subclass overrides of this function.
- */
- virtual GrXferBarrierType onXferBarrier(const GrCaps&) const {
- return kNone_GrXferBarrierType;
- }
-
- /**
* If we are not performing a dst read, returns whether the subclass will set a secondary
* output. When using dst reads, the base class controls the secondary output and this method
* will not be called.
@@ -229,8 +203,6 @@ private:
bool fWillReadDstColor;
bool fDstReadUsesMixedSamples;
- SkIPoint fDstTextureOffset;
- TextureSampler fDstTexture;
typedef GrFragmentProcessor INHERITED;
};
@@ -267,7 +239,6 @@ public:
GrXferProcessor* createXferProcessor(const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
bool hasMixedSamples,
- const DstTexture*,
const GrCaps& caps) const;
enum class AnalysisProperties : unsigned {
@@ -314,8 +285,7 @@ private:
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const DstTexture*) const = 0;
+ bool hasMixedSamples) const = 0;
/**
* Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 1319c1fe58..4d4b00a379 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -221,8 +221,7 @@ const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool inv
GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const DstTexture*) const {
+ bool hasMixedSamples) const {
// We don't support inverting coverage with mixed samples. We don't expect to ever want this in
// the future, however we could at some point make this work using an inverted coverage
// modulation table. Note that an inverted table still won't work if there are coverage procs.
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index 2e1feed01e..a0fe4f9f8a 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -31,8 +31,8 @@ private:
constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
GrXferProcessor* onCreateXferProcessor(const GrCaps&, const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage, bool hasMixedSamples,
- const DstTexture*) const override;
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 5f21c75f11..8d7c410eb7 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -78,10 +78,10 @@ public:
this->initClassID<CustomXP>();
}
- CustomXP(const DstTexture* dstTexture, bool hasMixedSamples, SkBlendMode mode)
- : INHERITED(dstTexture, true, hasMixedSamples),
- fMode(mode),
- fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
+ CustomXP(bool hasMixedSamples, SkBlendMode mode)
+ : INHERITED(true, hasMixedSamples)
+ , fMode(mode)
+ , fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
this->initClassID<CustomXP>();
}
@@ -97,11 +97,11 @@ public:
return fHWBlendEquation;
}
+ GrXferBarrierType xferBarrierType(const GrCaps&) const override;
+
private:
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
- GrXferBarrierType onXferBarrier(const GrCaps&) const override;
-
void onGetBlendInfo(BlendInfo*) const override;
bool onIsEqual(const GrXferProcessor& xpBase) const override;
@@ -187,7 +187,7 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
}
-GrXferBarrierType CustomXP::onXferBarrier(const GrCaps& caps) const {
+GrXferBarrierType CustomXP::xferBarrierType(const GrCaps& caps) const {
if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport()) {
return kBlend_GrXferBarrierType;
}
@@ -214,8 +214,8 @@ public:
private:
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage, bool hasMixedSamples,
- const DstTexture*) const override;
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
@@ -235,14 +235,12 @@ private:
GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const DstTexture* dstTexture) const {
+ bool hasMixedSamples) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
- SkASSERT(!dstTexture || !dstTexture->texture());
return new CustomXP(fMode, fHWBlendEquation);
}
- return new CustomXP(dstTexture, hasMixedSamples, fMode);
+ return new CustomXP(hasMixedSamples, fMode);
}
GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties(
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 4780b28647..917f5c8e01 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -84,8 +84,7 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const
GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor&,
GrProcessorAnalysisCoverage,
- bool hasMixedSamples,
- const DstTexture* dst) const {
+ bool hasMixedSamples) const {
return DisableColorXP::Create();
}
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
index ccd85c773a..b3c4677508 100644
--- a/src/gpu/effects/GrDisableColorXP.h
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -32,8 +32,8 @@ private:
}
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage, bool hasMixedSamples,
- const DstTexture* dstTexture) const override;
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples) const override;
GR_DECLARE_XP_FACTORY_TEST;
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 646f9426fc..da73f4b4d8 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -447,11 +447,8 @@ GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const {
class ShaderPDXferProcessor : public GrXferProcessor {
public:
- ShaderPDXferProcessor(const DstTexture* dstTexture,
- bool hasMixedSamples,
- SkBlendMode xfermode)
- : INHERITED(dstTexture, true, hasMixedSamples)
- , fXfermode(xfermode) {
+ ShaderPDXferProcessor(bool hasMixedSamples, SkBlendMode xfermode)
+ : INHERITED(true, hasMixedSamples), fXfermode(xfermode) {
this->initClassID<ShaderPDXferProcessor>();
}
@@ -702,8 +699,7 @@ const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) {
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor& color,
GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const DstTexture* dstTexture) const {
+ bool hasMixedSamples) const {
BlendFormula blendFormula;
if (coverage == GrProcessorAnalysisCoverage::kLCD) {
if (SkBlendMode::kSrcOver == fBlendMode && color.isConstant() &&
@@ -711,7 +707,6 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps
!caps.shaderCaps()->dstReadInShaderSupport()) {
// If we don't have dual source blending or in shader dst reads, we fall back to this
// trick for rendering SrcOver LCD text instead of doing a dst copy.
- SkASSERT(!dstTexture || !dstTexture->texture());
return PDLCDXferProcessor::Create(fBlendMode, color);
}
blendFormula = get_lcd_blend_formula(fBlendMode);
@@ -722,10 +717,8 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps
}
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
- return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fBlendMode);
+ return new ShaderPDXferProcessor(hasMixedSamples, fBlendMode);
}
-
- SkASSERT(!dstTexture || !dstTexture->texture());
return new PorterDuffXferProcessor(blendFormula);
}
@@ -813,8 +806,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
const GrCaps& caps,
const GrProcessorAnalysisColor& color,
GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const GrXferProcessor::DstTexture* dstTexture) {
+ bool hasMixedSamples) {
// We want to not make an xfer processor if possible. Thus for the simple case where we are not
// doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
// the general case where we convert a src-over blend that has solid coverage and an opaque
@@ -832,17 +824,14 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
// If we don't have dual source blending or in shader dst reads, we fall
// back to this trick for rendering SrcOver LCD text instead of doing a
// dst copy.
- SkASSERT(!dstTexture || !dstTexture->texture());
return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, color);
}
BlendFormula blendFormula;
blendFormula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
- return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
+ return new ShaderPDXferProcessor(hasMixedSamples, SkBlendMode::kSrcOver);
}
-
- SkASSERT(!dstTexture || !dstTexture->texture());
return new PorterDuffXferProcessor(blendFormula);
}
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.h b/src/gpu/effects/GrPorterDuffXferProcessor.h
index d42146a32d..6effc18d4c 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.h
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.h
@@ -26,8 +26,7 @@ public:
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
const GrProcessorAnalysisColor& color,
GrProcessorAnalysisCoverage coverage,
- bool hasMixedSamples,
- const GrXferProcessor::DstTexture*);
+ bool hasMixedSamples);
/** Returns a simple non-LCD porter duff blend XP with no optimizations or coverage. */
static sk_sp<GrXferProcessor> CreateNoCoverageXP(SkBlendMode);
@@ -44,8 +43,8 @@ private:
constexpr GrPorterDuffXPFactory(SkBlendMode);
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrProcessorAnalysisColor&,
- GrProcessorAnalysisCoverage, bool hasMixedSamples,
- const DstTexture*) const override;
+ GrProcessorAnalysisCoverage,
+ bool hasMixedSamples) const override;
AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
const GrProcessorAnalysisCoverage&,
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 2aa572dfcb..29fe35c111 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -78,8 +78,13 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline
this->setFragmentData(primProc, pipeline, &nextSamplerIdx);
const GrXferProcessor& xp = pipeline.getXferProcessor();
- fXferProcessor->setData(fProgramDataManager, xp);
- this->bindTextures(xp, pipeline.getAllowSRGBInputs(), &nextSamplerIdx);
+ SkIPoint offset;
+ GrTexture* dstTexture = pipeline.dstTexture(&offset);
+ fXferProcessor->setData(fProgramDataManager, xp, dstTexture, offset);
+ if (dstTexture) {
+ fGpu->bindTexture(nextSamplerIdx++, GrSamplerParams::ClampNoFilter(), true,
+ static_cast<GrGLTexture*>(dstTexture));
+ }
}
void GrGLProgram::generateMipmaps(const GrPrimitiveProcessor& primProc,
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 1fcf0405f7..4cd4fd6ec5 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -62,7 +62,7 @@ bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage);
this->emitAndInstallFragProcs(inputColor, inputCoverage);
- this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage);
+ this->emitAndInstallXferProc(*inputColor, *inputCoverage);
this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
return this->checkSamplerCounts() && this->checkImageStorageCounts();
@@ -211,13 +211,13 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
fFS.codeAppend("}");
}
-void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
- const GrGLSLExpr4& colorIn,
+void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrGLSLExpr4& colorIn,
const GrGLSLExpr4& coverageIn) {
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
SkASSERT(!fXferProcessor);
+ const GrXferProcessor& xp = fPipeline.getXferProcessor();
fXferProcessor = xp.createGLSLInstance();
// Enable dual source secondary output if we have one
@@ -233,21 +233,28 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
fFS.codeAppend(openBrace.c_str());
- SkSTArray<4, SamplerHandle> texSamplers(xp.numTextureSamplers());
- SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
- SkSTArray<2, ImageStorageHandle> imageStorageArray(xp.numImageStorages());
- this->emitSamplersAndImageStorages(xp, &texSamplers, &bufferSamplers, &imageStorageArray);
+ SamplerHandle dstTextureSamplerHandle;
+ GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin;
+ if (GrTexture* dstTexture = fPipeline.dstTexture()) {
+ // GrProcessor::TextureSampler sampler(dstTexture);
+ SkString name("DstTextureSampler");
+ dstTextureSamplerHandle =
+ this->emitSampler(dstTexture->texturePriv().samplerType(), dstTexture->config(),
+ "DstTextureSampler", kFragment_GrShaderFlag);
+ dstTextureOrigin = dstTexture->origin();
+ SkASSERT(kTextureExternalSampler_GrSLType != dstTexture->texturePriv().samplerType());
+ }
GrGLSLXferProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->shaderCaps(),
- xp, colorIn.c_str(),
+ xp,
+ colorIn.c_str(),
coverageIn.c_str(),
fFS.getPrimaryColorOutputName(),
fFS.getSecondaryColorOutputName(),
- texSamplers.begin(),
- bufferSamplers.begin(),
- imageStorageArray.begin());
+ dstTextureSamplerHandle,
+ dstTextureOrigin);
fXferProcessor->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
@@ -276,11 +283,9 @@ void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
externalFeatureString);
}
- this->emitSampler(samplerType, sampler.texture()->config(), name.c_str(),
- sampler.visibility(), outTexSamplerHandles);
-
+ outTexSamplerHandles->emplace_back(this->emitSampler(
+ samplerType, sampler.texture()->config(), name.c_str(), sampler.visibility()));
}
-
if (int numBuffers = processor.numBuffers()) {
SkASSERT(this->shaderCaps()->texelBufferSupport());
GrShaderFlags texelBufferVisibility = kNone_GrShaderFlags;
@@ -288,8 +293,9 @@ void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
for (int b = 0; b < numBuffers; ++b) {
const GrProcessor::BufferAccess& access = processor.bufferAccess(b);
name.printf("BufferSampler_%d", outBufferSamplerHandles->count());
- this->emitSampler(kBufferSampler_GrSLType, access.texelConfig(), name.c_str(),
- access.visibility(), outBufferSamplerHandles);
+ outBufferSamplerHandles->emplace_back(
+ this->emitSampler(kBufferSampler_GrSLType, access.texelConfig(), name.c_str(),
+ access.visibility()));
texelBufferVisibility |= access.visibility();
}
@@ -303,15 +309,15 @@ void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
for (int i = 0; i < numImageStorages; ++i) {
const GrProcessor::ImageStorageAccess& imageStorageAccess = processor.imageStorageAccess(i);
name.printf("Image_%d", outImageStorageHandles->count());
- this->emitImageStorage(imageStorageAccess, name.c_str(), outImageStorageHandles);
+ outImageStorageHandles->emplace_back(
+ this->emitImageStorage(imageStorageAccess, name.c_str()));
}
}
-void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
- GrPixelConfig config,
- const char* name,
- GrShaderFlags visibility,
- SkTArray<SamplerHandle>* outSamplerHandles) {
+GrGLSLProgramBuilder::SamplerHandle GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
+ GrPixelConfig config,
+ const char* name,
+ GrShaderFlags visibility) {
if (visibility & kVertex_GrShaderFlag) {
++fNumVertexSamplers;
}
@@ -324,16 +330,11 @@ void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
}
GrSLPrecision precision = this->shaderCaps()->samplerPrecision(config, visibility);
GrSwizzle swizzle = this->shaderCaps()->configTextureSwizzle(config);
- outSamplerHandles->emplace_back(this->uniformHandler()->addSampler(visibility,
- swizzle,
- samplerType,
- precision,
- name));
+ return this->uniformHandler()->addSampler(visibility, swizzle, samplerType, precision, name);
}
-void GrGLSLProgramBuilder::emitImageStorage(const GrProcessor::ImageStorageAccess& access,
- const char* name,
- SkTArray<ImageStorageHandle>* outImageStorageHandles) {
+GrGLSLProgramBuilder::ImageStorageHandle GrGLSLProgramBuilder::emitImageStorage(
+ const GrProcessor::ImageStorageAccess& access, const char* name) {
if (access.visibility() & kVertex_GrShaderFlag) {
++fNumVertexImageStorages;
}
@@ -345,10 +346,9 @@ void GrGLSLProgramBuilder::emitImageStorage(const GrProcessor::ImageStorageAcces
++fNumFragmentImageStorages;
}
GrSLType uniformType = access.texture()->texturePriv().imageStorageType();
- ImageStorageHandle handle = this->uniformHandler()->addImageStorage(access.visibility(),
- uniformType, access.format(), access.memoryModel(), access.restrict(), access.ioType(),
- name);
- outImageStorageHandles->emplace_back(handle);
+ return this->uniformHandler()->addImageStorage(access.visibility(), uniformType,
+ access.format(), access.memoryModel(),
+ access.restrict(), access.ioType(), name);
}
void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 748664625f..2d2ab47a5e 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -152,18 +152,14 @@ private:
int transformedCoordVarsIdx,
const GrGLSLExpr4& input,
GrGLSLExpr4* output);
- void emitAndInstallXferProc(const GrXferProcessor&,
- const GrGLSLExpr4& colorIn,
- const GrGLSLExpr4& coverageIn);
+ void emitAndInstallXferProc(const GrGLSLExpr4& colorIn, const GrGLSLExpr4& coverageIn);
void emitSamplersAndImageStorages(const GrProcessor& processor,
SkTArray<SamplerHandle>* outTexSamplerHandles,
SkTArray<SamplerHandle>* outBufferSamplerHandles,
SkTArray<ImageStorageHandle>* outImageStorageHandles);
- void emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
- GrShaderFlags visibility, SkTArray<SamplerHandle >* outSamplerHandles);
- void emitImageStorage(const GrProcessor::ImageStorageAccess&,
- const char* name,
- SkTArray<ImageStorageHandle>* outImageStorageHandles);
+ SamplerHandle emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
+ GrShaderFlags visibility);
+ ImageStorageHandle emitImageStorage(const GrProcessor::ImageStorageAccess&, const char* name);
void emitFSOutputSwizzle(bool hasSecondaryOutput);
bool checkSamplerCounts();
bool checkImageStorageCounts();
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp
index 4101080090..545a9fd1f7 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp
@@ -25,8 +25,8 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
bool needsLocalOutColor = false;
- if (args.fXP.getDstTexture()) {
- bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
+ if (args.fDstTextureSamplerHandle.isValid()) {
+ bool flipY = kBottomLeft_GrSurfaceOrigin == args.fDstTextureOrigin;
if (args.fInputCoverage) {
// We don't think any shaders actually output negative coverage, but just as a safety
@@ -54,12 +54,13 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
fragBuilder->codeAppendf("vec2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
dstTopLeftName, dstCoordScaleName);
- if (!topDown) {
+ if (flipY) {
fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
}
fragBuilder->codeAppendf("vec4 %s = ", dstColor);
- fragBuilder->appendTextureLookup(args.fTexSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
+ fragBuilder->appendTextureLookup(args.fDstTextureSamplerHandle, "_dstTexCoord",
+ kVec2f_GrSLType);
fragBuilder->codeAppend(";");
} else {
needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch();
@@ -85,13 +86,13 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
}
}
-void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
- if (xp.getDstTexture()) {
+void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp,
+ const GrTexture* dstTexture, const SkIPoint& dstTextureOffset) {
+ if (dstTexture) {
if (fDstTopLeftUni.isValid()) {
- pdm.set2f(fDstTopLeftUni, static_cast<float>(xp.dstTextureOffset().fX),
- static_cast<float>(xp.dstTextureOffset().fY));
- pdm.set2f(fDstScaleUni, 1.f / xp.getDstTexture()->width(),
- 1.f / xp.getDstTexture()->height());
+ pdm.set2f(fDstTopLeftUni, static_cast<float>(dstTextureOffset.fX),
+ static_cast<float>(dstTextureOffset.fY));
+ pdm.set2f(fDstScaleUni, 1.f / dstTexture->width(), 1.f / dstTexture->height());
} else {
SkASSERT(!fDstScaleUni.isValid());
}
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.h b/src/gpu/glsl/GrGLSLXferProcessor.h
index b4bde37e30..791bb068e2 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ b/src/gpu/glsl/GrGLSLXferProcessor.h
@@ -8,6 +8,7 @@
#ifndef GrGLSLXferProcessor_DEFINED
#define GrGLSLXferProcessor_DEFINED
+#include "SkPoint.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
@@ -15,14 +16,15 @@ class GrXferProcessor;
class GrGLSLXPBuilder;
class GrGLSLXPFragmentBuilder;
class GrShaderCaps;
+class GrTexture;
class GrGLSLXferProcessor {
public:
GrGLSLXferProcessor() {}
virtual ~GrGLSLXferProcessor() {}
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
- using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
struct EmitArgs {
EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
@@ -33,9 +35,8 @@ public:
const char* inputCoverage,
const char* outputPrimary,
const char* outputSecondary,
- const SamplerHandle* texSamplers,
- const SamplerHandle* bufferSamplers,
- const ImageStorageHandle* imageStorages)
+ const SamplerHandle dstTextureSamplerHandle,
+ GrSurfaceOrigin dstTextureOrigin)
: fXPFragBuilder(fragBuilder)
, fUniformHandler(uniformHandler)
, fShaderCaps(caps)
@@ -44,10 +45,8 @@ public:
, fInputCoverage(inputCoverage)
, fOutputPrimary(outputPrimary)
, fOutputSecondary(outputSecondary)
- , fTexSamplers(texSamplers)
- , fBufferSamplers(bufferSamplers)
- , fImageStorages(imageStorages) {}
-
+ , fDstTextureSamplerHandle(dstTextureSamplerHandle)
+ , fDstTextureOrigin(dstTextureOrigin) {}
GrGLSLXPFragmentBuilder* fXPFragBuilder;
GrGLSLUniformHandler* fUniformHandler;
const GrShaderCaps* fShaderCaps;
@@ -56,9 +55,8 @@ public:
const char* fInputCoverage;
const char* fOutputPrimary;
const char* fOutputSecondary;
- const SamplerHandle* fTexSamplers;
- const SamplerHandle* fBufferSamplers;
- const ImageStorageHandle* fImageStorages;
+ const SamplerHandle fDstTextureSamplerHandle;
+ GrSurfaceOrigin fDstTextureOrigin;
};
/**
* This is similar to emitCode() in the base class, except it takes a full shader builder.
@@ -73,7 +71,8 @@ public:
to have an identical processor key as the one that created this GrGLSLXferProcessor. This
function calls onSetData on the subclass of GrGLSLXferProcessor
*/
- void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp);
+ void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp,
+ const GrTexture* dstTexture, const SkIPoint& dstTextureOffset);
protected:
static void DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index 6b2cd8ec30..8baf60e1e8 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -481,6 +481,17 @@ sk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
return pipelineState;
}
+static void set_texture_layout(GrVkTexture* vkTexture, GrVkGpu* gpu) {
+ // TODO: If we ever decide to create the secondary command buffers ahead of time before we
+ // are actually going to submit them, we will need to track the sampled images and delay
+ // adding the layout change/barrier until we are ready to submit.
+ vkTexture->setImageLayout(gpu,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
+ false);
+}
+
static void prepare_sampled_images(const GrProcessor& processor, GrVkGpu* gpu) {
for (int i = 0; i < processor.numTextureSamplers(); ++i) {
const GrProcessor::TextureSampler& sampler = processor.textureSampler(i);
@@ -501,15 +512,7 @@ static void prepare_sampled_images(const GrProcessor& processor, GrVkGpu* gpu) {
vkTexture->texturePriv().dirtyMipMaps(false);
}
}
-
- // TODO: If we ever decide to create the secondary command buffers ahead of time before we
- // are actually going to submit them, we will need to track the sampled images and delay
- // adding the layout change/barrier until we are ready to submit.
- vkTexture->setImageLayout(gpu,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- VK_ACCESS_SHADER_READ_BIT,
- VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
- false);
+ set_texture_layout(vkTexture, gpu);
}
}
@@ -532,7 +535,9 @@ void GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
while (const GrFragmentProcessor* fp = iter.next()) {
prepare_sampled_images(*fp, fGpu);
}
- prepare_sampled_images(pipeline.getXferProcessor(), fGpu);
+ if (GrVkTexture* dstTexture = static_cast<GrVkTexture*>(pipeline.dstTexture())) {
+ set_texture_layout(dstTexture, fGpu);
+ }
GrPrimitiveType primitiveType = meshes[0].primitiveType();
sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 91fdc3f990..b689866be2 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -214,8 +214,14 @@ void GrVkPipelineState::setData(GrVkGpu* gpu,
}
SkASSERT(!fp && !glslFP);
- fXferProcessor->setData(fDataManager, pipeline.getXferProcessor());
- append_texture_bindings(pipeline.getXferProcessor(), &textureBindings);
+ SkIPoint offset;
+ GrTexture* dstTexture = pipeline.dstTexture(&offset);
+ fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
+ GrProcessor::TextureSampler dstTextureSampler;
+ if (dstTexture) {
+ dstTextureSampler.reset(dstTexture);
+ textureBindings.push_back(&dstTextureSampler);
+ }
// Get new descriptor sets
if (fNumSamplers) {
diff --git a/tests/GrPorterDuffTest.cpp b/tests/GrPorterDuffTest.cpp
index a2ba9167bb..28465c2e81 100644
--- a/tests/GrPorterDuffTest.cpp
+++ b/tests/GrPorterDuffTest.cpp
@@ -66,7 +66,7 @@ public:
fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover();
fIgnoresInputColor = analysis.isInputColorIgnored();
sk_sp<GrXferProcessor> xp(
- xpf->createXferProcessor(inputColor, inputCoverage, false, nullptr, caps));
+ xpf->createXferProcessor(inputColor, inputCoverage, false, caps));
TEST_ASSERT(!analysis.requiresDstTexture());
GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
xp->getBlendInfo(&fBlendInfo);
@@ -992,7 +992,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
GrProcessorAnalysisCoverage coverage = GrProcessorAnalysisCoverage::kLCD;
SkASSERT(!(GrXPFactory::GetAnalysisProperties(xpf, color, coverage, caps) &
GrXPFactory::AnalysisProperties::kRequiresDstTexture));
- sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(color, coverage, false, nullptr, caps));
+ sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(color, coverage, false, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP with LCD coverage.");
return;
@@ -1042,10 +1042,8 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(xfermode);
GrProcessorSet::Analysis analysis;
analysis = GrProcessorSet::Analysis(colorInput, coverageType, xpf, caps);
- GrXferProcessor::DstTexture* dstTexture =
- analysis.requiresDstTexture() ? &fakeDstTexture : nullptr;
- sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(colorInput, coverageType, false,
- dstTexture, caps));
+ sk_sp<GrXferProcessor> xp(
+ xpf->createXferProcessor(colorInput, coverageType, false, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP without dual source blending.");
return;