Cleanup in GrPipelineBuilder

Review URL: https://codereview.chromium.org/956363003
This commit is contained in:
bsalomon 2015-02-26 13:05:21 -08:00 committed by Commit bot
parent 24aa0f0679
commit 6be6f7cb66
14 changed files with 182 additions and 227 deletions

View File

@ -316,7 +316,7 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
const SkPath& path,
const PathData* pathData) {
GrTexture* texture = fAtlas->getTexture();
GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp(pipelineBuilder);
SkASSERT(pathData->fPlot);
GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken();

View File

@ -32,10 +32,10 @@ namespace {
// stage matrix this also alters the vertex layout
void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder,
GrTexture* result,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
const SkIRect &devBound) {
SkASSERT(pipelineBuilder && are);
are->set(pipelineBuilder);
SkASSERT(pipelineBuilder && arfp);
arfp->set(pipelineBuilder);
SkMatrix mat;
// We use device coords to compute the texture coordinates. We set our matrix to be a
@ -112,7 +112,7 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder,
}
bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
const GrReducedClip::ElementList& elements,
const SkVector& clipToRTOffset,
const SkRect* drawBounds) {
@ -122,7 +122,7 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
}
are->set(pipelineBuilder);
arfp->set(pipelineBuilder);
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
GrReducedClip::ElementList::Iter iter(elements);
bool failed = false;
@ -199,7 +199,7 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
}
if (failed) {
are->set(NULL);
arfp->set(NULL);
}
return !failed;
}
@ -208,7 +208,7 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
const SkRect* devBounds) {
@ -294,7 +294,7 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
SkIntToScalar(-clip.origin().fY) };
if (elements.isEmpty() ||
this->installClipEffects(pipelineBuilder, are, elements, clipToRTOffset, devBounds)) {
this->installClipEffects(pipelineBuilder, arfp, elements, clipToRTOffset, devBounds)) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
if (NULL == devBounds ||
@ -333,12 +333,12 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
}
if (result) {
are->set(pipelineBuilder);
arfp->set(pipelineBuilder);
// The mask's top left coord should be pinned to the rounded-out top left corner of
// clipSpace bounds. We determine the mask's position WRT to the render target here.
SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
rtSpaceMaskBounds.offset(-clip.origin());
setup_drawstate_aaclip(pipelineBuilder, result, are, rtSpaceMaskBounds);
setup_drawstate_aaclip(pipelineBuilder, result, arfp, rtSpaceMaskBounds);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}

View File

@ -49,7 +49,7 @@ public:
* clip. devBounds is optional but can help optimize clipping.
*/
bool setupClipping(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreEffects*,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*,
GrScissorState*,
const SkRect* devBounds);
@ -94,7 +94,7 @@ private:
// Attempts to install a series of coverage effects to implement the clip. Return indicates
// whether the element list was successfully converted to effects.
bool installClipEffects(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreEffects*,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
const GrReducedClip::ElementList&,
const SkVector& clipOffset,
const SkRect* devBounds);

View File

