aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2015-11-23 13:20:41 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-11-23 13:20:42 -0800
commitc4b72720e75313079212e69e46a5ef7c474b2305 (patch)
treeb0bf74db86503bd22684bb3107613db4e6625244 /src/gpu
parent60ce86d4718dab83f33488ec41710ad6763fc7f8 (diff)
Don't create a GXPFactory when blend is SrcOver
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrContext.cpp6
-rw-r--r--src/gpu/GrDrawTarget.cpp2
-rw-r--r--src/gpu/GrPaint.cpp9
-rw-r--r--src/gpu/GrPipeline.cpp32
-rw-r--r--src/gpu/GrPipelineBuilder.cpp10
-rw-r--r--src/gpu/GrPipelineBuilder.h7
-rw-r--r--src/gpu/GrYUVProvider.cpp1
-rw-r--r--src/gpu/SkGr.cpp9
-rw-r--r--src/gpu/batches/GrDefaultPathRenderer.cpp3
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp3
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp4
-rw-r--r--src/gpu/effects/GrDisableColorXP.h4
-rw-r--r--src/gpu/effects/GrPorterDuffXferProcessor.cpp62
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();
+}
+