Don't create a GXPFactory when blend is SrcOver
BUG=skia: Review URL: https://codereview.chromium.org/1471053002
This commit is contained in:
parent
60ce86d471
commit
c4b72720e7
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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]],
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user