Index: src/gpu/GrClipMaskManager.cpp |
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp |
index b87788b286bc0d22f32cd79c78430d53919e3524..b57f3cc1bcc5fa54e0d5a2ef797f53284640f185 100644 |
--- a/src/gpu/GrClipMaskManager.cpp |
+++ b/src/gpu/GrClipMaskManager.cpp |
@@ -46,71 +46,24 @@ |
kDevice_GrCoordSet); |
} |
-// 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) { |
- 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. |
- return false; |
- } else { |
- // We shouldn't get here with an empty clip element. |
- SkASSERT(Element::kEmpty_Type != element->getType()); |
- |
- // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer |
- SkPath path; |
- element->asPath(&path); |
- if (path.isInverseFillType()) { |
- path.toggleInverseFillType(); |
- } |
- GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
- |
- GrPathRendererChain::DrawType type; |
- |
- if (needsStencil) { |
- type = element->isAA() |
- ? GrPathRendererChain::kStencilAndColorAntiAlias_DrawType |
- : GrPathRendererChain::kStencilAndColor_DrawType; |
- } else { |
- type = element->isAA() |
- ? GrPathRendererChain::kColorAntiAlias_DrawType |
- : GrPathRendererChain::kColor_DrawType; |
- } |
- |
- // the 'false' parameter disallows use of the SW path renderer |
- GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path, |
- stroke, false, type); |
- if (prOut) { |
- *prOut = pr; |
- } |
- return SkToBool(!pr); |
- } |
-} |
- |
-// 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); |
+ const SkPath& origPath, |
+ const GrStrokeInfo& stroke, |
+ bool doAA) { |
+ // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer |
+ SkTCopyOnFirstWrite<SkPath> path(origPath); |
+ if (path->isInverseFillType()) { |
+ path.writable()->toggleInverseFillType(); |
+ } |
+ // last (false) parameter disallows use of the SW path renderer |
+ GrPathRendererChain::DrawType type = doAA ? |
+ GrPathRendererChain::kColorAntiAlias_DrawType : |
+ GrPathRendererChain::kColor_DrawType; |
+ |
+ return nullptr == context->getPathRenderer(&pipelineBuilder, viewMatrix, *path, stroke, |
+ false, type); |
} |
GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
@@ -131,22 +84,24 @@ |
// TODO: generalize this function so that when |
// a clip gets complex enough it can just be done in SW regardless |
// of whether it would invoke the GrSoftwarePathRenderer. |
+ GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
// Set the matrix so that rendered clip elements are transformed to mask space from clip |
// space. |
- const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); |
+ SkMatrix translate; |
+ translate.setTranslate(clipToMaskOffset); |
for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { |
const Element* element = iter.get(); |
- |
- SkRegion::Op op = element->getOp(); |
- bool invert = element->isInverseFilled(); |
- bool needsStencil = invert || |
- SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; |
- |
- if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate, |
- element, nullptr, needsStencil)) { |
- return true; |
+ // rects can always be drawn directly w/o using the software path |
+ // Skip rrects once we're drawing them directly. |
+ if (Element::kRect_Type != element->getType()) { |
+ SkPath path; |
+ element->asPath(&path); |
+ if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate, |
+ path, stroke, element->isAA())) { |
+ return true; |
+ } |
} |
} |
return false; |
@@ -457,7 +412,7 @@ |
GrPathRendererChain::DrawType type; |
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : |
GrPathRendererChain::kColor_DrawType; |
- pr = this->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix, |
+ pr = this->getContext()->getPathRenderer(pipelineBuilder, viewMatrix, |
path, stroke, false, type); |
} |
if (nullptr == pr) { |
@@ -479,6 +434,32 @@ |
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, |
@@ -574,7 +555,8 @@ |
// Set the matrix so that rendered clip elements are transformed to mask space from clip |
// space. |
- const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMaskOffset.fY); |
+ SkMatrix translate; |
+ translate.setTranslate(clipToMaskOffset); |
// The texture may be larger than necessary, this rect represents the part of the texture |
// we populate with a rasterization of the clip. |
@@ -604,16 +586,13 @@ |
pipelineBuilder.setClip(clip); |
GrPathRenderer* pr = nullptr; |
- bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pipelineBuilder, |
- texture, translate, element, &pr); |
+ bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, texture, &pr, element); |
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 |
// touch the minimum number of pixels necessary and use decal mode to combine it with |
// the accumulator. |
SkIRect maskSpaceElementIBounds; |
- |
- SkASSERT(!useTemp); |
if (useTemp) { |
if (invert) { |
@@ -780,7 +759,7 @@ |
if (fillInverted) { |
clipPath.toggleInverseFillType(); |
} |
- pr = this->getContext()->getPathRenderer(pipelineBuilder, |
+ pr = this->getContext()->getPathRenderer(&pipelineBuilder, |
viewMatrix, |
clipPath, |
stroke, |