Don't ref/unref the static src-over xp
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1540363002 bug=chromium:570301 Review URL: https://codereview.chromium.org/1540363002
This commit is contained in:
parent
bada1885da
commit
2047b78555
@ -21,10 +21,16 @@ public:
|
||||
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
|
||||
GrXPFactory::InvariantBlendedColor*) const override;
|
||||
|
||||
|
||||
/** Because src-over is so common we special case it for performance reasons. If this returns
|
||||
null then the SimpleSrcOverXP() below should be used. */
|
||||
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool hasMixedSamples,
|
||||
const GrXferProcessor::DstTexture*);
|
||||
/** This XP implements non-LCD src-over using hw blend with no optimizations. It is returned
|
||||
by reference because it is global and its ref-cnting methods are not thread safe. */
|
||||
static const GrXferProcessor& SimpleSrcOverXP();
|
||||
|
||||
static inline void SrcOverInvariantBlendedColor(
|
||||
GrColor inputColor,
|
||||
|
@ -28,29 +28,30 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
builder.hasMixedSamples(),
|
||||
&args.fDstTexture,
|
||||
*args.fCaps));
|
||||
if (!xferProcessor) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// This may return nullptr in the common case of src-over implemented using hw blending.
|
||||
xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
*args.fCaps,
|
||||
args.fOpts,
|
||||
builder.hasMixedSamples(),
|
||||
&args.fDstTexture));
|
||||
}
|
||||
|
||||
if (!xferProcessor) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrColor overrideColor = GrColor_ILLEGAL;
|
||||
GrColor overrideColor = GrColor_ILLEGAL;
|
||||
if (args.fOpts.fColorPOI.firstEffectiveProcessorIndex() != 0) {
|
||||
overrideColor = args.fOpts.fColorPOI.inputColorToFirstEffectiveProccesor();
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
|
||||
|
||||
optFlags = xferProcessor->getOptimizations(args.fOpts,
|
||||
builder.getStencil().doesWrite(),
|
||||
&overrideColor,
|
||||
*args.fCaps);
|
||||
const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
|
||||
&GrPorterDuffXPFactory::SimpleSrcOverXP();
|
||||
optFlags = xpForOpts->getOptimizations(args.fOpts,
|
||||
builder.getStencil().doesWrite(),
|
||||
&overrideColor,
|
||||
*args.fCaps);
|
||||
|
||||
// When path rendering the stencil settings are not always set on the GrPipelineBuilder
|
||||
// so we must check the draw type. In cases where we will skip drawing we simply return a
|
||||
@ -167,14 +168,12 @@ void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
|
||||
add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
|
||||
}
|
||||
|
||||
if (fXferProcessor.get()) {
|
||||
const GrXferProcessor* xfer = fXferProcessor.get();
|
||||
const GrXferProcessor& xfer = this->getXferProcessor();
|
||||
|
||||
for (int i = 0; i < xfer->numTextures(); ++i) {
|
||||
GrTexture* texture = xfer->textureAccess(i).getTexture();
|
||||
SkASSERT(rt->getLastDrawTarget());
|
||||
rt->getLastDrawTarget()->addDependency(texture);
|
||||
}
|
||||
for (int i = 0; i < xfer.numTextures(); ++i) {
|
||||
GrTexture* texture = xfer.textureAccess(i).getTexture();
|
||||
SkASSERT(rt->getLastDrawTarget());
|
||||
rt->getLastDrawTarget()->addDependency(texture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +184,7 @@ void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelin
|
||||
int* firstColorProcessorIdx,
|
||||
int* firstCoverageProcessorIdx) {
|
||||
fIgnoresCoverage = SkToBool(flags & GrXferProcessor::kIgnoreCoverage_OptFlag);
|
||||
fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
|
||||
fReadsFragPosition = this->getXferProcessor().willReadFragmentPosition();
|
||||
|
||||
if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
|
||||
(flags & GrXferProcessor::kOverrideColor_OptFlag)) {
|
||||
@ -221,8 +220,11 @@ bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.getXferProcessor()->isEqual(*b.getXferProcessor())) {
|
||||
return false;
|
||||
// Most of the time both are nullptr
|
||||
if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
|
||||
if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < a.numFragmentProcessors(); i++) {
|
||||
|
@ -103,7 +103,15 @@ public:
|
||||
}
|
||||
int numFragmentProcessors() const { return fFragmentProcessors.count(); }
|
||||
|
||||
const GrXferProcessor* getXferProcessor() const { return fXferProcessor.get(); }
|
||||
const GrXferProcessor& getXferProcessor() const {
|
||||
if (fXferProcessor.get()) {
|
||||
return *fXferProcessor.get();
|
||||
} else {
|
||||
// A null xp member means the common src-over case. GrXferProcessor's ref'ing
|
||||
// mechanism is not thread safe so we do not hold a ref on this global.
|
||||
return GrPorterDuffXPFactory::SimpleSrcOverXP();
|
||||
}
|
||||
}
|
||||
|
||||
const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
|
||||
SkASSERT(idx < this->numColorFragmentProcessors());
|
||||
@ -136,7 +144,7 @@ public:
|
||||
bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
|
||||
|
||||
GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
|
||||
return fXferProcessor->xferBarrierType(fRenderTarget.get(), caps);
|
||||
return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
this->pipeline()->getCoverageFragmentProcessor(i).name(),
|
||||
this->pipeline()->getCoverageFragmentProcessor(i).dumpInfo().c_str());
|
||||
}
|
||||
string.appendf("XP: %s\n", this->pipeline()->getXferProcessor()->name());
|
||||
string.appendf("XP: %s\n", this->pipeline()->getXferProcessor().name());
|
||||
return string;
|
||||
}
|
||||
|
||||
|
@ -850,6 +850,12 @@ void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp,
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SrcOver Global functions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
|
||||
static BlendFormula gSrcOverBlendFormula = COEFF_FORMULA(kOne_GrBlendCoeff,
|
||||
kISA_GrBlendCoeff);
|
||||
static PorterDuffXferProcessor gSrcOverXP(gSrcOverBlendFormula);
|
||||
return gSrcOverXP;
|
||||
}
|
||||
|
||||
GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
const GrCaps& caps,
|
||||
@ -860,12 +866,11 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
!(optimizations.fCoveragePOI.isSolidWhite() &&
|
||||
!hasMixedSamples &&
|
||||
optimizations.fColorPOI.isOpaque())) {
|
||||
static BlendFormula gSrcOverBlendFormula = COEFF_FORMULA(kOne_GrBlendCoeff,
|
||||
kISA_GrBlendCoeff);
|
||||
static PorterDuffXferProcessor gSrcOverXP(gSrcOverBlendFormula);
|
||||
SkASSERT(!dstTexture || !dstTexture->texture());
|
||||
gSrcOverXP.ref();
|
||||
return &gSrcOverXP;
|
||||
// We return nullptr here, which our caller interprets as meaning "use SimpleSrcOverXP".
|
||||
// We don't simply return the address of that XP here because our caller would have to unref
|
||||
// it and since it is a global object and GrProgramElement's ref-cnting system is not thread
|
||||
// safe.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BlendFormula blendFormula;
|
||||
|
@ -1495,7 +1495,7 @@ void GrGLGpu::flushScissor(const GrScissorState& scissorState,
|
||||
bool GrGLGpu::flushGLState(const DrawArgs& args) {
|
||||
GrXferProcessor::BlendInfo blendInfo;
|
||||
const GrPipeline& pipeline = *args.fPipeline;
|
||||
args.fPipeline->getXferProcessor()->getBlendInfo(&blendInfo);
|
||||
args.fPipeline->getXferProcessor().getBlendInfo(&blendInfo);
|
||||
|
||||
this->flushColorWrite(blendInfo.fWriteColor);
|
||||
this->flushDrawFace(pipeline.getDrawFace());
|
||||
|
@ -89,7 +89,7 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc,
|
||||
|
||||
this->setFragmentData(primProc, pipeline, textureBindings);
|
||||
|
||||
const GrXferProcessor& xp = *pipeline.getXferProcessor();
|
||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||
fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
|
||||
append_texture_bindings(fXferProcessor.get(), xp, textureBindings);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
||||
}
|
||||
}
|
||||
|
||||
const GrXferProcessor& xp = *pipeline.getXferProcessor();
|
||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||
xp.getGLSLProcessorKey(*gpu->glCaps().glslCaps(), &b);
|
||||
//**** use glslCaps here?
|
||||
if (!gen_meta_key(xp, gpu->glCaps(), 0, &b)) {
|
||||
|
@ -93,7 +93,7 @@ bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
|
||||
this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors(), inputColor);
|
||||
this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(), numProcs,
|
||||
inputCoverage);
|
||||
this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputColor, *inputCoverage,
|
||||
this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage,
|
||||
this->pipeline().ignoresCoverage());
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user