Index: src/gpu/GrClipMaskManager.cpp |
=================================================================== |
--- src/gpu/GrClipMaskManager.cpp (revision 13379) |
+++ src/gpu/GrClipMaskManager.cpp (working copy) |
@@ -30,12 +30,11 @@ |
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 |
-void setup_drawstate_aaclip(GrGpu* gpu, |
- GrTexture* result, |
- const SkIRect &devBound) { |
+static void setup_drawstate_aaclip(GrGpu* gpu, |
+ GrTexture* result, |
+ const SkIRect &devBound) { |
GrDrawState* drawState = gpu->drawState(); |
SkASSERT(drawState); |
@@ -59,26 +58,23 @@ |
kPosition_GrCoordSet))->unref(); |
} |
-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 |
+static bool path_needs_SW_renderer(GrContext* context, |
+ GrGpu* gpu, |
+ const SkPath& origPath, |
+ const SkStrokeRec& stroke, |
+ bool doAA) { |
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()); |
- return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); |
+ // 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(); |
} |
-} |
- |
/* |
* 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 |
@@ -313,9 +309,20 @@ |
} |
//////////////////////////////////////////////////////////////////////////////// |
+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, |
- GrPathRenderer* pr) { |
+ const SkClipStack::Element* element) { |
GrDrawState* drawState = fGpu->drawState(); |
drawState->setRenderTarget(target->asRenderTarget()); |
@@ -336,21 +343,19 @@ |
} |
return true; |
case Element::kPath_Type: { |
- SkTCopyOnFirstWrite<SkPath> path(element->getPath()); |
- if (path->isInverseFillType()) { |
- path.writable()->toggleInverseFillType(); |
- } |
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
- 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) { |
+ 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()) { |
return false; |
} |
- pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); |
+ acp->drawPath(stroke, fGpu, element->isAA()); |
break; |
} |
default: |
@@ -363,7 +368,7 @@ |
bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, |
const SkClipStack::Element* element, |
- GrPathRenderer** pr) { |
+ GrPathRenderer::AutoClearPath* acp) { |
GrDrawState* drawState = fGpu->drawState(); |
drawState->setRenderTarget(target->asRenderTarget()); |
@@ -371,16 +376,15 @@ |
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; |
- *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); |
- return NULL != *pr; |
+ SkPath::FillType fillType = element->getPath().getFillType(); |
+ acp->set(this->getContext()->getPathRenderer(element->getPath(), |
+ stroke, fGpu, false, type, |
+ SkPath::ConvertToNonInverseFillType(fillType))); |
+ return NULL != acp->renderer(); |
} |
default: |
// something is wrong if we're trying to draw an empty element. |
@@ -525,8 +529,8 @@ |
bool invert = element->isInverseFilled(); |
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { |
- GrPathRenderer* pr = NULL; |
- bool useTemp = !this->canStencilAndDrawElement(result, element, &pr); |
+ GrPathRenderer::AutoClearPath acp; |
+ bool useTemp = !this->canStencilAndDrawElement(result, element, &acp); |
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 |
@@ -573,9 +577,13 @@ |
drawState->setAlpha(invert ? 0x00 : 0xff); |
- if (!this->drawElement(dst, element, pr)) { |
- fAACache.reset(); |
- return NULL; |
+ if (NULL != acp.renderer()) { |
+ this->drawFilledPath(dst, acp.renderer(), element->isAA()); |
+ } else { |
+ if (!this->drawElement(dst, element)) { |
+ fAACache.reset(); |
+ return NULL; |
+ } |
} |
if (useTemp) { |
@@ -601,7 +609,7 @@ |
drawState->disableStencil(); |
} |
} else { |
- // all the remaining ops can just be directly draw into the accumulation buffer |
+ // all the remaining ops can just be directly drawn into the accumulation buffer |
drawState->setAlpha(0xff); |
setup_boolean_blendcoeffs(drawState, op); |
this->drawElement(result, element); |
@@ -687,25 +695,22 @@ |
SkRegion::Op op = element->getOp(); |
- GrPathRenderer* pr = NULL; |
- SkTCopyOnFirstWrite<SkPath> clipPath; |
+ GrPathRenderer::AutoClearPath acp; |
if (Element::kRect_Type == element->getType()) { |
stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
fillInverted = false; |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
- clipPath.init(element->getPath()); |
- fillInverted = clipPath->isInverseFillType(); |
- if (fillInverted) { |
- clipPath.writable()->toggleInverseFillType(); |
- } |
- pr = this->getContext()->getPathRenderer(*clipPath, |
+ fillInverted = element->getPath().isInverseFillType(); |
+ SkPath::FillType fill = element->getPath().getFillType(); |
+ acp.set(this->getContext()->getPathRenderer(element->getPath(), |
stroke, |
fGpu, |
false, |
GrPathRendererChain::kStencilOnly_DrawType, |
- &stencilSupport); |
- if (NULL == pr) { |
+ SkPath::ConvertToNonInverseFillType(fill), |
+ &stencilSupport)); |
+ if (NULL == acp.renderer()) { |
return false; |
} |
} |
@@ -741,12 +746,12 @@ |
fGpu->drawSimpleRect(element->getRect(), NULL); |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
- if (!clipPath->isEmpty()) { |
+ if (NULL != acp.renderer()) { |
if (canRenderDirectToStencil) { |
*drawState->stencil() = gDrawToStencil; |
- pr->drawPath(*clipPath, stroke, fGpu, false); |
+ acp->drawPath(stroke, fGpu, false); |
} else { |
- pr->stencilPath(*clipPath, stroke, fGpu); |
+ acp->stencilPath(stroke, fGpu); |
} |
} |
} |
@@ -764,7 +769,7 @@ |
} else { |
SkASSERT(Element::kPath_Type == element->getType()); |
SET_RANDOM_COLOR |
- pr->drawPath(*clipPath, stroke, fGpu, false); |
+ acp->drawPath(stroke, fGpu, false); |
} |
} else { |
SET_RANDOM_COLOR |