Revert "Revert "Make it possible to query GrXPFactory for dst texture without GrPipelineAnalysis.""
This reverts commit 3329cceab5
.
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 <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
aaedae7acb
commit
5be6c95fa9
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user