Don't create a GXPFactory when blend is SrcOver

BUG=skia:

Review URL: https://codereview.chromium.org/1471053002
This commit is contained in:
egdaniel 2015-11-23 13:20:41 -08:00 committed by Commit bot
parent 60ce86d471
commit c4b72720e7
35 changed files with 199 additions and 90 deletions

View File

@ -221,6 +221,8 @@ protected:
SkASSERT(tt.target());
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.setRenderTarget(rt);
BezierCubicOrConicTestBatch::Geometry geometry;
@ -366,6 +368,8 @@ protected:
SkASSERT(tt.target());
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.setRenderTarget(rt);
BezierCubicOrConicTestBatch::Geometry geometry;
@ -604,6 +608,8 @@ protected:
SkASSERT(tt.target());
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.setRenderTarget(rt);
GrPathUtils::QuadUVMatrix DevToUV(pts);

View File

@ -71,6 +71,8 @@ protected:
return;
}
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
SkRRect rrect = fRRects[curRRect];
rrect.offset(SkIntToScalar(x), SkIntToScalar(y));

View File

@ -190,6 +190,8 @@ protected:
}
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.addCoverageFragmentProcessor(fp);
pipelineBuilder.setRenderTarget(rt);
@ -239,6 +241,8 @@ protected:
}
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.addCoverageFragmentProcessor(fp);
pipelineBuilder.setRenderTarget(rt);

View File

@ -107,6 +107,8 @@ protected:
return;
}
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
SkRRect rrect = fRRects[curRRect];
rrect.offset(SkIntToScalar(x), SkIntToScalar(y));

View File

@ -117,6 +117,8 @@ protected:
for (int m = 0; m < GrTextureDomain::kModeCount; ++m) {
GrTextureDomain::Mode mode = (GrTextureDomain::Mode) m;
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
SkAutoTUnref<const GrFragmentProcessor> fp(
GrTextureDomainEffect::Create(texture, textureMatrices[tm],
GrTextureDomain::MakeTexelDomain(texture,

View File

@ -115,6 +115,8 @@ protected:
for (int i = 0; i < 6; ++i) {
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
SkAutoTUnref<GrFragmentProcessor> fp(
GrYUVtoRGBEffect::Create(texture[indices[i][0]],
texture[indices[i][1]],

View File

@ -204,18 +204,26 @@ public:
const GrFragmentProcessor* dst) const;
/** A subclass may implement this factory function to work with the GPU backend. It is legal
to call this with xpf NULL to simply test the return value. If xpf is non-NULL then the
xfermode may optionally allocate a factory to return to the caller as *xpf. The caller
will install it and own a ref to it. Since the xfermode may or may not assign *xpf, the
caller should set *xpf to NULL beforehand. XferProcessors cannot use a background texture.
*/
to call this with xpf NULL to simply test the return value. If xpf is non-NULL then the
xfermode may optionally allocate a factory to return to the caller as *xpf. The caller
will install it and own a ref to it. Since the xfermode may or may not assign *xpf, the
caller should set *xpf to NULL beforehand. XferProcessors cannot use a background texture.
*/
virtual bool asXPFactory(GrXPFactory** xpf) const;
/** Returns true if the xfermode can be expressed as an xfer processor factory (xpFactory).
This helper calls the asXPFactory() virtual. If the xfermode is NULL, it is treated as
kSrcOver_Mode. It is legal to call this with xpf param NULL to simply test the return value.
*/
static bool AsXPFactory(SkXfermode*, GrXPFactory**);
This helper calls the asXPFactory() virtual. If the xfermode is NULL, it is treated as
kSrcOver_Mode. It is legal to call this with xpf param NULL to simply test the return value.
*/
static inline bool AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) {
if (nullptr == xfermode) {
if (xpf) {
*xpf = nullptr;
}
return true;
}
return xfermode->asXPFactory(xpf);
}
SK_TO_STRING_PUREVIRT()
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()

View File

@ -57,7 +57,7 @@ public:
bool isAntiAlias() const { return fAntiAlias; }
const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory.reset(SkRef(xpFactory));
fXPFactory.reset(SkSafeRef(xpFactory));
return xpFactory;
}
@ -100,10 +100,7 @@ public:
this->numCoverageFragmentProcessors(); }
const GrXPFactory* getXPFactory() const {
if (!fXPFactory) {
fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
}
return fXPFactory.get();
return fXPFactory;
}
const GrFragmentProcessor* getColorFragmentProcessor(int i) const {
@ -127,7 +124,7 @@ public:
fCoverageFragmentProcessors[i]->ref();
}
fXPFactory.reset(SkRef(paint.getXPFactory()));
fXPFactory.reset(SkSafeRef(paint.getXPFactory()));
return *this;
}

View File

@ -316,14 +316,6 @@ public:
bool hasMixedSamples,
const DstTexture*,
const GrCaps& caps) const;
/**
* This function returns true if the GrXferProcessor generated from this factory will be able to
* correctly blend when using RGB coverage. The knownColor and knownColorFlags represent the
* final computed color from the color stages.
*/
virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const = 0;
/**
* Known color information after blending, but before accounting for any coverage.
*/

View File

@ -23,11 +23,6 @@ class GrCoverageSetOpXPFactory : public GrXPFactory {
public:
static GrXPFactory* Create(SkRegion::Op regionOp, bool invertCoverage = false);
bool supportsRGBCoverage(GrColor /*knownColor*/,
uint32_t /*knownColorFlags*/) const override {
return true;
}
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
GrXPFactory::InvariantBlendedColor*) const override;

View File

@ -18,13 +18,36 @@ class GrPorterDuffXPFactory : public GrXPFactory {
public:
static GrXPFactory* Create(SkXfermode::Mode mode);
bool supportsRGBCoverage(GrColor /*knownColor*/, uint32_t /*knownColorFlags*/) const override {
return true;
}
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
GrXPFactory::InvariantBlendedColor*) const override;
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
bool hasMixedSamples,
const GrXferProcessor::DstTexture*);
static inline void SrcOverInvariantBlendedColor(
GrColor inputColor,
GrColorComponentFlags validColorFlags,
bool isOpaque,
GrXPFactory::InvariantBlendedColor* blendedColor) {
if (!isOpaque) {
blendedColor->fWillBlendWithDst = true;
blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
return;
}
blendedColor->fWillBlendWithDst = false;
blendedColor->fKnownColor = inputColor;
blendedColor->fKnownColorFlags = validColorFlags;
}
static bool SrcOverWillNeedDstTexture(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
bool hasMixedSamples);
private:
GrPorterDuffXPFactory(SkXfermode::Mode);

