aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-10-29 12:12:21 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-29 12:12:21 -0700
commit687378229aecefc0ab7e639181593774ec8a4290 (patch)
tree18eef745eb26d302a6bf90bcb2615984b5dfea10 /src/gpu
parent89fe56bb98de55c7bd2b547c875b74a98bd5a1ca (diff)
Remove GrPipelineBuilder from getPathRenderer call
Logically this CL: Moves the PathRendererChain from GrContext to GrDrawManager - this was needed to untangled the Path-Chain/Renderer header mess - this entailed adding getDrawingMgr so the CMM could access the PathRenderingChain - this also entailed re-adding freeGpuResources to the GrDrawingMgr Moves the CanDrawArgs struct up stack Removes the GrPipelineBuilder from the CanDrawArgs struct Review URL: https://codereview.chromium.org/1407883004
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrClipMaskManager.cpp93
-rw-r--r--src/gpu/GrClipMaskManager.h17
-rw-r--r--src/gpu/GrContext.cpp50
-rw-r--r--src/gpu/GrDrawContext.cpp38
-rw-r--r--src/gpu/GrDrawingManager.cpp38
-rw-r--r--src/gpu/GrDrawingManager.h16
-rw-r--r--src/gpu/GrPathRenderer.h24
-rw-r--r--src/gpu/GrPathRendererChain.cpp19
-rw-r--r--src/gpu/GrPathRendererChain.h72
-rw-r--r--src/gpu/GrPipelineBuilder.h5
-rw-r--r--src/gpu/batches/GrStencilAndCoverPathRenderer.cpp4
11 files changed, 248 insertions, 128 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 445c6dbc78..9617e0dc65 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -7,6 +7,7 @@
#include "GrClipMaskManager.h"
#include "GrCaps.h"
+#include "GrDrawingManager.h"
#include "GrDrawContext.h"
#include "GrDrawTarget.h"
#include "GrGpuResourcePriv.h"
@@ -49,12 +50,13 @@ static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const Sk
// Does the path in 'element' require SW rendering? If so, return true (and,
// optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
// 'prOut' to the non-SW path renderer that will do the job).
-static bool path_needs_SW_renderer(GrContext* context,
- const GrPipelineBuilder& pipelineBuilder,
- const SkMatrix& viewMatrix,
- const Element* element,
- GrPathRenderer** prOut,
- bool needsStencil) {
+bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
+ bool isStencilDisabled,
+ const GrRenderTarget* rt,
+ const SkMatrix& viewMatrix,
+ const Element* element,
+ GrPathRenderer** prOut,
+ bool needsStencil) {
if (Element::kRect_Type == element->getType()) {
// rects can always be drawn directly w/o using the software path
// TODO: skip rrects once we're drawing them directly.
@@ -86,9 +88,17 @@ static bool path_needs_SW_renderer(GrContext* context,
: GrPathRendererChain::kColor_DrawType;
}
+ GrPathRenderer::CanDrawPathArgs canDrawArgs;
+ canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
+ canDrawArgs.fViewMatrix = &viewMatrix;
+ canDrawArgs.fPath = &path;
+ canDrawArgs.fStroke = &stroke;
+ canDrawArgs.fAntiAlias = element->isAA();
+ canDrawArgs.fIsStencilDisabled = isStencilDisabled;
+ canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+
// the 'false' parameter disallows use of the SW path renderer
- GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path,
- stroke, false, type);
+ GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, type);
if (prOut) {
*prOut = pr;
}
@@ -99,13 +109,20 @@ static bool path_needs_SW_renderer(GrContext* context,
// Determines whether it is possible to draw the element to both the stencil buffer and the
// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
// also returned.
-static GrPathRenderer* get_path_renderer(GrContext* context,
- GrPipelineBuilder* pipelineBuilder,
- const SkMatrix& viewMatrix,
- const SkClipStack::Element* element) {
+GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
+ GrTexture* texture,
+ const SkMatrix& viewMatrix,
+ const SkClipStack::Element* element) {
GrPathRenderer* pr;
static const bool kNeedsStencil = true;
- path_needs_SW_renderer(context, *pipelineBuilder, viewMatrix, element, &pr, kNeedsStencil);
+ static const bool kStencilIsDisabled = true;
+ PathNeedsSWRenderer(context,
+ kStencilIsDisabled,
+ texture->asRenderTarget(),
+ viewMatrix,
+ element,
+ &pr,
+ kNeedsStencil);
return pr;
}
@@ -131,6 +148,7 @@ GrResourceProvider* GrClipMaskManager::resourceProvider() {
* entire clip should be rendered in SW and then uploaded en masse to the gpu.
*/
bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
+ const GrRenderTarget* rt,
const SkVector& clipToMaskOffset,
const GrReducedClip::ElementList& elements) {
// TODO: generalize this function so that when
@@ -149,8 +167,8 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
bool needsStencil = invert ||
SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
- if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate,
- element, nullptr, needsStencil)) {
+ if (PathNeedsSWRenderer(this->getContext(), pipelineBuilder.getStencil().isDisabled(),
+ rt, translate, element, nullptr, needsStencil)) {
return true;
}
}
@@ -360,7 +378,7 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
SkIntToScalar(-clipSpaceIBounds.fTop)
};
- if (this->useSWOnlyPath(pipelineBuilder, clipToMaskOffset, elements)) {
+ if (this->useSWOnlyPath(pipelineBuilder, rt, clipToMaskOffset, elements)) {
// The clip geometry is complex enough that it will be more efficient to create it
// entirely in software
result.reset(this->createSoftwareClipMask(genID,
@@ -426,7 +444,8 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
const SkClipStack::Element* element,
GrPathRenderer* pr) {
- pipelineBuilder->setRenderTarget(target->asRenderTarget());
+ GrRenderTarget* rt = target->asRenderTarget();
+ pipelineBuilder->setRenderTarget(rt);
// The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
// which ignores color.
@@ -462,8 +481,17 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
GrPathRendererChain::DrawType type;
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- pr = this->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
- path, stroke, false, type);
+
+ GrPathRenderer::CanDrawPathArgs canDrawArgs;
+ canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
+ canDrawArgs.fViewMatrix = &viewMatrix;
+ canDrawArgs.fPath = &path;
+ canDrawArgs.fStroke = &stroke;
+ canDrawArgs.fAntiAlias = element->isAA();;
+ canDrawArgs.fIsStencilDisabled = pipelineBuilder->getStencil().isDisabled();
+ canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+
+ pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false, type);
}
if (nullptr == pr) {
return false;
@@ -566,8 +594,9 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
pipelineBuilder.setClip(clip);
pipelineBuilder.setRenderTarget(texture->asRenderTarget());
- GrPathRenderer* pr = get_path_renderer(this->getContext(), &pipelineBuilder,
- translate, element);
+ SkASSERT(pipelineBuilder.getStencil().isDisabled());
+ GrPathRenderer* pr = GetPathRenderer(this->getContext(),
+ texture, translate, element);
if (Element::kRect_Type != element->getType() && !pr) {
// useSWOnlyPath should now filter out all cases where gpu-side mask merging would
// be performed (i.e., pr would be NULL for a non-rect path). See skbug.com/4519
@@ -701,13 +730,21 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
if (fillInverted) {
clipPath.toggleInverseFillType();
}
- pr = this->getContext()->getPathRenderer(pipelineBuilder,
- viewMatrix,
- clipPath,
- stroke,
- false,
- GrPathRendererChain::kStencilOnly_DrawType,
- &stencilSupport);
+
+ SkASSERT(pipelineBuilder.getStencil().isDisabled());
+
+ GrPathRenderer::CanDrawPathArgs canDrawArgs;
+ canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
+ canDrawArgs.fViewMatrix = &viewMatrix;
+ canDrawArgs.fPath = &clipPath;
+ canDrawArgs.fStroke = &stroke;
+ canDrawArgs.fAntiAlias = false;
+ canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().isDisabled();
+ canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+
+ pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false,
+ GrPathRendererChain::kStencilOnly_DrawType,
+ &stencilSupport);
if (nullptr == pr) {
return false;
}
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 2d9816c84c..98fd3af351 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -76,6 +76,18 @@ private:
inline const GrCaps* caps() const;
inline GrResourceProvider* resourceProvider();
+ static bool PathNeedsSWRenderer(GrContext* context,
+ bool isStencilDisabled,
+ const GrRenderTarget* rt,
+ const SkMatrix& viewMatrix,
+ const SkClipStack::Element* element,
+ GrPathRenderer** prOut,
+ bool needsStencil);
+ static GrPathRenderer* GetPathRenderer(GrContext* context,
+ GrTexture* texture,
+ const SkMatrix& viewMatrix,
+ const SkClipStack::Element* element);
+
/**
* Informs the helper function adjustStencilParams() about how the stencil
* buffer clip is being used.
@@ -125,8 +137,9 @@ private:
const SkIRect& clipSpaceIBounds);
bool useSWOnlyPath(const GrPipelineBuilder&,
- const SkVector& clipToMaskOffset,
- const GrReducedClip::ElementList& elements);
+ const GrRenderTarget* rt,
+ const SkVector& clipToMaskOffset,
+ const GrReducedClip::ElementList& elements);
// Draws a clip element into the target alpha mask. The caller should have already setup the
// desired blend operation. Optionally if the caller already selected a path renderer it can
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 04e1b8d203..755b0f2ec9 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -60,8 +60,6 @@ GrContext::GrContext() : fUniqueID(next_id()) {
fCaps = nullptr;
fResourceCache = nullptr;
fResourceProvider = nullptr;
- fPathRendererChain = nullptr;
- fSoftwarePathRenderer = nullptr;
fBatchFontCache = nullptr;
fFlushToReduceCacheSize = false;
}
@@ -118,8 +116,6 @@ GrContext::~GrContext() {
fGpu->unref();
fCaps->unref();
- SkSafeUnref(fPathRendererChain);
- SkSafeUnref(fSoftwarePathRenderer);
}
void GrContext::abandonContext() {
@@ -130,11 +126,6 @@ void GrContext::abandonContext() {
fGpu->contextAbandoned();
- // a path renderer may be holding onto resources that
- // are now unusable
- SkSafeSetNull(fPathRendererChain);
- SkSafeSetNull(fSoftwarePathRenderer);
-
fDrawingManager->abandon();
fBatchFontCache->freeAll();
@@ -151,9 +142,8 @@ void GrContext::freeGpuResources() {
fBatchFontCache->freeAll();
fLayerCache->freeAll();
- // a path renderer may be holding onto resources
- SkSafeSetNull(fPathRendererChain);
- SkSafeSetNull(fSoftwarePathRenderer);
+
+ fDrawingManager->freeGpuResources();
fResourceCache->purgeAllUnlocked();
}
@@ -535,42 +525,6 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) {
}
}
-/*
- * This method finds a path renderer that can draw the specified path on
- * the provided target.
- * Due to its expense, the software path renderer has split out so it can
- * can be individually allowed/disallowed via the "allowSW" boolean.
- */
-GrPathRenderer* GrContext::getPathRenderer(const GrPipelineBuilder& pipelineBuilder,
- const SkMatrix& viewMatrix,
- const SkPath& path,
- const GrStrokeInfo& stroke,
- bool allowSW,
- GrPathRendererChain::DrawType drawType,
- GrPathRendererChain::StencilSupport* stencilSupport) {
-
- if (!fPathRendererChain) {
- fPathRendererChain = new GrPathRendererChain(this);
- }
-
- GrPathRenderer* pr = fPathRendererChain->getPathRenderer(this->caps()->shaderCaps(),
- pipelineBuilder,
- viewMatrix,
- path,
- stroke,
- drawType,
- stencilSupport);
-
- if (!pr && allowSW) {
- if (!fSoftwarePathRenderer) {
- fSoftwarePathRenderer = new GrSoftwarePathRenderer(this);
- }
- pr = fSoftwarePathRenderer;
- }
-
- return pr;
-}
-
////////////////////////////////////////////////////////////////////////////////
int GrContext::getRecommendedSampleCount(GrPixelConfig config,
SkScalar dpi) const {
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index d64273a828..82e1057c6a 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -680,21 +680,28 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
// thing WRT to the blend then we'll need some query on the PR.
bool useCoverageAA = useAA &&
!pipelineBuilder->getRenderTarget()->isUnifiedMultisampled();
+ bool isStencilDisabled = pipelineBuilder->getStencil().isDisabled();
+ bool isStencilBufferMSAA = pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
-
- GrPathRendererChain::DrawType type =
- useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
- GrPathRendererChain::kColor_DrawType;
+ const GrPathRendererChain::DrawType type =
+ useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
+ : GrPathRendererChain::kColor_DrawType;
const SkPath* pathPtr = &path;
SkTLazy<SkPath> tmpPath;
const GrStrokeInfo* strokeInfoPtr = &strokeInfo;
+ GrPathRenderer::CanDrawPathArgs canDrawArgs;
+ canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
+ canDrawArgs.fViewMatrix = &viewMatrix;
+ canDrawArgs.fPath = pathPtr;
+ canDrawArgs.fStroke = strokeInfoPtr;
+ canDrawArgs.fAntiAlias = useCoverageAA;
+ canDrawArgs.fIsStencilDisabled = isStencilDisabled;
+ canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
+
// Try a 1st time without stroking the path and without allowing the SW renderer
- GrPathRenderer* pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder,
- viewMatrix, *pathPtr,
- *strokeInfoPtr, false,
- type);
+ GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
GrStrokeInfo dashlessStrokeInfo(strokeInfo, false);
if (nullptr == pr && strokeInfo.isDashed()) {
@@ -707,9 +714,11 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
return;
}
strokeInfoPtr = &dashlessStrokeInfo;
- pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
- *pathPtr, *strokeInfoPtr,
- false, type);
+
+ canDrawArgs.fPath = pathPtr;
+ canDrawArgs.fStroke = strokeInfoPtr;
+
+ pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
}
if (nullptr == pr) {
@@ -731,10 +740,11 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder,
strokeInfoPtr = &dashlessStrokeInfo;
}
+ canDrawArgs.fPath = pathPtr;
+ canDrawArgs.fStroke = strokeInfoPtr;
+
// This time, allow SW renderer
- pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix,
- *pathPtr, *strokeInfoPtr,
- true, type);
+ pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
}
if (nullptr == pr) {
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 0dbd476c79..0a487daf41 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -10,6 +10,7 @@
#include "GrDrawingManager.h"
#include "GrDrawTarget.h"
#include "GrResourceProvider.h"
+#include "GrSoftwarePathRenderer.h"
#include "GrStencilAndCoverTextContext.h"
#include "SkTTopoSort.h"
@@ -29,6 +30,9 @@ void GrDrawingManager::cleanup() {
delete fTextContexts[i][1];
fTextContexts[i][1] = nullptr;
}
+
+ SkSafeSetNull(fPathRendererChain);
+ SkSafeSetNull(fSoftwarePathRenderer);
}
GrDrawingManager::~GrDrawingManager() {
@@ -40,6 +44,12 @@ void GrDrawingManager::abandon() {
this->cleanup();
}
+void GrDrawingManager::freeGpuResources() {
+ // a path renderer may be holding onto resources
+ SkSafeSetNull(fPathRendererChain);
+ SkSafeSetNull(fSoftwarePathRenderer);
+}
+
void GrDrawingManager::reset() {
for (int i = 0; i < fDrawTargets.count(); ++i) {
fDrawTargets[i]->reset();
@@ -114,7 +124,33 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
return SkRef(dt);
}
-GrDrawContext* GrDrawingManager::drawContext(GrRenderTarget* rt,
+/*
+ * This method finds a path renderer that can draw the specified path on
+ * the provided target.
+ * Due to its expense, the software path renderer has split out so it can
+ * can be individually allowed/disallowed via the "allowSW" boolean.
+ */
+GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
+ bool allowSW,
+ GrPathRendererChain::DrawType drawType,
+ GrPathRenderer::StencilSupport* stencilSupport) {
+
+ if (!fPathRendererChain) {
+ fPathRendererChain = new GrPathRendererChain(fContext);
+ }
+
+ GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
+ if (!pr && allowSW) {
+ if (!fSoftwarePathRenderer) {
+ fSoftwarePathRenderer = new GrSoftwarePathRenderer(fContext);
+ }
+ pr = fSoftwarePathRenderer;
+ }
+
+ return pr;
+}
+
+GrDrawContext* GrDrawingManager::drawContext(GrRenderTarget* rt,
const SkSurfaceProps* surfaceProps) {
if (this->abandoned()) {
return nullptr;
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index be21d68ea8..c8b9a9b471 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -9,10 +9,13 @@
#define GrDrawingManager_DEFINED
#include "GrDrawTarget.h"
+#include "GrPathRendererChain.h"
+#include "GrPathRenderer.h"
#include "SkTDArray.h"
class GrContext;
class GrDrawContext;
+class GrSoftwarePathRenderer;
class GrTextContext;
// Currently the DrawingManager creates a separate GrTextContext for each
@@ -29,6 +32,7 @@ public:
~GrDrawingManager();
bool abandoned() const { return fAbandoned; }
+ void freeGpuResources();
GrDrawContext* drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps);
@@ -40,12 +44,19 @@ public:
GrContext* getContext() { return fContext; }
+ GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
+ bool allowSW,
+ GrPathRendererChain::DrawType drawType,
+ GrPathRenderer::StencilSupport* stencilSupport = NULL);
+
private:
GrDrawingManager(GrContext* context, GrDrawTarget::Options options)
: fContext(context)
, fAbandoned(false)
, fOptions(options)
- , fNVPRTextContext(nullptr) {
+ , fNVPRTextContext(nullptr)
+ , fPathRendererChain(nullptr)
+ , fSoftwarePathRenderer(nullptr) {
sk_bzero(fTextContexts, sizeof(fTextContexts));
}
@@ -67,6 +78,9 @@ private:
GrTextContext* fNVPRTextContext;
GrTextContext* fTextContexts[kNumPixelGeometries][kNumDFTOptions];
+
+ GrPathRendererChain* fPathRendererChain;
+ GrSoftwarePathRenderer* fSoftwarePathRenderer;
};
#endif
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 2390ba0f97..25a2a68abb 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -10,7 +10,6 @@
#define GrPathRenderer_DEFINED
#include "GrDrawTarget.h"
-#include "GrPathRendererChain.h"
#include "GrStencil.h"
#include "GrStrokeInfo.h"
@@ -51,13 +50,11 @@ public:
* covered by the path.
* 3) kNoSupport: This path renderer cannot be used to stencil the path.
*/
- typedef GrPathRendererChain::StencilSupport StencilSupport;
- static const StencilSupport kNoSupport_StencilSupport =
- GrPathRendererChain::kNoSupport_StencilSupport;
- static const StencilSupport kStencilOnly_StencilSupport =
- GrPathRendererChain::kStencilOnly_StencilSupport;
- static const StencilSupport kNoRestriction_StencilSupport =
- GrPathRendererChain::kNoRestriction_StencilSupport;
+ enum StencilSupport {
+ kNoSupport_StencilSupport,
+ kStencilOnly_StencilSupport,
+ kNoRestriction_StencilSupport,
+ };
/**
* This function is to get the stencil support for a particular path. The path's fill must
@@ -82,15 +79,17 @@ public:
*/
struct CanDrawPathArgs {
const GrShaderCaps* fShaderCaps;
- const GrPipelineBuilder* fPipelineBuilder;// only used by GrStencilAndCoverPathRenderer
const SkMatrix* fViewMatrix;
const SkPath* fPath;
const GrStrokeInfo* fStroke;
bool fAntiAlias;
+ // These next two are only used by GrStencilAndCoverPathRenderer
+ bool fIsStencilDisabled;
+ bool fIsStencilBufferMSAA;
+
void validate() const {
SkASSERT(fShaderCaps);
- SkASSERT(fPipelineBuilder);
SkASSERT(fViewMatrix);
SkASSERT(fPath);
SkASSERT(fStroke);
@@ -151,11 +150,14 @@ public:
#ifdef SK_DEBUG
CanDrawPathArgs canArgs;
canArgs.fShaderCaps = args.fTarget->caps()->shaderCaps();
- canArgs.fPipelineBuilder = args.fPipelineBuilder;
canArgs.fViewMatrix = args.fViewMatrix;
canArgs.fPath = args.fPath;
canArgs.fStroke = args.fStroke;
canArgs.fAntiAlias = args.fAntiAlias;
+
+ canArgs.fIsStencilDisabled = args.fPipelineBuilder->getStencil().isDisabled();
+ canArgs.fIsStencilBufferMSAA =
+ args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
SkASSERT(this->canDrawPath(canArgs));
SkASSERT(args.fPipelineBuilder->getStencil().isDisabled() ||
kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath,
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index c6bc4c08f1..63195c6414 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -39,18 +39,12 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
return pr;
}
-GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderCaps,
- const GrPipelineBuilder& pipelineBuilder,
- const SkMatrix& viewMatrix,
- const SkPath& path,
- const GrStrokeInfo& stroke,
+GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
DrawType drawType,
- StencilSupport* stencilSupport) {
+ GrPathRenderer::StencilSupport* stencilSupport) {
if (!fInit) {
this->init();
}
- bool antiAlias = (kColorAntiAlias_DrawType == drawType ||
- kStencilAndColorAntiAlias_DrawType == drawType);
GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
GrPathRenderer::kStencilOnly_StencilSupport);
@@ -68,17 +62,10 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderC
for (int i = 0; i < fChain.count(); ++i) {
- GrPathRenderer::CanDrawPathArgs args;
- args.fShaderCaps = shaderCaps;
- args.fPipelineBuilder = &pipelineBuilder;
- args.fViewMatrix = &viewMatrix;
- args.fPath = &path;
- args.fStroke = &stroke;
- args.fAntiAlias = antiAlias;
if (fChain[i]->canDrawPath(args)) {
if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
GrPathRenderer::StencilSupport support =
- fChain[i]->getStencilSupport(path, stroke);
+ fChain[i]->getStencilSupport(*args.fPath, *args.fStroke);
if (support < minStencilSupport) {
continue;
} else if (stencilSupport) {
diff --git a/src/gpu/GrPathRendererChain.h b/src/gpu/GrPathRendererChain.h
new file mode 100644
index 0000000000..e0e7d46f06
--- /dev/null
+++ b/src/gpu/GrPathRendererChain.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrPathRendererChain_DEFINED
+#define GrPathRendererChain_DEFINED
+
+#include "GrPathRenderer.h"
+
+#include "SkRefCnt.h"
+#include "SkTArray.h"
+
+class GrContext;
+class GrPipelineBuilder;
+class GrShaderCaps;
+class GrStrokeInfo;
+class SkMatrix;
+class SkPath;
+
+/**
+ * Keeps track of an ordered list of path renderers. When a path needs to be
+ * drawn this list is scanned to find the most preferred renderer. To add your
+ * path renderer to the list implement the GrPathRenderer::AddPathRenderers
+ * function.
+ */
+class GrPathRendererChain : public SkRefCnt {
+public:
+ GrPathRendererChain(GrContext* context);
+
+ ~GrPathRendererChain();
+
+ /** Documents how the caller plans to use a GrPathRenderer to draw a path. It affects the PR
+ returned by getPathRenderer */
+ enum DrawType {
+ kColor_DrawType, // draw to the color buffer, no AA
+ kColorAntiAlias_DrawType, // draw to color buffer, with partial coverage AA
+ kStencilOnly_DrawType, // draw just to the stencil buffer
+ kStencilAndColor_DrawType, // draw the stencil and color buffer, no AA
+ kStencilAndColorAntiAlias_DrawType // draw the stencil and color buffer, with partial
+ // coverage AA.
+ };
+
+ /** Returns a GrPathRenderer compatible with the request if one is available. If the caller
+ is drawing the path to the stencil buffer then stencilSupport can be used to determine
+ whether the path can be rendered with arbitrary stencil rules or not. See comments on
+ StencilSupport in GrPathRenderer.h. */
+ GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
+ DrawType drawType,
+ GrPathRenderer::StencilSupport* stencilSupport);
+
+private:
+ GrPathRendererChain();
+
+ // takes a ref and unrefs in destructor
+ GrPathRenderer* addPathRenderer(GrPathRenderer* pr);
+
+ void init();
+
+ enum {
+ kPreAllocCount = 8,
+ };
+ bool fInit;
+ GrContext* fOwner;
+ SkSTArray<kPreAllocCount, GrPathRenderer*, true> fChain;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index e329bc5736..2bafd9aeab 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -229,11 +229,6 @@ public:
*/
void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
- /**
- * Shortcut to disable stencil testing and ops.
- */
- void disableStencil() { fStencilSettings.setDisabled(); }
-
GrStencilSettings* stencil() { return &fStencilSettings; }
/**
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 720c1c34f6..c96e2074c5 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -49,11 +49,11 @@ bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
if (args.fStroke->isHairlineStyle()) {
return false;
}
- if (!args.fPipelineBuilder->getStencil().isDisabled()) {
+ if (!args.fIsStencilDisabled) {
return false;
}
if (args.fAntiAlias) {
- return args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
+ return args.fIsStencilBufferMSAA;
} else {
return true; // doesn't do per-path AA, relies on the target having MSAA
}