bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, const GrPipelineOptimizations& optimizations) { if (caps.shaderCaps()->dstReadInShaderSupport() || 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 (optimizations.fCoveragePOI.isFourChannelOutput()) { if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() && !caps.shaderCaps()->dstReadInShaderSupport()) { return false; } return get_lcd_blend_formula(optimizations.fCoveragePOI, SkBlendMode::kSrcOver).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. return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI, kHasMixedSamples, SkBlendMode::kSrcOver).hasSecondaryOutput(); }
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrPipelineOptimizations& optimizations, bool hasMixedSamples, const DstTexture* dstTexture) const { if (optimizations.fOverrides.fUsePLSDstRead) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode); } BlendFormula blendFormula; if (optimizations.fCoveragePOI.isFourChannelOutput()) { if (SkBlendMode::kSrcOver == fXfermode && kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() && !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(fXfermode, optimizations.fColorPOI); } blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode); } else { blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI, hasMixedSamples, fXfermode); } if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode); } SkASSERT(!dstTexture || !dstTexture->texture()); return new PorterDuffXferProcessor(blendFormula); }
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, bool hasMixedSamples, const DstTexture* dstTexture) const { BlendFormula blendFormula; if (covPOI.isFourChannelOutput()) { if (SkXfermode::kSrcOver_Mode == fXfermode && kRGBA_GrColorComponentFlags == colorPOI.validFlags()) { SkASSERT(!dstTexture || !dstTexture->texture()); return PDLCDXferProcessor::Create(fXfermode, colorPOI); } blendFormula = get_lcd_blend_formula(covPOI, fXfermode); } else { blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode); } if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode); } SkASSERT(!dstTexture || !dstTexture->texture()); return new PorterDuffXferProcessor(blendFormula); }
bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const { if (coveragePOI.isFourChannelOutput()) { return false; // The LCD XP never does a dst read. } // We fallback on the shader XP when the blend formula would use dual source blending but we // don't have support for it. return !caps.shaderCaps()->dualSourceBlendingSupport() && get_blend_formula(fXfermode, colorPOI, coveragePOI).hasSecondaryOutput(); }
bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, bool hasMixedSamples) const { if (caps.shaderCaps()->dualSourceBlendingSupport()) { return false; } if (covPOI.isFourChannelOutput()) { return false; // The LCD XP will abort rather than doing a dst read. } // We fallback on the shader XP when the blend formula would use dual source blending but we // don't have support for it. return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSecondaryOutput(); }
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const DstTexture* dstTexture) const { if (covPOI.isFourChannelOutput()) { SkASSERT(!dstTexture || !dstTexture->texture()); return PDLCDXferProcessor::Create(fXfermode, colorPOI); } BlendFormula blendFormula = get_blend_formula(fXfermode, colorPOI, covPOI); if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { return ShaderPDXferProcessor::Create(fXfermode, dstTexture); } SkASSERT(!dstTexture || !dstTexture->texture()); return PorterDuffXferProcessor::Create(blendFormula); }
bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, bool hasMixedSamples) 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 (covPOI.isFourChannelOutput()) { if (SkXfermode::kSrcOver_Mode == fXfermode && kRGBA_GrColorComponentFlags == colorPOI.validFlags()) { return false; } return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput(); } // We fallback on the shader XP when the blend formula would use dual source blending but we // don't have support for it. return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSecondaryOutput(); }