| 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
|
|
|