}
}
-GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget)
+GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
: fCurrClipMaskType(kNone_ClipMaskType)
- , fAACache(clipTarget->getContext()->resourceProvider())
- , fClipTarget(clipTarget)
+ , fAACache(drawTarget->cmmAccess().resourceProvider())
+ , fDrawTarget(drawTarget)
, fClipMode(kIgnoreClip_StencilClipMode) {
}
-GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); }
+GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().context(); }
/*
* This method traverses the clip stack to see if the GrSoftwarePathRenderer
if (Element::kRect_Type != element->getType()) {
SkPath path;
element->asPath(&path);
- if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipelineBuilder, translate,
+ if (path_needs_SW_renderer(this->getContext(), fDrawTarget, pipelineBuilder, translate,
path, stroke, element->isAA())) {
return true;
}
SkRect devRect = element->getRect();
viewMatrix.mapRect(&devRect);
- fClipTarget->drawAARect(*pipelineBuilder, color, viewMatrix,
+ fDrawTarget->drawAARect(*pipelineBuilder, color, viewMatrix,
element->getRect(), devRect);
} else {
- fClipTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix,
+ fDrawTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix,
element->getRect());
}
return true;
GrPathRendererChain::DrawType type;
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, viewMatrix,
+ pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder, viewMatrix,
path, stroke, false, type);
}
if (nullptr == pr) {
return false;
}
GrPathRenderer::DrawPathArgs args;
- args.fTarget = fClipTarget;
+ args.fTarget = fDrawTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = pipelineBuilder;
args.fColor = color;
GrPathRendererChain::DrawType type = element->isAA() ?
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
GrPathRendererChain::kStencilAndColor_DrawType;
- *pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, SkMatrix::I(), path,
+ *pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder, SkMatrix::I(), path,
stroke, false, type);
return SkToBool(*pr);
}
GrTextureParams::kNone_FilterMode))->unref();
// The color passed in here does not matter since the coverageSetOpXP won't read it.
- fClipTarget->drawNonAARect(*pipelineBuilder,
+ fDrawTarget->drawNonAARect(*pipelineBuilder,
GrColor_WHITE,
SkMatrix::I(),
SkRect::Make(dstBound));
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
// clear the part that we care about.
- fClipTarget->clear(&maskSpaceIBounds,
+ fDrawTarget->clear(&maskSpaceIBounds,
GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
true,
result->asRenderTarget());
}
dst = temp;
// clear the temp target and set blend to replace
- fClipTarget->clear(&maskSpaceElementIBounds,
+ fDrawTarget->clear(&maskSpaceElementIBounds,
invert ? 0xffffffff : 0x00000000,
true,
dst->asRenderTarget());
backgroundPipelineBuilder.setStencil(kDrawOutsideElement);
// The color passed in here does not matter since the coverageSetOpXP won't read it.
- fClipTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WHITE, translate,
+ fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WHITE, translate,
clipSpaceIBounds);
}
} else {
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
- fClipTarget->clearStencilClip(stencilSpaceIBounds,
- GrReducedClip::kAllIn_InitialState == initialState,
- rt);
+ fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
+ GrReducedClip::kAllIn_InitialState == initialState, rt);
// walk through each clip element and perform its set op
// with the existing clip.
if (fillInverted) {
clipPath.toggleInverseFillType();
}
- pr = this->getContext()->getPathRenderer(fClipTarget,
+ pr = this->getContext()->getPathRenderer(fDrawTarget,
&pipelineBuilder,
viewMatrix,
clipPath,
*pipelineBuilder.stencil() = gDrawToStencil;
// We need this AGP until everything is in GrBatch
- fClipTarget->drawNonAARect(pipelineBuilder,
+ fDrawTarget->drawNonAARect(pipelineBuilder,
GrColor_WHITE,
viewMatrix,
element->getRect());
*pipelineBuilder.stencil() = gDrawToStencil;
GrPathRenderer::DrawPathArgs args;
- args.fTarget = fClipTarget;
+ args.fTarget = fDrawTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fColor = GrColor_WHITE;
pr->drawPath(args);
} else {
GrPathRenderer::StencilPathArgs args;
- args.fTarget = fClipTarget;
+ args.fTarget = fDrawTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fViewMatrix = &viewMatrix;
if (canDrawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
// We need this AGP until everything is in GrBatch
- fClipTarget->drawNonAARect(pipelineBuilder,
+ fDrawTarget->drawNonAARect(pipelineBuilder,
GrColor_WHITE,
viewMatrix,
element->getRect());
} else {
GrPathRenderer::DrawPathArgs args;
- args.fTarget = fClipTarget;
+ args.fTarget = fDrawTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fColor = GrColor_WHITE;
} else {
// The view matrix is setup to do clip space -> stencil space translation, so
// draw rect in clip space.
- fClipTarget->drawNonAARect(pipelineBuilder,
+ fDrawTarget->drawNonAARect(pipelineBuilder,
GrColor_WHITE,
viewMatrix,
SkRect::Make(clipSpaceIBounds));
stencilBits = stencilAttachment->bits();
}
- SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
- SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
+ SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
+ SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits);
ars->set(&pipelineBuilder);
ars->setStencil(settings);
unsigned int userBits = clipBit - 1;
GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
- bool twoSided = fClipTarget->caps()->twoSidedStencilSupport();
+ bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport();
bool finished = false;
while (!finished) {
#include "SkTLList.h"
#include "SkTypes.h"
-class GrClipTarget;
+class GrDrawTarget;
class GrPathRenderer;
class GrPathRendererChain;
class GrTexture;
*/
class GrClipMaskManager : SkNoncopyable {
public:
- GrClipMaskManager(GrClipTarget* owner);
+ GrClipMaskManager(GrDrawTarget* owner);
/**
* Creates a clip mask if necessary as a stencil buffer or alpha texture
/**
* Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
- * which will allow Resourcecache to automatically purge anything this class has created.
+ * which will allow GrResourceCache to automatically purge anything this class has created.
*/
void purgeResources();
return kAlpha_ClipMaskType == fCurrClipMaskType;
}
- void setClipTarget(GrClipTarget*);
-
void adjustPathStencilParams(const GrStencilAttachment*, GrStencilSettings*);
private:
} fCurrClipMaskType;
GrClipMaskCache fAACache; // cache for the AA path
- GrClipTarget* fClipTarget; // This is our owning clip target.
+ GrDrawTarget* fDrawTarget; // This is our owning draw target.
StencilClipMode fClipMode;
typedef SkNoncopyable INHERITED;
void GrContext::DrawingMgr::init(GrContext* context) {
fContext = context;
- fDrawTarget = new GrClipTarget(context);
+ fDrawTarget = new GrDrawTarget(context->getGpu(), context->resourceProvider());
}
void GrContext::DrawingMgr::cleanup() {
GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
: fGpu(SkRef(gpu))
- , fCaps(SkRef(gpu->caps()))
, fResourceProvider(resourceProvider)
, fFlushing(false)
, fLastFlushToken(0) {
+ // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
+ fContext = fGpu->getContext();
}
GrDrawTarget::~GrDrawTarget() {
fGpu->unref();
- fCaps->unref();
}
////////////////////////////////////////////////////////////////////////////////
bounds.roundOut(&drawIBounds);
if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
- GrCapsDebugf(fCaps, "Missed an early reject. "
- "Bailing on draw from setupDstReadIfNecessary.\n");
+ GrCapsDebugf(this->caps(), "Missed an early reject. "
+ "Bailing on draw from setupDstReadIfNecessary.\n");
#endif
return false;
}
// MSAA consideration: When there is support for reading MSAA samples in the shader we could
// have per-sample dst values by making the copy multisampled.
GrSurfaceDesc desc;
- if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) {
+ if (!fGpu->initCopySurfaceDstDesc(rt, &desc)) {
desc.fOrigin = kDefault_GrSurfaceOrigin;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = rt->config();
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
GrPipelineBuilder::AutoRestoreStencil ars;
- if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
+ if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
+ &batch->bounds())) {
return;
}
*outStencilSettings = even_odd_path_stencil_settings();
break;
}
- this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
+ fClipMaskManager->adjustPathStencilParams(sb, outStencilSettings);
}
void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
GrPipelineBuilder::AutoRestoreStencil ars;
- if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, nullptr)) {
+
+ if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState, nullptr)) {
return;
}
GrDrawPathBatchBase* batch,
GrPathRendering::FillType fill) {
// This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted
- // after setupClip() but before onDrawBatch(). TODO: Figure out a better model for handling
- // stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and batches.
+ // after setting up clipping but before onDrawBatch(). TODO: Figure out a better model for
+ // handling stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and
+ // batches.
GrScissorState scissorState;
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
GrPipelineBuilder::AutoRestoreStencil ars;
- if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
+ if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
+ &batch->bounds())) {
return;
}
rect = &clippedRect;
}
- if (fCaps->useDrawInsteadOfClear()) {
+ if (this->caps()->useDrawInsteadOfClear()) {
// This works around a driver bug with clear by drawing a rect instead.
// The driver will ignore a clear if it is the only thing rendered to a
// target before the target is read.
return true;
}
-///////////////////////////////////////////////////////////////////////////////
-GrClipTarget::GrClipTarget(GrContext* context)
- : INHERITED(context->getGpu(), context->resourceProvider())
- , fContext(context) {
- fClipMaskManager.reset(new GrClipMaskManager(this));
-}
-
-
-bool GrClipTarget::setupClip(const GrPipelineBuilder& pipelineBuilder,
- GrPipelineBuilder::AutoRestoreFragmentProcessorState* arfps,
- GrPipelineBuilder::AutoRestoreStencil* ars,
- GrScissorState* scissorState,
- const SkRect* devBounds) {
- return fClipMaskManager->setupClipping(pipelineBuilder,
- arfps,
- ars,
- scissorState,
- devBounds);
-}
-
-void GrClipTarget::purgeResources() {
- // The clip mask manager can rebuild all its clip masks so just
- // get rid of them all.
- fClipMaskManager->purgeResources();
-};
-
-void GrClipTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
+void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
this->recordBatch(batch);
batch->unref();
class GrDrawPathBatchBase;
class GrPathRangeDraw;
-class GrDrawTarget : public SkRefCnt {
+class GrDrawTarget final : public SkRefCnt {
public:
// The context may not be fully constructed and should not be used during GrDrawTarget
// construction.
/**
* Gets the capabilities of the draw target.
*/
- const GrCaps* caps() const { return fCaps; }
+ const GrCaps* caps() const { return fGpu->caps(); }
void drawBatch(const GrPipelineBuilder&, GrDrawBatch*);
/**
* Release any resources that are cached but not currently in use. This
* is intended to give an application some recourse when resources are low.
+ * TODO: Stop holding on to resources.
*/
- virtual void purgeResources() {};
+ virtual void purgeResources() {
+ // The clip mask manager can rebuild all its clip masks so just get rid of them all.
+ fClipMaskManager->purgeResources();
+ };
bool programUnitTest(GrContext* owner, int maxStages);
-protected:
- GrGpu* getGpu() { return fGpu; }
- const GrGpu* getGpu() const { return fGpu; }
+ /** Provides access to internal functions to GrClipMaskManager without friending all of
+ GrDrawTarget to CMM. */
+ class CMMAccess {
+ public:
+ CMMAccess(GrDrawTarget* drawTarget) : fDrawTarget(drawTarget) {}
+ private:
+ void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) const {
+ fDrawTarget->clearStencilClip(rect, insideClip, rt);
+ }
- void recordBatch(GrBatch*);
+ GrContext* context() const { return fDrawTarget->fContext; }
+ GrResourceProvider* resourceProvider() const { return fDrawTarget->fResourceProvider; }
+ GrDrawTarget* fDrawTarget;
+ friend class GrClipMaskManager;
+ };
-private:
- SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
+ const CMMAccess cmmAccess() { return CMMAccess(this); }
+private:
+ void recordBatch(GrBatch*);
bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
const GrScissorState* scissor,
GrDrawBatch* batch);
void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
const GrStencilAttachment*,
GrStencilSettings*);
- virtual GrClipMaskManager* clipMaskManager() = 0;
- virtual bool setupClip(const GrPipelineBuilder&,
+ bool setupClip(const GrPipelineBuilder&,
GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
GrPipelineBuilder::AutoRestoreStencil*,
GrScissorState*,
- const SkRect* devBounds) = 0;
+ const SkRect* devBounds);
- GrGpu* fGpu;
- const GrCaps* fCaps;
- GrResourceProvider* fResourceProvider;
- bool fFlushing;
- GrBatchToken fLastFlushToken;
-
- typedef SkRefCnt INHERITED;
-};
-
-/*
- * This class is JUST for clip mask manager. Everyone else should just use draw target above.
- */
-class GrClipTarget : public GrDrawTarget {
-public:
- GrClipTarget(GrContext*);
-
- /* Clip mask manager needs access to the context.
- * TODO we only need a very small subset of context in the CMM.
- */
- GrContext* getContext() { return fContext; }
- const GrContext* getContext() const { return fContext; }
-
- /**
- * Clip Mask Manager(and no one else) needs to clear private stencil bits.
- * ClipTarget subclass sets clip bit in the stencil buffer. The subclass
- * is free to clear the remaining bits to zero if masked clears are more
- * expensive than clearing all bits.
- */
+ // Used only by CMM.
void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);
- /**
- * Release any resources that are cached but not currently in use. This
- * is intended to give an application some recourse when resources are low.
- */
- void purgeResources() override;
-
-protected:
- SkAutoTDelete<GrClipMaskManager> fClipMaskManager;
- GrContext* fContext;
-
-private:
- GrClipMaskManager* clipMaskManager() override { return fClipMaskManager; }
-
- bool setupClip(const GrPipelineBuilder&,
- GrPipelineBuilder::AutoRestoreFragmentProcessorState*,
- GrPipelineBuilder::AutoRestoreStencil*,
- GrScissorState* scissorState,
- const SkRect* devBounds) override;
+ SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
+ SkAutoTDelete<GrClipMaskManager> fClipMaskManager;
+ // The context is only in service of the clip mask manager, remove once CMM doesn't need this.
+ GrContext* fContext;
+ GrGpu* fGpu;
+ GrResourceProvider* fResourceProvider;
+ bool fFlushing;
+ GrBatchToken fLastFlushToken;
- typedef GrDrawTarget INHERITED;
+ typedef SkRefCnt INHERITED;
};
#endif