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:
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 kDataIndicesPerProcessor = 1;
static const uint32_t kPreAllocDataPerProcessor = 1;

View File

@ -30,12 +30,14 @@ typedef SkClipStack::Element Element;
namespace {
// set up the draw state to enable the aa clipping mask. Besides setting up the
// stage matrix this also alters the vertex layout
void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder,
void setup_drawstate_aaclip(const GrPipelineBuilder& pipelineBuilder,
GrTexture* result,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreProcessorDataManager* arpdm,
const SkIRect &devBound) {
SkASSERT(pipelineBuilder && arfp);
arfp->set(pipelineBuilder);
SkASSERT(arfp && arpdm);
arfp->set(&pipelineBuilder);
arpdm->set(&pipelineBuilder);
SkMatrix mat;
// 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());
// This could be a long-lived effect that is cached with the alpha-mask.
pipelineBuilder->addCoverageProcessor(
GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager(),
arfp->addCoverageProcessor(
GrTextureDomainEffect::Create(arpdm->getProcessorDataManager(),
result,
mat,
GrTextureDomain::MakeTexelDomain(result, domainTexels),
@ -58,7 +60,7 @@ void setup_drawstate_aaclip(GrPipelineBuilder* pipelineBuilder,
bool path_needs_SW_renderer(GrContext* context,
const GrDrawTarget* gpu,
const GrPipelineBuilder* pipelineBuilder,
const GrPipelineBuilder& pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& origPath,
const GrStrokeInfo& stroke,
@ -73,7 +75,7 @@ bool path_needs_SW_renderer(GrContext* context,
GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
return NULL == context->getPathRenderer(gpu, pipelineBuilder, viewMatrix, *path, stroke,
return NULL == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix, *path, stroke,
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
* 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 GrReducedClip::ElementList& elements) {
// TODO: generalize this function so that when
@ -121,7 +123,7 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder,
return false;
}
bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
bool GrClipMaskManager::installClipEffects(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
const GrReducedClip::ElementList& elements,
const SkVector& clipToRTOffset,
@ -132,8 +134,8 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
}
arfp->set(pipelineBuilder);
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
arfp->set(&pipelineBuilder);
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrReducedClip::ElementList::Iter iter(elements);
bool failed = false;
while (iter.get()) {
@ -174,8 +176,8 @@ bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
edgeType =
invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProcessorEdgeType;
} else {
edgeType =
invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
edgeType = invert ? kInverseFillBW_GrProcessorEdgeType :
kFillBW_GrProcessorEdgeType;
}
SkAutoTUnref<GrFragmentProcessor> fp;
switch (iter.get()->getType()) {
@ -199,7 +201,7 @@ invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
break;
}
if (fp) {
pipelineBuilder->addCoverageProcessor(fp);
arfp->addCoverageProcessor(fp);
} else {
failed = true;
break;
@ -217,9 +219,10 @@ invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProcessorEdgeType;
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrPipelineBuilder::AutoRestoreProcessorDataManager* arpdm,
GrScissorState* scissorState,
const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType;
@ -232,13 +235,13 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds;
bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
const GrClip& clip = pipelineBuilder->clip();
const GrClip& clip = pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
@ -333,12 +336,12 @@ bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
}
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
// 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, arfp, rtSpaceMaskBounds);
setup_drawstate_aaclip(pipelineBuilder, result, arfp, arpdm, rtSpaceMaskBounds);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
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) {
// 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
@ -938,18 +941,18 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
// The GrGpu client may not be using the stencil buffer but we may need to
// enable it in order to respect a stencil clip.
if (pipelineBuilder->getStencil().isDisabled()) {
if (pipelineBuilder.getStencil().isDisabled()) {
if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
settings = basic_apply_stencil_clip_settings();
} else {
return;
}
} else {
settings = pipelineBuilder->getStencil();
settings = pipelineBuilder.getStencil();
}
int stencilBits = 0;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStencilAttachment();
if (stencilAttachment) {
stencilBits = stencilAttachment->bits();
@ -958,8 +961,8 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits);
ars->set(pipelineBuilder);
pipelineBuilder->setStencil(settings);
ars->set(&pipelineBuilder);
ars->setStencil(settings);
}
void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,

View File

@ -43,9 +43,10 @@ public:
* the manager when it must install additional effects to implement the
* clip. devBounds is optional but can help optimize clipping.
*/
bool setupClipping(GrPipelineBuilder*,
bool setupClipping(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
GrPipelineBuilder::AutoRestoreStencil*,
GrPipelineBuilder::AutoRestoreProcessorDataManager*,
GrScissorState*,
const SkRect* devBounds);
@ -86,7 +87,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*,
bool installClipEffects(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreFragmentProcessors*,
const GrReducedClip::ElementList&,
const SkVector& clipOffset,
@ -125,7 +126,7 @@ private:
const SkIRect& clipSpaceIBounds,
bool willUpload);
bool useSWOnlyPath(const GrPipelineBuilder*,
bool useSWOnlyPath(const GrPipelineBuilder&,
const SkVector& clipToMaskOffset,
const GrReducedClip::ElementList& elements);
@ -161,7 +162,8 @@ private:
* Called prior to return control back the GrGpu in setupClipping. It updates the
* 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

View File

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

View File

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

View File

@ -99,7 +99,8 @@ bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
this->hasMixedSamples());
}
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(
const GrPipelineBuilder* pipelineBuilder) {
if (fPipelineBuilder) {
int m = fPipelineBuilder->numColorFragmentStages() - fColorEffectCnt;
SkASSERT(m >= 0);
@ -114,7 +115,7 @@ void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pi
}
SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
}
fPipelineBuilder = pipelineBuilder;
fPipelineBuilder = const_cast<GrPipelineBuilder*>(pipelineBuilder);
if (NULL != pipelineBuilder) {
fColorEffectCnt = pipelineBuilder->numColorFragmentStages();
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
* 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 {
public:
@ -127,14 +129,20 @@ public:
~AutoRestoreFragmentProcessors() { this->set(NULL); }
void set(GrPipelineBuilder* ds);
void set(const GrPipelineBuilder* ds);
bool isSet() const { return SkToBool(fPipelineBuilder); }
const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* processor) {
SkASSERT(this->isSet());
return fPipelineBuilder->addCoverageProcessor(processor);
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
int fColorEffectCnt;
int fCoverageEffectCnt;
int fColorEffectCnt;
int fCoverageEffectCnt;
};
/// @}
@ -246,20 +254,22 @@ public:
* AutoRestoreStencil
*
* 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 {
public:
AutoRestoreStencil() : fPipelineBuilder(NULL) {}
AutoRestoreStencil(GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
AutoRestoreStencil(const GrPipelineBuilder* ds) : fPipelineBuilder(NULL) { this->set(ds); }
~AutoRestoreStencil() { this->set(NULL); }
void set(GrPipelineBuilder* ds) {
void set(const GrPipelineBuilder* ds) {
if (fPipelineBuilder) {
fPipelineBuilder->setStencil(fStencilSettings);
}
fPipelineBuilder = ds;
fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
if (ds) {
fStencilSettings = ds->getStencil();
}
@ -267,7 +277,13 @@ public:
bool isSet() const { return SkToBool(fPipelineBuilder); }
void setStencil(const GrStencilSettings& settings) {
SkASSERT(this->isSet());
fPipelineBuilder->setStencil(settings);
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
GrStencilSettings fStencilSettings;
};
@ -399,6 +415,48 @@ public:
GrProcessorDataManager* getProcessorDataManager() { 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:
// Calculating invariant color / coverage information is expensive, so we partially cache the
// results.
@ -435,7 +493,7 @@ private:
// Some of the auto restore objects assume that no effects are removed during their lifetime.
// This is used to assert that this condition holds.
SkDEBUGCODE(int fBlockEffectRemovalCnt;)
SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;