@ -353,16 +353,16 @@ bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder,
}
}
for (int s = 0; s < pipelineBuilder.numColorStages(); ++s) {
const GrProcessor* effect = pipelineBuilder.getColorStage(s).processor();
for (int s = 0; s < pipelineBuilder.numColorFragmentStages(); ++s) {
const GrProcessor* effect = pipelineBuilder.getColorFragmentStage(s).processor();
int numTextures = effect->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = effect->texture(t);
SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget());
}
}
for (int s = 0; s < pipelineBuilder.numCoverageStages(); ++s) {
const GrProcessor* effect = pipelineBuilder.getCoverageStage(s).processor();
for (int s = 0; s < pipelineBuilder.numCoverageFragmentStages(); ++s) {
const GrProcessor* effect = pipelineBuilder.getCoverageFragmentStage(s).processor();
int numTextures = effect->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = effect->texture(t);
@ -443,9 +443,9 @@ void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) {
return;
}
@ -488,9 +488,9 @@ void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) {
return;
}
@ -530,9 +530,9 @@ void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) {
return;
}
@ -590,9 +590,9 @@ void GrDrawTarget::stencilPath(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, NULL)) {
return;
}
@ -619,9 +619,9 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, &devBounds)) {
return;
}
@ -658,10 +658,10 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, NULL)) {
return;
}
@ -769,9 +769,9 @@ void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder,
// Setup clip
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, devBounds)) {
return;
}
@ -1268,12 +1268,12 @@ uint32_t GrDrawTargetCaps::CreateUniqueID() {
///////////////////////////////////////////////////////////////////////////////////////////////////
bool GrClipTarget::setupClip(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
const SkRect* devBounds) {
return fClipMaskManager.setupClipping(pipelineBuilder,
are,
arfp,
ars,
scissorState,
devBounds);

View File

@ -789,9 +789,9 @@ private:
GrStencilSettings*);
virtual GrClipMaskManager* clipMaskManager() = 0;
virtual bool setupClip(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*,
GrScissorState*,
const SkRect* devBounds) = 0;
enum {
@ -848,8 +848,8 @@ private:
GrClipMaskManager* clipMaskManager() SK_OVERRIDE { return &fClipMaskManager; }
virtual bool setupClip(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreEffects* are,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*,
GrScissorState* scissorState,
const SkRect* devBounds) SK_OVERRIDE;

View File

@ -1555,7 +1555,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
const SkRRect& origInner) {
bool applyAA = useAA &&
!pipelineBuilder->getRenderTarget()->isMultisampled();
GrPipelineBuilder::AutoRestoreEffects are;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
if (!origInner.isEmpty()) {
SkTCopyOnFirstWrite<SkRRect> inner(origInner);
if (!viewMatrix.isIdentity()) {
@ -1571,7 +1571,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
if (NULL == fp) {
return false;
}
are.set(pipelineBuilder);
arfp.set(pipelineBuilder);
pipelineBuilder->addCoverageProcessor(fp)->unref();
}
@ -1593,8 +1593,8 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
if (NULL == effect) {
return false;
}
if (!are.isSet()) {
are.set(pipelineBuilder);
if (!arfp.isSet()) {
arfp.set(pipelineBuilder);
}
SkMatrix invert;

View File

@ -80,7 +80,7 @@ GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
bool usesLocalCoords = false;
// Copy Stages from PipelineBuilder to Pipeline
for (int i = firstColorStageIdx; i < pipelineBuilder.numColorStages(); ++i) {
for (int i = firstColorStageIdx; i < pipelineBuilder.numColorFragmentStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
(pipelineBuilder.fColorStages[i]));
@ -89,7 +89,7 @@ GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
}
fNumColorStages = fFragmentStages.count();
for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageStages(); ++i) {
for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageFragmentStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
(pipelineBuilder.fCoverageStages[i]));
@ -116,13 +116,13 @@ void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelin
if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
(flags & GrXferProcessor::kOverrideColor_OptFlag)) {
*firstColorStageIdx = pipelineBuilder.numColorStages();
*firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
} else {
fReadsFragPosition = colorPOI.readsFragPosition();
}
if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
*firstCoverageStageIdx = pipelineBuilder.numCoverageStages();
*firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
} else {
if (coveragePOI.readsFragPosition()) {
fReadsFragPosition = true;

View File

@ -37,42 +37,28 @@ public:
const GrDeviceCoordTexture* dstCopy);
/*
* Returns true if it is possible to combine the two GrPipelines and it will update 'this'
* to subsume 'that''s draw.
* Returns true if these pipelines are equivalent.
*/
bool isEqual(const GrPipeline& that) const;
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Effect Stages
/// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
/// fragment shader. Its inputs are the output from the previous stage as well as some variables
/// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
/// the fragment position, local coordinates).
///
/// The stages are divided into two sets, color-computing and coverage-computing. The final
/// color stage produces the final pixel color. The coverage-computing stages function exactly
/// as the color-computing but the output of the final coverage stage is treated as a fractional
/// pixel coverage rather than as input to the src/dst color blend step.
///
/// The input color to the first color-stage is either the constant color or interpolated
/// per-vertex colors. The input to the first coverage stage is either a constant coverage
/// (usually full-coverage) or interpolated per-vertex coverage.
////
/// @name GrFragmentProcessors
int numColorStages() const { return fNumColorStages; }
int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
int numColorFragmentStages() const { return fNumColorStages; }
int numCoverageFragmentStages() const { return fFragmentStages.count() - fNumColorStages; }
int numFragmentStages() const { return fFragmentStages.count(); }
const GrXferProcessor* getXferProcessor() const { return fXferProcessor.get(); }
const GrPendingFragmentStage& getColorStage(int idx) const {
SkASSERT(idx < this->numColorStages());
SkASSERT(idx < this->numColorFragmentStages());
return fFragmentStages[idx];
}
const GrPendingFragmentStage& getCoverageStage(int idx) const {
SkASSERT(idx < this->numCoverageStages());
SkASSERT(idx < this->numCoverageFragmentStages());
return fFragmentStages[fNumColorStages + idx];
}
const GrPendingFragmentStage& getFragmentStage(int idx) const {
@ -81,10 +67,6 @@ public:
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Render Target
////
/**
* Retrieves the currently set render-target.
*
@ -92,34 +74,15 @@ public:
*/
GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Stencil
////
const GrStencilSettings& getStencil() const { return fStencilSettings; }
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name ScissorState
////
const GrScissorState& getScissorState() const { return fScissorState; }
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Boolean Queries
////
bool isDitherState() const { return SkToBool(fFlags & kDither_Flag); }
bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
// Skip any draws that refer to this pipeline (they should be a no-op).
bool mustSkip() const { return NULL == this->getRenderTarget(); }
/// @}
/**
* Gets whether the target is drawing clockwise, counterclockwise,
* or both faces.
@ -127,7 +90,6 @@ public:
*/
GrPipelineBuilder::DrawFace getDrawFace() const { return fDrawFace; }
/// @}
///////////////////////////////////////////////////////////////////////////

View File

@ -90,13 +90,13 @@ bool GrPipelineBuilder::willXPNeedDstCopy(const GrDrawTargetCaps& caps,
return this->getXPFactory()->willNeedDstCopy(caps, colorPOI, coveragePOI);
}
void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) {
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {
if (fPipelineBuilder) {
int m = fPipelineBuilder->numColorStages() - fColorEffectCnt;
int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt;
SkASSERT(m >= 0);
fPipelineBuilder->fColorStages.pop_back_n(m);
int n = fPipelineBuilder->numCoverageStages() - fCoverageEffectCnt;
int n = fPipelineBuilder->numCoverageFragmentStages() - fCoverageEffectCnt;
SkASSERT(n >= 0);
fPipelineBuilder->fCoverageStages.pop_back_n(n);
if (m + n > 0) {
@ -107,8 +107,8 @@ void GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuild
}
fPipelineBuilder = pipelineBuilder;
if (NULL != pipelineBuilder) {
fColorEffectCnt = pipelineBuilder->numColorStages();
fCoverageEffectCnt = pipelineBuilder->numCoverageStages();
fColorEffectCnt = pipelineBuilder->numColorFragmentStages();
fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentStages();
SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
}
}
@ -139,25 +139,25 @@ bool GrPipelineBuilder::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
}
void GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorFragmentStages());
fColorProcInfoValid = false;
}
void GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
this->numCoverageStages());
this->numCoverageFragmentStages());
fCoverageProcInfoValid = false;
}
void GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const {
fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorStages());
fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorFragmentStages());
fColorProcInfoValid = false;
}
void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const {
fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(),
this->numCoverageStages());
this->numCoverageFragmentStages());
fCoverageProcInfoValid = false;
}
@ -165,8 +165,8 @@ void GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const
void GrPipelineBuilder::calcColorInvariantOutput(GrColor color) const {
if (!fColorProcInfoValid || color != fColorCache) {
GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
flags, false);
fColorProcInfo.calcWithInitialValues(fColorStages.begin(),this->numColorFragmentStages(),
color, flags, false);
fColorProcInfoValid = true;
fColorCache = color;
}
@ -176,7 +176,7 @@ void GrPipelineBuilder::calcCoverageInvariantOutput(GrColor coverage) const {
if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
this->numCoverageStages(), coverage, flags,
this->numCoverageFragmentStages(), coverage, flags,
true);
fCoverageProcInfoValid = true;
fCoverageCache = coverage;

