Modify GrClipMaskManager to reflect logical constness

TBR=bsalomon@google.com
BUG=skia:

Review URL: https://codereview.chromium.org/1230023003
This commit is contained in:
joshualitt 2015-07-13 07:35:05 -07:00 committed by Commit bot
parent 672bb7fc66
commit 5e6ba21f07
7 changed files with 129 additions and 53 deletions

View File

@ -30,6 +30,11 @@ public:
} }
private: private:
uint32_t currentSaveMarker() const { return 0; }
void restoreToSaveMarker(/*uint32_t marker*/) {}
// For GrPipelineBuilder::AutoRestoreProcessorDataManager
friend class GrPipelineBuilder;
static const uint32_t kNumProcessor = 1; static const uint32_t kNumProcessor = 1;
static const uint32_t kDataIndicesPerProcessor = 1; static const uint32_t kDataIndicesPerProcessor = 1;
static const uint32_t kPreAllocDataPerProcessor = 1; static const uint32_t kPreAllocDataPerProcessor = 1;

View File

@ -30,12 +30,14 @@ typedef SkClipStack::Element Element;
namespace { namespace {
// set up the draw state to enable the aa clipping mask. Besides setting up the // set up the draw state to enable the aa clipping mask. Besides setting up the
// stage matrix this also alters the vertex layout // stage matrix this also alters the vertex layout
void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder, void setup_drawstate_aaclip(const GrPipelineBuilder& pipelineBuilder,
GrTexture* result, GrTexture* result,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp, GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreProcessorDataManager* arpdm,
const SkIRect &devBound) { const SkIRect &devBound) {
SkASSERT(pipelineBuilder && arfp); SkASSERT(arfp && arpdm);
arfp->set(pipelineBuilder); arfp->set(&pipelineBuilder);
arpdm->set(&pipelineBuilder);
SkMatrix mat; SkMatrix mat;
// We use device coords to compute the texture coordinates. We set our matrix to be a // We use device coords to compute the texture coordinates. We set our matrix to be a
@ -46,8 +48,8 @@ void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder,
SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
// This could be a long-lived effect that is cached with the alpha-mask. // This could be a long-lived effect that is cached with the alpha-mask.
pipelineBuilder->addCoverageProcessor( arfp->addCoverageProcessor(
GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager(), GrTextureDomainEffect::Create(arpdm->getProcessorDataManager(),
result, result,
mat, mat,
GrTextureDomain::MakeTexelDomain(result, domainTexels), GrTextureDomain::MakeTexelDomain(result, domainTexels),
@ -58,7 +60,7 @@ void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder,
bool path_needs_SW_renderer(GrContext* context, bool path_needs_SW_renderer(GrContext* context,
const GrDrawTarget* gpu, const GrDrawTarget* gpu,
const GrPipelineBuilder* pipelineBuilder, const GrPipelineBuilder& pipelineBuilder,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkPath& origPath, const SkPath& origPath,
const GrStrokeInfo& stroke, const GrStrokeInfo& stroke,
@ -73,7 +75,7 @@ bool path_needs_SW_renderer(GrContext* context,
GrPathRendererChain::kColorAntiAlias_DrawType : GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType; GrPathRendererChain::kColor_DrawType;
return NULL == context->getPathRenderer(gpu, pipelineBuilder, viewMatrix, *path, stroke, return NULL == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix, *path, stroke,
false, type); false, type);
} }
} }
@ -92,7 +94,7 @@ GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); }
* will be used on any element. If so, it returns true to indicate that the * will be used on any element. If so, it returns true to indicate that the
* entire clip should be rendered in SW and then uploaded en masse to the gpu. * entire clip should be rendered in SW and then uploaded en masse to the gpu.
*/ */
bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder, bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
const SkVector& clipToMaskOffset, const SkVector& clipToMaskOffset,
const GrReducedClip::ElementList& elements) { const GrReducedClip::ElementList& elements) {
// TODO: generalize this function so that when // TODO: generalize this function so that when
@ -121,7 +123,7 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder,
return false; return false;
} }
bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder, bool GrClipMaskManager::installClipEffects(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp, GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
const GrReducedClip::ElementList& elements, const GrReducedClip::ElementList& elements,
const SkVector& clipToRTOffset, const SkVector& clipToRTOffset,
@ -132,8 +134,8 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
} }
arfp->set(pipelineBuilder); arfp->set(&pipelineBuilder);
GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrReducedClip::ElementList::Iter iter(elements); GrReducedClip::ElementList::Iter iter(elements);
bool failed = false; bool failed = false;
while (iter.get()) { while (iter.get()) {
@ -174,8 +176,8 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
edgeType = edgeType =
invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType; invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType;
} else { } else {
edgeType = edgeType = invert ? kInverseFillBW_GrProcessorEdgeType :
invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType; kFillBW_GrProcessorEdgeType;
} }
SkAutoTUnref<GrFragmentProcessor> fp; SkAutoTUnref<GrFragmentProcessor> fp;
switch (iter.get()->getType()) { switch (iter.get()->getType()) {
@ -199,7 +201,7 @@ invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
break; break;
} }
if (fp) { if (fp) {
pipelineBuilder->addCoverageProcessor(fp); arfp->addCoverageProcessor(fp);
} else { } else {
failed = true; failed = true;
break; break;
@ -217,9 +219,10 @@ invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil, // sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software // scissor, or entirely software
bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder, bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp, GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars, GrPipelineBuilder::AutoRestoreStencil* ars,
GrPipelineBuilder::AutoRestoreProcessorDataManager* arpdm,
GrScissorState* scissorState, GrScissorState* scissorState,
const SkRect* devBounds) { const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType; fCurrClipMaskType = kNone_ClipMaskType;
@ -232,13 +235,13 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState; GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds; SkIRect clipSpaceIBounds;
bool requiresAA = false; bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
// GrDrawTarget should have filtered this for us // GrDrawTarget should have filtered this for us
SkASSERT(rt); SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
const GrClip& clip = pipelineBuilder->clip(); const GrClip& clip = pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) { if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars); this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true; return true;
@ -333,12 +336,12 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
} }
if (result) { if (result) {
arfp->set(pipelineBuilder); arfp->set(&pipelineBuilder);
// The mask's top left coord should be pinned to the rounded-out top left corner of // 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. // clipSpace bounds. We determine the mask's position WRT to the render target here.
SkIRect rtSpaceMaskBounds = clipSpaceIBounds; SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
rtSpaceMaskBounds.offset(-clip.origin()); rtSpaceMaskBounds.offset(-clip.origin());
setup_drawstate_aaclip(pipelineBuilder, result, arfp, rtSpaceMaskBounds); setup_drawstate_aaclip(pipelineBuilder, result, arfp, arpdm, rtSpaceMaskBounds);
this->setPipelineBuilderStencil(pipelineBuilder, ars); this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true; return true;
} }
@ -925,7 +928,7 @@ const GrStencilSettings& basic_apply_stencil_clip_settings() {
} }
} }
void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBuilder, void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreStencil* ars) { GrPipelineBuilder::AutoRestoreStencil* ars) {
// We make two copies of the StencilSettings here (except in the early // We make two copies of the StencilSettings here (except in the early
// exit scenario. One copy from draw state to the stack var. Then another // exit scenario. One copy from draw state to the stack var. Then another
@ -938,18 +941,18 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
// The GrGpu client may not be using the stencil buffer but we may need to // The GrGpu client may not be using the stencil buffer but we may need to
// enable it in order to respect a stencil clip. // enable it in order to respect a stencil clip.
if (pipelineBuilder->getStencil().isDisabled()) { if (pipelineBuilder.getStencil().isDisabled()) {
if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
settings = basic_apply_stencil_clip_settings(); settings = basic_apply_stencil_clip_settings();
} else { } else {
return; return;
} }
} else { } else {
settings = pipelineBuilder->getStencil(); settings = pipelineBuilder.getStencil();
} }
int stencilBits = 0; int stencilBits = 0;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStencilAttachment(); GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStencilAttachment();
if (stencilAttachment) { if (stencilAttachment) {
stencilBits = stencilAttachment->bits(); stencilBits = stencilAttachment->bits();
@ -958,8 +961,8 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits); this->adjustStencilParams(&settings, fClipMode, stencilBits);
ars->set(pipelineBuilder); ars->set(&pipelineBuilder);
pipelineBuilder->setStencil(settings); ars->setStencil(settings);
} }
void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,

