diff options
-rw-r--r-- | src/gpu/GrPipeline.cpp | 19 | ||||
-rw-r--r-- | src/gpu/GrPipeline.h | 46 | ||||
-rw-r--r-- | src/gpu/GrProgramDesc.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrXferProcessor.cpp | 44 | ||||
-rw-r--r-- | src/gpu/GrXferProcessor.h | 54 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrCoverageSetOpXP.h | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 24 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.h | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 23 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.h | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 9 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLProgramBuilder.cpp | 70 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLProgramBuilder.h | 12 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLXferProcessor.cpp | 21 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLXferProcessor.h | 25 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpuCommandBuffer.cpp | 25 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineState.cpp | 10 | ||||
-rw-r--r-- | tests/GrPorterDuffTest.cpp | 10 |
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; |