| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrClipMaskManager.h" | 9 #include "GrClipMaskManager.h" |
| 10 #include "GrAAConvexPathRenderer.h" | 10 #include "GrAAConvexPathRenderer.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "SkStrokeRec.h" | 23 #include "SkStrokeRec.h" |
| 24 #include "SkTLazy.h" | 24 #include "SkTLazy.h" |
| 25 | 25 |
| 26 #define GR_AA_CLIP 1 | 26 #define GR_AA_CLIP 1 |
| 27 | 27 |
| 28 typedef SkClipStack::Element Element; | 28 typedef SkClipStack::Element Element; |
| 29 | 29 |
| 30 using namespace GrReducedClip; | 30 using namespace GrReducedClip; |
| 31 | 31 |
| 32 //////////////////////////////////////////////////////////////////////////////// | 32 //////////////////////////////////////////////////////////////////////////////// |
| 33 namespace { |
| 33 // set up the draw state to enable the aa clipping mask. Besides setting up the | 34 // set up the draw state to enable the aa clipping mask. Besides setting up the |
| 34 // stage matrix this also alters the vertex layout | 35 // stage matrix this also alters the vertex layout |
| 35 static void setup_drawstate_aaclip(GrGpu* gpu, | 36 void setup_drawstate_aaclip(GrGpu* gpu, |
| 36 GrTexture* result, | 37 GrTexture* result, |
| 37 const SkIRect &devBound) { | 38 const SkIRect &devBound) { |
| 38 GrDrawState* drawState = gpu->drawState(); | 39 GrDrawState* drawState = gpu->drawState(); |
| 39 SkASSERT(drawState); | 40 SkASSERT(drawState); |
| 40 | 41 |
| 41 SkMatrix mat; | 42 SkMatrix mat; |
| 42 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be | 43 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be |
| 43 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to | 44 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to |
| 44 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. | 45 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. |
| 45 mat.setIDiv(result->width(), result->height()); | 46 mat.setIDiv(result->width(), result->height()); |
| 46 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 47 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
| 47 SkIntToScalar(-devBound.fTop)); | 48 SkIntToScalar(-devBound.fTop)); |
| 48 mat.preConcat(drawState->getViewMatrix()); | 49 mat.preConcat(drawState->getViewMatrix()); |
| 49 | 50 |
| 50 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 51 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
| 51 // This could be a long-lived effect that is cached with the alpha-mask. | 52 // This could be a long-lived effect that is cached with the alpha-mask. |
| 52 drawState->addCoverageEffect( | 53 drawState->addCoverageEffect( |
| 53 GrTextureDomainEffect::Create(result, | 54 GrTextureDomainEffect::Create(result, |
| 54 mat, | 55 mat, |
| 55 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), | 56 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), |
| 56 GrTextureDomain::kDecal_Mode, | 57 GrTextureDomain::kDecal_Mode, |
| 57 GrTextureParams::kNone_FilterMode, | 58 GrTextureParams::kNone_FilterMode, |
| 58 kPosition_GrCoordSet))->unref(); | 59 kPosition_GrCoordSet))->unref(); |
| 59 } | 60 } |
| 60 | 61 |
| 61 static bool path_needs_SW_renderer(GrContext* context, | 62 bool path_needs_SW_renderer(GrContext* context, |
| 62 GrGpu* gpu, | 63 GrGpu* gpu, |
| 63 const SkPath& origPath, | 64 const SkPath& origPath, |
| 64 const SkStrokeRec& stroke, | 65 const SkStrokeRec& stroke, |
| 65 bool doAA) { | 66 bool doAA) { |
| 67 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer |
| 68 SkTCopyOnFirstWrite<SkPath> path(origPath); |
| 69 if (path->isInverseFillType()) { |
| 70 path.writable()->toggleInverseFillType(); |
| 71 } |
| 72 // last (false) parameter disallows use of the SW path renderer |
| 66 GrPathRendererChain::DrawType type = doAA ? | 73 GrPathRendererChain::DrawType type = doAA ? |
| 67 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 74 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 68 GrPathRendererChain::kColor_DrawType; | 75 GrPathRendererChain::kColor_DrawType; |
| 69 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer | |
| 70 SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.get
FillType()); | |
| 71 | 76 |
| 72 // the 'false' parameter disallows use of the SW path renderer | 77 return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); |
| 73 GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke,
gpu, | 78 } |
| 74 false, type, fill
Type)); | 79 |
| 75 return NULL == acp.renderer(); | |
| 76 } | 80 } |
| 77 | 81 |
| 78 /* | 82 /* |
| 79 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 83 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
| 80 * will be used on any element. If so, it returns true to indicate that the | 84 * will be used on any element. If so, it returns true to indicate that the |
| 81 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 85 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
| 82 */ | 86 */ |
| 83 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { | 87 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { |
| 84 | 88 |
| 85 // TODO: generalize this function so that when | 89 // TODO: generalize this function so that when |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 break; | 306 break; |
| 303 default: | 307 default: |
| 304 SkASSERT(false); | 308 SkASSERT(false); |
| 305 break; | 309 break; |
| 306 } | 310 } |
| 307 } | 311 } |
| 308 | 312 |
| 309 } | 313 } |
| 310 | 314 |
| 311 //////////////////////////////////////////////////////////////////////////////// | 315 //////////////////////////////////////////////////////////////////////////////// |
| 312 bool GrClipMaskManager::drawFilledPath(GrTexture* target, | 316 bool GrClipMaskManager::drawElement(GrTexture* target, |
| 313 GrPathRenderer* pathRenderer, | 317 const SkClipStack::Element* element, |
| 314 bool isAA) { | 318 GrPathRenderer* pr) { |
| 315 GrDrawState* drawState = fGpu->drawState(); | 319 GrDrawState* drawState = fGpu->drawState(); |
| 316 | 320 |
| 317 drawState->setRenderTarget(target->asRenderTarget()); | 321 drawState->setRenderTarget(target->asRenderTarget()); |
| 318 | |
| 319 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | |
| 320 pathRenderer->drawPath(stroke, fGpu, isAA); | |
| 321 return true; | |
| 322 } | |
| 323 | |
| 324 bool GrClipMaskManager::drawElement(GrTexture* target, | |
| 325 const SkClipStack::Element* element) { | |
| 326 GrDrawState* drawState = fGpu->drawState(); | |
| 327 | |
| 328 drawState->setRenderTarget(target->asRenderTarget()); | |
| 329 | 322 |
| 330 switch (element->getType()) { | 323 switch (element->getType()) { |
| 331 case Element::kRect_Type: | 324 case Element::kRect_Type: |
| 332 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the | 325 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the |
| 333 // entire mask bounds and writes 0 outside the rect. | 326 // entire mask bounds and writes 0 outside the rect. |
| 334 if (element->isAA()) { | 327 if (element->isAA()) { |
| 335 getContext()->getAARectRenderer()->fillAARect(fGpu, | 328 getContext()->getAARectRenderer()->fillAARect(fGpu, |
| 336 fGpu, | 329 fGpu, |
| 337 element->getRect()
, | 330 element->getRect()
, |
| 338 SkMatrix::I(), | 331 SkMatrix::I(), |
| 339 element->getRect()
, | 332 element->getRect()
, |
| 340 false); | 333 false); |
| 341 } else { | 334 } else { |
| 342 fGpu->drawSimpleRect(element->getRect(), NULL); | 335 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 343 } | 336 } |
| 344 return true; | 337 return true; |
| 345 case Element::kPath_Type: { | 338 case Element::kPath_Type: { |
| 339 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); |
| 340 if (path->isInverseFillType()) { |
| 341 path.writable()->toggleInverseFillType(); |
| 342 } |
| 346 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 343 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 347 GrPathRendererChain::DrawType type; | 344 if (NULL == pr) { |
| 348 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawTy
pe : | 345 GrPathRendererChain::DrawType type; |
| 349 GrPathRendererChain::kColor_DrawType; | 346 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 350 SkPath::FillType fillType = element->getPath().getFillType(); | 347 GrPathRendererChain::kColor_DrawType; |
| 351 GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRendere
r( | 348 pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, fa
lse, type); |
| 352 element->getPath(), | 349 } |
| 353 stroke, fGpu, false, type, | 350 if (NULL == pr) { |
| 354 SkPath::ConvertToNonInverseFil
lType(fillType))); | |
| 355 if (NULL == acp.renderer()) { | |
| 356 return false; | 351 return false; |
| 357 } | 352 } |
| 358 acp->drawPath(stroke, fGpu, element->isAA()); | 353 pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); |
| 359 break; | 354 break; |
| 360 } | 355 } |
| 361 default: | 356 default: |
| 362 // something is wrong if we're trying to draw an empty element. | 357 // something is wrong if we're trying to draw an empty element. |
| 363 GrCrash("Unexpected element type"); | 358 GrCrash("Unexpected element type"); |
| 364 return false; | 359 return false; |
| 365 } | 360 } |
| 366 return true; | 361 return true; |
| 367 } | 362 } |
| 368 | 363 |
| 369 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, | 364 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, |
| 370 const SkClipStack::Element* ele
ment, | 365 const SkClipStack::Element* ele
ment, |
| 371 GrPathRenderer::AutoClearPath*
acp) { | 366 GrPathRenderer** pr) { |
| 372 GrDrawState* drawState = fGpu->drawState(); | 367 GrDrawState* drawState = fGpu->drawState(); |
| 373 drawState->setRenderTarget(target->asRenderTarget()); | 368 drawState->setRenderTarget(target->asRenderTarget()); |
| 374 | 369 |
| 375 switch (element->getType()) { | 370 switch (element->getType()) { |
| 376 case Element::kRect_Type: | 371 case Element::kRect_Type: |
| 377 return true; | 372 return true; |
| 378 case Element::kPath_Type: { | 373 case Element::kPath_Type: { |
| 374 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); |
| 375 if (path->isInverseFillType()) { |
| 376 path.writable()->toggleInverseFillType(); |
| 377 } |
| 379 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 378 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 380 GrPathRendererChain::DrawType type = element->isAA() ? | 379 GrPathRendererChain::DrawType type = element->isAA() ? |
| 381 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : | 380 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
| 382 GrPathRendererChain::kStencilAndColor_DrawType; | 381 GrPathRendererChain::kStencilAndColor_DrawType; |
| 383 SkPath::FillType fillType = element->getPath().getFillType(); | 382 *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false
, type); |
| 384 acp->set(this->getContext()->getPathRenderer(element->getPath(), | 383 return NULL != *pr; |
| 385 stroke, fGpu, false, type, | |
| 386 SkPath::ConvertToNonInverseFi
llType(fillType))); | |
| 387 return NULL != acp->renderer(); | |
| 388 } | 384 } |
| 389 default: | 385 default: |
| 390 // something is wrong if we're trying to draw an empty element. | 386 // something is wrong if we're trying to draw an empty element. |
| 391 GrCrash("Unexpected element type"); | 387 GrCrash("Unexpected element type"); |
| 392 return false; | 388 return false; |
| 393 } | 389 } |
| 394 } | 390 } |
| 395 | 391 |
| 396 void GrClipMaskManager::mergeMask(GrTexture* dstMask, | 392 void GrClipMaskManager::mergeMask(GrTexture* dstMask, |
| 397 GrTexture* srcMask, | 393 GrTexture* srcMask, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 drawState->enableState(GrDrawState::kClip_StateBit); | 518 drawState->enableState(GrDrawState::kClip_StateBit); |
| 523 | 519 |
| 524 GrAutoScratchTexture temp; | 520 GrAutoScratchTexture temp; |
| 525 // walk through each clip element and perform its set op | 521 // walk through each clip element and perform its set op |
| 526 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ | 522 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ |
| 527 const Element* element = iter.get(); | 523 const Element* element = iter.get(); |
| 528 SkRegion::Op op = element->getOp(); | 524 SkRegion::Op op = element->getOp(); |
| 529 bool invert = element->isInverseFilled(); | 525 bool invert = element->isInverseFilled(); |
| 530 | 526 |
| 531 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 527 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
| 532 GrPathRenderer::AutoClearPath acp; | 528 GrPathRenderer* pr = NULL; |
| 533 bool useTemp = !this->canStencilAndDrawElement(result, element, &acp
); | 529 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; |
| 534 GrTexture* dst; | 530 GrTexture* dst; |
| 535 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 531 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
| 536 // mask buffer can be substantially larger than the actually clip st
ack element. We | 532 // mask buffer can be substantially larger than the actually clip st
ack element. We |
| 537 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 533 // touch the minimum number of pixels necessary and use decal mode t
o combine it with |
| 538 // the accumulator. | 534 // the accumulator. |
| 539 SkIRect maskSpaceElementIBounds; | 535 SkIRect maskSpaceElementIBounds; |
| 540 | 536 |
| 541 if (useTemp) { | 537 if (useTemp) { |
| 542 if (invert) { | 538 if (invert) { |
| 543 maskSpaceElementIBounds = maskSpaceIBounds; | 539 maskSpaceElementIBounds = maskSpaceIBounds; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 570 kAlways_StencilFunc, | 566 kAlways_StencilFunc, |
| 571 0xffff, | 567 0xffff, |
| 572 0xffff, | 568 0xffff, |
| 573 0xffff); | 569 0xffff); |
| 574 drawState->setStencil(kStencilInElement); | 570 drawState->setStencil(kStencilInElement); |
| 575 setup_boolean_blendcoeffs(drawState, op); | 571 setup_boolean_blendcoeffs(drawState, op); |
| 576 } | 572 } |
| 577 | 573 |
| 578 drawState->setAlpha(invert ? 0x00 : 0xff); | 574 drawState->setAlpha(invert ? 0x00 : 0xff); |
| 579 | 575 |
| 580 if (NULL != acp.renderer()) { | 576 if (!this->drawElement(dst, element, pr)) { |
| 581 this->drawFilledPath(dst, acp.renderer(), element->isAA()); | 577 fAACache.reset(); |
| 582 } else { | 578 return NULL; |
| 583 if (!this->drawElement(dst, element)) { | |
| 584 fAACache.reset(); | |
| 585 return NULL; | |
| 586 } | |
| 587 } | 579 } |
| 588 | 580 |
| 589 if (useTemp) { | 581 if (useTemp) { |
| 590 // Now draw into the accumulator using the real operation and th
e temp buffer as a | 582 // Now draw into the accumulator using the real operation and th
e temp buffer as a |
| 591 // texture | 583 // texture |
| 592 this->mergeMask(result, | 584 this->mergeMask(result, |
| 593 temp.texture(), | 585 temp.texture(), |
| 594 op, | 586 op, |
| 595 maskSpaceIBounds, | 587 maskSpaceIBounds, |
| 596 maskSpaceElementIBounds); | 588 maskSpaceElementIBounds); |
| 597 } else { | 589 } else { |
| 598 // Draw to the exterior pixels (those with a zero stencil value)
. | 590 // Draw to the exterior pixels (those with a zero stencil value)
. |
| 599 drawState->setAlpha(invert ? 0xff : 0x00); | 591 drawState->setAlpha(invert ? 0xff : 0x00); |
| 600 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 592 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
| 601 kZero_StencilOp, | 593 kZero_StencilOp, |
| 602 kZero_StencilOp, | 594 kZero_StencilOp, |
| 603 kEqual_StencilFunc, | 595 kEqual_StencilFunc, |
| 604 0xffff, | 596 0xffff, |
| 605 0x0000, | 597 0x0000, |
| 606 0xffff); | 598 0xffff); |
| 607 drawState->setStencil(kDrawOutsideElement); | 599 drawState->setStencil(kDrawOutsideElement); |
| 608 fGpu->drawSimpleRect(clipSpaceIBounds); | 600 fGpu->drawSimpleRect(clipSpaceIBounds); |
| 609 drawState->disableStencil(); | 601 drawState->disableStencil(); |
| 610 } | 602 } |
| 611 } else { | 603 } else { |
| 612 // all the remaining ops can just be directly drawn into the accumul
ation buffer | 604 // all the remaining ops can just be directly draw into the accumula
tion buffer |
| 613 drawState->setAlpha(0xff); | 605 drawState->setAlpha(0xff); |
| 614 setup_boolean_blendcoeffs(drawState, op); | 606 setup_boolean_blendcoeffs(drawState, op); |
| 615 this->drawElement(result, element); | 607 this->drawElement(result, element); |
| 616 } | 608 } |
| 617 } | 609 } |
| 618 | 610 |
| 619 fCurrClipMaskType = kAlpha_ClipMaskType; | 611 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 620 return result; | 612 return result; |
| 621 } | 613 } |
| 622 | 614 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 680 } |
| 689 | 681 |
| 690 // This will be used to determine whether the clip shape can be rend
ered into the | 682 // This will be used to determine whether the clip shape can be rend
ered into the |
| 691 // stencil with arbitrary stencil settings. | 683 // stencil with arbitrary stencil settings. |
| 692 GrPathRenderer::StencilSupport stencilSupport; | 684 GrPathRenderer::StencilSupport stencilSupport; |
| 693 | 685 |
| 694 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 686 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 695 | 687 |
| 696 SkRegion::Op op = element->getOp(); | 688 SkRegion::Op op = element->getOp(); |
| 697 | 689 |
| 698 GrPathRenderer::AutoClearPath acp; | 690 GrPathRenderer* pr = NULL; |
| 691 SkTCopyOnFirstWrite<SkPath> clipPath; |
| 699 if (Element::kRect_Type == element->getType()) { | 692 if (Element::kRect_Type == element->getType()) { |
| 700 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 693 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 701 fillInverted = false; | 694 fillInverted = false; |
| 702 } else { | 695 } else { |
| 703 SkASSERT(Element::kPath_Type == element->getType()); | 696 SkASSERT(Element::kPath_Type == element->getType()); |
| 704 fillInverted = element->getPath().isInverseFillType(); | 697 clipPath.init(element->getPath()); |
| 705 SkPath::FillType fill = element->getPath().getFillType(); | 698 fillInverted = clipPath->isInverseFillType(); |
| 706 acp.set(this->getContext()->getPathRenderer(element->getPath(), | 699 if (fillInverted) { |
| 700 clipPath.writable()->toggleInverseFillType(); |
| 701 } |
| 702 pr = this->getContext()->getPathRenderer(*clipPath, |
| 707 stroke, | 703 stroke, |
| 708 fGpu, | 704 fGpu, |
| 709 false, | 705 false, |
| 710 GrPathRendererChain::kS
tencilOnly_DrawType, | 706 GrPathRendererChain::kS
tencilOnly_DrawType, |
| 711 SkPath::ConvertToNonInv
erseFillType(fill), | 707 &stencilSupport); |
| 712 &stencilSupport)); | 708 if (NULL == pr) { |
| 713 if (NULL == acp.renderer()) { | |
| 714 return false; | 709 return false; |
| 715 } | 710 } |
| 716 } | 711 } |
| 717 | 712 |
| 718 int passes; | 713 int passes; |
| 719 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; | 714 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; |
| 720 | 715 |
| 721 bool canRenderDirectToStencil = | 716 bool canRenderDirectToStencil = |
| 722 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; | 717 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; |
| 723 bool canDrawDirectToClip; // Given the renderer, the element, | 718 bool canDrawDirectToClip; // Given the renderer, the element, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 739 kAlways_StencilFunc, | 734 kAlways_StencilFunc, |
| 740 0xffff, | 735 0xffff, |
| 741 0x0000, | 736 0x0000, |
| 742 0xffff); | 737 0xffff); |
| 743 SET_RANDOM_COLOR | 738 SET_RANDOM_COLOR |
| 744 if (Element::kRect_Type == element->getType()) { | 739 if (Element::kRect_Type == element->getType()) { |
| 745 *drawState->stencil() = gDrawToStencil; | 740 *drawState->stencil() = gDrawToStencil; |
| 746 fGpu->drawSimpleRect(element->getRect(), NULL); | 741 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 747 } else { | 742 } else { |
| 748 SkASSERT(Element::kPath_Type == element->getType()); | 743 SkASSERT(Element::kPath_Type == element->getType()); |
| 749 if (NULL != acp.renderer()) { | 744 if (!clipPath->isEmpty()) { |
| 750 if (canRenderDirectToStencil) { | 745 if (canRenderDirectToStencil) { |
| 751 *drawState->stencil() = gDrawToStencil; | 746 *drawState->stencil() = gDrawToStencil; |
| 752 acp->drawPath(stroke, fGpu, false); | 747 pr->drawPath(*clipPath, stroke, fGpu, false); |
| 753 } else { | 748 } else { |
| 754 acp->stencilPath(stroke, fGpu); | 749 pr->stencilPath(*clipPath, stroke, fGpu); |
| 755 } | 750 } |
| 756 } | 751 } |
| 757 } | 752 } |
| 758 } | 753 } |
| 759 | 754 |
| 760 // now we modify the clip bit by rendering either the clip | 755 // now we modify the clip bit by rendering either the clip |
| 761 // element directly or a bounding rect of the entire clip. | 756 // element directly or a bounding rect of the entire clip. |
| 762 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); | 757 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); |
| 763 for (int p = 0; p < passes; ++p) { | 758 for (int p = 0; p < passes; ++p) { |
| 764 *drawState->stencil() = stencilSettings[p]; | 759 *drawState->stencil() = stencilSettings[p]; |
| 765 if (canDrawDirectToClip) { | 760 if (canDrawDirectToClip) { |
| 766 if (Element::kRect_Type == element->getType()) { | 761 if (Element::kRect_Type == element->getType()) { |
| 767 SET_RANDOM_COLOR | 762 SET_RANDOM_COLOR |
| 768 fGpu->drawSimpleRect(element->getRect(), NULL); | 763 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 769 } else { | 764 } else { |
| 770 SkASSERT(Element::kPath_Type == element->getType()); | 765 SkASSERT(Element::kPath_Type == element->getType()); |
| 771 SET_RANDOM_COLOR | 766 SET_RANDOM_COLOR |
| 772 acp->drawPath(stroke, fGpu, false); | 767 pr->drawPath(*clipPath, stroke, fGpu, false); |
| 773 } | 768 } |
| 774 } else { | 769 } else { |
| 775 SET_RANDOM_COLOR | 770 SET_RANDOM_COLOR |
| 776 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 771 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 777 // draw rect in clip space. | 772 // draw rect in clip space. |
| 778 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); | 773 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); |
| 779 } | 774 } |
| 780 } | 775 } |
| 781 } | 776 } |
| 782 } | 777 } |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 | 1079 |
| 1085 // TODO: dynamically attach a stencil buffer | 1080 // TODO: dynamically attach a stencil buffer |
| 1086 int stencilBits = 0; | 1081 int stencilBits = 0; |
| 1087 GrStencilBuffer* stencilBuffer = | 1082 GrStencilBuffer* stencilBuffer = |
| 1088 drawState.getRenderTarget()->getStencilBuffer(); | 1083 drawState.getRenderTarget()->getStencilBuffer(); |
| 1089 if (NULL != stencilBuffer) { | 1084 if (NULL != stencilBuffer) { |
| 1090 stencilBits = stencilBuffer->bits(); | 1085 stencilBits = stencilBuffer->bits(); |
| 1091 this->adjustStencilParams(settings, clipMode, stencilBits); | 1086 this->adjustStencilParams(settings, clipMode, stencilBits); |
| 1092 } | 1087 } |
| 1093 } | 1088 } |
| OLD | NEW |