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*,
virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
InvariantBlendedColor*) const = 0;
- bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const;
+ bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) 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& caps, const GrPipelineAnalysis& analysis) const;
+ bool willReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const;
/**
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
- * shader. This will not be called for draws that read from PLS since the dst color is always
- * available in such draws.
+ * shader.
*/
- virtual bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const = 0;
+ virtual bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const = 0;
};
#if defined(__GNUC__) || defined(__clang)
#pragma GCC diagnostic pop
bool hasMixedSamples,
const DstTexture*) const override;
- bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override { return false; }
+ bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override {
+ return false;
+ }
GR_DECLARE_XP_FACTORY_TEST;
bool hasMixedSamples,
const DstTexture*) const override;
- bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override;
+ bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override;
GR_DECLARE_XP_FACTORY_TEST;
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);
///////////////////////////////////////////////////////////////////////////////
-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,
}
bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
- return !analysis.fUsesPLSDstRead && !caps.shaderCaps()->dstReadInShaderSupport() &&
- this->willReadDstColor(caps, analysis);
+ 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);
}
}
static bool can_use_hw_blend_equation(GrBlendEquation equation,
- bool usePLSRead,
- bool isLCDCoverage,
+ const GrPipelineAnalysis& analysis,
const GrCaps& caps) {
if (!caps.advancedBlendEquationSupport()) {
return false;
}
- if (usePLSRead) {
+ if (analysis.fUsesPLSDstRead) {
return false;
}
- if (isLCDCoverage) {
+ if (analysis.fCoveragePOI.isLCDCoverage()) {
return false; // LCD coverage must be applied after the blend equation.
}
if (caps.canUseAdvancedBlendEquation(equation)) {
bool hasMixedSamples,
const DstTexture*) const override;
- bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override;
+ bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override;
+
GR_DECLARE_XP_FACTORY_TEST;
bool hasMixedSamples,
const DstTexture* dstTexture) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
- if (can_use_hw_blend_equation(fHWBlendEquation, analysis.fUsesPLSDstRead,
- analysis.fCoveragePOI.isLCDCoverage(), caps)) {
+ if (can_use_hw_blend_equation(fHWBlendEquation, analysis, caps)) {
SkASSERT(!dstTexture || !dstTexture->texture());
return new CustomXP(fMode, fHWBlendEquation);
}
return new CustomXP(dstTexture, hasMixedSamples, fMode);
}
-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);
+bool CustomXPFactory::onWillReadDstColor(const GrCaps& caps,
+ const GrPipelineAnalysis& analysis) const {
+ return !can_use_hw_blend_equation(fHWBlendEquation, analysis, caps);
}
void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
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;
/* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
};
-static BlendFormula get_blend_formula(bool isOpaque,
- bool hasCoverage,
+static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
bool hasMixedSamples,
SkBlendMode xfermode) {
SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
- bool conflatesCoverage = hasCoverage || hasMixedSamples;
- return gBlendTable[isOpaque][conflatesCoverage][(int)xfermode];
+ SkASSERT(!coveragePOI.isLCDCoverage());
+
+ bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples;
+ return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][(int)xfermode];
}
-static BlendFormula get_lcd_blend_formula(SkBlendMode xfermode) {
+static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI,
+ SkBlendMode xfermode) {
SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
+ SkASSERT(coveragePOI.isLCDCoverage());
return gLCDBlendTable[(int)xfermode];
}
SkASSERT(!dstTexture || !dstTexture->texture());
return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI);
}
- blendFormula = get_lcd_blend_formula(fBlendMode);
+ blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode);
} else {
- blendFormula = get_blend_formula(analysis.fColorPOI.isOpaque(),
- !analysis.fCoveragePOI.isSolidWhite(), hasMixedSamples,
+ blendFormula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, hasMixedSamples,
fBlendMode);
}
}
}
-bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, ColorType colorType,
- CoverageType coverageType) const {
+bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps,
+ const GrPipelineAnalysis& analysis) const {
if (caps.shaderCaps()->dualSourceBlendingSupport()) {
return false;
}
// 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 (CoverageType::kLCD == coverageType) {
- if (SkBlendMode::kSrcOver == fBlendMode && ColorTypeIsConstant(colorType) &&
+ if (analysis.fCoveragePOI.isLCDCoverage()) {
+ if (SkBlendMode::kSrcOver == fBlendMode &&
+ kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
!caps.shaderCaps()->dstReadInShaderSupport()) {
return false;
}
- return get_lcd_blend_formula(fBlendMode).hasSecondaryOutput();
+ return get_lcd_blend_formula(analysis.fCoveragePOI, 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(ColorTypeIsOpaque(colorType),
- CoverageType::kSingleChannel == coverageType, kHasMixedSamples,
+ auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples,
fBlendMode);
return formula.hasSecondaryOutput();
}
}
BlendFormula blendFormula;
- blendFormula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
+ blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver);
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
}
!caps.shaderCaps()->dstReadInShaderSupport()) {
return false;
}
- auto formula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
+ auto formula = get_lcd_blend_formula(analysis.fCoveragePOI, 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(isOpaque, hasCoverage, kHasMixedSamples, SkBlendMode::kSrcOver);
+ auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples,
+ SkBlendMode::kSrcOver);
return formula.hasSecondaryOutput();
}