View File

@ -377,6 +377,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
if (this->asFragmentProcessor(&fp, srcTexture, matrix, bounds)) {
SkASSERT(fp);
paint.addColorFragmentProcessor(fp)->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (drawContext) {

View File

@ -660,26 +660,6 @@ bool SkXfermode::asXPFactory(GrXPFactory**) const {
return false;
}
#if SK_SUPPORT_GPU
#include "effects/GrPorterDuffXferProcessor.h"
bool SkXfermode::AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) {
if (nullptr == xfermode) {
if (xpf) {
*xpf = GrPorterDuffXPFactory::Create(kSrcOver_Mode);
}
return true;
} else {
return xfermode->asXPFactory(xpf);
}
}
#else
bool SkXfermode::AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) {
return false;
}
#endif
SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{
// no-op. subclasses should override this
return dst;
@ -920,6 +900,7 @@ void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
#if SK_SUPPORT_GPU
#include "effects/GrCustomXfermode.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrXfermodeFragmentProcessor.h"
bool SkProcCoeffXfermode::asFragmentProcessor(const GrFragmentProcessor** fp,

View File

@ -81,10 +81,6 @@ public:
return new GrArithmeticXPFactory(k1, k2, k3, k4, enforcePMColor);
}
bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const override {
return true;
}
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
GrXPFactory::InvariantBlendedColor*) const override;

View File

@ -1262,6 +1262,8 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
// outer: dst = dst * (1 - src)
// = 0 * src + (1 - src) * dst
paint.setCoverageSetOpXPFactory(SkRegion::kDifference_Op);
} else {
paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
}
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext((*result)->asRenderTarget()));

View File

@ -445,6 +445,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
offsetMatrix,
color,
colorBM.dimensions()))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkIRect colorBounds = bounds;
colorBounds.offset(-colorOffset);
SkMatrix matrix;

View File

@ -59,6 +59,7 @@ static void convolve_gaussian_1d(GrDrawContext* drawContext,
SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
texture, direction, radius, sigma, useBounds, bounds));
paint.addColorFragmentProcessor(conv);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y());
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix);
}
@ -89,6 +90,7 @@ static void convolve_gaussian_2d(GrDrawContext* drawContext,
srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode,
true, sigmaX, sigmaY));
paint.addColorFragmentProcessor(conv);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix);
}
@ -247,6 +249,7 @@ GrTexture* GaussianBlur(GrContext* context,
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
paint.addColorTextureProcessor(srcTexture, matrix, params);
}
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
i < scaleFactorY ? 0.5f : 1.0f);
@ -374,6 +377,7 @@ GrTexture* GaussianBlur(GrContext* context,
// FIXME: this should be mitchell, not bilinear.
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
paint.addColorTextureProcessor(srcTexture, matrix, params);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkRect dstRect(srcRect);
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);

View File

@ -354,6 +354,7 @@ void SkLightingImageFilterInternal::drawRect(GrDrawContext* drawContext,
GrPaint paint;
GrFragmentProcessor* fp = this->getFragmentProcessor(src, matrix, bounds, boundaryMode);
paint.addColorFragmentProcessor(fp)->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
}

View File

@ -479,6 +479,7 @@ void apply_morphology_rect(GrDrawContext* drawContext,
radius,
morphType,
bounds))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
SkRect::Make(srcRect));
}
@ -496,6 +497,7 @@ void apply_morphology_rect_no_bounds(GrDrawContext* drawContext,
direction,
radius,
morphType))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
SkRect::Make(srcRect));
}

View File

@ -608,7 +608,6 @@ const GrFragmentProcessor* GrPerlinNoiseEffect::TestCreate(GrProcessorTestData*
SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
stitchTiles ? &tileSize : nullptr));
GrPaint grPaint;
return shader->asFragmentProcessor(d->fContext,
GrTest::TestMatrix(d->fRandom), nullptr,
kNone_SkFilterQuality);

View File

@ -191,6 +191,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
if (xferFP) {
paint.addColorFragmentProcessor(xferFP)->unref();
}
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (!drawContext) {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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(

View File

@ -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;
}
/**

View File

@ -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));

View File

@ -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) {

View File

@ -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());

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -236,6 +236,8 @@ static void test_path(GrDrawTarget* dt, GrRenderTarget* rt, GrResourceProvider*
const SkPath& path) {
GrTessellatingPathRenderer tess;
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setXPFactory(
GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
pipelineBuilder.setRenderTarget(rt);
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
GrPathRenderer::DrawPathArgs args;