Index: src/gpu/effects/GrPorterDuffXferProcessor.cpp |
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
index 4245caafed06339c622c077147a65dcc592210fe..f0682f480c4930e22e576f38bb62923d74e6d436 100644 |
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
@@ -691,30 +691,30 @@ PDLCDXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, |
/////////////////////////////////////////////////////////////////////////////// |
-GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkXfermode::Mode xfermode) |
+GrPDXPFactory::GrPDXPFactory(SkXfermode::Mode xfermode) |
: fXfermode(xfermode) { |
SkASSERT(fXfermode <= SkXfermode::kLastCoeffMode); |
- this->initClassID<GrPorterDuffXPFactory>(); |
+ this->initClassID<GrPDXPFactory>(); |
} |
-GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode xfermode) { |
- static GrPorterDuffXPFactory gClearPDXPF(SkXfermode::kClear_Mode); |
- static GrPorterDuffXPFactory gSrcPDXPF(SkXfermode::kSrc_Mode); |
- static GrPorterDuffXPFactory gDstPDXPF(SkXfermode::kDst_Mode); |
- static GrPorterDuffXPFactory gSrcOverPDXPF(SkXfermode::kSrcOver_Mode); |
- static GrPorterDuffXPFactory gDstOverPDXPF(SkXfermode::kDstOver_Mode); |
- static GrPorterDuffXPFactory gSrcInPDXPF(SkXfermode::kSrcIn_Mode); |
- static GrPorterDuffXPFactory gDstInPDXPF(SkXfermode::kDstIn_Mode); |
- static GrPorterDuffXPFactory gSrcOutPDXPF(SkXfermode::kSrcOut_Mode); |
- static GrPorterDuffXPFactory gDstOutPDXPF(SkXfermode::kDstOut_Mode); |
- static GrPorterDuffXPFactory gSrcATopPDXPF(SkXfermode::kSrcATop_Mode); |
- static GrPorterDuffXPFactory gDstATopPDXPF(SkXfermode::kDstATop_Mode); |
- static GrPorterDuffXPFactory gXorPDXPF(SkXfermode::kXor_Mode); |
- static GrPorterDuffXPFactory gPlusPDXPF(SkXfermode::kPlus_Mode); |
- static GrPorterDuffXPFactory gModulatePDXPF(SkXfermode::kModulate_Mode); |
- static GrPorterDuffXPFactory gScreenPDXPF(SkXfermode::kScreen_Mode); |
- |
- static GrPorterDuffXPFactory* gFactories[] = { |
+const GrXPFactory* GrPDXPFactory::Create(SkXfermode::Mode xfermode) { |
+ static const GrPDXPFactory gClearPDXPF(SkXfermode::kClear_Mode); |
+ static const GrPDXPFactory gSrcPDXPF(SkXfermode::kSrc_Mode); |
+ static const GrPDXPFactory gDstPDXPF(SkXfermode::kDst_Mode); |
+ static const GrPDXPFactory gSrcOverPDXPF(SkXfermode::kSrcOver_Mode); |
+ static const GrPDXPFactory gDstOverPDXPF(SkXfermode::kDstOver_Mode); |
+ static const GrPDXPFactory gSrcInPDXPF(SkXfermode::kSrcIn_Mode); |
+ static const GrPDXPFactory gDstInPDXPF(SkXfermode::kDstIn_Mode); |
+ static const GrPDXPFactory gSrcOutPDXPF(SkXfermode::kSrcOut_Mode); |
+ static const GrPDXPFactory gDstOutPDXPF(SkXfermode::kDstOut_Mode); |
+ static const GrPDXPFactory gSrcATopPDXPF(SkXfermode::kSrcATop_Mode); |
+ static const GrPDXPFactory gDstATopPDXPF(SkXfermode::kDstATop_Mode); |
+ static const GrPDXPFactory gXorPDXPF(SkXfermode::kXor_Mode); |
+ static const GrPDXPFactory gPlusPDXPF(SkXfermode::kPlus_Mode); |
+ static const GrPDXPFactory gModulatePDXPF(SkXfermode::kModulate_Mode); |
+ static const GrPDXPFactory gScreenPDXPF(SkXfermode::kScreen_Mode); |
+ |
+ static const GrPDXPFactory* gFactories[] = { |
&gClearPDXPF, &gSrcPDXPF, &gDstPDXPF, &gSrcOverPDXPF, &gDstOverPDXPF, &gSrcInPDXPF, |
&gDstInPDXPF, &gSrcOutPDXPF, &gDstOutPDXPF, &gSrcATopPDXPF, &gDstATopPDXPF, &gXorPDXPF, |
&gPlusPDXPF, &gModulatePDXPF, &gScreenPDXPF |
@@ -728,7 +728,7 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode xfermode) { |
} |
GrXferProcessor* |
-GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
+GrPDXPFactory::onCreateXferProcessor(const GrCaps& caps, |
const GrProcOptInfo& colorPOI, |
const GrProcOptInfo& covPOI, |
bool hasMixedSamples, |
@@ -757,7 +757,7 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
return new PorterDuffXferProcessor(blendFormula); |
} |
-void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
+void GrPDXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
InvariantBlendedColor* blendedColor) const { |
// Find the blended color info based on the formula that does not have coverage. |
BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; |
@@ -788,7 +788,7 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP |
} |
} |
-bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, |
+bool GrPDXPFactory::willReadDstColor(const GrCaps& caps, |
const GrProcOptInfo& colorPOI, |
const GrProcOptInfo& covPOI, |
bool hasMixedSamples) const { |
@@ -812,16 +812,16 @@ bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, |
return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSecondaryOutput(); |
} |
-GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |
+GR_DEFINE_XP_FACTORY_TEST(GrPDXPFactory); |
-const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { |
+const GrXPFactory* GrPDXPFactory::TestCreate(GrProcessorTestData* d) { |
SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermode::kLastCoeffMode)); |
- return GrPorterDuffXPFactory::Create(mode); |
+ return GrPDXPFactory::Create(mode); |
} |
-void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, |
- int* outPrimary, |
- int* outSecondary) { |
+void GrPDXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, |
+ int* outPrimary, |
+ int* outSecondary) { |
if (!!strcmp(xp->name(), "Porter Duff")) { |
*outPrimary = *outSecondary = -1; |
return; |
@@ -830,3 +830,84 @@ void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, |
*outPrimary = blendFormula.fPrimaryOutputType; |
*outSecondary = blendFormula.fSecondaryOutputType; |
} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+GrSrcOverPDXPFactory::GrSrcOverPDXPFactory() { |
+ this->initClassID<GrSrcOverPDXPFactory>(); |
+} |
+ |
+GrXferProcessor* |
+GrSrcOverPDXPFactory::onCreateXferProcessor(const GrCaps& caps, |
+ const GrProcOptInfo& colorPOI, |
+ const GrProcOptInfo& covPOI, |
+ bool hasMixedSamples, |
+ const DstTexture* dstTexture) const { |
+ BlendFormula blendFormula; |
+ if (covPOI.isFourChannelOutput()) { |
+ if (kRGBA_GrColorComponentFlags == colorPOI.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(SkXfermode::kSrcOver_Mode, colorPOI); |
+ } |
+ blendFormula = get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode); |
+ } else { |
+ blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, |
+ SkXfermode::kSrcOver_Mode); |
+ } |
+ |
+ if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { |
+ return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode::kSrcOver_Mode); |
+ } |
+ |
+ SkASSERT(!dstTexture || !dstTexture->texture()); |
+ return new PorterDuffXferProcessor(blendFormula); |
+} |
+ |
+void GrSrcOverPDXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
+ InvariantBlendedColor* blendedColor) const { |
+ if (!colorPOI.isOpaque()) { |
+ blendedColor->fWillBlendWithDst = true; |
+ blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; |
+ return; |
+ } |
+ |
+ blendedColor->fWillBlendWithDst = false; |
+ |
+ blendedColor->fKnownColor = colorPOI.color(); |
+ blendedColor->fKnownColorFlags = colorPOI.validFlags(); |
+} |
+ |
+bool GrSrcOverPDXPFactory::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 (kRGBA_GrColorComponentFlags == colorPOI.validFlags() && |
+ !caps.shaderCaps()->dstReadInShaderSupport()) { |
+ return false; |
+ } |
+ return get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode).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, SkXfermode::kSrcOver_Mode).hasSecondaryOutput(); |
+} |
+ |
+GR_DEFINE_XP_FACTORY_TEST(GrSrcOverPDXPFactory); |
+ |
+const GrXPFactory* GrSrcOverPDXPFactory::TestCreate(GrProcessorTestData* d) { |
+ return SkRef(&GrPorterDuffXPFactory::gSrcOverPDXPFactory); |
+} |
+ |