This renames methods and classes that relate to static analysis of combinations of GrDrawOps and GrPipelines.
Change-Id: I737b901a19d3c67d2ff7f95802fb4df35656beb2 Reviewed-on: https://skia-review.googlesource.com/6199 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
bd81a327b5
commit
92aee3d685
@ -10,12 +10,16 @@
|
||||
|
||||
#include "GrColor.h"
|
||||
|
||||
struct GrInitInvariantOutput {
|
||||
GrInitInvariantOutput()
|
||||
: fValidFlags(kNone_GrColorComponentFlags)
|
||||
, fColor(0)
|
||||
, fIsSingleComponent(false)
|
||||
, fIsLCDCoverage(false) {}
|
||||
/**
|
||||
* This describes the color or coverage input that will be seen by the first color or coverage stage
|
||||
* of a GrPipeline. This is also the GrPrimitiveProcessor color or coverage *output*.
|
||||
*/
|
||||
struct GrPipelineInput {
|
||||
GrPipelineInput()
|
||||
: fValidFlags(kNone_GrColorComponentFlags)
|
||||
, fColor(0)
|
||||
, fIsSingleComponent(false)
|
||||
, fIsLCDCoverage(false) {}
|
||||
|
||||
void setKnownFourComponents(GrColor color) {
|
||||
fColor = color;
|
||||
@ -54,6 +58,7 @@ struct GrInitInvariantOutput {
|
||||
// updated
|
||||
};
|
||||
|
||||
/** This describes the output of a GrFragmentProcessor in a GrPipeline. */
|
||||
class GrInvariantOutput {
|
||||
public:
|
||||
GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
|
||||
@ -64,13 +69,13 @@ public:
|
||||
, fWillUseInputColor(true)
|
||||
, fIsLCDCoverage(false) {}
|
||||
|
||||
GrInvariantOutput(const GrInitInvariantOutput& io)
|
||||
: fColor(io.fColor)
|
||||
, fValidFlags(io.fValidFlags)
|
||||
, fIsSingleComponent(io.fIsSingleComponent)
|
||||
, fNonMulStageFound(false)
|
||||
, fWillUseInputColor(false)
|
||||
, fIsLCDCoverage(io.fIsLCDCoverage) {}
|
||||
GrInvariantOutput(const GrPipelineInput& input)
|
||||
: fColor(input.fColor)
|
||||
, fValidFlags(input.fValidFlags)
|
||||
, fIsSingleComponent(input.fIsSingleComponent)
|
||||
, fNonMulStageFound(false)
|
||||
, fWillUseInputColor(false)
|
||||
, fIsLCDCoverage(input.fIsLCDCoverage) {}
|
||||
|
||||
virtual ~GrInvariantOutput() {}
|
||||
|
||||
@ -282,13 +287,13 @@ private:
|
||||
fWillUseInputColor = true;
|
||||
}
|
||||
|
||||
void reset(const GrInitInvariantOutput& io) {
|
||||
fColor = io.fColor;
|
||||
fValidFlags = io.fValidFlags;
|
||||
fIsSingleComponent = io.fIsSingleComponent;
|
||||
void reset(const GrPipelineInput& input) {
|
||||
fColor = input.fColor;
|
||||
fValidFlags = input.fValidFlags;
|
||||
fIsSingleComponent = input.fIsSingleComponent;
|
||||
fNonMulStageFound = false;
|
||||
fWillUseInputColor = true;
|
||||
fIsLCDCoverage = io.fIsLCDCoverage;
|
||||
fIsLCDCoverage = input.fIsLCDCoverage;
|
||||
}
|
||||
|
||||
void internalSetToTransparentBlack() {
|
||||
|
@ -17,7 +17,7 @@
|
||||
class GrShaderCaps;
|
||||
class GrGLSLXferProcessor;
|
||||
class GrProcOptInfo;
|
||||
struct GrPipelineOptimizations;
|
||||
struct GrPipelineAnalysis;
|
||||
|
||||
/**
|
||||
* Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes
|
||||
@ -139,7 +139,7 @@ public:
|
||||
* A caller who calls this function on a XP is required to honor the returned OptFlags
|
||||
* and color values for its draw.
|
||||
*/
|
||||
OptFlags getOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
OptFlags getOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const;
|
||||
@ -227,7 +227,7 @@ public:
|
||||
}
|
||||
return this->onIsEqual(that);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
GrXferProcessor();
|
||||
GrXferProcessor(const DstTexture*, bool willReadDstColor, bool hasMixedSamples);
|
||||
@ -235,7 +235,7 @@ protected:
|
||||
private:
|
||||
void notifyRefCntIsZero() const final {}
|
||||
|
||||
virtual OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
virtual OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const = 0;
|
||||
@ -297,7 +297,7 @@ GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags);
|
||||
class GrXPFactory : public SkRefCnt {
|
||||
public:
|
||||
typedef GrXferProcessor::DstTexture DstTexture;
|
||||
GrXferProcessor* createXferProcessor(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor* createXferProcessor(const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*,
|
||||
const GrCaps& caps) const;
|
||||
@ -319,7 +319,7 @@ public:
|
||||
virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
|
||||
InvariantBlendedColor*) const = 0;
|
||||
|
||||
bool willNeedDstTexture(const GrCaps& caps, const GrPipelineOptimizations& optimizations) const;
|
||||
bool willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) const;
|
||||
|
||||
bool isEqual(const GrXPFactory& that) const {
|
||||
if (this->classID() != that.classID()) {
|
||||
@ -347,18 +347,18 @@ protected:
|
||||
|
||||
private:
|
||||
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const = 0;
|
||||
|
||||
virtual bool onIsEqual(const GrXPFactory&) const = 0;
|
||||
|
||||
bool willReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const;
|
||||
bool willReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const;
|
||||
/**
|
||||
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
|
||||
* shader.
|
||||
*/
|
||||
virtual bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const = 0;
|
||||
virtual bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const = 0;
|
||||
|
||||
static uint32_t GenClassID() {
|
||||
// fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The
|
||||
|
@ -29,12 +29,12 @@ public:
|
||||
private:
|
||||
GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps&,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override {
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
/** 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,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const GrXferProcessor::DstTexture*);
|
||||
/** This XP implements non-LCD src-over using hw blend with no optimizations. It is returned
|
||||
@ -48,17 +48,17 @@ public:
|
||||
blendedColor->fKnownColorFlags = validColorFlags;
|
||||
}
|
||||
|
||||
static bool SrcOverWillNeedDstTexture(const GrCaps&, const GrPipelineOptimizations&);
|
||||
static bool SrcOverWillNeedDstTexture(const GrCaps&, const GrPipelineAnalysis&);
|
||||
|
||||
private:
|
||||
GrPorterDuffXPFactory(SkBlendMode);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override;
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override;
|
||||
|
||||
bool onIsEqual(const GrXPFactory& xpfBase) const override {
|
||||
const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
bool enforcePMColor() const { return fEnforcePMColor; }
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const override;
|
||||
@ -247,12 +247,11 @@ void ArithmeticXP::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKe
|
||||
|
||||
GrGLSLXferProcessor* ArithmeticXP::createGLSLInstance() const { return new GLArithmeticXP(*this); }
|
||||
|
||||
GrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
return GrXferProcessor::kNone_OptFlags;
|
||||
GrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
return GrXferProcessor::kNone_OptFlags;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -263,11 +262,10 @@ GrArithmeticXPFactory::GrArithmeticXPFactory(float k1, float k2, float k3, float
|
||||
this->initClassID<GrArithmeticXPFactory>();
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
GrXferProcessor* GrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
return new ArithmeticXP(dstTexture, hasMixedSamples, fK1, fK2, fK3, fK4, fEnforcePMColor);
|
||||
}
|
||||
|
||||
|
@ -88,11 +88,11 @@ private:
|
||||
GrArithmeticXPFactory(float k1, float k2, float k3, float k4, bool enforcePMColor);
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override {
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "SkTArray.h"
|
||||
#include <map>
|
||||
|
||||
class GrBatchTracker;
|
||||
class GrBuffer;
|
||||
class GrContext;
|
||||
struct GrContextOptions;
|
||||
|
@ -20,8 +20,8 @@ public:
|
||||
static void GenKey(const GrPathProcessor& pathProc,
|
||||
const GrShaderCaps&,
|
||||
GrProcessorKeyBuilder* b) {
|
||||
b->add32(SkToInt(pathProc.overrides().readsColor()) |
|
||||
(SkToInt(pathProc.overrides().readsCoverage()) << 1) |
|
||||
b->add32(SkToInt(pathProc.optimizations().readsColor()) |
|
||||
(SkToInt(pathProc.optimizations().readsCoverage()) << 1) |
|
||||
(SkToInt(pathProc.viewMatrix().hasPerspective()) << 2));
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler);
|
||||
|
||||
// Setup uniform color
|
||||
if (pathProc.overrides().readsColor()) {
|
||||
if (pathProc.optimizations().readsColor()) {
|
||||
const char* stagedLocalVarName;
|
||||
fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
|
||||
kVec4f_GrSLType,
|
||||
@ -48,7 +48,7 @@ public:
|
||||
}
|
||||
|
||||
// setup constant solid coverage
|
||||
if (pathProc.overrides().readsCoverage()) {
|
||||
if (pathProc.optimizations().readsCoverage()) {
|
||||
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
}
|
||||
}
|
||||
@ -79,7 +79,7 @@ public:
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
FPCoordTransformIter&& transformIter) override {
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
if (pathProc.overrides().readsColor() && pathProc.color() != fColor) {
|
||||
if (pathProc.optimizations().readsColor() && pathProc.color() != fColor) {
|
||||
float c[4];
|
||||
GrColorToRGBAFloat(pathProc.color(), c);
|
||||
pd.set4fv(fColorUniform, 1, c);
|
||||
@ -120,13 +120,13 @@ private:
|
||||
};
|
||||
|
||||
GrPathProcessor::GrPathProcessor(GrColor color,
|
||||
const GrXPOverridesForBatch& overrides,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkMatrix& localMatrix)
|
||||
: fColor(color)
|
||||
, fViewMatrix(viewMatrix)
|
||||
, fLocalMatrix(localMatrix)
|
||||
, fOverrides(overrides) {
|
||||
: fColor(color)
|
||||
, fViewMatrix(viewMatrix)
|
||||
, fLocalMatrix(localMatrix)
|
||||
, fOptimizations(optimizations) {
|
||||
this->initClassID<GrPathProcessor>();
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,10 @@
|
||||
class GrPathProcessor : public GrPrimitiveProcessor {
|
||||
public:
|
||||
static GrPathProcessor* Create(GrColor color,
|
||||
const GrXPOverridesForBatch& overrides,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const SkMatrix& viewMatrix = SkMatrix::I(),
|
||||
const SkMatrix& localMatrix = SkMatrix::I()) {
|
||||
return new GrPathProcessor(color, overrides, viewMatrix, localMatrix);
|
||||
return new GrPathProcessor(color, optimizations, viewMatrix, localMatrix);
|
||||
}
|
||||
|
||||
const char* name() const override { return "PathProcessor"; }
|
||||
@ -36,20 +36,20 @@ public:
|
||||
|
||||
virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
|
||||
|
||||
const GrXPOverridesForBatch& overrides() const { return fOverrides; }
|
||||
const GrPipelineOptimizations& optimizations() const { return fOptimizations; }
|
||||
|
||||
virtual bool isPathRendering() const override { return true; }
|
||||
|
||||
private:
|
||||
GrPathProcessor(GrColor color, const GrXPOverridesForBatch& overrides,
|
||||
const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
|
||||
GrPathProcessor(GrColor, const GrPipelineOptimizations&, const SkMatrix& viewMatrix,
|
||||
const SkMatrix& localMatrix);
|
||||
|
||||
bool hasExplicitLocalCoords() const override { return false; }
|
||||
|
||||
GrColor fColor;
|
||||
const SkMatrix fViewMatrix;
|
||||
const SkMatrix fLocalMatrix;
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
|
||||
typedef GrPrimitiveProcessor INHERITED;
|
||||
};
|
||||
|
@ -19,14 +19,14 @@
|
||||
#include "ops/GrOp.h"
|
||||
|
||||
GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
GrXPOverridesForBatch* overrides) {
|
||||
GrPipelineOptimizations* optimizations) {
|
||||
const GrPipelineBuilder& builder = *args.fPipelineBuilder;
|
||||
const GrUserStencilSettings* userStencil = builder.getUserStencil();
|
||||
GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
|
||||
if (!rt) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
GrPipeline* pipeline = new (memory) GrPipeline;
|
||||
pipeline->fRenderTarget.reset(rt);
|
||||
SkASSERT(pipeline->fRenderTarget);
|
||||
@ -64,10 +64,8 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
const GrXPFactory* xpFactory = builder.getXPFactory();
|
||||
sk_sp<GrXferProcessor> xferProcessor;
|
||||
if (xpFactory) {
|
||||
xferProcessor.reset(xpFactory->createXferProcessor(args.fOpts,
|
||||
hasMixedSamples,
|
||||
&args.fDstTexture,
|
||||
*args.fCaps));
|
||||
xferProcessor.reset(xpFactory->createXferProcessor(
|
||||
args.fAnalysis, hasMixedSamples, &args.fDstTexture, *args.fCaps));
|
||||
if (!xferProcessor) {
|
||||
pipeline->~GrPipeline();
|
||||
return nullptr;
|
||||
@ -75,21 +73,18 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
} else {
|
||||
// This may return nullptr in the common case of src-over implemented using hw blending.
|
||||
xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
*args.fCaps,
|
||||
args.fOpts,
|
||||
hasMixedSamples,
|
||||
&args.fDstTexture));
|
||||
*args.fCaps, args.fAnalysis, hasMixedSamples, &args.fDstTexture));
|
||||
}
|
||||
GrColor overrideColor = GrColor_ILLEGAL;
|
||||
if (args.fOpts.fColorPOI.firstEffectiveProcessorIndex() != 0) {
|
||||
overrideColor = args.fOpts.fColorPOI.inputColorToFirstEffectiveProccesor();
|
||||
if (args.fAnalysis.fColorPOI.firstEffectiveProcessorIndex() != 0) {
|
||||
overrideColor = args.fAnalysis.fColorPOI.inputColorToFirstEffectiveProccesor();
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
|
||||
|
||||
const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
|
||||
&GrPorterDuffXPFactory::SimpleSrcOverXP();
|
||||
optFlags = xpForOpts->getOptimizations(args.fOpts,
|
||||
optFlags = xpForOpts->getOptimizations(args.fAnalysis,
|
||||
userStencil->doesWrite(args.fHasStencilClip),
|
||||
&overrideColor,
|
||||
*args.fCaps);
|
||||
@ -109,15 +104,15 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
|
||||
pipeline->fXferProcessor.reset(xferProcessor.get());
|
||||
|
||||
int firstColorProcessorIdx = args.fOpts.fColorPOI.firstEffectiveProcessorIndex();
|
||||
int firstColorProcessorIdx = args.fAnalysis.fColorPOI.firstEffectiveProcessorIndex();
|
||||
|
||||
// TODO: Once we can handle single or four channel input into coverage GrFragmentProcessors
|
||||
// then we can use GrPipelineBuilder's coverageProcInfo (like color above) to set this initial
|
||||
// information.
|
||||
int firstCoverageProcessorIdx = 0;
|
||||
|
||||
pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fOpts.fColorPOI,
|
||||
args.fOpts.fCoveragePOI, &firstColorProcessorIdx,
|
||||
pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fAnalysis.fColorPOI,
|
||||
args.fAnalysis.fCoveragePOI, &firstColorProcessorIdx,
|
||||
&firstCoverageProcessorIdx);
|
||||
|
||||
bool usesLocalCoords = false;
|
||||
@ -143,35 +138,35 @@ GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
|
||||
}
|
||||
|
||||
// Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
|
||||
overrides->fFlags = 0;
|
||||
optimizations->fFlags = 0;
|
||||
if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kReadsColor_Flag;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kReadsColor_Flag;
|
||||
}
|
||||
if (GrColor_ILLEGAL != overrideColor) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kUseOverrideColor_Flag;
|
||||
overrides->fOverrideColor = overrideColor;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
|
||||
optimizations->fOverrideColor = overrideColor;
|
||||
}
|
||||
if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kReadsCoverage_Flag;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kReadsCoverage_Flag;
|
||||
}
|
||||
if (usesLocalCoords) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kReadsLocalCoords_Flag;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
|
||||
}
|
||||
if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kCanTweakAlphaForCoverage_Flag;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
|
||||
}
|
||||
|
||||
GrXPFactory::InvariantBlendedColor blendedColor;
|
||||
if (xpFactory) {
|
||||
xpFactory->getInvariantBlendedColor(args.fOpts.fColorPOI, &blendedColor);
|
||||
xpFactory->getInvariantBlendedColor(args.fAnalysis.fColorPOI, &blendedColor);
|
||||
} else {
|
||||
GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fOpts.fColorPOI.color(),
|
||||
args.fOpts.fColorPOI.validFlags(),
|
||||
args.fOpts.fColorPOI.isOpaque(),
|
||||
GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fAnalysis.fColorPOI.color(),
|
||||
args.fAnalysis.fColorPOI.validFlags(),
|
||||
args.fAnalysis.fColorPOI.isOpaque(),
|
||||
&blendedColor);
|
||||
}
|
||||
if (blendedColor.fWillBlendWithDst) {
|
||||
overrides->fFlags |= GrXPOverridesForBatch::kWillColorBlendWithDst_Flag;
|
||||
optimizations->fFlags |= GrPipelineOptimizations::kWillColorBlendWithDst_Flag;
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
|
@ -31,17 +31,32 @@ class GrOp;
|
||||
class GrPipelineBuilder;
|
||||
class GrRenderTargetContext;
|
||||
|
||||
struct GrBatchToXPOverrides {
|
||||
GrBatchToXPOverrides()
|
||||
: fUsePLSDstRead(false) {}
|
||||
/**
|
||||
* This Describes aspects of the GrPrimitiveProcessor produced by a GrDrawOp that are used in
|
||||
* pipeline analysis.
|
||||
*/
|
||||
class GrPipelineAnalysisDrawOpInput {
|
||||
public:
|
||||
GrPipelineAnalysisDrawOpInput(GrPipelineInput* color, GrPipelineInput* coverage)
|
||||
: fColorInput(color), fCoverageInput(coverage) {}
|
||||
GrPipelineInput* pipelineColorInput() { return fColorInput; }
|
||||
GrPipelineInput* pipelineCoverageInput() { return fCoverageInput; }
|
||||
|
||||
bool fUsePLSDstRead;
|
||||
void setUsesPLSDstRead() { fUsesPLSDstRead = true; }
|
||||
|
||||
bool usesPLSDstRead() const { return fUsesPLSDstRead; }
|
||||
|
||||
private:
|
||||
GrPipelineInput* fColorInput;
|
||||
GrPipelineInput* fCoverageInput;
|
||||
bool fUsesPLSDstRead = false;
|
||||
};
|
||||
|
||||
struct GrPipelineOptimizations {
|
||||
/** This is used to track pipeline analysis through the color and coverage fragment processors. */
|
||||
struct GrPipelineAnalysis {
|
||||
GrProcOptInfo fColorPOI;
|
||||
GrProcOptInfo fCoveragePOI;
|
||||
GrBatchToXPOverrides fOverrides;
|
||||
bool fUsesPLSDstRead = false;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -54,18 +69,18 @@ public:
|
||||
/// @name Creation
|
||||
|
||||
struct CreateArgs {
|
||||
const GrPipelineBuilder* fPipelineBuilder;
|
||||
GrRenderTargetContext* fRenderTargetContext;
|
||||
const GrCaps* fCaps;
|
||||
GrPipelineOptimizations fOpts;
|
||||
const GrScissorState* fScissor;
|
||||
const GrWindowRectsState* fWindowRectsState;
|
||||
bool fHasStencilClip;
|
||||
const GrPipelineBuilder* fPipelineBuilder;
|
||||
GrRenderTargetContext* fRenderTargetContext;
|
||||
const GrCaps* fCaps;
|
||||
GrPipelineAnalysis fAnalysis;
|
||||
const GrScissorState* fScissor;
|
||||
const GrWindowRectsState* fWindowRectsState;
|
||||
bool fHasStencilClip;
|
||||
GrXferProcessor::DstTexture fDstTexture;
|
||||
};
|
||||
|
||||
/** Creates a pipeline into a pre-allocated buffer */
|
||||
static GrPipeline* CreateAt(void* memory, const CreateArgs&, GrXPOverridesForBatch*);
|
||||
static GrPipeline* CreateAt(void* memory, const CreateArgs&, GrPipelineOptimizations*);
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -43,11 +43,11 @@ GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrAAType aaType)
|
||||
//////////////////////////////////////////////////////////////////////////////s
|
||||
|
||||
bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const {
|
||||
const GrPipelineAnalysis& analysis) const {
|
||||
if (this->getXPFactory()) {
|
||||
return this->getXPFactory()->willNeedDstTexture(caps, optimizations);
|
||||
return this->getXPFactory()->willNeedDstTexture(caps, analysis);
|
||||
}
|
||||
return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, optimizations);
|
||||
return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, analysis);
|
||||
}
|
||||
|
||||
void GrPipelineBuilder::AutoRestoreFragmentProcessorState::set(
|
||||
|
@ -164,8 +164,7 @@ public:
|
||||
/**
|
||||
* Checks whether the xp will need destination in a texture to correctly blend.
|
||||
*/
|
||||
bool willXPNeedDstTexture(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const;
|
||||
bool willXPNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis&) const;
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -25,21 +25,9 @@
|
||||
* might be useful for correctness / optimization decisions. The GrPrimitiveProcessor seeds these
|
||||
* loops, one with initial color and one with initial coverage, in its
|
||||
* onComputeInvariantColor / Coverage calls. These seed values are processed by the subsequent
|
||||
* stages of the rendering pipeline and the output is then fed back into the GrPrimitiveProcessor in
|
||||
* the initBatchTracker call, where the GrPrimitiveProcessor can then initialize the GrBatchTracker
|
||||
* struct with the appropriate values.
|
||||
*
|
||||
* We are evolving this system to move towards generating geometric meshes and their associated
|
||||
* vertex data after we have batched and reordered draws. This system, known as 'deferred geometry'
|
||||
* will allow the GrPrimitiveProcessor much greater control over how data is transmitted to shaders.
|
||||
*
|
||||
* In a deferred geometry world, the GrPrimitiveProcessor can always 'batch' To do this, each
|
||||
* primitive type is associated with one GrPrimitiveProcessor, who has complete control of how
|
||||
* it draws. Each primitive draw will bundle all required data to perform the draw, and these
|
||||
* bundles of data will be owned by an instance of the associated GrPrimitiveProcessor. Bundles
|
||||
* can be updated alongside the GrBatchTracker struct itself, ultimately allowing the
|
||||
* GrPrimitiveProcessor complete control of how it gets data into the fragment shader as long as
|
||||
* it emits the appropriate color, or none at all, as directed.
|
||||
* stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
|
||||
* the applyPipelineOptimizations call, where the op can use the information to inform decisions
|
||||
* about GrPrimitiveProcessor creation.
|
||||
*/
|
||||
|
||||
class GrGLSLPrimitiveProcessor;
|
||||
@ -57,15 +45,16 @@ enum GrPixelLocalStorageState {
|
||||
};
|
||||
|
||||
/*
|
||||
* This class allows the GrPipeline to communicate information about the pipeline to a
|
||||
* GrOp which should be forwarded to the GrPrimitiveProcessor(s) created by the batch.
|
||||
* These are not properly part of the pipeline because they assume the specific inputs
|
||||
* that the batch provided when it created the pipeline. Identical pipelines may be
|
||||
* created by different batches with different input assumptions and therefore different
|
||||
* computed optimizations. It is the batch-specific optimizations that allow the pipelines
|
||||
* to be equal.
|
||||
* This class allows the GrPipeline to communicate information about the pipeline to a GrOp which
|
||||
* inform its decisions for GrPrimitiveProcessor setup. These are not properly part of the pipeline
|
||||
* because they reflect the specific inputs that the op provided to perform the analysis (e.g. that
|
||||
* the GrGeometryProcessor would output an opaque color).
|
||||
*
|
||||
* The pipeline analysis that produced this may have decided to elide some GrProcessors. However,
|
||||
* those elisions may depend upon changing the color output by the GrGeometryProcessor used by the
|
||||
* GrDrawOp. The op must check getOverrideColorIfSet() for this.
|
||||
*/
|
||||
class GrXPOverridesForBatch {
|
||||
class GrPipelineOptimizations {
|
||||
public:
|
||||
/** Does the pipeline require the GrPrimitiveProcessor's color? */
|
||||
bool readsColor() const { return SkToBool(kReadsColor_Flag & fFlags); }
|
||||
@ -104,7 +93,7 @@ public:
|
||||
* can conflate coverage and color, so the destination color may still bleed into pixels that
|
||||
* have partial coverage, even if this function returns false.
|
||||
*
|
||||
* The above comment seems incorrect for the use case. This funciton is used to turn two
|
||||
* The above comment seems incorrect for the use case. This function is used to turn two
|
||||
* overlapping draws into a single draw (really to stencil multiple paths and do a single
|
||||
* cover). It seems that what really matters is whether the dst is read for color OR for
|
||||
* coverage.
|
||||
|
@ -17,7 +17,7 @@ void GrProcOptInfo::calcWithInitialValues(const GrFragmentProcessor * const proc
|
||||
GrColorComponentFlags flags,
|
||||
bool areCoverageStages,
|
||||
bool isLCD) {
|
||||
GrInitInvariantOutput out;
|
||||
GrPipelineInput out;
|
||||
out.fIsSingleComponent = areCoverageStages;
|
||||
out.fColor = startColor;
|
||||
out.fValidFlags = flags;
|
||||
@ -26,10 +26,6 @@ void GrProcOptInfo::calcWithInitialValues(const GrFragmentProcessor * const proc
|
||||
this->internalCalc(processors, cnt);
|
||||
}
|
||||
|
||||
void GrProcOptInfo::initUsingInvariantOutput(GrInitInvariantOutput invOutput) {
|
||||
fInOut.reset(invOutput);
|
||||
}
|
||||
|
||||
void GrProcOptInfo::completeCalculations(const GrFragmentProcessor * const processors[], int cnt) {
|
||||
this->internalCalc(processors, cnt);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
void calcWithInitialValues(const GrFragmentProcessor* const *, int cnt, GrColor startColor,
|
||||
GrColorComponentFlags, bool areCoverageStages, bool isLCD = false);
|
||||
void initUsingInvariantOutput(GrInitInvariantOutput invOutput);
|
||||
void initFromPipelineInput(const GrPipelineInput& input) { fInOut.reset(input); }
|
||||
void completeCalculations(const GrFragmentProcessor * const processors[], int cnt);
|
||||
|
||||
bool isSolidWhite() const { return fInOut.isSolidWhite(); }
|
||||
|
@ -297,8 +297,8 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
|
||||
args.fPipelineBuilder = &pipelineBuilder;
|
||||
args.fRenderTargetContext = renderTargetContext;
|
||||
args.fCaps = this->caps();
|
||||
op->getPipelineOptimizations(&args.fOpts);
|
||||
if (args.fOpts.fOverrides.fUsePLSDstRead || fClipOpToBounds) {
|
||||
op->initPipelineAnalysis(&args.fAnalysis);
|
||||
if (args.fAnalysis.fUsesPLSDstRead || fClipOpToBounds) {
|
||||
GrGLIRect viewport;
|
||||
viewport.fLeft = 0;
|
||||
viewport.fBottom = 0;
|
||||
@ -317,12 +317,12 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
|
||||
return;
|
||||
}
|
||||
}
|
||||
args.fOpts.fColorPOI.completeCalculations(
|
||||
sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
|
||||
pipelineBuilder.numColorFragmentProcessors());
|
||||
args.fOpts.fCoveragePOI.completeCalculations(
|
||||
sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
|
||||
pipelineBuilder.numCoverageFragmentProcessors());
|
||||
args.fAnalysis.fColorPOI.completeCalculations(
|
||||
sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
|
||||
pipelineBuilder.numColorFragmentProcessors());
|
||||
args.fAnalysis.fCoveragePOI.completeCalculations(
|
||||
sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
|
||||
pipelineBuilder.numCoverageFragmentProcessors());
|
||||
args.fScissor = &appliedClip.scissorState();
|
||||
args.fWindowRectsState = &appliedClip.windowRectsState();
|
||||
args.fHasStencilClip = appliedClip.hasStencilClip();
|
||||
@ -330,7 +330,7 @@ void GrRenderTargetOpList::addDrawOp(const GrPipelineBuilder& pipelineBuilder,
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), args.fOpts)) {
|
||||
if (pipelineBuilder.willXPNeedDstTexture(*this->caps(), args.fAnalysis)) {
|
||||
this->setupDstTexture(renderTargetContext->accessRenderTarget(), clip, op->bounds(),
|
||||
&args.fDstTexture);
|
||||
if (!args.fDstTexture.texture()) {
|
||||
|
@ -31,20 +31,17 @@ GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
|
||||
}
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
GrXferProcessor::OptFlags flags = this->onGetOptimizations(optimizations,
|
||||
doesStencilWrite,
|
||||
overrideColor,
|
||||
caps);
|
||||
GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrPipelineAnalysis& analysis,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
GrXferProcessor::OptFlags flags =
|
||||
this->onGetOptimizations(analysis, doesStencilWrite, overrideColor, caps);
|
||||
|
||||
if (this->willReadDstColor()) {
|
||||
// When performing a dst read we handle coverage in the base class.
|
||||
SkASSERT(!(flags & GrXferProcessor::kIgnoreCoverage_OptFlag));
|
||||
if (optimizations.fCoveragePOI.isSolidWhite()) {
|
||||
if (analysis.fCoveragePOI.isSolidWhite()) {
|
||||
flags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
|
||||
}
|
||||
}
|
||||
@ -192,12 +189,12 @@ SkString GrXferProcessor::BlendInfo::dump() const {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture,
|
||||
const GrCaps& caps) const {
|
||||
#ifdef SK_DEBUG
|
||||
if (this->willReadDstColor(caps, optimizations)) {
|
||||
if (this->willReadDstColor(caps, analysis)) {
|
||||
if (!caps.shaderCaps()->dstReadInShaderSupport()) {
|
||||
SkASSERT(dstTexture && dstTexture->texture());
|
||||
} else {
|
||||
@ -208,16 +205,13 @@ GrXferProcessor* GrXPFactory::createXferProcessor(const GrPipelineOptimizations&
|
||||
}
|
||||
SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
|
||||
#endif
|
||||
return this->onCreateXferProcessor(caps, optimizations, hasMixedSamples, dstTexture);
|
||||
return this->onCreateXferProcessor(caps, analysis, hasMixedSamples, dstTexture);
|
||||
}
|
||||
|
||||
bool GrXPFactory::willNeedDstTexture(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const {
|
||||
return (this->willReadDstColor(caps, optimizations) &&
|
||||
!caps.shaderCaps()->dstReadInShaderSupport());
|
||||
bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
|
||||
return (this->willReadDstColor(caps, analysis) && !caps.shaderCaps()->dstReadInShaderSupport());
|
||||
}
|
||||
|
||||
bool GrXPFactory::willReadDstColor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const {
|
||||
return optimizations.fOverrides.fUsePLSDstRead || this->onWillReadDstColor(caps, optimizations);
|
||||
bool GrXPFactory::willReadDstColor(const GrCaps& caps, const GrPipelineAnalysis& analysis) const {
|
||||
return analysis.fUsesPLSDstRead || this->onWillReadDstColor(caps, analysis);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
private:
|
||||
CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
|
||||
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis& analysis,
|
||||
bool doesStencilWrite,
|
||||
GrColor* color,
|
||||
const GrCaps& caps) const override;
|
||||
@ -107,11 +107,10 @@ GrGLSLXferProcessor* CoverageSetOpXP::createGLSLInstance() const {
|
||||
return new GLCoverageSetOpXP(*this);
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags
|
||||
CoverageSetOpXP::onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
bool doesStencilWrite,
|
||||
GrColor* color,
|
||||
const GrCaps& caps) const {
|
||||
GrXferProcessor::OptFlags CoverageSetOpXP::onGetOptimizations(const GrPipelineAnalysis& analysis,
|
||||
bool doesStencilWrite,
|
||||
GrColor* color,
|
||||
const GrCaps& caps) const {
|
||||
// We never look at the color input
|
||||
return GrXferProcessor::kIgnoreColor_OptFlag;
|
||||
}
|
||||
@ -168,7 +167,7 @@ public:
|
||||
bool invertCoverage() const { return fInvertCoverage; }
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&, bool, GrColor*,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, bool, GrColor*,
|
||||
const GrCaps&) const override {
|
||||
// We never look at the color input
|
||||
return GrXferProcessor::kIgnoreColor_OptFlag;
|
||||
@ -310,11 +309,10 @@ sk_sp<GrXPFactory> GrCoverageSetOpXPFactory::Make(SkRegion::Op regionOp, bool in
|
||||
}
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
GrXferProcessor* GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
// We don't support inverting coverage with mixed samples. We don't expect to ever want this in
|
||||
// the future, however we could at some point make this work using an inverted coverage
|
||||
// modulation table. Note that an inverted table still won't work if there are coverage procs.
|
||||
@ -323,7 +321,7 @@ GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (optimizations.fOverrides.fUsePLSDstRead) {
|
||||
if (analysis.fUsesPLSDstRead) {
|
||||
return new ShaderCSOXferProcessor(dst, hasMixedSamples, fRegionOp, fInvertCoverage);
|
||||
}
|
||||
return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
|
||||
|
@ -53,15 +53,15 @@ static GrBlendEquation hw_blend_equation(SkBlendMode mode) {
|
||||
}
|
||||
|
||||
static bool can_use_hw_blend_equation(GrBlendEquation equation,
|
||||
const GrPipelineOptimizations& opt,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
const GrCaps& caps) {
|
||||
if (!caps.advancedBlendEquationSupport()) {
|
||||
return false;
|
||||
}
|
||||
if (opt.fOverrides.fUsePLSDstRead) {
|
||||
if (analysis.fUsesPLSDstRead) {
|
||||
return false;
|
||||
}
|
||||
if (opt.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
return false; // LCD coverage must be applied after the blend equation.
|
||||
}
|
||||
if (caps.canUseAdvancedBlendEquation(equation)) {
|
||||
@ -102,7 +102,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const override;
|
||||
@ -200,111 +200,113 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
|
||||
return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrPipelineAnalysis& analysis,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
/*
|
||||
Most the optimizations we do here are based on tweaking alpha for coverage.
|
||||
/*
|
||||
Most the optimizations we do here are based on tweaking alpha for coverage.
|
||||
|
||||
The general SVG blend equation is defined in the spec as follows:
|
||||
The general SVG blend equation is defined in the spec as follows:
|
||||
|
||||
Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
|
||||
Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)
|
||||
Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
|
||||
Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)
|
||||
|
||||
(Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
|
||||
and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
|
||||
RGB colors.)
|
||||
(Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
|
||||
and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
|
||||
RGB colors.)
|
||||
|
||||
For every blend mode supported by this class, i.e. the "advanced" blend
|
||||
modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.
|
||||
For every blend mode supported by this class, i.e. the "advanced" blend
|
||||
modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.
|
||||
|
||||
It can be shown that when X=Y=Z=1, these equations can modulate alpha for
|
||||
coverage.
|
||||
It can be shown that when X=Y=Z=1, these equations can modulate alpha for
|
||||
coverage.
|
||||
|
||||
|
||||
== Color ==
|
||||
== Color ==
|
||||
|
||||
We substitute Y=Z=1 and define a blend() function that calculates Dca' in
|
||||
terms of premultiplied alpha only:
|
||||
We substitute Y=Z=1 and define a blend() function that calculates Dca' in
|
||||
terms of premultiplied alpha only:
|
||||
|
||||
blend(Sca, Dca, Sa, Da) = {Dca : if Sa == 0,
|
||||
Sca : if Da == 0,
|
||||
B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa) : if Sa,Da != 0}
|
||||
blend(Sca, Dca, Sa, Da) = {Dca : if Sa == 0,
|
||||
Sca : if Da == 0,
|
||||
B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa) : if
|
||||
Sa,Da != 0}
|
||||
|
||||
And for coverage modulation, we use a post blend src-over model:
|
||||
And for coverage modulation, we use a post blend src-over model:
|
||||
|
||||
Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
|
||||
(Where f is the fractional coverage.)
|
||||
(Where f is the fractional coverage.)
|
||||
|
||||
Next we show that canTweakAlphaForCoverage() is true by proving the
|
||||
following relationship:
|
||||
Next we show that canTweakAlphaForCoverage() is true by proving the
|
||||
following relationship:
|
||||
|
||||
blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
|
||||
General case (f,Sa,Da != 0):
|
||||
General case (f,Sa,Da != 0):
|
||||
|
||||
f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f) * Dca [Sa,Da != 0, definition of blend()]
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * Sa + Dca - f*Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
|
||||
= B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa) [f!=0]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [definition of blend()]
|
||||
f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f) * Dca [Sa,Da !=
|
||||
0, definition of blend()]
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * Sa + Dca - f*Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
|
||||
= B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
|
||||
= B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa) [f!=0]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [definition of blend()]
|
||||
|
||||
Corner cases (Sa=0, Da=0, and f=0):
|
||||
Corner cases (Sa=0, Da=0, and f=0):
|
||||
|
||||
Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * Dca + (1-f) * Dca [Sa=0, definition of blend()]
|
||||
= Dca
|
||||
= blend(0, Dca, 0, Da) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [Sa=0]
|
||||
Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * Dca + (1-f) * Dca [Sa=0, definition of blend()]
|
||||
= Dca
|
||||
= blend(0, Dca, 0, Da) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [Sa=0]
|
||||
|
||||
Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * Sca + (1-f) * Dca [Da=0, definition of blend()]
|
||||
= f * Sca [Da=0]
|
||||
= blend(f*Sca, 0, f*Sa, 0) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [Da=0]
|
||||
Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= f * Sca + (1-f) * Dca [Da=0, definition of blend()]
|
||||
= f * Sca [Da=0]
|
||||
= blend(f*Sca, 0, f*Sa, 0) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [Da=0]
|
||||
|
||||
f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= Dca [f=0]
|
||||
= blend(0, Dca, 0, Da) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [f=0]
|
||||
f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
|
||||
= Dca [f=0]
|
||||
= blend(0, Dca, 0, Da) [definition of blend()]
|
||||
= blend(f*Sca, Dca, f*Sa, Da) [f=0]
|
||||
|
||||
== Alpha ==
|
||||
== Alpha ==
|
||||
|
||||
We substitute X=Y=Z=1 and define a blend() function that calculates Da':
|
||||
We substitute X=Y=Z=1 and define a blend() function that calculates Da':
|
||||
|
||||
blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
|
||||
= Sa * Da + Sa - Sa * Da + Da - Da * Sa
|
||||
= Sa + Da - Sa * Da
|
||||
blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
|
||||
= Sa * Da + Sa - Sa * Da + Da - Da * Sa
|
||||
= Sa + Da - Sa * Da
|
||||
|
||||
We use the same model for coverage modulation as we did with color:
|
||||
We use the same model for coverage modulation as we did with color:
|
||||
|
||||
Da'' = f * blend(Sa, Da) + (1-f) * Da
|
||||
Da'' = f * blend(Sa, Da) + (1-f) * Da
|
||||
|
||||
And show that canTweakAlphaForCoverage() is true by proving the following
|
||||
relationship:
|
||||
And show that canTweakAlphaForCoverage() is true by proving the following
|
||||
relationship:
|
||||
|
||||
blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da
|
||||
blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da
|
||||
|
||||
|
||||
f * blend(Sa, Da) + (1-f) * Da
|
||||
= f * (Sa + Da - Sa * Da) + (1-f) * Da
|
||||
= f*Sa + f*Da - f*Sa * Da + Da - f*Da
|
||||
= f*Sa - f*Sa * Da + Da
|
||||
= f*Sa + Da - f*Sa * Da
|
||||
= blend(f*Sa, Da)
|
||||
*/
|
||||
f * blend(Sa, Da) + (1-f) * Da
|
||||
= f * (Sa + Da - Sa * Da) + (1-f) * Da
|
||||
= f*Sa + f*Da - f*Sa * Da + Da - f*Da
|
||||
= f*Sa - f*Sa * Da + Da
|
||||
= f*Sa + Da - f*Sa * Da
|
||||
= blend(f*Sa, Da)
|
||||
*/
|
||||
|
||||
OptFlags flags = kNone_OptFlags;
|
||||
if (optimizations.fColorPOI.allStagesMultiplyInput()) {
|
||||
if (analysis.fColorPOI.allStagesMultiplyInput()) {
|
||||
flags |= kCanTweakAlphaForCoverage_OptFlag;
|
||||
}
|
||||
if (this->hasHWBlendEquation() && optimizations.fCoveragePOI.isSolidWhite()) {
|
||||
if (this->hasHWBlendEquation() && analysis.fCoveragePOI.isSolidWhite()) {
|
||||
flags |= kIgnoreCoverage_OptFlag;
|
||||
}
|
||||
return flags;
|
||||
@ -333,11 +335,11 @@ public:
|
||||
|
||||
private:
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture*) const override;
|
||||
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override;
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override;
|
||||
|
||||
bool onIsEqual(const GrXPFactory& xpfBase) const override {
|
||||
const CustomXPFactory& xpf = xpfBase.cast<CustomXPFactory>();
|
||||
@ -360,10 +362,10 @@ CustomXPFactory::CustomXPFactory(SkBlendMode mode)
|
||||
}
|
||||
|
||||
GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& opt,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
if (can_use_hw_blend_equation(fHWBlendEquation, opt, caps)) {
|
||||
if (can_use_hw_blend_equation(fHWBlendEquation, analysis, caps)) {
|
||||
SkASSERT(!dstTexture || !dstTexture->texture());
|
||||
return new CustomXP(fMode, fHWBlendEquation);
|
||||
}
|
||||
@ -371,8 +373,8 @@ GrXferProcessor* CustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
}
|
||||
|
||||
bool CustomXPFactory::onWillReadDstColor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const {
|
||||
return !can_use_hw_blend_equation(fHWBlendEquation, optimizations, caps);
|
||||
const GrPipelineAnalysis& analysis) const {
|
||||
return !can_use_hw_blend_equation(fHWBlendEquation, analysis, caps);
|
||||
}
|
||||
|
||||
void CustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
private:
|
||||
DisableColorXP();
|
||||
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* color,
|
||||
const GrCaps& caps) const override {
|
||||
@ -93,12 +93,11 @@ GrDisableColorXPFactory::GrDisableColorXPFactory() {
|
||||
this->initClassID<GrDisableColorXPFactory>();
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
SkASSERT(!optimizations.fOverrides.fUsePLSDstRead);
|
||||
GrXferProcessor* GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dst) const {
|
||||
SkASSERT(!analysis.fUsesPLSDstRead);
|
||||
return DisableColorXP::Create();
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,11 @@ private:
|
||||
GrDisableColorXPFactory();
|
||||
|
||||
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis&,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const override;
|
||||
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineOptimizations&) const override {
|
||||
bool onWillReadDstColor(const GrCaps&, const GrPipelineAnalysis&) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -354,10 +354,10 @@ public:
|
||||
BlendFormula getBlendFormula() const { return fBlendFormula; }
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const override;
|
||||
const GrCaps&) const override;
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
@ -471,11 +471,11 @@ GrGLSLXferProcessor* PorterDuffXferProcessor::createGLSLInstance() const {
|
||||
return new GLPorterDuffXferProcessor;
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags
|
||||
PorterDuffXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
GrXferProcessor::OptFlags PorterDuffXferProcessor::onGetOptimizations(
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
|
||||
if (!fBlendFormula.modifiesDst()) {
|
||||
if (!doesStencilWrite) {
|
||||
@ -488,12 +488,12 @@ PorterDuffXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optim
|
||||
if (!fBlendFormula.usesInputColor()) {
|
||||
optFlags |= GrXferProcessor::kIgnoreColor_OptFlag;
|
||||
}
|
||||
if (optimizations.fCoveragePOI.isSolidWhite()) {
|
||||
if (analysis.fCoveragePOI.isSolidWhite()) {
|
||||
optFlags |= GrXferProcessor::kIgnoreCoverage_OptFlag;
|
||||
}
|
||||
if (optimizations.fColorPOI.allStagesMultiplyInput() &&
|
||||
if (analysis.fColorPOI.allStagesMultiplyInput() &&
|
||||
fBlendFormula.canTweakAlphaForCoverage() &&
|
||||
!optimizations.fCoveragePOI.isFourChannelOutput()) {
|
||||
!analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
optFlags |= GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag;
|
||||
}
|
||||
}
|
||||
@ -519,7 +519,7 @@ public:
|
||||
SkBlendMode getXfermode() const { return fXfermode; }
|
||||
|
||||
private:
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&, bool, GrColor*,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&, bool, GrColor*,
|
||||
const GrCaps&) const override {
|
||||
return kNone_OptFlags;
|
||||
}
|
||||
@ -594,10 +594,10 @@ public:
|
||||
private:
|
||||
PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha);
|
||||
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const override;
|
||||
const GrCaps&) const override;
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
|
||||
|
||||
@ -683,17 +683,16 @@ GrGLSLXferProcessor* PDLCDXferProcessor::createGLSLInstance() const {
|
||||
return new GLPDLCDXferProcessor(*this);
|
||||
}
|
||||
|
||||
GrXferProcessor::OptFlags
|
||||
PDLCDXferProcessor::onGetOptimizations(const GrPipelineOptimizations& optimizations,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
// We want to force our primary output to be alpha * Coverage, where alpha is the alpha
|
||||
// value of the blend the constant. We should already have valid blend coeff's if we are at
|
||||
// a point where we have RGB coverage. We don't need any color stages since the known color
|
||||
// output is already baked into the blendConstant.
|
||||
*overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha);
|
||||
return GrXferProcessor::kOverrideColor_OptFlag;
|
||||
GrXferProcessor::OptFlags PDLCDXferProcessor::onGetOptimizations(const GrPipelineAnalysis&,
|
||||
bool doesStencilWrite,
|
||||
GrColor* overrideColor,
|
||||
const GrCaps& caps) const {
|
||||
// We want to force our primary output to be alpha * Coverage, where alpha is the alpha
|
||||
// value of the blend the constant. We should already have valid blend coeff's if we are at
|
||||
// a point where we have RGB coverage. We don't need any color stages since the known color
|
||||
// output is already baked into the blendConstant.
|
||||
*overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha);
|
||||
return GrXferProcessor::kOverrideColor_OptFlag;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -734,29 +733,28 @@ sk_sp<GrXPFactory> GrPorterDuffXPFactory::Make(SkBlendMode xfermode) {
|
||||
return sk_sp<GrXPFactory>(SkRef(gFactories[(int)xfermode]));
|
||||
}
|
||||
|
||||
GrXferProcessor*
|
||||
GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
if (optimizations.fOverrides.fUsePLSDstRead) {
|
||||
GrXferProcessor* GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const DstTexture* dstTexture) const {
|
||||
if (analysis.fUsesPLSDstRead) {
|
||||
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode);
|
||||
}
|
||||
BlendFormula blendFormula;
|
||||
if (optimizations.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (SkBlendMode::kSrcOver == fXfermode &&
|
||||
kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() &&
|
||||
kRGBA_GrColorComponentFlags == analysis.fColorPOI.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(fXfermode, optimizations.fColorPOI);
|
||||
return PDLCDXferProcessor::Create(fXfermode, analysis.fColorPOI);
|
||||
}
|
||||
blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode);
|
||||
blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, fXfermode);
|
||||
} else {
|
||||
blendFormula = get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI,
|
||||
hasMixedSamples, fXfermode);
|
||||
blendFormula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, hasMixedSamples,
|
||||
fXfermode);
|
||||
}
|
||||
|
||||
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
|
||||
@ -799,7 +797,7 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
|
||||
}
|
||||
|
||||
bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) const {
|
||||
const GrPipelineAnalysis& analysis) const {
|
||||
if (caps.shaderCaps()->dualSourceBlendingSupport()) {
|
||||
return false;
|
||||
}
|
||||
@ -807,21 +805,22 @@ bool GrPorterDuffXPFactory::onWillReadDstColor(const GrCaps& caps,
|
||||
// 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 (optimizations.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (SkBlendMode::kSrcOver == fXfermode &&
|
||||
kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() &&
|
||||
kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
|
||||
!caps.shaderCaps()->dstReadInShaderSupport()) {
|
||||
return false;
|
||||
}
|
||||
return get_lcd_blend_formula(optimizations.fCoveragePOI, fXfermode).hasSecondaryOutput();
|
||||
return get_lcd_blend_formula(analysis.fCoveragePOI, fXfermode).hasSecondaryOutput();
|
||||
}
|
||||
|
||||
// We fallback on the shader XP when the blend formula would use dual source blending but we
|
||||
// don't have support for it.
|
||||
static const bool kHasMixedSamples = false;
|
||||
SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending.
|
||||
return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI, kHasMixedSamples,
|
||||
fXfermode).hasSecondaryOutput();
|
||||
auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples,
|
||||
fXfermode);
|
||||
return formula.hasSecondaryOutput();
|
||||
}
|
||||
|
||||
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
|
||||
@ -856,10 +855,10 @@ const GrXferProcessor& GrPorterDuffXPFactory::SimpleSrcOverXP() {
|
||||
|
||||
GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const GrPipelineAnalysis& analysis,
|
||||
bool hasMixedSamples,
|
||||
const GrXferProcessor::DstTexture* dstTexture) {
|
||||
if (optimizations.fOverrides.fUsePLSDstRead) {
|
||||
if (analysis.fUsesPLSDstRead) {
|
||||
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
|
||||
}
|
||||
|
||||
@ -867,7 +866,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
// doing lcd blending we will just use our global SimpleSrcOverXP. This slightly differs from
|
||||
// the general case where we convert a src-over blend that has solid coverage and an opaque
|
||||
// color to src-mode, which allows disabling of blending.
|
||||
if (!optimizations.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (!analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
// 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
|
||||
@ -875,18 +874,18 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() &&
|
||||
if (kRGBA_GrColorComponentFlags == analysis.fColorPOI.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(SkBlendMode::kSrcOver, optimizations.fColorPOI);
|
||||
return PDLCDXferProcessor::Create(SkBlendMode::kSrcOver, analysis.fColorPOI);
|
||||
}
|
||||
|
||||
BlendFormula blendFormula;
|
||||
blendFormula = get_lcd_blend_formula(optimizations.fCoveragePOI, SkBlendMode::kSrcOver);
|
||||
blendFormula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver);
|
||||
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
|
||||
return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkBlendMode::kSrcOver);
|
||||
}
|
||||
@ -896,7 +895,7 @@ GrXferProcessor* GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
|
||||
}
|
||||
|
||||
bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) {
|
||||
const GrPipelineAnalysis& analysis) {
|
||||
if (caps.shaderCaps()->dstReadInShaderSupport() ||
|
||||
caps.shaderCaps()->dualSourceBlendingSupport()) {
|
||||
return false;
|
||||
@ -905,19 +904,20 @@ bool GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(const GrCaps& caps,
|
||||
// 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 (optimizations.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (kRGBA_GrColorComponentFlags == optimizations.fColorPOI.validFlags() &&
|
||||
if (analysis.fCoveragePOI.isFourChannelOutput()) {
|
||||
if (kRGBA_GrColorComponentFlags == analysis.fColorPOI.validFlags() &&
|
||||
!caps.shaderCaps()->dstReadInShaderSupport()) {
|
||||
return false;
|
||||
}
|
||||
return get_lcd_blend_formula(optimizations.fCoveragePOI,
|
||||
SkBlendMode::kSrcOver).hasSecondaryOutput();
|
||||
auto formula = get_lcd_blend_formula(analysis.fCoveragePOI, SkBlendMode::kSrcOver);
|
||||
return formula.hasSecondaryOutput();
|
||||
}
|
||||
|
||||
// We fallback on the shader XP when the blend formula would use dual source blending but we
|
||||
// don't have support for it.
|
||||
static const bool kHasMixedSamples = false;
|
||||
SkASSERT(!caps.usesMixedSamples()); // We never use mixed samples without dual source blending.
|
||||
return get_blend_formula(optimizations.fColorPOI, optimizations.fCoveragePOI,
|
||||
kHasMixedSamples, SkBlendMode::kSrcOver).hasSecondaryOutput();
|
||||
auto formula = get_blend_formula(analysis.fColorPOI, analysis.fCoveragePOI, kHasMixedSamples,
|
||||
SkBlendMode::kSrcOver);
|
||||
return formula.hasSecondaryOutput();
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLUniformHandler.h"
|
||||
|
||||
class GrBatchTracker;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrGLSLPPFragmentBuilder;
|
||||
class GrGLSLGeometryBuilder;
|
||||
|
@ -334,21 +334,20 @@ void InstancedRendering::Op::appendParamsTexel(SkScalar x, SkScalar y, SkScalar
|
||||
fInfo.fHasParams = true;
|
||||
}
|
||||
|
||||
void InstancedRendering::Op::computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const {
|
||||
color->setKnownFourComponents(this->getSingleInstance().fColor);
|
||||
void InstancedRendering::Op::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const {
|
||||
input->pipelineColorInput()->setKnownFourComponents(this->getSingleInstance().fColor);
|
||||
|
||||
if (AntialiasMode::kCoverage == fInfo.fAntialiasMode ||
|
||||
(AntialiasMode::kNone == fInfo.fAntialiasMode &&
|
||||
!fInfo.isSimpleRects() && fInfo.fCannotDiscard)) {
|
||||
coverage->setUnknownSingleComponent();
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
} else {
|
||||
coverage->setKnownSingleComponent(255);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(255);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancedRendering::Op::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
void InstancedRendering::Op::applyPipelineOptimizations(
|
||||
const GrPipelineOptimizations& optimizations) {
|
||||
Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 command.
|
||||
SkASSERT(draw.fGeometry.isEmpty());
|
||||
SkASSERT(SkIsPow2(fInfo.fShapeTypes));
|
||||
@ -370,12 +369,12 @@ void InstancedRendering::Op::initBatchTracker(const GrXPOverridesForBatch& overr
|
||||
}
|
||||
|
||||
GrColor overrideColor;
|
||||
if (overrides.getOverrideColorIfSet(&overrideColor)) {
|
||||
if (optimizations.getOverrideColorIfSet(&overrideColor)) {
|
||||
SkASSERT(State::kRecordingDraws == fInstancedRendering->fState);
|
||||
this->getSingleInstance().fColor = overrideColor;
|
||||
}
|
||||
fInfo.fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fInfo.fCannotTweakAlphaForCoverage = !overrides.canTweakAlphaForCoverage();
|
||||
fInfo.fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fInfo.fCannotTweakAlphaForCoverage = !optimizations.canTweakAlphaForCoverage();
|
||||
|
||||
fInstancedRendering->fTrackedOps.addToTail(this);
|
||||
fIsTracked = true;
|
||||
@ -475,7 +474,7 @@ void InstancedRendering::Op::onDraw(GrOpFlushState* state, const SkRect& bounds)
|
||||
}
|
||||
|
||||
void InstancedRendering::endFlush() {
|
||||
// The caller is expected to delete all tracked ops (i.e. ops whose initBatchTracker
|
||||
// The caller is expected to delete all tracked ops (i.e. ops whose applyPipelineOptimizations
|
||||
// method has been called) before ending the flush.
|
||||
SkASSERT(fTrackedOps.isEmpty());
|
||||
fParams.reset();
|
||||
|
@ -134,16 +134,6 @@ protected:
|
||||
protected:
|
||||
Op(uint32_t classID, InstancedRendering* ir);
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override;
|
||||
bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides*) const override;
|
||||
|
||||
void onPrepare(GrOpFlushState*) override {}
|
||||
void onDraw(GrOpFlushState*, const SkRect& bounds) override;
|
||||
|
||||
InstancedRendering* const fInstancedRendering;
|
||||
OpInfo fInfo;
|
||||
SkScalar fPixelLoad;
|
||||
@ -154,6 +144,13 @@ protected:
|
||||
Draw* fHeadDraw;
|
||||
Draw* fTailDraw;
|
||||
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override;
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
|
||||
bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override;
|
||||
void onPrepare(GrOpFlushState*) override {}
|
||||
void onDraw(GrOpFlushState*, const SkRect& bounds) override;
|
||||
|
||||
typedef GrDrawOp INHERITED;
|
||||
|
||||
friend class InstancedRendering;
|
||||
|
@ -749,13 +749,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
AAConvexPathOp(GrColor color, const SkMatrix& viewMatrix, const SkPath& path)
|
||||
: INHERITED(ClassID()), fColor(color) {
|
||||
@ -763,17 +756,21 @@ private:
|
||||
this->setTransformedBounds(path.getBounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
fLinesOnly = SkPath::kLine_SegmentMask == fPaths[0].fPath.getSegmentMasks();
|
||||
fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
|
||||
fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
|
||||
}
|
||||
|
||||
void prepareLinesOnlyDraws(Target* target) const {
|
||||
|
@ -145,13 +145,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fShapes[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
AADistanceFieldPathOp(GrColor color, const GrShape& shape, const SkMatrix& viewMatrix,
|
||||
GrDrawOpAtlas* atlas, ShapeCache* shapeCache, ShapeDataList* shapeList,
|
||||
@ -170,16 +163,20 @@ private:
|
||||
this->setTransformedBounds(shape.bounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fShapes[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fShapes[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fShapes[0].fColor);
|
||||
optimizations.getOverrideColorIfSet(&fShapes[0].fColor);
|
||||
|
||||
fColorIgnored = !overrides.readsColor();
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fColorIgnored = !optimizations.readsColor();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
struct FlushInfo {
|
||||
|
@ -52,7 +52,7 @@ static void generate_aa_fill_rect_geometry(intptr_t verts,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkRect& rect,
|
||||
const SkRect& devRect,
|
||||
const GrXPOverridesForBatch& overrides,
|
||||
const GrPipelineOptimizations& optimizations,
|
||||
const SkMatrix* localMatrix) {
|
||||
SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
|
||||
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
|
||||
@ -115,7 +115,7 @@ static void generate_aa_fill_rect_geometry(intptr_t verts,
|
||||
localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
|
||||
}
|
||||
|
||||
bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
|
||||
bool tweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
|
||||
|
||||
// Make verts point to vertex color and then set all the color and coverage vertex attrs
|
||||
// values.
|
||||
@ -195,30 +195,27 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one rect
|
||||
color->setKnownFourComponents(this->first()->color());
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
GrColor color;
|
||||
if (overrides.getOverrideColorIfSet(&color)) {
|
||||
if (optimizations.getOverrideColorIfSet(&color)) {
|
||||
this->first()->setColor(color);
|
||||
}
|
||||
fOverrides = overrides;
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(this->first()->color());
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
bool needLocalCoords = fOverrides.readsLocalCoords();
|
||||
bool needLocalCoords = fOptimizations.readsLocalCoords();
|
||||
using namespace GrDefaultGeoProcFactory;
|
||||
|
||||
Color color(Color::kAttribute_Type);
|
||||
Coverage::Type coverageType;
|
||||
if (fOverrides.canTweakAlphaForCoverage()) {
|
||||
if (fOptimizations.canTweakAlphaForCoverage()) {
|
||||
coverageType = Coverage::kSolid_Type;
|
||||
} else {
|
||||
coverageType = Coverage::kAttribute_Type;
|
||||
@ -258,7 +255,8 @@ private:
|
||||
}
|
||||
}
|
||||
generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(),
|
||||
info->rect(), info->devRect(), fOverrides, localMatrix);
|
||||
info->rect(), info->devRect(), fOptimizations,
|
||||
localMatrix);
|
||||
info = this->next(info);
|
||||
}
|
||||
helper.recordDraw(target, gp.get());
|
||||
@ -273,8 +271,9 @@ private:
|
||||
|
||||
// In the event of two ops, one who can tweak, one who cannot, we just fall back to not
|
||||
// tweaking.
|
||||
if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
|
||||
fOverrides = that->fOverrides;
|
||||
if (fOptimizations.canTweakAlphaForCoverage() &&
|
||||
!that->fOptimizations.canTweakAlphaForCoverage()) {
|
||||
fOptimizations = that->fOptimizations;
|
||||
}
|
||||
|
||||
fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin());
|
||||
@ -335,7 +334,7 @@ private:
|
||||
return reinterpret_cast<const RectInfo*>(next);
|
||||
}
|
||||
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData;
|
||||
int fRectCnt;
|
||||
|
||||
|
@ -704,13 +704,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
AAHairlineOp(GrColor color,
|
||||
uint8_t coverage,
|
||||
@ -724,14 +717,17 @@ private:
|
||||
IsZeroArea::kYes);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target*) const override;
|
||||
|
@ -152,14 +152,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one path.
|
||||
color->setKnownFourComponents(fPaths[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
AAFlatteningConvexPathOp(GrColor color,
|
||||
const SkMatrix& viewMatrix,
|
||||
@ -186,18 +178,22 @@ private:
|
||||
this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fPaths[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fPaths[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fPaths[0].fColor);
|
||||
optimizations.getOverrideColorIfSet(&fPaths[0].fColor);
|
||||
|
||||
// setup batch properties
|
||||
fColor = fPaths[0].fColor;
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
|
||||
}
|
||||
|
||||
void draw(GrMeshDrawOp::Target* target, const GrGeometryProcessor* gp, int vertexCount,
|
||||
|
@ -163,18 +163,15 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fRects[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
AAStrokeRectOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fRects[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
|
||||
void onPrepareDraws(Target*) const override;
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override;
|
||||
|
||||
static const int kMiterIndexCnt = 3 * 24;
|
||||
static const int kMiterVertexCnt = 16;
|
||||
@ -224,15 +221,15 @@ private:
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
};
|
||||
|
||||
void AAStrokeRectOp::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
if (!overrides.readsColor()) {
|
||||
void AAStrokeRectOp::applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) {
|
||||
if (!optimizations.readsColor()) {
|
||||
fRects[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
optimizations.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
|
||||
// setup batch properties
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCanTweakAlphaForCoverage = overrides.canTweakAlphaForCoverage();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
|
||||
fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
|
||||
}
|
||||
|
||||
void AAStrokeRectOp::onPrepareDraws(Target* target) const {
|
||||
|
@ -267,19 +267,15 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one rect.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
|
@ -45,40 +45,37 @@ SkString GrAtlasTextOp::dumpInfo() const {
|
||||
return str;
|
||||
}
|
||||
|
||||
void GrAtlasTextOp::computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const {
|
||||
void GrAtlasTextOp::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const {
|
||||
if (kColorBitmapMask_MaskType == fMaskType) {
|
||||
color->setUnknownFourComponents();
|
||||
input->pipelineColorInput()->setUnknownFourComponents();
|
||||
} else {
|
||||
color->setKnownFourComponents(fColor);
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
}
|
||||
switch (fMaskType) {
|
||||
case kGrayscaleDistanceField_MaskType:
|
||||
case kGrayscaleCoverageMask_MaskType:
|
||||
coverage->setUnknownSingleComponent();
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
break;
|
||||
case kLCDCoverageMask_MaskType:
|
||||
case kLCDDistanceField_MaskType:
|
||||
coverage->setUnknownOpaqueFourComponents();
|
||||
coverage->setUsingLCDCoverage();
|
||||
input->pipelineCoverageInput()->setUnknownOpaqueFourComponents();
|
||||
input->pipelineCoverageInput()->setUsingLCDCoverage();
|
||||
break;
|
||||
case kColorBitmapMask_MaskType:
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
}
|
||||
|
||||
void GrAtlasTextOp::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void GrAtlasTextOp::applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) {
|
||||
if (!optimizations.readsColor()) {
|
||||
fGeoData[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
|
||||
fColorIgnored = !overrides.readsColor();
|
||||
fColorIgnored = !optimizations.readsColor();
|
||||
fColor = fGeoData[0].fColor;
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
void GrAtlasTextOp::onPrepareDraws(Target* target) const {
|
||||
|
@ -92,13 +92,9 @@ public:
|
||||
|
||||
SkString dumpInfo() const override;
|
||||
|
||||
protected:
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override;
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput*) const override;
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
|
||||
|
||||
struct FlushInfo {
|
||||
sk_sp<const GrBuffer> fVertexBuffer;
|
||||
|
@ -276,13 +276,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
DashOp(const LineData& geometry, GrColor color, SkPaint::Cap cap, AAMode aaMode, bool fullDash)
|
||||
: INHERITED(ClassID()), fColor(color), fCap(cap), fAAMode(aaMode), fFullDash(fullDash) {
|
||||
@ -304,15 +297,19 @@ private:
|
||||
this->setTransformedBounds(bounds, combinedMatrix, aaBloat, zeroArea);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
struct DashDraw {
|
||||
|
@ -118,13 +118,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setKnownSingleComponent(this->coverage());
|
||||
}
|
||||
|
||||
private:
|
||||
DefaultPathOp(GrColor color, const SkPath& path, SkScalar tolerance, uint8_t coverage,
|
||||
const SkMatrix& viewMatrix, bool isHairline, const SkRect& devBounds)
|
||||
@ -139,13 +132,18 @@ private:
|
||||
isHairline ? IsZeroArea::kYes : IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(this->coverage());
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
|
@ -12,13 +12,12 @@
|
||||
#include "SkRSXform.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
void GrDrawAtlasOp::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
void GrDrawAtlasOp::applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) {
|
||||
SkASSERT(fGeoData.count() == 1);
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
if (!optimizations.readsColor()) {
|
||||
fGeoData[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
if (overrides.getOverrideColorIfSet(&fGeoData[0].fColor) && fHasColors) {
|
||||
if (optimizations.getOverrideColorIfSet(&fGeoData[0].fColor) && fHasColors) {
|
||||
size_t vertexStride =
|
||||
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0);
|
||||
uint8_t* currVertex = fGeoData[0].fVerts.begin();
|
||||
@ -29,11 +28,11 @@ void GrDrawAtlasOp::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
}
|
||||
|
||||
// setup batch properties
|
||||
fColorIgnored = !overrides.readsColor();
|
||||
fColorIgnored = !optimizations.readsColor();
|
||||
fColor = fGeoData[0].fColor;
|
||||
// We'd like to assert this, but we can't because of GLPrograms test
|
||||
// SkASSERT(init.readsLocalCoords());
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
static sk_sp<GrGeometryProcessor> set_vertex_attributes(bool hasColors,
|
||||
|
@ -35,25 +35,22 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one atlas draw.
|
||||
if (this->hasColors()) {
|
||||
color->setUnknownFourComponents();
|
||||
} else {
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
}
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
private:
|
||||
GrDrawAtlasOp(GrColor color, const SkMatrix& viewMatrix, int spriteCount,
|
||||
const SkRSXform* xforms, const SkRect* rects, const SkColor* colors);
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
if (this->hasColors()) {
|
||||
input->pipelineColorInput()->setUnknownFourComponents();
|
||||
} else {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
}
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target*) const override;
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override;
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
|
||||
|
||||
GrColor color() const { return fColor; }
|
||||
bool colorIgnored() const { return fColorIgnored; }
|
||||
|
@ -15,21 +15,23 @@ GrDrawOp::~GrDrawOp() {
|
||||
}
|
||||
}
|
||||
|
||||
void GrDrawOp::getPipelineOptimizations(GrPipelineOptimizations* opt) const {
|
||||
GrInitInvariantOutput color;
|
||||
GrInitInvariantOutput coverage;
|
||||
this->computePipelineOptimizations(&color, &coverage, &opt->fOverrides);
|
||||
opt->fColorPOI.initUsingInvariantOutput(color);
|
||||
opt->fCoveragePOI.initUsingInvariantOutput(coverage);
|
||||
void GrDrawOp::initPipelineAnalysis(GrPipelineAnalysis* analysis) const {
|
||||
GrPipelineInput color;
|
||||
GrPipelineInput coverage;
|
||||
GrPipelineAnalysisDrawOpInput input(&color, &coverage);
|
||||
this->getPipelineAnalysisInput(&input);
|
||||
analysis->fColorPOI.initFromPipelineInput(color);
|
||||
analysis->fCoveragePOI.initFromPipelineInput(coverage);
|
||||
analysis->fUsesPLSDstRead = input.usesPLSDstRead();
|
||||
}
|
||||
|
||||
bool GrDrawOp::installPipeline(const GrPipeline::CreateArgs& args) {
|
||||
GrXPOverridesForBatch overrides;
|
||||
GrPipelineOptimizations optimizations;
|
||||
void* location = fPipelineStorage.get();
|
||||
if (!GrPipeline::CreateAt(location, args, &overrides)) {
|
||||
if (!GrPipeline::CreateAt(location, args, &optimizations)) {
|
||||
return false;
|
||||
}
|
||||
fPipelineInstalled = true;
|
||||
this->initBatchTracker(overrides);
|
||||
this->applyPipelineOptimizations(optimizations);
|
||||
return true;
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include "GrOp.h"
|
||||
#include "GrPipeline.h"
|
||||
|
||||
struct GrInitInvariantOutput;
|
||||
|
||||
/**
|
||||
* GrDrawOps are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources
|
||||
* and draws are determined and scheduled. They are issued in the draw phase. GrDrawOpUploadToken is
|
||||
@ -60,9 +58,9 @@ public:
|
||||
~GrDrawOp() override;
|
||||
|
||||
/**
|
||||
* Fills in a structure informing the XP of overrides to its normal behavior.
|
||||
* Gets the inputs to pipeline analysis from the GrDrawOp.
|
||||
*/
|
||||
void getPipelineOptimizations(GrPipelineOptimizations* override) const;
|
||||
void initPipelineAnalysis(GrPipelineAnalysis*) const;
|
||||
|
||||
bool installPipeline(const GrPipeline::CreateArgs&);
|
||||
|
||||
@ -112,16 +110,18 @@ protected:
|
||||
return reinterpret_cast<const GrPipeline*>(fPipelineStorage.get());
|
||||
}
|
||||
|
||||
virtual void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* initBatchTracker is a hook for the some additional overrides / optimization possibilities
|
||||
* from the GrXferProcessor.
|
||||
* Provides information about the GrPrimitiveProccesor that will be used to issue draws by this
|
||||
* op to GrPipeline analysis.
|
||||
*/
|
||||
virtual void initBatchTracker(const GrXPOverridesForBatch&) = 0;
|
||||
virtual void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput*) const = 0;
|
||||
|
||||
/**
|
||||
* After GrPipeline analysis is complete this is called so that the op can use the analysis
|
||||
* results when constructing its GrPrimitiveProcessor.
|
||||
*/
|
||||
virtual void applyPipelineOptimizations(const GrPipelineOptimizations&) = 0;
|
||||
|
||||
protected:
|
||||
struct QueuedUpload {
|
||||
|
@ -31,7 +31,7 @@ void GrDrawPathOp::onDraw(GrOpFlushState* state, const SkRect& bounds) {
|
||||
GrProgramDesc desc;
|
||||
|
||||
sk_sp<GrPathProcessor> pathProc(
|
||||
GrPathProcessor::Create(this->color(), this->overrides(), this->viewMatrix()));
|
||||
GrPathProcessor::Create(this->color(), this->optimizations(), this->viewMatrix()));
|
||||
state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc,
|
||||
this->stencilPassSettings(), fPath.get());
|
||||
}
|
||||
@ -100,10 +100,10 @@ bool GrDrawPathRangeOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
|
||||
// combined. (Glyphs in the same font tend to wind the same direction so it works out OK.)
|
||||
if (GrPathRendering::kWinding_FillType != this->fillType() ||
|
||||
GrPathRendering::kWinding_FillType != that->fillType() ||
|
||||
this->overrides().willColorBlendWithDst()) {
|
||||
this->optimizations().willColorBlendWithDst()) {
|
||||
return false;
|
||||
}
|
||||
SkASSERT(!that->overrides().willColorBlendWithDst());
|
||||
SkASSERT(!that->optimizations().willColorBlendWithDst());
|
||||
fTotalPathCount += that->fTotalPathCount;
|
||||
while (Draw* head = that->fDraws.head()) {
|
||||
Draw* draw = fDraws.addToTail();
|
||||
@ -128,7 +128,7 @@ void GrDrawPathRangeOp::onDraw(GrOpFlushState* state, const SkRect& bounds) {
|
||||
localMatrix.preTranslate(head.fX, head.fY);
|
||||
|
||||
sk_sp<GrPathProcessor> pathProc(
|
||||
GrPathProcessor::Create(this->color(), this->overrides(), drawMatrix, localMatrix));
|
||||
GrPathProcessor::Create(this->color(), this->optimizations(), drawMatrix, localMatrix));
|
||||
|
||||
if (fDraws.count() == 1) {
|
||||
const InstanceData& instances = *head.fInstanceData;
|
||||
|
@ -19,14 +19,6 @@
|
||||
#include "SkTLList.h"
|
||||
|
||||
class GrDrawPathOpBase : public GrDrawOp {
|
||||
public:
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
protected:
|
||||
GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrColor initialColor,
|
||||
GrPathRendering::FillType fill)
|
||||
@ -36,15 +28,22 @@ protected:
|
||||
SkASSERT(!fStencilPassSettings.isDisabled()); // This shouldn't be called before onPrepare.
|
||||
return fStencilPassSettings;
|
||||
}
|
||||
const GrXPOverridesForBatch& overrides() const { return fOverrides; }
|
||||
|
||||
protected:
|
||||
const GrPipelineOptimizations& optimizations() const { return fOptimizations; }
|
||||
const SkMatrix& viewMatrix() const { return fViewMatrix; }
|
||||
GrColor color() const { return fColor; }
|
||||
GrPathRendering::FillType fillType() const { return fFillType; }
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
fOverrides = overrides;
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xFF);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
void onPrepare(GrOpFlushState*) override; // Initializes fStencilPassSettings.
|
||||
@ -53,7 +52,7 @@ private:
|
||||
GrColor fColor;
|
||||
GrPathRendering::FillType fFillType;
|
||||
GrStencilSettings fStencilPassSettings;
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
|
||||
typedef GrDrawOp INHERITED;
|
||||
};
|
||||
|
@ -71,28 +71,25 @@ GrDrawVerticesOp::GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType,
|
||||
this->setBounds(bounds, HasAABloat::kNo, zeroArea);
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const {
|
||||
// When this is called there is only one mesh.
|
||||
void GrDrawVerticesOp::getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const {
|
||||
if (fVariableColor) {
|
||||
color->setUnknownFourComponents();
|
||||
input->pipelineColorInput()->setUnknownFourComponents();
|
||||
} else {
|
||||
color->setKnownFourComponents(fMeshes[0].fColor);
|
||||
input->pipelineColorInput()->setKnownFourComponents(fMeshes[0].fColor);
|
||||
}
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void GrDrawVerticesOp::initBatchTracker(const GrXPOverridesForBatch& overrides) {
|
||||
void GrDrawVerticesOp::applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) {
|
||||
SkASSERT(fMeshes.count() == 1);
|
||||
GrColor overrideColor;
|
||||
if (overrides.getOverrideColorIfSet(&overrideColor)) {
|
||||
if (optimizations.getOverrideColorIfSet(&overrideColor)) {
|
||||
fMeshes[0].fColor = overrideColor;
|
||||
fMeshes[0].fColors.reset();
|
||||
fVariableColor = false;
|
||||
}
|
||||
fCoverageIgnored = !overrides.readsCoverage();
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
fCoverageIgnored = !optimizations.readsCoverage();
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fMeshes[0].fLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
|
@ -43,18 +43,15 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override;
|
||||
|
||||
private:
|
||||
GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType, const SkMatrix& viewMatrix,
|
||||
const SkPoint* positions, int vertexCount, const uint16_t* indices,
|
||||
int indexCount, const GrColor* colors, const SkPoint* localCoords,
|
||||
const SkRect& bounds);
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override;
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override;
|
||||
void onPrepareDraws(Target*) const override;
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override;
|
||||
|
||||
GrPrimitiveType primitiveType() const { return fPrimitiveType; }
|
||||
bool batchablePrimitiveType() const {
|
||||
@ -78,7 +75,7 @@ private:
|
||||
bool fVariableColor;
|
||||
int fVertexCount;
|
||||
int fIndexCount;
|
||||
bool fCoverageIgnored; // comes from initBatchTracker.
|
||||
bool fCoverageIgnored; // comes from applyPipelineOptimizations.
|
||||
|
||||
SkSTArray<1, Mesh, true> fMeshes;
|
||||
|
||||
|
@ -62,16 +62,19 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setUnknownFourComponents();
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setUnknownFourComponents();
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& analysioptimizations) override {
|
||||
analysioptimizations.getOverrideColorIfSet(&fPatches[0].fColor);
|
||||
fOptimizations = analysioptimizations;
|
||||
}
|
||||
|
||||
private:
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
sk_sp<GrGeometryProcessor> gp(create_gp(fOverrides.readsCoverage()));
|
||||
sk_sp<GrGeometryProcessor> gp(create_gp(fOptimizations.readsCoverage()));
|
||||
if (!gp) {
|
||||
SkDebugf("Couldn't create GrGeometryProcessor\n");
|
||||
return;
|
||||
@ -135,11 +138,6 @@ private:
|
||||
helper.recordDraw(target, gp.get());
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fPatches[0].fColor);
|
||||
fOverrides = overrides;
|
||||
}
|
||||
|
||||
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
|
||||
NonAALatticeOp* that = t->cast<NonAALatticeOp>();
|
||||
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
|
||||
@ -152,8 +150,9 @@ private:
|
||||
|
||||
// In the event of two ops, one who can tweak, one who cannot, we just fall back to not
|
||||
// tweaking.
|
||||
if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
|
||||
fOverrides = that->fOverrides;
|
||||
if (fOptimizations.canTweakAlphaForCoverage() &&
|
||||
!that->fOptimizations.canTweakAlphaForCoverage()) {
|
||||
fOptimizations = that->fOptimizations;
|
||||
}
|
||||
|
||||
fPatches.move_back_n(that->fPatches.count(), that->fPatches.begin());
|
||||
@ -168,7 +167,7 @@ private:
|
||||
GrColor fColor;
|
||||
};
|
||||
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
int fImageWidth;
|
||||
int fImageHeight;
|
||||
SkSTArray<1, Patch, true> fPatches;
|
||||
|
@ -246,14 +246,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one path.
|
||||
color->setKnownFourComponents(fPaths[0].fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
private:
|
||||
MSAAPathOp(GrColor color, const SkPath& path, const SkMatrix& viewMatrix,
|
||||
const SkRect& devBounds, int maxLineVertices, int maxQuadVertices, bool isIndexed)
|
||||
@ -266,12 +258,16 @@ private:
|
||||
this->setBounds(devBounds, HasAABloat::kNo, IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fPaths[0].fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fPaths[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fPaths[0].fColor);
|
||||
optimizations.getOverrideColorIfSet(&fPaths[0].fColor);
|
||||
}
|
||||
|
||||
static void ComputeWorstCasePointCount(const SkPath& path, int* subpaths,
|
||||
|
@ -110,24 +110,21 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one rect.
|
||||
color->setKnownFourComponents(fRects[0].fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
fOverrides = overrides;
|
||||
}
|
||||
|
||||
private:
|
||||
NonAAFillRectOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fRects[0].fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
sk_sp<GrGeometryProcessor> gp = make_gp(fOverrides.readsCoverage());
|
||||
sk_sp<GrGeometryProcessor> gp = make_gp(fOptimizations.readsCoverage());
|
||||
if (!gp) {
|
||||
SkDebugf("Couldn't create GrGeometryProcessor\n");
|
||||
return;
|
||||
@ -166,8 +163,9 @@ private:
|
||||
|
||||
// In the event of two ops, one who can tweak, one who cannot, we just fall back to not
|
||||
// tweaking.
|
||||
if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
|
||||
fOverrides = that->fOverrides;
|
||||
if (fOptimizations.canTweakAlphaForCoverage() &&
|
||||
!that->fOptimizations.canTweakAlphaForCoverage()) {
|
||||
fOptimizations = that->fOptimizations;
|
||||
}
|
||||
|
||||
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
|
||||
@ -182,7 +180,7 @@ private:
|
||||
GrQuad fLocalQuad;
|
||||
};
|
||||
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
SkSTArray<1, RectInfo, true> fRects;
|
||||
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
|
@ -127,25 +127,22 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called on a batch, there is only one geometry bundle
|
||||
color->setKnownFourComponents(fRects[0].fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
fOverrides = overrides;
|
||||
}
|
||||
|
||||
private:
|
||||
NonAAFillRectPerspectiveOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fRects[0].fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fRects[0].fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix,
|
||||
fOverrides.readsCoverage(),
|
||||
fOptimizations.readsCoverage(),
|
||||
fHasLocalRect,
|
||||
fHasLocalMatrix ? &fLocalMatrix : nullptr);
|
||||
if (!gp) {
|
||||
@ -205,8 +202,9 @@ private:
|
||||
|
||||
// In the event of two batches, one who can tweak, one who cannot, we just fall back to
|
||||
// not tweaking
|
||||
if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) {
|
||||
fOverrides = that->fOverrides;
|
||||
if (fOptimizations.canTweakAlphaForCoverage() &&
|
||||
!that->fOptimizations.canTweakAlphaForCoverage()) {
|
||||
fOptimizations = that->fOptimizations;
|
||||
}
|
||||
|
||||
fRects.push_back_n(that->fRects.count(), that->fRects.begin());
|
||||
@ -220,7 +218,7 @@ private:
|
||||
SkRect fLocalRect;
|
||||
};
|
||||
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
SkSTArray<1, RectInfo, true> fRects;
|
||||
bool fHasLocalMatrix;
|
||||
bool fHasLocalRect;
|
||||
|
@ -62,14 +62,6 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called on a batch, there is only one geometry bundle
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
static sk_sp<GrDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
|
||||
const SkStrokeRec& stroke, bool snapToPixelCenters) {
|
||||
if (!allowed_stroke(stroke)) {
|
||||
@ -108,15 +100,21 @@ public:
|
||||
private:
|
||||
NonAAStrokeRectOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xFF);
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
sk_sp<GrGeometryProcessor> gp;
|
||||
{
|
||||
using namespace GrDefaultGeoProcFactory;
|
||||
Color color(fColor);
|
||||
Coverage coverage(fOverrides.readsCoverage() ? Coverage::kSolid_Type
|
||||
: Coverage::kNone_Type);
|
||||
LocalCoords localCoords(fOverrides.readsLocalCoords() ? LocalCoords::kUsePosition_Type
|
||||
: LocalCoords::kUnused_Type);
|
||||
Coverage coverage(fOptimizations.readsCoverage() ? Coverage::kSolid_Type
|
||||
: Coverage::kNone_Type);
|
||||
LocalCoords localCoords(fOptimizations.readsLocalCoords()
|
||||
? LocalCoords::kUsePosition_Type
|
||||
: LocalCoords::kUnused_Type);
|
||||
gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fViewMatrix);
|
||||
}
|
||||
|
||||
@ -161,9 +159,9 @@ private:
|
||||
target->draw(gp.get(), mesh);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
fOverrides = overrides;
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
bool onCombineIfPossible(GrOp* t, const GrCaps&) override {
|
||||
@ -176,8 +174,7 @@ private:
|
||||
SkMatrix fViewMatrix;
|
||||
SkRect fRect;
|
||||
SkScalar fStrokeWidth;
|
||||
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
|
||||
const static int kVertsPerHairlineRect = 5;
|
||||
const static int kVertsPerStrokeRect = 10;
|
||||
|
@ -797,20 +797,17 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one circle.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
CircleOp() : INHERITED(ClassID()) {}
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
@ -1245,23 +1242,19 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called, there is only one ellipse.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
EllipseOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
if (!overrides.readsCoverage()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsCoverage()) {
|
||||
fGeoData[0].fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
@ -1466,21 +1459,17 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one ellipse.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
DIEllipseOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
@ -1787,19 +1776,15 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one rrect.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
@ -2145,21 +2130,17 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one rrect.
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
EllipticalRRectOp() : INHERITED(ClassID()) {}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
|
@ -780,22 +780,27 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
overrides->fUsePLSDstRead = true;
|
||||
private:
|
||||
PLSPathOp(GrColor color, const SkPath& path, const SkMatrix& viewMatrix)
|
||||
: INHERITED(ClassID()), fColor(color), fPath(path), fViewMatrix(viewMatrix) {
|
||||
// compute bounds
|
||||
this->setTransformedBounds(path.getBounds(), fViewMatrix, HasAABloat::kYes,
|
||||
IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
input->setUsesPLSDstRead();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
@ -906,14 +911,6 @@ public:
|
||||
target->draw(finishProcessor.get(), mesh);
|
||||
}
|
||||
|
||||
private:
|
||||
PLSPathOp(GrColor color, const SkPath& path, const SkMatrix& viewMatrix)
|
||||
: INHERITED(ClassID()), fColor(color), fPath(path), fViewMatrix(viewMatrix) {
|
||||
// compute bounds
|
||||
this->setTransformedBounds(path.getBounds(), fViewMatrix, HasAABloat::kYes,
|
||||
IsZeroArea::kNo);
|
||||
}
|
||||
|
||||
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
|
||||
return false;
|
||||
}
|
||||
|
@ -79,22 +79,19 @@ public:
|
||||
return str;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called there is only one region.
|
||||
color->setKnownFourComponents(fRegions[0].fColor);
|
||||
coverage->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fRegions[0].fColor);
|
||||
fOverrides = overrides;
|
||||
}
|
||||
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fRegions[0].fColor);
|
||||
input->pipelineCoverageInput()->setKnownSingleComponent(0xff);
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fRegions[0].fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
sk_sp<GrGeometryProcessor> gp = make_gp(fOverrides.readsCoverage(), fViewMatrix);
|
||||
sk_sp<GrGeometryProcessor> gp = make_gp(fOptimizations.readsCoverage(), fViewMatrix);
|
||||
if (!gp) {
|
||||
SkDebugf("Couldn't create GrGeometryProcessor\n");
|
||||
return;
|
||||
@ -149,7 +146,7 @@ private:
|
||||
};
|
||||
|
||||
SkMatrix fViewMatrix;
|
||||
GrXPOverridesForBatch fOverrides;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
SkSTArray<1, RegionInfo, true> fRegions;
|
||||
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
|
@ -114,8 +114,8 @@ public:
|
||||
SkRect devBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius,
|
||||
center.fX + outerRadius, center.fY + outerRadius);
|
||||
|
||||
op->fGeoData.emplace_back(
|
||||
Geometry{color, outerRadius, innerRadius, blurRadius, devBounds, stroked});
|
||||
op->fCircles.emplace_back(
|
||||
Circle{color, outerRadius, innerRadius, blurRadius, devBounds, stroked});
|
||||
|
||||
// Use the original radius and stroke radius for the bounds so that it does not include the
|
||||
// AA bloat.
|
||||
@ -132,33 +132,30 @@ public:
|
||||
|
||||
SkString dumpInfo() const override {
|
||||
SkString string;
|
||||
for (int i = 0; i < fGeoData.count(); ++i) {
|
||||
for (int i = 0; i < fCircles.count(); ++i) {
|
||||
string.appendf(
|
||||
"Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], "
|
||||
"OuterRad: %.2f, InnerRad: %.2f, BlurRad: %.2f\n",
|
||||
fGeoData[i].fColor, fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
|
||||
fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
|
||||
fGeoData[i].fOuterRadius, fGeoData[i].fInnerRadius, fGeoData[i].fBlurRadius);
|
||||
fCircles[i].fColor, fCircles[i].fDevBounds.fLeft, fCircles[i].fDevBounds.fTop,
|
||||
fCircles[i].fDevBounds.fRight, fCircles[i].fDevBounds.fBottom,
|
||||
fCircles[i].fOuterRadius, fCircles[i].fInnerRadius, fCircles[i].fBlurRadius);
|
||||
}
|
||||
string.append(DumpPipelineInfo(*this->pipeline()));
|
||||
string.append(INHERITED::dumpInfo());
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called on a batch, there is only one geometry bundle
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
ShadowCircleOp() : INHERITED(ClassID()) {}
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fCircles[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fCircles[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
@ -180,7 +177,7 @@ private:
|
||||
SkScalar fBlurRadius;
|
||||
};
|
||||
|
||||
int instanceCount = fGeoData.count();
|
||||
int instanceCount = fCircles.count();
|
||||
size_t vertexStride = gp->getVertexStride();
|
||||
SkASSERT(vertexStride == sizeof(CircleVertex));
|
||||
|
||||
@ -203,14 +200,14 @@ private:
|
||||
|
||||
int currStartVertex = 0;
|
||||
for (int i = 0; i < instanceCount; i++) {
|
||||
const Geometry& geom = fGeoData[i];
|
||||
const Circle& circle = fCircles[i];
|
||||
|
||||
GrColor color = geom.fColor;
|
||||
SkScalar outerRadius = geom.fOuterRadius;
|
||||
SkScalar innerRadius = geom.fInnerRadius;
|
||||
SkScalar blurRadius = geom.fBlurRadius;
|
||||
GrColor color = circle.fColor;
|
||||
SkScalar outerRadius = circle.fOuterRadius;
|
||||
SkScalar innerRadius = circle.fInnerRadius;
|
||||
SkScalar blurRadius = circle.fBlurRadius;
|
||||
|
||||
const SkRect& bounds = geom.fDevBounds;
|
||||
const SkRect& bounds = circle.fDevBounds;
|
||||
CircleVertex* ov0 = reinterpret_cast<CircleVertex*>(vertices + 0 * vertexStride);
|
||||
CircleVertex* ov1 = reinterpret_cast<CircleVertex*>(vertices + 1 * vertexStride);
|
||||
CircleVertex* ov2 = reinterpret_cast<CircleVertex*>(vertices + 2 * vertexStride);
|
||||
@ -275,7 +272,7 @@ private:
|
||||
ov7->fOuterRadius = outerRadius;
|
||||
ov7->fBlurRadius = blurRadius;
|
||||
|
||||
if (geom.fStroked) {
|
||||
if (circle.fStroked) {
|
||||
// compute the inner ring
|
||||
CircleVertex* iv0 = reinterpret_cast<CircleVertex*>(vertices + 8 * vertexStride);
|
||||
CircleVertex* iv1 = reinterpret_cast<CircleVertex*>(vertices + 9 * vertexStride);
|
||||
@ -289,7 +286,7 @@ private:
|
||||
// cosine and sine of pi/8
|
||||
SkScalar c = 0.923579533f;
|
||||
SkScalar s = 0.382683432f;
|
||||
SkScalar r = geom.fInnerRadius;
|
||||
SkScalar r = circle.fInnerRadius;
|
||||
|
||||
iv0->fPos = center + SkPoint::Make(-s * r, -c * r);
|
||||
iv0->fColor = color;
|
||||
@ -348,14 +345,14 @@ private:
|
||||
iv->fBlurRadius = blurRadius;
|
||||
}
|
||||
|
||||
const uint16_t* primIndices = circle_type_to_indices(geom.fStroked);
|
||||
const int primIndexCount = circle_type_to_index_count(geom.fStroked);
|
||||
const uint16_t* primIndices = circle_type_to_indices(circle.fStroked);
|
||||
const int primIndexCount = circle_type_to_index_count(circle.fStroked);
|
||||
for (int i = 0; i < primIndexCount; ++i) {
|
||||
*indices++ = primIndices[i] + currStartVertex;
|
||||
}
|
||||
|
||||
currStartVertex += circle_type_to_vert_count(geom.fStroked);
|
||||
vertices += circle_type_to_vert_count(geom.fStroked) * vertexStride;
|
||||
currStartVertex += circle_type_to_vert_count(circle.fStroked);
|
||||
vertices += circle_type_to_vert_count(circle.fStroked) * vertexStride;
|
||||
}
|
||||
|
||||
GrMesh mesh;
|
||||
@ -375,14 +372,14 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
|
||||
fCircles.push_back_n(that->fCircles.count(), that->fCircles.begin());
|
||||
this->joinBounds(*that);
|
||||
fVertCount += that->fVertCount;
|
||||
fIndexCount += that->fIndexCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Geometry {
|
||||
struct Circle {
|
||||
GrColor fColor;
|
||||
SkScalar fOuterRadius;
|
||||
SkScalar fInnerRadius;
|
||||
@ -391,7 +388,7 @@ private:
|
||||
bool fStroked;
|
||||
};
|
||||
|
||||
SkSTArray<1, Geometry, true> fGeoData;
|
||||
SkSTArray<1, Circle, true> fCircles;
|
||||
SkMatrix fViewMatrixIfUsingLocalCoords;
|
||||
int fVertCount;
|
||||
int fIndexCount;
|
||||
@ -584,19 +581,15 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called on a batch, there is only one geometry bundle
|
||||
color->setKnownFourComponents(fGeoData[0].fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fGeoData[0].fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any overrides that affect our GP.
|
||||
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!overrides.readsLocalCoords()) {
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||
if (!optimizations.readsLocalCoords()) {
|
||||
fViewMatrixIfUsingLocalCoords.reset();
|
||||
}
|
||||
}
|
||||
|
@ -179,21 +179,18 @@ public:
|
||||
return string;
|
||||
}
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
private:
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
// Handle any color overrides
|
||||
if (!overrides.readsColor()) {
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
if (!optimizations.readsColor()) {
|
||||
fColor = GrColor_ILLEGAL;
|
||||
}
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
fPipelineInfo = overrides;
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
fOptimizations = optimizations;
|
||||
}
|
||||
|
||||
SkPath getPath() const {
|
||||
@ -265,7 +262,7 @@ private:
|
||||
SkScalar tol = GrPathUtils::kDefaultTolerance;
|
||||
bool isLinear;
|
||||
DynamicVertexAllocator allocator(gp->getVertexStride(), target);
|
||||
bool canTweakAlphaForCoverage = fPipelineInfo.canTweakAlphaForCoverage();
|
||||
bool canTweakAlphaForCoverage = fOptimizations.canTweakAlphaForCoverage();
|
||||
int count = GrTessellator::PathToTriangles(path, tol, clipBounds, &allocator,
|
||||
true, fColor, canTweakAlphaForCoverage,
|
||||
&isLinear);
|
||||
@ -281,18 +278,18 @@ private:
|
||||
using namespace GrDefaultGeoProcFactory;
|
||||
|
||||
Color color(fColor);
|
||||
LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
|
||||
LocalCoords::kUsePosition_Type :
|
||||
LocalCoords::kUnused_Type);
|
||||
LocalCoords localCoords(fOptimizations.readsLocalCoords()
|
||||
? LocalCoords::kUsePosition_Type
|
||||
: LocalCoords::kUnused_Type);
|
||||
Coverage::Type coverageType;
|
||||
if (fAntiAlias) {
|
||||
color = Color(Color::kAttribute_Type);
|
||||
if (fPipelineInfo.canTweakAlphaForCoverage()) {
|
||||
if (fOptimizations.canTweakAlphaForCoverage()) {
|
||||
coverageType = Coverage::kSolid_Type;
|
||||
} else {
|
||||
coverageType = Coverage::kAttribute_Type;
|
||||
}
|
||||
} else if (fPipelineInfo.readsCoverage()) {
|
||||
} else if (fOptimizations.readsCoverage()) {
|
||||
coverageType = Coverage::kSolid_Type;
|
||||
} else {
|
||||
coverageType = Coverage::kNone_Type;
|
||||
@ -349,7 +346,7 @@ private:
|
||||
SkMatrix fViewMatrix;
|
||||
SkIRect fDevClipBounds;
|
||||
bool fAntiAlias;
|
||||
GrXPOverridesForBatch fPipelineInfo;
|
||||
GrPipelineOptimizations fOptimizations;
|
||||
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
};
|
||||
|
@ -21,22 +21,6 @@ class GrTestMeshDrawOp : public GrMeshDrawOp {
|
||||
public:
|
||||
virtual const char* name() const override = 0;
|
||||
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
// When this is called on a batch, there is only one geometry bundle
|
||||
color->setKnownFourComponents(fColor);
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
|
||||
overrides.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fOptimizations.fColorIgnored = !overrides.readsColor();
|
||||
fOptimizations.fUsesLocalCoords = overrides.readsLocalCoords();
|
||||
fOptimizations.fCoverageIgnored = !overrides.readsCoverage();
|
||||
}
|
||||
|
||||
protected:
|
||||
GrTestMeshDrawOp(uint32_t classID, const SkRect& bounds, GrColor color)
|
||||
: INHERITED(classID), fColor(color) {
|
||||
@ -44,6 +28,19 @@ protected:
|
||||
this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kYes);
|
||||
}
|
||||
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(fColor);
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override {
|
||||
optimizations.getOverrideColorIfSet(&fColor);
|
||||
|
||||
fOptimizations.fColorIgnored = !optimizations.readsColor();
|
||||
fOptimizations.fUsesLocalCoords = optimizations.readsLocalCoords();
|
||||
fOptimizations.fCoverageIgnored = !optimizations.readsCoverage();
|
||||
}
|
||||
|
||||
struct Optimizations {
|
||||
bool fColorIgnored = false;
|
||||
bool fUsesLocalCoords = false;
|
||||
|
@ -94,13 +94,12 @@ static GrPipeline* construct_dummy_pipeline(GrRenderTargetContext* dc, void* sto
|
||||
GrPipelineBuilder dummyBuilder(GrPaint(), GrAAType::kNone);
|
||||
GrScissorState dummyScissor;
|
||||
GrWindowRectsState dummyWindows;
|
||||
GrXPOverridesForBatch dummyOverrides;
|
||||
GrPipelineOptimizations dummyOverrides;
|
||||
|
||||
GrPipeline::CreateArgs args;
|
||||
args.fPipelineBuilder = &dummyBuilder;
|
||||
args.fRenderTargetContext = dc;
|
||||
args.fCaps = dc->caps();
|
||||
args.fOpts = GrPipelineOptimizations();
|
||||
args.fScissor = &dummyScissor;
|
||||
args.fWindowRectsState = &dummyWindows;
|
||||
args.fHasStencilClip = false;
|
||||
|
@ -67,13 +67,12 @@ class GrPorterDuffTest {
|
||||
public:
|
||||
struct XPInfo {
|
||||
XPInfo(skiatest::Reporter* reporter, SkBlendMode xfermode, const GrCaps& caps,
|
||||
const GrPipelineOptimizations& optimizations) {
|
||||
const GrPipelineAnalysis& analysis) {
|
||||
sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(xfermode));
|
||||
sk_sp<GrXferProcessor> xp(
|
||||
xpf->createXferProcessor(optimizations, false, nullptr, caps));
|
||||
TEST_ASSERT(!xpf->willNeedDstTexture(caps, optimizations));
|
||||
xpf->getInvariantBlendedColor(optimizations.fColorPOI, &fBlendedColor);
|
||||
fOptFlags = xp->getOptimizations(optimizations, false, nullptr, caps);
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
|
||||
TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis));
|
||||
xpf->getInvariantBlendedColor(analysis.fColorPOI, &fBlendedColor);
|
||||
fOptFlags = xp->getOptimizations(analysis, false, nullptr, caps);
|
||||
GetXPOutputTypes(xp.get(), &fPrimaryOutputType, &fSecondaryOutputType);
|
||||
xp->getBlendInfo(&fBlendInfo);
|
||||
TEST_ASSERT(!xp->willReadDstColor());
|
||||
@ -93,19 +92,20 @@ public:
|
||||
};
|
||||
|
||||
static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
GrPipelineOptimizations opt;
|
||||
opt.fColorPOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false);
|
||||
// Setting 2nd to last value to false and last to true will force covPOI to LCD coverage.
|
||||
opt.fCoveragePOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false, true);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(NULL, 0, 0, kNone_GrColorComponentFlags, false,
|
||||
true);
|
||||
|
||||
SkASSERT(!opt.fColorPOI.isOpaque());
|
||||
SkASSERT(!opt.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!opt.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(opt.fCoveragePOI.isFourChannelOutput());
|
||||
SkASSERT(!analysis.fColorPOI.isOpaque());
|
||||
SkASSERT(!analysis.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(analysis.fCoveragePOI.isFourChannelOutput());
|
||||
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, opt);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
|
||||
|
||||
switch (xfermode) {
|
||||
case SkBlendMode::kClear:
|
||||
@ -284,21 +284,18 @@ static void test_lcd_coverage(skiatest::Reporter* reporter, const GrCaps& caps)
|
||||
}
|
||||
}
|
||||
static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
GrPipelineOptimizations optimizations;
|
||||
optimizations.fColorPOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags,
|
||||
false);
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags,
|
||||
true);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, false);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, true);
|
||||
|
||||
SkASSERT(!optimizations.fColorPOI.isOpaque());
|
||||
SkASSERT(!optimizations.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isFourChannelOutput());
|
||||
SkASSERT(!analysis.fColorPOI.isOpaque());
|
||||
SkASSERT(!analysis.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
|
||||
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, optimizations);
|
||||
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
|
||||
|
||||
switch (xfermode) {
|
||||
case SkBlendMode::kClear:
|
||||
@ -478,20 +475,21 @@ static void test_color_unknown_with_coverage(skiatest::Reporter* reporter, const
|
||||
}
|
||||
|
||||
static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
GrPipelineOptimizations optimizations;
|
||||
optimizations.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(229, 0, 154, 0),
|
||||
kR_GrColorComponentFlag | kB_GrColorComponentFlag, false);
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(229, 0, 154, 0),
|
||||
kR_GrColorComponentFlag | kB_GrColorComponentFlag,
|
||||
false);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
|
||||
SkASSERT(!optimizations.fColorPOI.isOpaque());
|
||||
SkASSERT(!optimizations.fColorPOI.isSolidWhite());
|
||||
SkASSERT(optimizations.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isFourChannelOutput());
|
||||
SkASSERT(!analysis.fColorPOI.isOpaque());
|
||||
SkASSERT(!analysis.fColorPOI.isSolidWhite());
|
||||
SkASSERT(analysis.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
|
||||
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, optimizations);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
|
||||
|
||||
switch (xfermode) {
|
||||
case SkBlendMode::kClear:
|
||||
@ -682,20 +680,19 @@ static void test_color_unknown_no_coverage(skiatest::Reporter* reporter, const G
|
||||
}
|
||||
|
||||
static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
GrPipelineOptimizations optimizations;
|
||||
optimizations.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kA_GrColorComponentFlag, false);
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags,
|
||||
true);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kA_GrColorComponentFlag, false);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0, kNone_GrColorComponentFlags, true);
|
||||
|
||||
SkASSERT(optimizations.fColorPOI.isOpaque());
|
||||
SkASSERT(!optimizations.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isFourChannelOutput());
|
||||
SkASSERT(analysis.fColorPOI.isOpaque());
|
||||
SkASSERT(!analysis.fColorPOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
|
||||
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, optimizations);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
|
||||
|
||||
switch (xfermode) {
|
||||
case SkBlendMode::kClear:
|
||||
@ -881,20 +878,21 @@ static void test_color_opaque_with_coverage(skiatest::Reporter* reporter, const
|
||||
}
|
||||
|
||||
static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
GrPipelineOptimizations optimizations;
|
||||
optimizations.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(0, 82, 0, 255),
|
||||
kG_GrColorComponentFlag | kA_GrColorComponentFlag, false);
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(nullptr, 0, GrColorPackRGBA(0, 82, 0, 255),
|
||||
kG_GrColorComponentFlag | kA_GrColorComponentFlag,
|
||||
false);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
|
||||
SkASSERT(optimizations.fColorPOI.isOpaque());
|
||||
SkASSERT(!optimizations.fColorPOI.isSolidWhite());
|
||||
SkASSERT(optimizations.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!optimizations.fCoveragePOI.isFourChannelOutput());
|
||||
SkASSERT(analysis.fColorPOI.isOpaque());
|
||||
SkASSERT(!analysis.fColorPOI.isSolidWhite());
|
||||
SkASSERT(analysis.fCoveragePOI.isSolidWhite());
|
||||
SkASSERT(!analysis.fCoveragePOI.isFourChannelOutput());
|
||||
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, optimizations);
|
||||
const GrPorterDuffTest::XPInfo xpi(reporter, xfermode, caps, analysis);
|
||||
|
||||
switch (xfermode) {
|
||||
case SkBlendMode::kClear:
|
||||
@ -1090,40 +1088,40 @@ static void test_color_opaque_no_coverage(skiatest::Reporter* reporter, const Gr
|
||||
}
|
||||
|
||||
static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const GrCaps& caps) {
|
||||
class TestLCDCoverageBatch : public GrMeshDrawOp {
|
||||
class TestLCDCoverageOp : public GrMeshDrawOp {
|
||||
public:
|
||||
DEFINE_OP_CLASS_ID
|
||||
|
||||
TestLCDCoverageBatch() : INHERITED(ClassID()) {}
|
||||
|
||||
private:
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setKnownFourComponents(GrColorPackRGBA(123, 45, 67, 221));
|
||||
coverage->setUnknownFourComponents();
|
||||
coverage->setUsingLCDCoverage(); }
|
||||
TestLCDCoverageOp() : INHERITED(ClassID()) {}
|
||||
|
||||
const char* name() const override { return "Test LCD Text Batch"; }
|
||||
void initBatchTracker(const GrXPOverridesForBatch&) override {}
|
||||
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setKnownFourComponents(GrColorPackRGBA(123, 45, 67, 221));
|
||||
input->pipelineCoverageInput()->setUnknownFourComponents();
|
||||
input->pipelineCoverageInput()->setUsingLCDCoverage();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override {}
|
||||
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
|
||||
void onPrepareDraws(Target*) const override {}
|
||||
|
||||
typedef GrMeshDrawOp INHERITED;
|
||||
} testLCDCoverageBatch;
|
||||
} testLCDCoverageOp;
|
||||
|
||||
GrPipelineOptimizations opts;
|
||||
testLCDCoverageBatch.getPipelineOptimizations(&opts);
|
||||
GrProcOptInfo colorPOI = opts.fColorPOI;
|
||||
GrProcOptInfo covPOI = opts.fCoveragePOI;
|
||||
GrPipelineAnalysis analysis;
|
||||
testLCDCoverageOp.initPipelineAnalysis(&analysis);
|
||||
GrProcOptInfo colorPOI = analysis.fColorPOI;
|
||||
GrProcOptInfo covPOI = analysis.fCoveragePOI;
|
||||
|
||||
SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags());
|
||||
SkASSERT(covPOI.isFourChannelOutput());
|
||||
|
||||
sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(SkBlendMode::kSrcOver));
|
||||
TEST_ASSERT(!xpf->willNeedDstTexture(caps, opts));
|
||||
TEST_ASSERT(!xpf->willNeedDstTexture(caps, analysis));
|
||||
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(opts, false, nullptr, caps));
|
||||
sk_sp<GrXferProcessor> xp(xpf->createXferProcessor(analysis, false, nullptr, caps));
|
||||
if (!xp) {
|
||||
ERRORF(reporter, "Failed to create an XP with LCD coverage.");
|
||||
return;
|
||||
@ -1135,7 +1133,7 @@ static void test_lcd_coverage_fallback_case(skiatest::Reporter* reporter, const
|
||||
TEST_ASSERT(kNone_GrColorComponentFlags == blendedColor.fKnownColorFlags);
|
||||
|
||||
GrColor overrideColor;
|
||||
xp->getOptimizations(opts, false, &overrideColor, caps);
|
||||
xp->getOptimizations(analysis, false, &overrideColor, caps);
|
||||
|
||||
GrXferProcessor::BlendInfo blendInfo;
|
||||
xp->getBlendInfo(&blendInfo);
|
||||
@ -1181,30 +1179,30 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, /*factory*/) {
|
||||
GR_STATIC_ASSERT(SK_ARRAY_COUNT(testColors) == SK_ARRAY_COUNT(testColorFlags));
|
||||
|
||||
for (size_t c = 0; c < SK_ARRAY_COUNT(testColors); c++) {
|
||||
GrPipelineOptimizations optimizations;
|
||||
optimizations.fColorPOI.calcWithInitialValues(nullptr, 0, testColors[c], testColorFlags[c],
|
||||
false);
|
||||
GrPipelineAnalysis analysis;
|
||||
analysis.fColorPOI.calcWithInitialValues(nullptr, 0, testColors[c], testColorFlags[c],
|
||||
false);
|
||||
for (int f = 0; f <= 1; f++) {
|
||||
if (!f) {
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0,
|
||||
kNone_GrColorComponentFlags, true);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, 0,
|
||||
kNone_GrColorComponentFlags, true);
|
||||
} else {
|
||||
optimizations.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
analysis.fCoveragePOI.calcWithInitialValues(nullptr, 0, GrColorPackA4(255),
|
||||
kRGBA_GrColorComponentFlags, true);
|
||||
}
|
||||
for (int m = 0; m <= (int)SkBlendMode::kLastCoeffMode; m++) {
|
||||
SkBlendMode xfermode = static_cast<SkBlendMode>(m);
|
||||
sk_sp<GrXPFactory> xpf(GrPorterDuffXPFactory::Make(xfermode));
|
||||
GrXferProcessor::DstTexture* dstTexture =
|
||||
xpf->willNeedDstTexture(caps, optimizations) ? &fakeDstTexture : 0;
|
||||
xpf->willNeedDstTexture(caps, analysis) ? &fakeDstTexture : 0;
|
||||
sk_sp<GrXferProcessor> xp(
|
||||
xpf->createXferProcessor(optimizations, false, dstTexture, caps));
|
||||
xpf->createXferProcessor(analysis, false, dstTexture, caps));
|
||||
if (!xp) {
|
||||
ERRORF(reporter, "Failed to create an XP without dual source blending.");
|
||||
return;
|
||||
}
|
||||
TEST_ASSERT(!xp->hasSecondaryOutput());
|
||||
xp->getOptimizations(optimizations, false, 0, caps);
|
||||
xp->getOptimizations(analysis, false, 0, caps);
|
||||
TEST_ASSERT(!xp->hasSecondaryOutput());
|
||||
}
|
||||
}
|
||||
|
@ -30,14 +30,6 @@ public:
|
||||
DEFINE_OP_CLASS_ID
|
||||
|
||||
const char* name() const override { return "Dummy Batch"; }
|
||||
void computePipelineOptimizations(GrInitInvariantOutput* color,
|
||||
GrInitInvariantOutput* coverage,
|
||||
GrBatchToXPOverrides* overrides) const override {
|
||||
color->setUnknownFourComponents();
|
||||
coverage->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {}
|
||||
|
||||
Batch(int numAttribs)
|
||||
: INHERITED(ClassID())
|
||||
@ -46,6 +38,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override {
|
||||
input->pipelineColorInput()->setUnknownFourComponents();
|
||||
input->pipelineCoverageInput()->setUnknownSingleComponent();
|
||||
}
|
||||
|
||||
void applyPipelineOptimizations(const GrPipelineOptimizations&) override {}
|
||||
bool onCombineIfPossible(GrOp*, const GrCaps&) override { return false; }
|
||||
void onPrepareDraws(Target* target) const override {
|
||||
class GP : public GrGeometryProcessor {
|
||||
|
Loading…
Reference in New Issue
Block a user