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:
Brian Salomon 2017-01-20 19:06:29 +00:00 committed by Skia Commit-Bot
parent aaedae7acb
commit 5be6c95fa9
7 changed files with 97 additions and 48 deletions

View File

@ -307,6 +307,16 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
class GrXPFactory { class GrXPFactory {
public: public:
typedef GrXferProcessor::DstTexture DstTexture; 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&, GrXferProcessor* createXferProcessor(const GrPipelineAnalysis&,
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture*, const DstTexture*,
@ -329,24 +339,33 @@ public:
virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
InvariantBlendedColor*) const = 0; InvariantBlendedColor*) const = 0;
bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) const; bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const;
protected: protected:
constexpr GrXPFactory() {} 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: private:
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrPipelineAnalysis&, const GrPipelineAnalysis&,
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture*) const = 0; 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 * 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) #if defined(__GNUC__) || defined(__clang)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop

View File

@ -40,9 +40,7 @@ private:
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture*) const override; const DstTexture*) const override;
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override { bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override { return false; }
return false;
}
GR_DECLARE_XP_FACTORY_TEST; GR_DECLARE_XP_FACTORY_TEST;

View File

@ -63,7 +63,7 @@ private:
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture*) const override; 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; GR_DECLARE_XP_FACTORY_TEST;
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary); static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);

View File

@ -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, GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& analysis,
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture* dstTexture, const DstTexture* dstTexture,
@ -200,9 +234,6 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& anal
} }
bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const { bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
return (this->willReadDstColor(caps, analysis) && !caps.shaderCaps()->dstReadInShaderSupport()); return !analysis.fUsesPLSDstRead && !caps.shaderCaps()->dstReadInShaderSupport() &&
} this->willReadDstColor(caps, analysis);
bool GrXPFactory::willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
return analysis.fUsesPLSDstRead || this->onWillReadDstColor(caps, analysis);
} }

View File

@ -54,15 +54,16 @@ static constexpr GrBlendEquation hw_blend_equation(SkBlendMode mode) {
} }
static bool can_use_hw_blend_equation(GrBlendEquation equation, static bool can_use_hw_blend_equation(GrBlendEquation equation,
const GrPipelineAnalysis& analysis, bool usePLSRead,
bool isLCDCoverage,
const GrCaps& caps) { const GrCaps& caps) {
if (!caps.advancedBlendEquationSupport()) { if (!caps.advancedBlendEquationSupport()) {
return false; return false;
} }
if (analysis.fUsesPLSDstRead) { if (usePLSRead) {
return false; return false;
} }
if (analysis.fCoveragePOI.isLCDCoverage()) { if (isLCDCoverage) {
return false; // LCD coverage must be applied after the blend equation. return false; // LCD coverage must be applied after the blend equation.
} }
if (caps.canUseAdvancedBlendEquation(equation)) { if (caps.canUseAdvancedBlendEquation(equation)) {
@ -340,8 +341,7 @@ private:
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture*) const override; 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; GR_DECLARE_XP_FACTORY_TEST;
@ -359,16 +359,20 @@ GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture* dstTexture) const { const DstTexture* dstTexture) const {
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); 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()); SkASSERT(!dstTexture || !dstTexture->texture());
return new CustomXP(fMode, fHWBlendEquation); return new CustomXP(fMode, fHWBlendEquation);
} }
return new CustomXP(dstTexture, hasMixedSamples, fMode); return new CustomXP(dstTexture, hasMixedSamples, fMode);
} }
bool CustomXPFactory::onWillReadDstColor(const GrCaps& caps, bool CustomXPFactory::willReadDstColor(const GrCaps& caps, ColorType colorType,
const GrPipelineAnalysis& analysis) const { CoverageType coverageType) const {
return !can_use_hw_blend_equation(fHWBlendEquation, analysis, caps); // 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, void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,

View File

@ -32,15 +32,13 @@ public:
private: private:
constexpr GrDisableColorXPFactory() {} constexpr GrDisableColorXPFactory() {}
bool willReadDstColor(const GrCaps&, ColorType, CoverageType) const override { return false; }
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrPipelineAnalysis&, const GrPipelineAnalysis&,
bool hasMixedSamples, bool hasMixedSamples,
const DstTexture* dstTexture) const override; const DstTexture* dstTexture) const override;
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override {
return false;
}
GR_DECLARE_XP_FACTORY_TEST; GR_DECLARE_XP_FACTORY_TEST;
typedef GrXPFactory INHERITED; typedef GrXPFactory INHERITED;