View File

@ -43,9 +43,10 @@ public:
* the manager when it must install additional effects to implement the * the manager when it must install additional effects to implement the
* clip. devBounds is optional but can help optimize clipping. * clip. devBounds is optional but can help optimize clipping.
*/ */
bool setupClipping(GrPipelineBuilder*, bool setupClipping(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreFragmentProcessors*, GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*, GrPipelineBuilder::AutoRestoreStencil*,
GrPipelineBuilder::AutoRestoreProcessorDataManager*,
GrScissorState*, GrScissorState*,
const SkRect* devBounds); const SkRect* devBounds);
@ -86,7 +87,7 @@ private:
// Attempts to install a series of coverage effects to implement the clip. Return indicates // Attempts to install a series of coverage effects to implement the clip. Return indicates
// whether the element list was successfully converted to effects. // whether the element list was successfully converted to effects.
bool installClipEffects(GrPipelineBuilder*, bool installClipEffects(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreFragmentProcessors*, GrPipelineBuilder::AutoRestoreFragmentProcessors*,
const GrReducedClip::ElementList&, const GrReducedClip::ElementList&,
const SkVector& clipOffset, const SkVector& clipOffset,
@ -125,7 +126,7 @@ private:
const SkIRect& clipSpaceIBounds, const SkIRect& clipSpaceIBounds,
bool willUpload); bool willUpload);
bool useSWOnlyPath(const GrPipelineBuilder*, bool useSWOnlyPath(const GrPipelineBuilder&,
const SkVector& clipToMaskOffset, const SkVector& clipToMaskOffset,
const GrReducedClip::ElementList& elements); const GrReducedClip::ElementList& elements);
@ -161,7 +162,8 @@ private:
* Called prior to return control back the GrGpu in setupClipping. It updates the * Called prior to return control back the GrGpu in setupClipping. It updates the
* GrPipelineBuilder with stencil settings that account for stencil-based clipping. * GrPipelineBuilder with stencil settings that account for stencil-based clipping.
*/ */
void setPipelineBuilderStencil(GrPipelineBuilder*, GrPipelineBuilder::AutoRestoreStencil*); void setPipelineBuilderStencil(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreStencil*);
/** /**
* Adjusts the stencil settings to account for interaction with stencil * Adjusts the stencil settings to account for interaction with stencil

View File

@ -135,7 +135,8 @@ void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder,
GrScissorState scissorState; GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars; GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, &batch->bounds())) { GrPipelineBuilder::AutoRestoreProcessorDataManager arpdm;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &arpdm, &scissorState, &batch->bounds())) {
return; return;
} }
@ -201,7 +202,8 @@ void GrDrawTarget::stencilPath(GrPipelineBuilder* pipelineBuilder,
GrScissorState scissorState; GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars; GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, NULL)) { GrPipelineBuilder::AutoRestoreProcessorDataManager arpdm;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &arpdm, &scissorState, NULL)) {
return; return;
} }
@ -230,7 +232,8 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
GrScissorState scissorState; GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars; GrPipelineBuilder::AutoRestoreStencil ars;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, &devBounds)) { GrPipelineBuilder::AutoRestoreProcessorDataManager arpdm;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &arpdm, &scissorState, &devBounds)) {
return; return;
} }
@ -269,8 +272,8 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
GrScissorState scissorState; GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
GrPipelineBuilder::AutoRestoreStencil ars; GrPipelineBuilder::AutoRestoreStencil ars;
GrPipelineBuilder::AutoRestoreProcessorDataManager arpdm;
if (!this->setupClip(pipelineBuilder, &arfp, &ars, &scissorState, NULL)) { if (!this->setupClip(pipelineBuilder, &arfp, &ars, &arpdm, &scissorState, NULL)) {
return; return;
} }
@ -504,13 +507,15 @@ GrClipTarget::GrClipTarget(GrContext* context)
bool GrClipTarget::setupClip(GrPipelineBuilder* pipelineBuilder, bool GrClipTarget::setupClip(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp, GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars, GrPipelineBuilder::AutoRestoreStencil* ars,
GrPipelineBuilder::AutoRestoreProcessorDataManager* arpdm,
GrScissorState* scissorState, GrScissorState* scissorState,
const SkRect* devBounds) { const SkRect* devBounds) {
return fClipMaskManager->setupClipping(pipelineBuilder, return fClipMaskManager->setupClipping(*pipelineBuilder,
arfp, arfp,
ars, ars,
scissorState, arpdm,
devBounds); scissorState,
devBounds);
} }
void GrClipTarget::purgeResources() { void GrClipTarget::purgeResources() {

View File

@ -290,6 +290,7 @@ private:
virtual bool setupClip(GrPipelineBuilder*, virtual bool setupClip(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreFragmentProcessors*, GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*, GrPipelineBuilder::AutoRestoreStencil*,
GrPipelineBuilder::AutoRestoreProcessorDataManager*,
GrScissorState*, GrScissorState*,
const SkRect* devBounds) = 0; const SkRect* devBounds) = 0;
@ -339,11 +340,12 @@ protected:
private: private:
GrClipMaskManager* clipMaskManager() override { return fClipMaskManager; } GrClipMaskManager* clipMaskManager() override { return fClipMaskManager; }
virtual bool setupClip(GrPipelineBuilder*, bool setupClip(GrPipelineBuilder*,
GrPipelineBuilder::AutoRestoreFragmentProcessors*, GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*, GrPipelineBuilder::AutoRestoreStencil*,
GrScissorState* scissorState, GrPipelineBuilder::AutoRestoreProcessorDataManager*,
const SkRect* devBounds) override; GrScissorState* scissorState,
const SkRect* devBounds) override;
typedef GrDrawTarget INHERITED; typedef GrDrawTarget INHERITED;
}; };

View File

@ -99,7 +99,8 @@ bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
this->hasMixedSamples()); this->hasMixedSamples());
} }
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) { void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(
const GrPipelineBuilder* pipelineBuilder) {
if (fPipelineBuilder) { if (fPipelineBuilder) {
int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt; int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt;
SkASSERT(m >= 0); SkASSERT(m >= 0);
@ -114,7 +115,7 @@ void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pi
} }
SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;) SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
} }
fPipelineBuilder = pipelineBuilder; fPipelineBuilder = const_cast<GrPipelineBuilder*>(pipelineBuilder);
if (NULL != pipelineBuilder) { if (NULL != pipelineBuilder) {
fColorEffectCnt = pipelineBuilder->numColorFragmentStages(); fColorEffectCnt = pipelineBuilder->numColorFragmentStages();
fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentStages(); fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentStages();

View File

@ -110,6 +110,8 @@ public:
/** /**
* When this object is destroyed it will remove any color/coverage FPs from the pipeline builder * When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
* that were added after its constructor. * that were added after its constructor.
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/ */
class AutoRestoreFragmentProcessors : public ::SkNoncopyable { class AutoRestoreFragmentProcessors : public ::SkNoncopyable {
public: public:
@ -127,14 +129,20 @@ public:
~AutoRestoreFragmentProcessors() { this->set(NULL); } ~AutoRestoreFragmentProcessors() { this->set(NULL); }
void set(GrPipelineBuilder* ds); void set(const GrPipelineBuilder* ds);
bool isSet() const { return SkToBool(fPipelineBuilder); } bool isSet() const { return SkToBool(fPipelineBuilder); }
const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* processor) {
SkASSERT(this->isSet());
return fPipelineBuilder->addCoverageProcessor(processor);
}
private: private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder; GrPipelineBuilder* fPipelineBuilder;
int fColorEffectCnt; int fColorEffectCnt;
int fCoverageEffectCnt; int fCoverageEffectCnt;
}; };
/// @} /// @}
@ -246,20 +254,22 @@ public:
* AutoRestoreStencil * AutoRestoreStencil
* *
* This simple struct saves and restores the stencil settings * This simple struct saves and restores the stencil settings
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/ */
class AutoRestoreStencil : public ::SkNoncopyable { class AutoRestoreStencil : public ::SkNoncopyable {
public: public:
AutoRestoreStencil() : fPipelineBuilder(NULL) {} AutoRestoreStencil() : fPipelineBuilder(NULL) {}
AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); } AutoRestoreStencil(const GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
~AutoRestoreStencil() { this->set(NULL); } ~AutoRestoreStencil() { this->set(NULL); }
void set(GrPipelineBuilder* ds) { void set(const GrPipelineBuilder* ds) {
if (fPipelineBuilder) { if (fPipelineBuilder) {
fPipelineBuilder->setStencil(fStencilSettings); fPipelineBuilder->setStencil(fStencilSettings);
} }
fPipelineBuilder = ds; fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
if (ds) { if (ds) {
fStencilSettings = ds->getStencil(); fStencilSettings = ds->getStencil();
} }
@ -267,7 +277,13 @@ public:
bool isSet() const { return SkToBool(fPipelineBuilder); } bool isSet() const { return SkToBool(fPipelineBuilder); }
void setStencil(const GrStencilSettings& settings) {
SkASSERT(this->isSet());
fPipelineBuilder->setStencil(settings);
}
private: private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder; GrPipelineBuilder* fPipelineBuilder;
GrStencilSettings fStencilSettings; GrStencilSettings fStencilSettings;
}; };
@ -399,6 +415,48 @@ public:
GrProcessorDataManager* getProcessorDataManager() { return fProcDataManager.get(); } GrProcessorDataManager* getProcessorDataManager() { return fProcDataManager.get(); }
const GrProcessorDataManager* processorDataManager() const { return fProcDataManager.get(); } const GrProcessorDataManager* processorDataManager() const { return fProcDataManager.get(); }
/**
* When this object is destroyed it will remove any additions to the GrProcessorDataManager
* owned by the GrPipelineBuilder
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/
class AutoRestoreProcessorDataManager : public ::SkNoncopyable {
public:
AutoRestoreProcessorDataManager() : fPipelineBuilder(NULL), fSaveMarker(0) {}
AutoRestoreProcessorDataManager(GrPipelineBuilder* ds)
: fPipelineBuilder(NULL)
, fSaveMarker(0) {
this->set(ds);
}
~AutoRestoreProcessorDataManager() { this->set(NULL); }
void set(const GrPipelineBuilder* ds) {
if (fPipelineBuilder) {
fPipelineBuilder->getProcessorDataManager()->restoreToSaveMarker(/*fSaveMarker*/);
}
fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
if (ds) {
fSaveMarker = ds->processorDataManager()->currentSaveMarker();
}
}
bool isSet() const { return SkToBool(fPipelineBuilder); }
GrProcessorDataManager* getProcessorDataManager() {
SkASSERT(this->isSet());
return fPipelineBuilder->getProcessorDataManager();
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
uint32_t fSaveMarker;
};
private: private:
// Calculating invariant color / coverage information is expensive, so we partially cache the // Calculating invariant color / coverage information is expensive, so we partially cache the
// results. // results.
@ -435,7 +493,7 @@ private:
// Some of the auto restore objects assume that no effects are removed during their lifetime. // Some of the auto restore objects assume that no effects are removed during their lifetime.
// This is used to assert that this condition holds. // This is used to assert that this condition holds.
SkDEBUGCODE(int fBlockEffectRemovalCnt;) SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray; typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;