diff options
author | egdaniel <egdaniel@google.com> | 2015-11-23 13:20:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-23 13:20:42 -0800 |
commit | c4b72720e75313079212e69e46a5ef7c474b2305 (patch) | |
tree | b0bf74db86503bd22684bb3107613db4e6625244 /src/gpu | |
parent | 60ce86d4718dab83f33488ec41710ad6763fc7f8 (diff) |
Don't create a GXPFactory when blend is SrcOver
BUG=skia:
Review URL: https://codereview.chromium.org/1471053002
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrContext.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrPaint.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrPipeline.cpp | 32 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.h | 7 | ||||
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 1 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 9 | ||||
-rw-r--r-- | src/gpu/batches/GrDefaultPathRenderer.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrDisableColorXP.h | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrPorterDuffXferProcessor.cpp | 62 |
13 files changed, 119 insertions, 33 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 348cdbaaca..920e3c4bbd 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -276,7 +276,6 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, SkAutoTUnref<const GrFragmentProcessor> fp; SkMatrix textureMatrix; textureMatrix.setIDiv(tempTexture->width(), tempTexture->height()); - GrPaint paint; if (applyPremulToSrc) { fp.reset(this->createUPMToPMEffect(tempTexture, tempDrawInfo.fSwapRAndB, textureMatrix)); @@ -324,7 +323,9 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, if (!drawContext) { return false; } + GrPaint paint; paint.addColorFragmentProcessor(fp); + paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); drawContext->drawRect(GrClip::WideOpen(), paint, matrix, rect, nullptr); @@ -412,7 +413,6 @@ bool GrContext::readSurfacePixels(GrSurface* src, SkMatrix textureMatrix; textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); textureMatrix.postIDiv(src->width(), src->height()); - GrPaint paint; SkAutoTUnref<const GrFragmentProcessor> fp; if (unpremul) { fp.reset(this->createPMToUPMEffect(src->asTexture(), tempDrawInfo.fSwapRAndB, @@ -430,7 +430,9 @@ bool GrContext::readSurfacePixels(GrSurface* src, GrConfigConversionEffect::kNone_PMConversion, textureMatrix)); } if (fp) { + GrPaint paint; paint.addColorFragmentProcessor(fp); + paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); SkAutoTUnref<GrDrawContext> drawContext(this->drawContext(temp->asRenderTarget())); drawContext->drawRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect, nullptr); diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 062a42fc5b..01d4f63bc5 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -431,6 +431,8 @@ void GrDrawTarget::clear(const SkIRect* rect, } GrPipelineBuilder pipelineBuilder; + pipelineBuilder.setXPFactory( + GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); pipelineBuilder.setRenderTarget(renderTarget); this->drawNonAARect(pipelineBuilder, color, SkMatrix::I(), *rect); diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index 6f218a4b0b..1ec8e502be 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -50,7 +50,14 @@ bool GrPaint::isConstantBlendedColor(GrColor* color) const { kRGBA_GrColorComponentFlags, false); GrXPFactory::InvariantBlendedColor blendedColor; - fXPFactory->getInvariantBlendedColor(colorProcInfo, &blendedColor); + if (fXPFactory) { + fXPFactory->getInvariantBlendedColor(colorProcInfo, &blendedColor); + } else { + GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(colorProcInfo.color(), + colorProcInfo.validFlags(), + colorProcInfo.isOpaque(), + &blendedColor); + } if (kRGBA_GrColorComponentFlags == blendedColor.fKnownColorFlags) { *color = blendedColor.fKnownColor; diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp index 073349be1e..73b20a9042 100644 --- a/src/gpu/GrPipeline.cpp +++ b/src/gpu/GrPipeline.cpp @@ -21,10 +21,23 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, const GrPipelineBuilder& builder = *args.fPipelineBuilder; // Create XferProcessor from DS's XPFactory - SkAutoTUnref<GrXferProcessor> xferProcessor( - builder.getXPFactory()->createXferProcessor(args.fColorPOI, args.fCoveragePOI, - builder.hasMixedSamples(), &args.fDstTexture, - *args.fCaps)); + const GrXPFactory* xpFactory = builder.getXPFactory(); + SkAutoTUnref<GrXferProcessor> xferProcessor; + if (xpFactory) { + xferProcessor.reset(xpFactory->createXferProcessor(args.fColorPOI, + args.fCoveragePOI, + builder.hasMixedSamples(), + &args.fDstTexture, + *args.fCaps)); + } else { + xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor( + *args.fCaps, + args.fColorPOI, + args.fCoveragePOI, + builder.hasMixedSamples(), + &args.fDstTexture)); + } + if (!xferProcessor) { return nullptr; } @@ -55,7 +68,7 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, } GrPipeline* pipeline = new (memory) GrPipeline; - pipeline->fXferProcessor.reset(xferProcessor.get()); + pipeline->fXferProcessor.reset(xferProcessor); pipeline->fRenderTarget.reset(builder.fRenderTarget.get()); SkASSERT(pipeline->fRenderTarget); @@ -123,7 +136,14 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args, } GrXPFactory::InvariantBlendedColor blendedColor; - builder.fXPFactory->getInvariantBlendedColor(args.fColorPOI, &blendedColor); + if (xpFactory) { + xpFactory->getInvariantBlendedColor(args.fColorPOI, &blendedColor); + } else { + GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fColorPOI.color(), + args.fColorPOI.validFlags(), + args.fColorPOI.isOpaque(), + &blendedColor); + } if (blendedColor.fWillBlendWithDst) { opts->fFlags |= GrPipelineOptimizations::kWillColorBlendWithDst_Flag; } diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp index ab185505d6..ce465c1c71 100644 --- a/src/gpu/GrPipelineBuilder.cpp +++ b/src/gpu/GrPipelineBuilder.cpp @@ -31,7 +31,7 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt, c fCoverageFragmentProcessors.push_back(SkRef(paint.getCoverageFragmentProcessor(i))); } - fXPFactory.reset(SkRef(paint.getXPFactory())); + fXPFactory.reset(SkSafeRef(paint.getXPFactory())); this->setRenderTarget(rt); @@ -51,8 +51,12 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt, c bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const { - return this->getXPFactory()->willNeedDstTexture(caps, colorPOI, coveragePOI, - this->hasMixedSamples()); + if (this->getXPFactory()) { + return this->getXPFactory()->willNeedDstTexture(caps, colorPOI, coveragePOI, + this->hasMixedSamples()); + } + return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, colorPOI, coveragePOI, + this->hasMixedSamples()); } void GrPipelineBuilder::AutoRestoreFragmentProcessorState::set( diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index 010685b3e2..bf0bed56c9 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -150,7 +150,7 @@ public: * and the dst color are blended. */ const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) { - fXPFactory.reset(SkRef(xpFactory)); + fXPFactory.reset(SkSafeRef(xpFactory)); return xpFactory; } @@ -171,10 +171,7 @@ public: } const GrXPFactory* getXPFactory() const { - if (!fXPFactory) { - fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode)); - } - return fXPFactory.get(); + return fXPFactory; } /** diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index 93859483ad..014c30574a 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -128,6 +128,7 @@ GrTexture* GrYUVProvider::refAsTexture(GrContext* ctx, const GrSurfaceDesc& desc yuvInfo.fSize, yuvInfo.fColorSpace)); paint.addColorFragmentProcessor(yuvToRgbProcessor); + paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); const SkRect r = SkRect::MakeIWH(yuvInfo.fSize[0].fWidth, yuvInfo.fSize[0].fHeight); SkAutoTUnref<GrDrawContext> drawContext(ctx->drawContext(renderTarget)); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 411b5b2b60..954bb80852 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -489,13 +489,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, SkXfermode* mode = skPaint.getXfermode(); GrXPFactory* xpFactory = nullptr; - if (!SkXfermode::AsXPFactory(mode, &xpFactory)) { - // Fall back to src-over - // return false here? - xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode); - } - SkASSERT(xpFactory); - grPaint->setXPFactory(xpFactory)->unref(); + SkXfermode::AsXPFactory(mode, &xpFactory); + SkSafeUnref(grPaint->setXPFactory(xpFactory)); #ifndef SK_IGNORE_GPU_DITHER if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) { diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp index d0777e253f..fa2ffe0b4d 100644 --- a/src/gpu/batches/GrDefaultPathRenderer.cpp +++ b/src/gpu/batches/GrDefaultPathRenderer.cpp @@ -564,7 +564,8 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, const bool isHairline = stroke->isHairlineStyle(); // Save the current xp on the draw state so we can reset it if needed - SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(pipelineBuilder->getXPFactory())); + const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory(); + SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory)); // face culling doesn't make sense here SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace()); diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 2510b5c9d7..4df894b40a 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -223,6 +223,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context tempTex, false, *pmToUPMRule, SkMatrix::I())); paint1.addColorFragmentProcessor(pmToUPM1); + paint1.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkAutoTUnref<GrDrawContext> readDrawContext( @@ -241,6 +242,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead); paint2.addColorFragmentProcessor(upmToPM); + paint2.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkAutoTUnref<GrDrawContext> tempDrawContext( context->drawContext(tempTex->asRenderTarget())); @@ -255,6 +257,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context kSrcRect); paint3.addColorFragmentProcessor(pmToUPM2); + paint3.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); readDrawContext.reset(context->drawContext(readTex->asRenderTarget())); if (!readDrawContext) { diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index 6b3a20ec2d..90ab030d24 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -321,10 +321,6 @@ class CustomXPFactory : public GrXPFactory { public: CustomXPFactory(SkXfermode::Mode mode); - bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const override { - return true; - } - void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor*) const override; diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index caa0eecec8..a79dd9b971 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -17,10 +17,6 @@ class GrDisableColorXPFactory : public GrXPFactory { public: static GrXPFactory* Create() { return new GrDisableColorXPFactory; } - bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const override { - return true; - } - void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, GrXPFactory::InvariantBlendedColor* blendedColor) const override { blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 4245caafed..2323c67040 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -830,3 +830,65 @@ void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, *outPrimary = blendFormula.fPrimaryOutputType; *outSecondary = blendFormula.fSecondaryOutputType; } + + +//////////////////////////////////////////////////////////////////////////////////////////////// +// SrcOver Global functions +//////////////////////////////////////////////////////////////////////////////////////////////// + +GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor( + const GrCaps& caps, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& covPOI, + bool hasMixedSamples, + const GrXferProcessor::DstTexture* dstTexture) { + 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); +} + +bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps, + const GrProcOptInfo& colorPOI, + const GrProcOptInfo& covPOI, + bool hasMixedSamples) { + 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 (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(); +} + |