View File

@ -320,21 +320,17 @@ static const BlendFormula gLCDBlendTable[(int)SkBlendMode::kLastCoeffMode + 1] =
/* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
}; };
static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, static BlendFormula get_blend_formula(bool isOpaque,
const GrProcOptInfo& coveragePOI, bool hasCoverage,
bool hasMixedSamples, bool hasMixedSamples,
SkBlendMode xfermode) { SkBlendMode xfermode) {
SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
SkASSERT(!coveragePOI.isLCDCoverage()); bool conflatesCoverage = hasCoverage || hasMixedSamples;
return gBlendTable[isOpaque][conflatesCoverage][(int)xfermode];
bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples;
return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][(int)xfermode];
} }
static BlendFormula get_lcd_blend_formula(const GrProcOptInfo& coveragePOI, static BlendFormula get_lcd_blend_formula(SkBlendMode xfermode) {
SkBlendMode xfermode) {
SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode); SkASSERT((unsigned)xfermode <= (unsigned)SkBlendMode::kLastCoeffMode);
SkASSERT(coveragePOI.isLCDCoverage());
return gLCDBlendTable[(int)xfermode]; return gLCDBlendTable[(int)xfermode];
} }
@ -759,9 +755,10 @@ GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps
SkASSERT(!dstTexture || !dstTexture->texture()); SkASSERT(!dstTexture || !dstTexture->texture());
return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI); return PDLCDXferProcessor::Create(fBlendMode, analysis.fColorPOI);
} }
blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fBlendMode); blendFormula = get_lcd_blend_formula(fBlendMode);
} else { } else {
blendFormula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, hasMixedSamples, blendFormula = get_blend_formula(analysis.fColorPOI.isOpaque(),
!analysis.fCoveragePOI.isSolidWhite(), hasMixedSamples,
fBlendMode); fBlendMode);
} }
@ -804,8 +801,8 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
} }
} }
bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps, bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, ColorType colorType,
const GrPipelineAnalysis& analysis) const { CoverageType coverageType) const {
if (caps.shaderCaps()->dualSourceBlendingSupport()) { if (caps.shaderCaps()->dualSourceBlendingSupport()) {
return false; 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 // 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 // blend. The one exception is when we are using srcover mode and we know the input color into
// the XP. // the XP.
if (analysis.fCoveragePOI.isLCDCoverage()) { if (CoverageType::kLCD == coverageType) {
if (SkBlendMode::kSrcOver == fBlendMode && if (SkBlendMode::kSrcOver == fBlendMode && ColorTypeIsConstant(colorType) &&
kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
!caps.shaderCaps()->dstReadInShaderSupport()) { !caps.shaderCaps()->dstReadInShaderSupport()) {
return false; 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 // We fallback on the shader XP when the blend formula would use dual source blending but we
// don't have support for it. // don't have support for it.
static const bool kHasMixedSamples = false; static const bool kHasMixedSamples = false;
SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending. 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); fBlendMode);
return formula.hasSecondaryOutput(); return formula.hasSecondaryOutput();
} }
@ -893,7 +890,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
} }
BlendFormula blendFormula; BlendFormula blendFormula;
blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver); blendFormula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver); return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
} }
@ -917,15 +914,17 @@ bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps,
!caps.shaderCaps()->dstReadInShaderSupport()) { !caps.shaderCaps()->dstReadInShaderSupport()) {
return false; return false;
} }
auto formula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver); auto formula = get_lcd_blend_formula(SkBlendMode::kSrcOver);
return formula.hasSecondaryOutput(); return formula.hasSecondaryOutput();
} }
// We fallback on the shader XP when the blend formula would use dual source blending but we // We fallback on the shader XP when the blend formula would use dual source blending but we
// don't have support for it. // don't have support for it.
static const bool kHasMixedSamples = false; 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. SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending.
auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples, auto formula =
SkBlendMode::kSrcOver); get_blend_formula(isOpaque, hasCoverage, kHasMixedSamples, SkBlendMode::kSrcOver);
return formula.hasSecondaryOutput(); return formula.hasSecondaryOutput();
} }