Index: src/gpu/GrClipMaskManager.cpp |
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp |
index b2b9bd28967ff68bde18b56f80be873beb676142..e6f1d591dfe9aad925354e532da27892f6799ee7 100644 |
--- a/src/gpu/GrClipMaskManager.cpp |
+++ b/src/gpu/GrClipMaskManager.cpp |
@@ -54,7 +54,7 @@ static bool path_needs_SW_renderer(GrContext* context, |
const SkMatrix& viewMatrix, |
const Element* element, |
GrPathRenderer** prOut, |
- bool tryStencilFirst) { |
+ 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. |
@@ -76,7 +76,7 @@ static bool path_needs_SW_renderer(GrContext* context, |
GrPathRendererChain::DrawType type; |
- if (tryStencilFirst) { |
+ if (needsStencil) { |
type = element->isAA() |
? GrPathRendererChain::kStencilAndColorAntiAlias_DrawType |
: GrPathRendererChain::kStencilAndColor_DrawType; |
@@ -89,16 +89,6 @@ static bool path_needs_SW_renderer(GrContext* context, |
// the 'false' parameter disallows use of the SW path renderer |
GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path, |
stroke, false, type); |
- if (tryStencilFirst && !pr) { |
- // If the path can't be stenciled, createAlphaClipMask falls back to color rendering |
- // it into a temporary buffer. If that fails then SW is truly required. |
- type = element->isAA() |
- ? GrPathRendererChain::kColorAntiAlias_DrawType |
- : GrPathRendererChain::kColor_DrawType; |
- |
- pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path, stroke, false, type); |
- } |
- |
if (prOut) { |
*prOut = pr; |
} |
@@ -106,6 +96,26 @@ 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 bool can_stencil_and_draw_element(GrContext* context, |
+ GrPipelineBuilder* pipelineBuilder, |
+ GrTexture* texture, |
+ const SkMatrix& viewMatrix, |
+ const SkClipStack::Element* element, |
+ GrPathRenderer** pr) { |
+ pipelineBuilder->setRenderTarget(texture->asRenderTarget()); |
+ |
+ static const bool kNeedsStencil = true; |
+ return !path_needs_SW_renderer(context, |
+ *pipelineBuilder, |
+ viewMatrix, |
+ element, |
+ pr, |
+ kNeedsStencil); |
+} |
+ |
GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
: fDrawTarget(drawTarget) |
, fClipMode(kIgnoreClip_StencilClipMode) { |
@@ -134,12 +144,11 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, |
SkRegion::Op op = element->getOp(); |
bool invert = element->isInverseFilled(); |
- bool tryStencilFirst = invert || |
- SkRegion::kIntersect_Op == op || |
- SkRegion::kReverseDifference_Op == op; |
+ bool needsStencil = invert || |
+ SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; |
if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate, |
- element, nullptr, tryStencilFirst)) { |
+ element, nullptr, needsStencil)) { |
return true; |
} |
} |
@@ -474,32 +483,6 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder, |
return true; |
} |
-bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuilder, |
- GrTexture* target, |
- GrPathRenderer** pr, |
- const SkClipStack::Element* element) { |
- pipelineBuilder->setRenderTarget(target->asRenderTarget()); |
- |
- if (Element::kRect_Type == element->getType()) { |
- return true; |
- } else { |
- // We shouldn't get here with an empty clip element. |
- SkASSERT(Element::kEmpty_Type != element->getType()); |
- SkPath path; |
- element->asPath(&path); |
- if (path.isInverseFillType()) { |
- path.toggleInverseFillType(); |
- } |
- GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
- GrPathRendererChain::DrawType type = element->isAA() ? |
- GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
- GrPathRendererChain::kStencilAndColor_DrawType; |
- *pr = this->getContext()->getPathRenderer(*pipelineBuilder, SkMatrix::I(), path, |
- stroke, false, type); |
- return SkToBool(*pr); |
- } |
-} |
- |
void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, |
GrTexture* dstMask, |
GrTexture* srcMask, |
@@ -625,7 +608,13 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
pipelineBuilder.setClip(clip); |
GrPathRenderer* pr = nullptr; |
- bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, texture, &pr, element); |
+ bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pipelineBuilder, |
+ texture, translate, element, &pr); |
+ |
+ // useSWOnlyPath should now filter out all cases where gpu-side mask merging is |
+ // performed. See skbug.com/4519 for rationale and details. |
+ SkASSERT(!useTemp); |
+ |
GrTexture* dst; |
// This is the bounds of the clip element in the space of the alpha-mask. The temporary |
// mask buffer can be substantially larger than the actually clip stack element. We |