From 5be6c95fa95a518ab109339df4695d6dda6e2419 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Fri, 20 Jan 2017 19:06:29 +0000 Subject: [PATCH] Revert "Revert "Make it possible to query GrXPFactory for dst texture without GrPipelineAnalysis."" This reverts commit 3329cceab5feca230df1caee16be045249228dc1. Reason for revert: Bot failures are unrelated to the original change. Change-Id: I21b5927dc4384a25930bdefe16e57bcc9276ffa4 Reviewed-on: https://skia-review.googlesource.com/7347 Commit-Queue: Brian Salomon Reviewed-by: Brian Salomon --- include/gpu/GrXferProcessor.h | 27 +++++++++++++--- include/gpu/effects/GrCoverageSetOpXP.h | 4 +-- include/gpu/effects/GrPorterDuffXferProcessor.h | 2 +- src/gpu/GrXferProcessor.cpp | 41 ++++++++++++++++++++--- src/gpu/effects/GrCustomXfermode.cpp | 22 +++++++------ src/gpu/effects/GrDisableColorXP.h | 6 ++-- src/gpu/effects/GrPorterDuffXferProcessor.cpp | 43 ++++++++++++------------- 7 files changed, 97 insertions(+), 48 deletions(-) diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h index 17cd2c7..353c682 100644 --- a/include/gpu/GrXferProcessor.h +++ b/include/gpu/GrXferProcessor.h @@ -307,6 +307,16 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); class GrXPFactory { public: typedef GrXferProcessor::DstTexture DstTexture; + + /** Describes known properties of a draw's color input to the GrXferProcessor. */ + enum class ColorType { kUnknown, kOpaqueConstant, kConstant, kOpaque }; + + /** + * Indicates whether a draw's coverage input to the GrXferProcessor is solid, single channel + * or LCD (four channel coverage). + */ + enum class CoverageType { kNone, kSingleChannel, kLCD }; + GrXferProcessor* createXferProcessor(const GrPipelineAnalysis&, bool hasMixedSamples, const DstTexture*, @@ -329,24 +339,33 @@ public: virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, InvariantBlendedColor*) const = 0; - bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) const; + bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const; protected: constexpr GrXPFactory() {} + static bool ColorTypeIsOpaque(ColorType type) { + return ColorType::kOpaqueConstant == type || ColorType::kOpaque == type; + } + + static bool ColorTypeIsConstant(ColorType type) { + return ColorType::kOpaqueConstant == type || ColorType::kConstant == type; + } + private: virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis&, bool hasMixedSamples, const DstTexture*) const = 0; - bool willReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const; + bool willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const; /** * Returns true if the XP generated by this factory will explicitly read dst in the fragment - * shader. + * shader. This will not be called for draws that read from PLS since the dst color is always + * available in such draws. */ - virtual bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const = 0; + virtual bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const = 0; }; #if defined(__GNUC__) || defined(__clang) #pragma GCC diagnostic pop diff --git a/include/gpu/effects/GrCoverageSetOpXP.h b/include/gpu/effects/GrCoverageSetOpXP.h index ca71abc..385cad8 100644 --- a/include/gpu/effects/GrCoverageSetOpXP.h +++ b/include/gpu/effects/GrCoverageSetOpXP.h @@ -40,9 +40,7 @@ private: bool hasMixedSamples, const DstTexture*) const override; - bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override { - return false; - } + bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override { return false; } GR_DECLARE_XP_FACTORY_TEST; diff --git a/include/gpu/effects/GrPorterDuffXferProcessor.h b/include/gpu/effects/GrPorterDuffXferProcessor.h index ca14275..028cac6 100644 --- a/include/gpu/effects/GrPorterDuffXferProcessor.h +++ b/include/gpu/effects/GrPorterDuffXferProcessor.h @@ -63,7 +63,7 @@ private: bool hasMixedSamples, const DstTexture*) const override; - bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override; + bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override; GR_DECLARE_XP_FACTORY_TEST; static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary); diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index 7de0d77..d88259d 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp @@ -180,6 +180,40 @@ SkString GrXferProcessor::BlendInfo::dump() const { /////////////////////////////////////////////////////////////////////////////// +using ColorType = GrXPFactory::ColorType; +using CoverageType = GrXPFactory::CoverageType; + +ColorType analysis_color_type(const GrPipelineAnalysis& analysis) { + if (analysis.fColorPOI.validFlags() == kRGBA_GrColorComponentFlags) { + return GrColorIsOpaque(analysis.fColorPOI.color()) ? ColorType::kOpaqueConstant + : ColorType::kConstant; + } + if ((analysis.fColorPOI.validFlags() & kA_GrColorComponentFlag) && + GrColorIsOpaque(analysis.fColorPOI.color())) { + return ColorType::kOpaque; + } + return ColorType::kUnknown; +} + +CoverageType analysis_coverage_type(const GrPipelineAnalysis& analysis) { + if (analysis.fCoveragePOI.isSolidWhite()) { + return CoverageType::kNone; + } + if (analysis.fCoveragePOI.isLCDCoverage()) { + return CoverageType::kLCD; + } + return CoverageType::kSingleChannel; +} + +bool GrXPFactory::willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { + if (analysis.fUsesPLSDstRead) { + return true; + } + ColorType colorType = analysis_color_type(analysis); + CoverageType coverageType = analysis_coverage_type(analysis); + return this->willReadDstColor(caps, colorType, coverageType); +} + GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& analysis, bool hasMixedSamples, const DstTexture* dstTexture, @@ -200,9 +234,6 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& anal } bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { - return (this->willReadDstColor(caps, analysis) && !caps.shaderCaps()->dstReadInShaderSupport()); -} - -bool GrXPFactory::willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { - return analysis.fUsesPLSDstRead || this->onWillReadDstColor(caps, analysis); + return !analysis.fUsesPLSDstRead && !caps.shaderCaps()->dstReadInShaderSupport() && + this->willReadDstColor(caps, analysis); } diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 070fa2f..f8af7db 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -54,15 +54,16 @@ static constexpr GrBlendEquation hw_blend_equation(SkBlendMode mode) { } static bool can_use_hw_blend_equation(GrBlendEquation equation, - const GrPipelineAnalysis& analysis, + bool usePLSRead, + bool isLCDCoverage, const GrCaps& caps) { if (!caps.advancedBlendEquationSupport()) { return false; } - if (analysis.fUsesPLSDstRead) { + if (usePLSRead) { return false; } - if (analysis.fCoveragePOI.isLCDCoverage()) { + if (isLCDCoverage) { return false; // LCD coverage must be applied after the blend equation. } if (caps.canUseAdvancedBlendEquation(equation)) { @@ -340,8 +341,7 @@ private: bool hasMixedSamples, const DstTexture*) const override; - bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override; - + bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override; GR_DECLARE_XP_FACTORY_TEST; @@ -359,16 +359,20 @@ GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps, bool hasMixedSamples, const DstTexture* dstTexture) const { SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); - if (can_use_hw_blend_equation(fHWBlendEquation, analysis, caps)) { + if (can_use_hw_blend_equation(fHWBlendEquation, analysis.fUsesPLSDstRead, + analysis.fCoveragePOI.isLCDCoverage(), caps)) { SkASSERT(!dstTexture || !dstTexture->texture()); return new CustomXP(fMode, fHWBlendEquation); } return new CustomXP(dstTexture, hasMixedSamples, fMode); } -bool CustomXPFactory::onWillReadDstColor(const GrCaps& caps, - const GrPipelineAnalysis& analysis) const { - return !can_use_hw_blend_equation(fHWBlendEquation, analysis, caps); +bool CustomXPFactory::willReadDstColor(const GrCaps& caps, ColorType colorType, + CoverageType coverageType) const { + // This should not be called if we're using PLS dst read. + static constexpr bool kUsesPLSRead = false; + return !can_use_hw_blend_equation(fHWBlendEquation, kUsesPLSRead, + CoverageType::kLCD == coverageType, caps); } void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index 9f56ae5..f027e3c 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -32,15 +32,13 @@ public: private: constexpr GrDisableColorXPFactory() {} + bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override { return false; } + GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysis&, bool hasMixedSamples, const DstTexture* dstTexture) const override; - bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override { - return false; - } - GR_DECLARE_XP_FACTORY_TEST; typedef GrXPFactory INHERITED; diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 7f40906..59710eb 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -320,21 +320,17 @@ static const BlendFormula gLCDBlendTable[(int)SkBlendMode::kLastCoeffMode + 1] = /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), }; -static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, +static BlendFormula get_blend_formula(bool isOpaque, + bool hasCoverage, bool hasMixedSamples, SkBlendMode xfermode) { SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); - SkASSERT(!coveragePOI.isLCDCoverage()); - - bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples; - return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][(int)xfermode]; + bool conflatesCoverage = hasCoverage || hasMixedSamples; + return gBlendTable[isOpaque][conflatesCoverage][(int)xfermode]; } -static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI, - SkBlendMode xfermode) { +static BlendFormula get_lcd_blend_formula(SkBlendMode xfermode) { SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); - SkASSERT(coveragePOI.isLCDCoverage()); return gLCDBlendTable[(int)xfermode]; } @@ -759,9 +755,10 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps SkASSERT(!dstTexture || !dstTexture->texture()); return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI); } - blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode); + blendFormula = get_lcd_blend_formula(fBlendMode); } else { - blendFormula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, hasMixedSamples, + blendFormula = get_blend_formula(analysis.fColorPOI.isOpaque(), + !analysis.fCoveragePOI.isSolidWhite(), hasMixedSamples, fBlendMode); } @@ -804,8 +801,8 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP } } -bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, - const GrPipelineAnalysis& analysis) const { +bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, ColorType colorType, + CoverageType coverageType) const { if (caps.shaderCaps()->dualSourceBlendingSupport()) { return false; } @@ -813,20 +810,20 @@ bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, // When we have four channel coverage we always need to read the dst in order to correctly // blend. The one exception is when we are using srcover mode and we know the input color into // the XP. - if (analysis.fCoveragePOI.isLCDCoverage()) { - if (SkBlendMode::kSrcOver == fBlendMode && - kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() && + if (CoverageType::kLCD == coverageType) { + if (SkBlendMode::kSrcOver == fBlendMode && ColorTypeIsConstant(colorType) && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } - return get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode).hasSecondaryOutput(); + return get_lcd_blend_formula(fBlendMode).hasSecondaryOutput(); } // We fallback on the shader XP when the blend formula would use dual source blending but we // don't have support for it. static const bool kHasMixedSamples = false; SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. - auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples, + auto formula = get_blend_formula(ColorTypeIsOpaque(colorType), + CoverageType::kSingleChannel == coverageType, kHasMixedSamples, fBlendMode); return formula.hasSecondaryOutput(); } @@ -893,7 +890,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( } BlendFormula blendFormula; - blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver); + blendFormula = get_lcd_blend_formula(SkBlendMode::kSrcOver); if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver); } @@ -917,15 +914,17 @@ bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } - auto formula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver); + auto formula = get_lcd_blend_formula(SkBlendMode::kSrcOver); return formula.hasSecondaryOutput(); } // We fallback on the shader XP when the blend formula would use dual source blending but we // don't have support for it. static const bool kHasMixedSamples = false; + bool isOpaque = analysis.fColorPOI.isOpaque(); + bool hasCoverage = !analysis.fCoveragePOI.isSolidWhite(); SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. - auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples, - SkBlendMode::kSrcOver); + auto formula = + get_blend_formula(isOpaque, hasCoverage, kHasMixedSamples, SkBlendMode::kSrcOver); return formula.hasSecondaryOutput(); } -- 2.7.4