Make analysis optional to GrPipeline::init().
GrXPFactory::createXferProcessor now takes GrPipelineAnalysisColor and GrPipelineAnalysisCoverage rather than GrProcessorSet::FragmentProcessorAnalysis. This will make it so ops do not have to retain the analysis or rerun it to create pipelines at flush time. Change-Id: Ib28ba65de425b20c2647329275f209aec168c3df Reviewed-on: https://skia-review.googlesource.com/10474 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
978533c302
commit
1c6025cc9d
@ -19,7 +19,10 @@
|
||||
#include "ops/GrOp.h"
|
||||
|
||||
void GrPipeline::init(const InitArgs& args) {
|
||||
SkASSERT(args.fAnalysis);
|
||||
if (args.fAnalysis) {
|
||||
SkASSERT(args.fAnalysis->outputColor() == args.fInputColor);
|
||||
SkASSERT(args.fAnalysis->outputCoverage() == args.fInputCoverage);
|
||||
}
|
||||
SkASSERT(args.fRenderTarget);
|
||||
|
||||
fRenderTarget.reset(args.fRenderTarget);
|
||||
@ -58,27 +61,33 @@ void GrPipeline::init(const InitArgs& args) {
|
||||
sk_sp<GrXferProcessor> xferProcessor;
|
||||
const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
|
||||
if (xpFactory) {
|
||||
xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, hasMixedSamples,
|
||||
xferProcessor.reset(xpFactory->createXferProcessor(args.fInputColor,
|
||||
args.fInputCoverage, hasMixedSamples,
|
||||
&args.fDstTexture, *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.fAnalysis, hasMixedSamples, &args.fDstTexture));
|
||||
*args.fCaps, args.fInputColor, args.fInputCoverage, hasMixedSamples,
|
||||
&args.fDstTexture));
|
||||
}
|
||||
fXferProcessor.reset(xferProcessor.get());
|
||||
}
|
||||
|
||||
// This is for the legacy GrPipeline creation in GrMeshDrawOp where analysis does not
|
||||
// eliminate fragment processors from GrProcessorSet.
|
||||
GrColor overrideColor = GrColor_ILLEGAL;
|
||||
int colorFPsToEliminate =
|
||||
args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(&overrideColor);
|
||||
colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0);
|
||||
if (args.fAnalysis->isInputColorIgnored()) {
|
||||
// No need to have an override color if it isn't even going to be used.
|
||||
overrideColor = GrColor_ILLEGAL;
|
||||
colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
|
||||
// This is for the legacy GrPipeline creation in GrMeshDrawOp where analysis does not eliminate
|
||||
// fragment processors from GrProcessorSet.
|
||||
int colorFPsToEliminate = 0;
|
||||
if (args.fAnalysis) {
|
||||
GrColor overrideColor = GrColor_ILLEGAL;
|
||||
colorFPsToEliminate =
|
||||
args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(
|
||||
&overrideColor);
|
||||
colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0);
|
||||
if (args.fAnalysis->isInputColorIgnored()) {
|
||||
// No need to have an override color if it isn't even going to be used.
|
||||
overrideColor = GrColor_ILLEGAL;
|
||||
colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
|
||||
}
|
||||
}
|
||||
|
||||
// Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline, possibly removing some of the
|
||||
|
@ -57,7 +57,10 @@ public:
|
||||
uint32_t fFlags = 0;
|
||||
GrDrawFace fDrawFace = GrDrawFace::kBoth;
|
||||
const GrProcessorSet* fProcessors = nullptr;
|
||||
const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis;
|
||||
GrPipelineAnalysisColor fInputColor;
|
||||
GrPipelineAnalysisCoverage fInputCoverage = GrPipelineAnalysisCoverage::kNone;
|
||||
// This is only used for GrMeshDrawOp's legacy pipeline creation system.
|
||||
const GrProcessorSet::FragmentProcessorAnalysis* fAnalysis = nullptr;
|
||||
const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
|
||||
const GrAppliedClip* fAppliedClip = nullptr;
|
||||
GrRenderTarget* fRenderTarget = nullptr;
|
||||
|
@ -51,6 +51,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const GrPipelineAnalysisColor& that) const {
|
||||
if (fFlags != that.fFlags) {
|
||||
return false;
|
||||
}
|
||||
return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
|
||||
}
|
||||
|
||||
private:
|
||||
enum Flags {
|
||||
kColorIsKnown_Flag = 0x1,
|
||||
|
@ -119,8 +119,7 @@ void GrProcessorSet::FragmentProcessorAnalysis::internalInit(
|
||||
|
||||
GrPipelineAnalysisColor outputColor = colorInfo.outputColor();
|
||||
if (outputColor.isConstant(&fKnownOutputColor)) {
|
||||
fOutputColorType = static_cast<unsigned>(outputColor.isOpaque() ? ColorType::kOpaqueConstant
|
||||
: ColorType::kConstant);
|
||||
fOutputColorType = static_cast<unsigned>(ColorType::kConstant);
|
||||
} else if (outputColor.isOpaque()) {
|
||||
fOutputColorType = static_cast<unsigned>(ColorType::kOpaque);
|
||||
} else {
|
||||
|
@ -128,27 +128,24 @@ public:
|
||||
}
|
||||
bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
|
||||
bool isInputColorIgnored() const { return fIgnoresInputColor; }
|
||||
bool isOutputColorOpaque() const {
|
||||
return ColorType::kOpaque == this->outputColorType() ||
|
||||
ColorType::kOpaqueConstant == this->outputColorType();
|
||||
}
|
||||
bool hasKnownOutputColor(GrColor* color = nullptr) const {
|
||||
bool constant = ColorType::kConstant == this->outputColorType() ||
|
||||
ColorType::kOpaqueConstant == this->outputColorType();
|
||||
if (constant && color) {
|
||||
*color = fKnownOutputColor;
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
GrPipelineAnalysisCoverage outputCoverageType() const {
|
||||
GrPipelineAnalysisCoverage outputCoverage() const {
|
||||
return static_cast<GrPipelineAnalysisCoverage>(fOutputCoverageType);
|
||||
}
|
||||
bool hasCoverage() const {
|
||||
return this->outputCoverageType() != GrPipelineAnalysisCoverage::kNone;
|
||||
GrPipelineAnalysisColor outputColor() const {
|
||||
switch (this->outputColorType()) {
|
||||
case ColorType::kConstant:
|
||||
return fKnownOutputColor;
|
||||
case ColorType::kOpaque:
|
||||
return GrPipelineAnalysisColor::Opaque::kYes;
|
||||
case ColorType::kUnknown:
|
||||
return GrPipelineAnalysisColor::Opaque::kNo;
|
||||
}
|
||||
SkFAIL("Unexpected color type");
|
||||
return GrPipelineAnalysisColor::Opaque::kNo;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class ColorType : unsigned { kUnknown, kOpaqueConstant, kConstant, kOpaque };
|
||||
enum class ColorType : unsigned { kUnknown, kConstant, kOpaque };
|
||||
|
||||
ColorType outputColorType() const { return static_cast<ColorType>(fOutputColorType); }
|
||||
|
||||
|
@ -1742,6 +1742,8 @@ uint32_t GrRenderTargetContext::addMeshDrawOp(const GrPipelineBuilder& pipelineB
|
||||
args.fRenderTarget = rt;
|
||||
args.fCaps = this->caps();
|
||||
args.fAnalysis = &analysis;
|
||||
args.fInputColor = analysis.outputColor();
|
||||
args.fInputCoverage = analysis.outputCoverage();
|
||||
|
||||
if (analysis.requiresDstTexture()) {
|
||||
this->setupDstTexture(rt, clip, bounds, &args.fDstTexture);
|
||||
|
@ -189,21 +189,11 @@ GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties(
|
||||
return result;
|
||||
}
|
||||
|
||||
GrXferProcessor* GrXPFactory::createXferProcessor(const FragmentProcessorAnalysis& analysis,
|
||||
GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysisColor& color,
|
||||
GrPipelineAnalysisCoverage coverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture,
|
||||
const GrCaps& caps) const {
|
||||
#ifdef SK_DEBUG
|
||||
if (analysis.requiresDstTexture()) {
|
||||
if (!caps.shaderCaps()->dstReadInShaderSupport()) {
|
||||
SkASSERT(dstTexture && dstTexture->texture());
|
||||
} else {
|
||||
SkASSERT(!dstTexture || !dstTexture->texture());
|
||||
}
|
||||
} else {
|
||||
SkASSERT(!dstTexture || !dstTexture->texture());
|
||||
}
|
||||
SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
|
||||
#endif
|
||||
return this->onCreateXferProcessor(caps, analysis, hasMixedSamples, dstTexture);
|
||||
return this->onCreateXferProcessor(caps, color, coverage, hasMixedSamples, dstTexture);
|
||||
}
|
||||
|
@ -268,7 +268,8 @@ public:
|
||||
|
||||
typedef GrXferProcessor::DstTexture DstTexture;
|
||||
|
||||
GrXferProcessor* createXferProcessor(const FragmentProcessorAnalysis&,
|
||||
GrXferProcessor* createXferProcessor(const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*,
|
||||
const GrCaps& caps) const;
|
||||
@ -293,7 +294,8 @@ protected:
|
||||
|
||||
private:
|
||||
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis&,
|
||||
const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const = 0;
|
||||
|
||||
|
@ -218,11 +218,11 @@ const GrXPFactory* GrCoverageSetOpXPFactory::Get(SkRegion::Op regionOp, bool inv
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(
|
||||
const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) 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.
|
||||
|
@ -30,9 +30,8 @@ public:
|
||||
private:
|
||||
constexpr GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps&,
|
||||
const FragmentProcessorAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps&, const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage, bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
|
||||
|
@ -213,9 +213,8 @@ public:
|
||||
: fMode(mode), fHWBlendEquation(hw_blend_equation(mode)) {}
|
||||
|
||||
private:
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage, bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
|
||||
@ -234,11 +233,12 @@ private:
|
||||
#endif
|
||||
|
||||
GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis& analysis,
|
||||
const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage coverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
|
||||
if (can_use_hw_blend_equation(fHWBlendEquation, analysis.outputCoverageType(), caps)) {
|
||||
if (can_use_hw_blend_equation(fHWBlendEquation, coverage, caps)) {
|
||||
SkASSERT(!dstTexture || !dstTexture->texture());
|
||||
return new CustomXP(fMode, fHWBlendEquation);
|
||||
}
|
||||
|
@ -81,11 +81,11 @@ void DisableColorXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(
|
||||
const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
return DisableColorXP::Create();
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,8 @@ private:
|
||||
AnalysisProperties::kIgnoresInputColor;
|
||||
}
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage, bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const override;
|
||||
|
||||
GR_DECLARE_XP_FACTORY_TEST;
|
||||
|
@ -521,7 +521,7 @@ GrGLSLXferProcessor* ShaderPDXferProcessor::createGLSLInstance() const {
|
||||
|
||||
class PDLCDXferProcessor : public GrXferProcessor {
|
||||
public:
|
||||
static GrXferProcessor* Create(SkBlendMode xfermode, const FragmentProcessorAnalysis& analysis);
|
||||
static GrXferProcessor* Create(SkBlendMode xfermode, const GrPipelineAnalysisColor& inputColor);
|
||||
|
||||
~PDLCDXferProcessor() override;
|
||||
|
||||
@ -603,12 +603,12 @@ PDLCDXferProcessor::PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha)
|
||||
}
|
||||
|
||||
GrXferProcessor* PDLCDXferProcessor::Create(SkBlendMode xfermode,
|
||||
const FragmentProcessorAnalysis& analysis) {
|
||||
const GrPipelineAnalysisColor& color) {
|
||||
if (SkBlendMode::kSrcOver != xfermode) {
|
||||
return nullptr;
|
||||
}
|
||||
GrColor blendConstant;
|
||||
if (!analysis.hasKnownOutputColor(&blendConstant)) {
|
||||
if (!color.isConstant(&blendConstant)) {
|
||||
return nullptr;
|
||||
}
|
||||
blendConstant = GrUnpremulColor(blendConstant);
|
||||
@ -698,25 +698,26 @@ const GrXPFactory* GrPorterDuffXPFactory::Get(SkBlendMode blendMode) {
|
||||
}
|
||||
}
|
||||
|
||||
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(
|
||||
const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysisColor& color,
|
||||
GrPipelineAnalysisCoverage coverage,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
BlendFormula blendFormula;
|
||||
if (analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD) {
|
||||
if (SkBlendMode::kSrcOver == fBlendMode && analysis.hasKnownOutputColor() &&
|
||||
if (coverage == GrPipelineAnalysisCoverage::kLCD) {
|
||||
if (SkBlendMode::kSrcOver == fBlendMode && color.isConstant() &&
|
||||
!caps.shaderCaps()->dualSourceBlendingSupport() &&
|
||||
!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, analysis);
|
||||
return PDLCDXferProcessor::Create(fBlendMode, color);
|
||||
}
|
||||
blendFormula = get_lcd_blend_formula(fBlendMode);
|
||||
} else {
|
||||
blendFormula = get_blend_formula(analysis.isOutputColorOpaque(), analysis.hasCoverage(),
|
||||
hasMixedSamples, fBlendMode);
|
||||
blendFormula =
|
||||
get_blend_formula(color.isOpaque(), GrPipelineAnalysisCoverage::kNone != coverage,
|
||||
hasMixedSamples, fBlendMode);
|
||||
}
|
||||
|
||||
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
|
||||
@ -809,15 +810,15 @@ const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
|
||||
|
||||
GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis& analysis,
|
||||
const GrPipelineAnalysisColor& color,
|
||||
GrPipelineAnalysisCoverage coverage,
|
||||
bool hasMixedSamples,
|
||||
const GrXferProcessor::DstTexture* dstTexture) {
|
||||
|
||||
// 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
|
||||
// color to src-mode, which allows disabling of blending.
|
||||
if (analysis.outputCoverageType() != GrPipelineAnalysisCoverage::kLCD) {
|
||||
if (coverage != GrPipelineAnalysisCoverage::kLCD) {
|
||||
// We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP".
|
||||
// We don't simply return the address of that XP here because our caller would have to unref
|
||||
// it and since it is a global object and GrProgramElement's ref-cnting system is not thread
|
||||
@ -825,13 +826,13 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (analysis.hasKnownOutputColor() && !caps.shaderCaps()->dualSourceBlendingSupport() &&
|
||||
if (color.isConstant() && !caps.shaderCaps()->dualSourceBlendingSupport() &&
|
||||
!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(SkBlendMode::kSrcOver, analysis);
|
||||
return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, color);
|
||||
}
|
||||
|
||||
BlendFormula blendFormula;
|
||||
|
@ -24,7 +24,8 @@ public:
|
||||
/** Because src-over is so common we special case it for performance reasons. If this returns
|
||||
null then the SimpleSrcOverXP() below should be used. */
|
||||
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis&,
|
||||
const GrPipelineAnalysisColor& color,
|
||||
GrPipelineAnalysisCoverage coverage,
|
||||
bool hasMixedSamples,
|
||||
const GrXferProcessor::DstTexture*);
|
||||
|
||||
@ -42,9 +43,8 @@ public:
|
||||
private:
|
||||
constexpr GrPorterDuffXPFactory(SkBlendMode);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const FragmentProcessorAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, const GrPipelineAnalysisColor&,
|
||||
GrPipelineAnalysisCoverage, bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
AnalysisProperties analysisProperties(const GrPipelineAnalysisColor&,
|
||||
|
@ -466,6 +466,7 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
|
||||
|
||||
state->gpu()->handleDirtyContext();
|
||||
|
||||
// TODO: Don't reanalyze the processors.
|
||||
GrProcessorSet::FragmentProcessorAnalysis analysis;
|
||||
GrPipelineAnalysisCoverage coverageInput;
|
||||
if (GrAAType::kCoverage == fInfo.aaType() ||
|
||||
@ -485,7 +486,8 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) {
|
||||
|
||||
GrPipeline pipeline;
|
||||
GrPipeline::InitArgs args;
|
||||
args.fAnalysis = &analysis;
|
||||
args.fInputColor = analysis.outputColor();
|
||||
args.fInputCoverage = analysis.outputCoverage();
|
||||
args.fAppliedClip = clip;
|
||||
args.fCaps = &state->caps();
|
||||
args.fProcessors = &fProcessors;
|
||||
|
@ -38,6 +38,7 @@ void GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pip
|
||||
0xffff>()
|
||||
};
|
||||
GrPipeline::InitArgs args;
|
||||
auto analysis = this->fragmentProcessorAnalysis();
|
||||
args.fProcessors = &this->processors();
|
||||
args.fFlags = GrAA::kYes == fAA ? GrPipeline::kHWAntialias_Flag : 0;
|
||||
args.fUserStencil = &kCoverPass;
|
||||
@ -45,8 +46,8 @@ void GrDrawPathOpBase::initPipeline(const GrOpFlushState& state, GrPipeline* pip
|
||||
args.fRenderTarget = state.drawOpArgs().fRenderTarget;
|
||||
args.fCaps = &state.caps();
|
||||
args.fDstTexture = state.drawOpArgs().fDstTexture;
|
||||
args.fAnalysis =
|
||||
&this->doFragmentProcessorAnalysis(state.caps(), state.drawOpArgs().fAppliedClip);
|
||||
args.fInputColor = analysis.outputColor();
|
||||
args.fInputCoverage = analysis.outputCoverage();
|
||||
|
||||
return pipeline->init(args);
|
||||
}
|
||||
|
@ -96,11 +96,9 @@ static void construct_dummy_pipeline(GrRenderTargetContext* dc, GrPipeline* pipe
|
||||
GrScissorState dummyScissor;
|
||||
GrWindowRectsState dummyWindows;
|
||||
|
||||
GrProcessorSet::FragmentProcessorAnalysis analysis;
|
||||
GrPipeline::InitArgs args;
|
||||
dummyBuilder.getPipelineInitArgs(&args);
|
||||
args.fRenderTarget = dc->accessRenderTarget();
|
||||
args.fAnalysis = &analysis;
|
||||
args.fCaps = dc->caps();
|
||||
args.fDstTexture = GrXferProcessor::DstTexture();
|
||||
pipeline->init(args);
|
||||
|
@ -66,7 +66,8 @@ public:
|
||||
fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
|
||||
fCanCombineOverlappedStencilAndCover = analysis.canCombineOverlappedStencilAndCover();
|
||||
fIgnoresInputColor = analysis.isInputColorIgnored();
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
|
||||
sk_sp<GrXferProcessor> xp(
|
||||
xpf->createXferProcessor(inputColor, inputCoverage, false, nullptr, caps));
|
||||
TEST_ASSERT(!analysis.requiresDstTexture());
|
||||
GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
|
||||
xp->getBlendInfo(&fBlendInfo);
|
||||
@ -987,39 +988,12 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
|
||||
}
|
||||
|
||||
static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
class TestLCDCoverageOp : public GrMeshDrawOp {
|
||||
public:
|
||||
DEFINE_OP_CLASS_ID
|
||||
|
||||
TestLCDCoverageOp() : INHERITED(ClassID()) {}
|
||||
|
||||
const char* name() const override { return "Test LCD Text Op"; }
|
||||
|
||||
private:
|
||||
void getFragmentProcessorAnalysisInputs(
|
||||
GrPipelineAnalysisColor* color,
|
||||
GrPipelineAnalysisCoverage* coverage) const override {
|
||||
color->setToConstant(GrColorPackRGBA(123, 45, 67, 221));
|
||||
*coverage = GrPipelineAnalysisCoverage::kLCD;
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const PipelineOptimizations&) override {}
|
||||
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
|
||||
void onPrepareDraws(Target*) const override {}
|
||||
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
} testLCDCoverageOp;
|
||||
|
||||
GrProcessorSet::FragmentProcessorAnalysis analysis;
|
||||
testLCDCoverageOp.analyzeProcessors(&analysis, GrProcessorSet(GrPaint()), nullptr, caps);
|
||||
|
||||
SkASSERT(analysis.hasKnownOutputColor());
|
||||
SkASSERT(analysis.outputCoverageType() == GrPipelineAnalysisCoverage::kLCD);
|
||||
|
||||
TEST_ASSERT(!analysis.requiresDstTexture());
|
||||
|
||||
const GrXPFactory* xpf = GrPorterDuffXPFactory::Get(SkBlendMode::kSrcOver);
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
|
||||
GrPipelineAnalysisColor color = GrColorPackRGBA(123, 45, 67, 221);
|
||||
GrPipelineAnalysisCoverage coverage = GrPipelineAnalysisCoverage::kLCD;
|
||||
SkASSERT(!(GrXPFactory::GetAnalysisProperties(xpf, color, coverage, caps) &
|
||||
GrXPFactory::AnalysisProperties::kRequiresDstTexture));
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(color, coverage, false, nullptr, caps));
|
||||
if (!xp) {
|
||||
ERRORF(reporter, "Failed to create an XP with LCD coverage.");
|
||||
return;
|
||||
@ -1072,8 +1046,8 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
|
||||
caps);
|
||||
GrXferProcessor::DstTexture* dstTexture =
|
||||
analysis.requiresDstTexture() ? &fakeDstTexture : nullptr;
|
||||
sk_sp<GrXferProcessor> xp(
|
||||
xpf->createXferProcessor(analysis, false, dstTexture, caps));
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(colorInput, coverageType, false,
|
||||
dstTexture, caps));
|
||||
if (!xp) {
|
||||
ERRORF(reporter, "Failed to create an XP without dual source blending.");
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user