View File

@ -47,69 +47,23 @@ public:
*/
void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip&);
/// @}
/**
* This function returns true if the render target destination pixel values will be read for
* blending during draw.
*/
bool willBlendWithDst(const GrPrimitiveProcessor*) const;
///////////////////////////////////////////////////////////////////////////
/// @name Effect Stages
/// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
/// fragment shader. Its inputs are the output from the previous stage as well as some variables
/// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
/// the fragment position, local coordinates).
/// @name Fragment Processors
///
/// The stages are divided into two sets, color-computing and coverage-computing. The final
/// color stage produces the final pixel color. The coverage-computing stages function exactly
/// as the color-computing but the output of the final coverage stage is treated as a fractional
/// pixel coverage rather than as input to the src/dst color blend step.
///
/// The input color to the first color-stage is either the constant color or interpolated
/// per-vertex colors. The input to the first coverage stage is either a constant coverage
/// (usually full-coverage) or interpolated per-vertex coverage.
///
/// See the documentation of kCoverageDrawing_StateBit for information about disabling the
/// the color / coverage distinction.
/// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
/// There are two chains of FPs, one for color and one for coverage. The first FP in each
/// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
/// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
/// feed their output to the GrXferProcessor which controls blending.
////
int numColorStages() const { return fColorStages.count(); }
int numCoverageStages() const { return fCoverageStages.count(); }
int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
int numColorFragmentStages() const { return fColorStages.count(); }
int numCoverageFragmentStages() const { return fCoverageStages.count(); }
int numFragmentStages() const { return this->numColorFragmentStages() +
this->numCoverageFragmentStages(); }
const GrXPFactory* getXPFactory() const {
if (!fXPFactory) {
fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
}
return fXPFactory.get();
}
const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
/**
* Checks whether the xp will need a copy of the destination to correctly blend.
*/
bool willXPNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const;
/**
* The xfer processor factory.
*/
const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory.reset(SkRef(xpFactory));
return xpFactory;
}
void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) {
fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
}
void setDisableColorXPFactory() {
fXPFactory.reset(GrDisableColorXPFactory::Create());
}
const GrFragmentStage& getColorFragmentStage(int idx) const { return fColorStages[idx]; }
const GrFragmentStage& getCoverageFragmentStage(int idx) const { return fCoverageStages[idx]; }
const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
SkASSERT(effect);
@ -149,29 +103,24 @@ public:
}
/**
* When this object is destroyed it will remove any color/coverage effects from the pipeline
* builder that were added after its constructor.
*
* This class has strange behavior around geometry processor. If there is a GP on the
* GrPipelineBuilder it will assert that the GP is not modified until after the destructor of
* the ARE. If the GrPipelineBuilder has a NULL GP when the ARE is constructed then it will reset
* it to null in the destructor.
* When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
* that were added after its constructor.
*/
class AutoRestoreEffects : public ::SkNoncopyable {
class AutoRestoreFragmentProcessors : public ::SkNoncopyable {
public:
AutoRestoreEffects()
AutoRestoreFragmentProcessors()
: fPipelineBuilder(NULL)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {}
AutoRestoreEffects(GrPipelineBuilder* ds)
AutoRestoreFragmentProcessors(GrPipelineBuilder* ds)
: fPipelineBuilder(NULL)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {
this->set(ds);
}
~AutoRestoreEffects() { this->set(NULL); }
~AutoRestoreFragmentProcessors() { this->set(NULL); }
void set(GrPipelineBuilder* ds);
@ -183,36 +132,6 @@ public:
int fCoverageEffectCnt;
};
/**
* AutoRestoreStencil
*
* This simple struct saves and restores the stencil settings
*/
class AutoRestoreStencil : public ::SkNoncopyable {
public:
AutoRestoreStencil() : fPipelineBuilder(NULL) {}
AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
~AutoRestoreStencil() { this->set(NULL); }
void set(GrPipelineBuilder* ds) {
if (fPipelineBuilder) {
fPipelineBuilder->setStencil(fStencilSettings);
}
fPipelineBuilder = ds;
if (ds) {
fStencilSettings = ds->getStencil();
}
}
bool isSet() const { return SkToBool(fPipelineBuilder); }
private:
GrPipelineBuilder* fPipelineBuilder;
GrStencilSettings fStencilSettings;
};
/// @}
///////////////////////////////////////////////////////////////////////////
@ -226,11 +145,53 @@ public:
*/
bool canTweakAlphaForCoverage() const;
/// @}
/**
* This function returns true if the render target destination pixel values will be read for
* blending during draw.
*/
bool willBlendWithDst(const GrPrimitiveProcessor*) const;
/**
* Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
* and the dst color are blended.
*/
const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory.reset(SkRef(xpFactory));
return xpFactory;
}
/**
* Sets a GrXPFactory that will ignore src color and perform a set operation between the draws
* output coverage and the destination. This is useful to render coverage masks as CSG.
*/
void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) {
fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
}
/**
* Sets a GrXPFactory that disables color writes to the destination. This is useful when
* rendering to the stencil buffer.
*/
void setDisableColorXPFactory() {
fXPFactory.reset(GrDisableColorXPFactory::Create());
}
const GrXPFactory* getXPFactory() const {
if (!fXPFactory) {
fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
}
return fXPFactory.get();
}
/**
* Checks whether the xp will need a copy of the destination to correctly blend.
*/
bool willXPNeedDstCopy(const GrDrawTargetCaps& caps, const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const;
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Render Target
////
@ -273,6 +234,37 @@ public:
GrStencilSettings* stencil() { return &fStencilSettings; }
/**
* AutoRestoreStencil
*
* This simple struct saves and restores the stencil settings
*/
class AutoRestoreStencil : public ::SkNoncopyable {
public:
AutoRestoreStencil() : fPipelineBuilder(NULL) {}
AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
~AutoRestoreStencil() { this->set(NULL); }
void set(GrPipelineBuilder* ds) {
if (fPipelineBuilder) {
fPipelineBuilder->setStencil(fStencilSettings);
}
fPipelineBuilder = ds;
if (ds) {
fStencilSettings = ds->getStencil();
}
}
bool isSet() const { return SkToBool(fPipelineBuilder); }
private:
GrPipelineBuilder* fPipelineBuilder;
GrStencilSettings fStencilSettings;
};
/// @}
///////////////////////////////////////////////////////////////////////////
@ -363,7 +355,7 @@ public:
///////////////////////////////////////////////////////////////////////////
GrPipelineBuilder& operator= (const GrPipelineBuilder& that);
GrPipelineBuilder& operator=(const GrPipelineBuilder& that);
// TODO delete when we have Batch
const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
@ -413,13 +405,13 @@ private:
/**
* If fColorProcInfoValid is false, function calculates the invariant output for the color
* stages and results are stored in fColorProcInfo.
* processors and results are stored in fColorProcInfo.
*/
void calcColorInvariantOutput(GrColor) const;
/**
* If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
* stages and results are stored in fCoverageProcInfo.
* processors and results are stored in fCoverageProcInfo.
*/
void calcCoverageInvariantOutput(GrColor) const;

View File

@ -355,7 +355,7 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
if (!viewMatrix.invert(&invert)) {
return;
}
GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp(pipelineBuilder);
SkRect dstRect = SkRect::MakeLTRB(SK_Scalar1 * rect.fLeft,
SK_Scalar1 * rect.fTop,

View File

@ -51,21 +51,21 @@ private:
kMaxPerformance_RenderMode,
};
GrPipelineBuilder fPipelineBuilder;
GrPipelineBuilder::AutoRestoreEffects fStateRestore;
SkScalar fTextRatio;
float fTextInverseRatio;
SkGlyphCache* fGlyphCache;
GrPathRange* fGlyphs;
SkStrokeRec fStroke;
uint16_t fGlyphIndices[kGlyphBufferSize];
SkPoint fGlyphPositions[kGlyphBufferSize];
int fQueuedGlyphCount;
int fFallbackGlyphsIdx;
SkMatrix fContextInitialMatrix;
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
bool fUsingDeviceSpaceGlyphs;
GrPipelineBuilder fPipelineBuilder;
GrPipelineBuilder::AutoRestoreFragmentProcessors fStateRestore;
SkScalar fTextRatio;
float fTextInverseRatio;
SkGlyphCache* fGlyphCache;
GrPathRange* fGlyphs;
SkStrokeRec fStroke;
uint16_t fGlyphIndices[kGlyphBufferSize];
SkPoint fGlyphPositions[kGlyphBufferSize];
int fQueuedGlyphCount;
int fFallbackGlyphsIdx;
SkMatrix fContextInitialMatrix;
SkMatrix fViewMatrix;
SkMatrix fLocalMatrix;
bool fUsingDeviceSpaceGlyphs;
GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);

View File

@ -142,8 +142,8 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
header->fFragPosKey = 0;
}
header->fColorEffectCnt = pipeline.numColorStages();
header->fCoverageEffectCnt = pipeline.numCoverageStages();
header->fColorEffectCnt = pipeline.numColorFragmentStages();
header->fCoverageEffectCnt = pipeline.numCoverageFragmentStages();
desc->finalize();
return true;
}

View File

@ -203,8 +203,9 @@ void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
int numProcs = this->pipeline().numFragmentStages();
this->emitAndInstallFragProcs(0, this->pipeline().numColorStages(), inputColor);
this->emitAndInstallFragProcs(this->pipeline().numColorStages(), numProcs, inputCoverage);
this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentStages(), inputColor);
this->emitAndInstallFragProcs(this->pipeline().numColorFragmentStages(), numProcs,
inputCoverage);
this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputColor, *inputCoverage);
}