Index: src/gpu/GrClipMaskManager.cpp |
=================================================================== |
--- src/gpu/GrClipMaskManager.cpp (revision 13407) |
+++ src/gpu/GrClipMaskManager.cpp (working copy) |
@@ -30,11 +30,12 @@ |
using namespace GrReducedClip; |
//////////////////////////////////////////////////////////////////////////////// |
+namespace { |
// set up the draw state to enable the aa clipping mask. Besides setting up the |
// stage matrix this also alters the vertex layout |
-static void setup_drawstate_aaclip(GrGpu* gpu, |
- GrTexture* result, |
- const SkIRect &devBound) { |
+void setup_drawstate_aaclip(GrGpu* gpu, |
+ GrTexture* result, |
+ const SkIRect &devBound) { |
GrDrawState* drawState = gpu->drawState(); |
SkASSERT(drawState); |
@@ -58,23 +59,26 @@ |
kPosition_GrCoordSet))->unref(); |
} |
-static bool path_needs_SW_renderer(GrContext* context, |
- GrGpu* gpu, |
- const SkPath& origPath, |
- const SkStrokeRec& stroke, |
- bool doAA) { |
+bool path_needs_SW_renderer(GrContext* context, |
+ GrGpu* gpu, |
+ const SkPath& origPath, |
+ const SkStrokeRec& 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; |
- // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer |
- SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.getFillType()); |
- // the 'false' parameter disallows use of the SW path renderer |
- GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu, |
- false, type, fillType)); |
- return NULL == acp.renderer(); |
+ return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); |
} |
+} |
+ |
/* |
* This method traverses the clip stack to see if the GrSoftwarePathRenderer |
* will be used on any element. If so, it returns true to indicate that the |
@@ -309,20 +313,9 @@ |
} |
//////////////////////////////////////////////////////////////////////////////// |
-bool GrClipMaskManager::drawFilledPath(GrTexture* target, |
- GrPathRenderer* pathRenderer, |
- bool isAA) { |
- GrDrawState* drawState = fGpu->drawState(); |
- |
- drawState->setRenderTarget(target->asRenderTarget()); |
- |
- SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
- pathRenderer->drawPath(stroke, fGpu, isAA); |
- return true; |
-} |
- |
bool GrClipMaskManager::drawElement(GrTexture* target, |
- const SkClipStack::Element* element) { |
+ const SkClipStack::Element* element, |
+ GrPathRenderer* pr) { |
GrDrawState* drawState = fGpu->drawState(); |
drawState->setRenderTarget(target->asRenderTarget()); |
@@ -343,19 +336,21 @@ |
} |
return true; |
case Element::kPath_Type: { |
+ SkTCopyOnFirstWrite<SkPath> path(element->getPath()); |
+ if (path->isInverseFillType()) { |
+ path.writable()->toggleInverseFillType(); |
+ } |
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
- GrPathRendererChain::DrawType type; |
- type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : |
- GrPathRendererChain::kColor_DrawType; |
- SkPath::FillType fillType = element->getPath().getFillType(); |
- GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRenderer( |
- element->getPath(), |
- stroke, fGpu, false, type, |
- SkPath::ConvertToNonInverseFillType(fillType))); |
- if (NULL == acp.renderer()) { |
+ if (NULL == pr) { |
+ GrPathRendererChain::DrawType type; |
+ type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : |
+ GrPathRendererChain::kColor_DrawType; |
+ pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); |
+ } |
+ if (NULL == pr) { |
return false; |
} |
- acp->drawPath(stroke, fGpu, element->isAA()); |
+ pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); |
break; |
} |
default: |
@@ -368,7 +363,7 @@ |
bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, |
const SkClipStack::Element* element, |
- GrPathRenderer::AutoClearPath* acp) { |
+ GrPathRenderer** pr) { |
GrDrawState* drawState = fGpu->drawState(); |
drawState->setRenderTarget(target->asRenderTarget()); |
@@ -376,15 +371,16 @@ |
case Element::kRect_Type: |
return true; |
case Element::kPath_Type: { |
+ SkTCopyOnFirstWrite<SkPath> path(element->getPath()); |
+ if (path->isInverseFillType()) { |
+ path.writable()->toggleInverseFillType(); |
+ } |
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
GrPathRendererChain::DrawType type = element->isAA() ? |
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
GrPathRendererChain::kStencilAndColor_DrawType; |
- SkPath::FillType fillType = element->getPath().getFillType(); |
- acp->set(this->getContext()->getPathRenderer(element->getPath(), |
- stroke, fGpu, false, type, |
- SkPath::ConvertToNonInverseFillType(fillType))); |
- return NULL != acp->renderer(); |
+ *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); |
+ return NULL != *pr; |
} |
default: |
// something is wrong if we're trying to draw an empty element. |
@@ -529,8 +525,8 @@ |
bool invert = element->isInverseFilled(); |
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { |
- GrPathRenderer::AutoClearPath acp; |
- bool useTemp = !this->canStencilAndDrawElement(result, element, &acp); |
+ GrPathRenderer* pr = NULL; |
+ bool useTemp = !this->canStencilAndDrawElement(result, element, &pr); |
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 |
@@ -577,13 +573,9 @@ |
drawState->setAlpha(invert ? 0x00 : 0xff); |
- if (NULL != acp.renderer()) { |
- this->drawFilledPath(dst, acp.renderer(), element->isAA()); |
- } else { |
- if (!this->drawElement(dst, element)) { |
- fAACache.reset(); |
- return NULL; |
- } |
+ if (!this->drawElement(dst, element, pr)) { |
+ fAACache.reset(); |
+ return NULL; |
} |
if (useTemp) { |
@@ -609,7 +601,7 @@ |
drawState->disableStencil(); |
} |
} else { |
- // all the remaining ops can just be directly drawn into the accumulation buffer |
+ // all the remaining ops can just be directly draw into the accumulation buffer |
drawState->setAlpha(0xff); |
setup_boolean_blendcoeffs(drawState, op); |
this->drawElement(result, element); |
@@ -695,22 +687,25 @@ |
SkRegion::Op op = element->getOp(); |
- GrPathRenderer::AutoClearPath acp; |
+ GrPathRenderer* pr = NULL; |
+ SkTCopyOnFirstWrite<SkPath> clipPath; |
if (Element::kRect_Type == element->getType()) { |
stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
fillInverted = false; |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
- fillInverted = element->getPath().isInverseFillType(); |
- SkPath::FillType fill = element->getPath().getFillType(); |
- acp.set(this->getContext()->getPathRenderer(element->getPath(), |
+ clipPath.init(element->getPath()); |
+ fillInverted = clipPath->isInverseFillType(); |
+ if (fillInverted) { |
+ clipPath.writable()->toggleInverseFillType(); |
+ } |
+ pr = this->getContext()->getPathRenderer(*clipPath, |
stroke, |
fGpu, |
false, |
GrPathRendererChain::kStencilOnly_DrawType, |
- SkPath::ConvertToNonInverseFillType(fill), |
- &stencilSupport)); |
- if (NULL == acp.renderer()) { |
+ &stencilSupport); |
+ if (NULL == pr) { |
return false; |
} |
} |
@@ -746,12 +741,12 @@ |
fGpu->drawSimpleRect(element->getRect(), NULL); |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
- if (NULL != acp.renderer()) { |
+ if (!clipPath->isEmpty()) { |
if (canRenderDirectToStencil) { |
*drawState->stencil() = gDrawToStencil; |
- acp->drawPath(stroke, fGpu, false); |
+ pr->drawPath(*clipPath, stroke, fGpu, false); |
} else { |
- acp->stencilPath(stroke, fGpu); |
+ pr->stencilPath(*clipPath, stroke, fGpu); |
} |
} |
} |
@@ -769,7 +764,7 @@ |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
SET_RANDOM_COLOR |
- acp->drawPath(stroke, fGpu, false); |
+ pr->drawPath(*clipPath, stroke, fGpu, false); |
} |
} else { |
SET_RANDOM_COLOR |