aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-04-03 16:57:43 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-03 21:35:47 +0000
commit18dfa980765bee6a1ce7c5f430cb32f487da6590 (patch)
treef82444c520111b4710746480652fde74d2db3815
parentb9c4a6fc7de252633f16d11c2df10ee6de16af03 (diff)
Store the dst texture used by an XP in GrPipeline rather than in the XP.
This will allow the XP to be created before the dst texture. Change-Id: I3e5bdfa8e5d47e58a3560792ce5cf3899d30a024 Reviewed-on: https://skia-review.googlesource.com/11011 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
-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;