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:
Brian Salomon 2016-12-21 09:20:25 -05:00 committed by Skia Commit-Bot
parent bd81a327b5
commit 92aee3d685
59 changed files with 799 additions and 913 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,7 +19,6 @@
#include "SkTArray.h"
#include <map>
class GrBatchTracker;
class GrBuffer;
class GrContext;
struct GrContextOptions;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,7 +13,6 @@
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
class GrBatchTracker;
class GrPrimitiveProcessor;
class GrGLSLPPFragmentBuilder;
class GrGLSLGeometryBuilder;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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