| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrClipMaskManager.h" | 8 #include "GrClipMaskManager.h" |
| 9 #include "GrCaps.h" | 9 #include "GrCaps.h" |
| 10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 // last (false) parameter disallows use of the SW path renderer | 69 // last (false) parameter disallows use of the SW path renderer |
| 70 GrPathRendererChain::DrawType type = doAA ? | 70 GrPathRendererChain::DrawType type = doAA ? |
| 71 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 71 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 72 GrPathRendererChain::kColor_DrawType; | 72 GrPathRendererChain::kColor_DrawType; |
| 73 | 73 |
| 74 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix
, *path, stroke, | 74 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix
, *path, stroke, |
| 75 false, type); | 75 false, type); |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget) | 79 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
| 80 : fCurrClipMaskType(kNone_ClipMaskType) | 80 : fCurrClipMaskType(kNone_ClipMaskType) |
| 81 , fAACache(clipTarget->getContext()->resourceProvider()) | 81 , fAACache(drawTarget->cmmAccess().resourceProvider()) |
| 82 , fClipTarget(clipTarget) | 82 , fDrawTarget(drawTarget) |
| 83 , fClipMode(kIgnoreClip_StencilClipMode) { | 83 , fClipMode(kIgnoreClip_StencilClipMode) { |
| 84 } | 84 } |
| 85 | 85 |
| 86 GrContext* GrClipMaskManager::getContext() { return fClipTarget->getContext(); } | 86 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con
text(); } |
| 87 | 87 |
| 88 /* | 88 /* |
| 89 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 89 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
| 90 * will be used on any element. If so, it returns true to indicate that the | 90 * will be used on any element. If so, it returns true to indicate that the |
| 91 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 91 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
| 92 */ | 92 */ |
| 93 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, | 93 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, |
| 94 const SkVector& clipToMaskOffset, | 94 const SkVector& clipToMaskOffset, |
| 95 const GrReducedClip::ElementList& elements
) { | 95 const GrReducedClip::ElementList& elements
) { |
| 96 // TODO: generalize this function so that when | 96 // TODO: generalize this function so that when |
| 97 // a clip gets complex enough it can just be done in SW regardless | 97 // a clip gets complex enough it can just be done in SW regardless |
| 98 // of whether it would invoke the GrSoftwarePathRenderer. | 98 // of whether it would invoke the GrSoftwarePathRenderer. |
| 99 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 99 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 100 | 100 |
| 101 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 101 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
| 102 // space. | 102 // space. |
| 103 SkMatrix translate; | 103 SkMatrix translate; |
| 104 translate.setTranslate(clipToMaskOffset); | 104 translate.setTranslate(clipToMaskOffset); |
| 105 | 105 |
| 106 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { | 106 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { |
| 107 const Element* element = iter.get(); | 107 const Element* element = iter.get(); |
| 108 // rects can always be drawn directly w/o using the software path | 108 // rects can always be drawn directly w/o using the software path |
| 109 // Skip rrects once we're drawing them directly. | 109 // Skip rrects once we're drawing them directly. |
| 110 if (Element::kRect_Type != element->getType()) { | 110 if (Element::kRect_Type != element->getType()) { |
| 111 SkPath path; | 111 SkPath path; |
| 112 element->asPath(&path); | 112 element->asPath(&path); |
| 113 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline
Builder, translate, | 113 if (path_needs_SW_renderer(this->getContext(), fDrawTarget, pipeline
Builder, translate, |
| 114 path, stroke, element->isAA())) { | 114 path, stroke, element->isAA())) { |
| 115 return true; | 115 return true; |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 return false; | 119 return false; |
| 120 } | 120 } |
| 121 | 121 |
| 122 bool GrClipMaskManager::installClipEffects( | 122 bool GrClipMaskManager::installClipEffects( |
| 123 const GrPipelineBuilder& pipelineBuilder, | 123 const GrPipelineBuilder& pipelineBuilder, |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 case Element::kEmpty_Type: | 398 case Element::kEmpty_Type: |
| 399 SkDEBUGFAIL("Should never get here with an empty element."); | 399 SkDEBUGFAIL("Should never get here with an empty element."); |
| 400 break; | 400 break; |
| 401 case Element::kRect_Type: | 401 case Element::kRect_Type: |
| 402 // TODO: Do rects directly to the accumulator using a aa-rect GrProc
essor that covers | 402 // TODO: Do rects directly to the accumulator using a aa-rect GrProc
essor that covers |
| 403 // the entire mask bounds and writes 0 outside the rect. | 403 // the entire mask bounds and writes 0 outside the rect. |
| 404 if (element->isAA()) { | 404 if (element->isAA()) { |
| 405 SkRect devRect = element->getRect(); | 405 SkRect devRect = element->getRect(); |
| 406 viewMatrix.mapRect(&devRect); | 406 viewMatrix.mapRect(&devRect); |
| 407 | 407 |
| 408 fClipTarget->drawAARect(*pipelineBuilder, color, viewMatrix, | 408 fDrawTarget->drawAARect(*pipelineBuilder, color, viewMatrix, |
| 409 element->getRect(), devRect); | 409 element->getRect(), devRect); |
| 410 } else { | 410 } else { |
| 411 fClipTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix, | 411 fDrawTarget->drawNonAARect(*pipelineBuilder, color, viewMatrix, |
| 412 element->getRect()); | 412 element->getRect()); |
| 413 } | 413 } |
| 414 return true; | 414 return true; |
| 415 default: { | 415 default: { |
| 416 SkPath path; | 416 SkPath path; |
| 417 element->asPath(&path); | 417 element->asPath(&path); |
| 418 path.setIsVolatile(true); | 418 path.setIsVolatile(true); |
| 419 if (path.isInverseFillType()) { | 419 if (path.isInverseFillType()) { |
| 420 path.toggleInverseFillType(); | 420 path.toggleInverseFillType(); |
| 421 } | 421 } |
| 422 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 422 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 423 if (nullptr == pr) { | 423 if (nullptr == pr) { |
| 424 GrPathRendererChain::DrawType type; | 424 GrPathRendererChain::DrawType type; |
| 425 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : | 425 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 426 GrPathRendererChain::kColor_DrawType; | 426 GrPathRendererChain::kColor_DrawType; |
| 427 pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBu
ilder, viewMatrix, | 427 pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBu
ilder, viewMatrix, |
| 428 path, stroke, false, ty
pe); | 428 path, stroke, false, ty
pe); |
| 429 } | 429 } |
| 430 if (nullptr == pr) { | 430 if (nullptr == pr) { |
| 431 return false; | 431 return false; |
| 432 } | 432 } |
| 433 GrPathRenderer::DrawPathArgs args; | 433 GrPathRenderer::DrawPathArgs args; |
| 434 args.fTarget = fClipTarget; | 434 args.fTarget = fDrawTarget; |
| 435 args.fResourceProvider = this->getContext()->resourceProvider(); | 435 args.fResourceProvider = this->getContext()->resourceProvider(); |
| 436 args.fPipelineBuilder = pipelineBuilder; | 436 args.fPipelineBuilder = pipelineBuilder; |
| 437 args.fColor = color; | 437 args.fColor = color; |
| 438 args.fViewMatrix = &viewMatrix; | 438 args.fViewMatrix = &viewMatrix; |
| 439 args.fPath = &path; | 439 args.fPath = &path; |
| 440 args.fStroke = &stroke; | 440 args.fStroke = &stroke; |
| 441 args.fAntiAlias = element->isAA(); | 441 args.fAntiAlias = element->isAA(); |
| 442 pr->drawPath(args); | 442 pr->drawPath(args); |
| 443 break; | 443 break; |
| 444 } | 444 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 459 SkASSERT(Element::kEmpty_Type != element->getType()); | 459 SkASSERT(Element::kEmpty_Type != element->getType()); |
| 460 SkPath path; | 460 SkPath path; |
| 461 element->asPath(&path); | 461 element->asPath(&path); |
| 462 if (path.isInverseFillType()) { | 462 if (path.isInverseFillType()) { |
| 463 path.toggleInverseFillType(); | 463 path.toggleInverseFillType(); |
| 464 } | 464 } |
| 465 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 465 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 466 GrPathRendererChain::DrawType type = element->isAA() ? | 466 GrPathRendererChain::DrawType type = element->isAA() ? |
| 467 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : | 467 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
| 468 GrPathRendererChain::kStencilAndColor_DrawType; | 468 GrPathRendererChain::kStencilAndColor_DrawType; |
| 469 *pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder,
SkMatrix::I(), path, | 469 *pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder,
SkMatrix::I(), path, |
| 470 stroke, false, type); | 470 stroke, false, type); |
| 471 return SkToBool(*pr); | 471 return SkToBool(*pr); |
| 472 } | 472 } |
| 473 } | 473 } |
| 474 | 474 |
| 475 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, | 475 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, |
| 476 GrTexture* dstMask, | 476 GrTexture* dstMask, |
| 477 GrTexture* srcMask, | 477 GrTexture* srcMask, |
| 478 SkRegion::Op op, | 478 SkRegion::Op op, |
| 479 const SkIRect& dstBound, | 479 const SkIRect& dstBound, |
| 480 const SkIRect& srcBound) { | 480 const SkIRect& srcBound) { |
| 481 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); | 481 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); |
| 482 | 482 |
| 483 // We want to invert the coverage here | 483 // We want to invert the coverage here |
| 484 set_coverage_drawing_xpf(op, false, pipelineBuilder); | 484 set_coverage_drawing_xpf(op, false, pipelineBuilder); |
| 485 | 485 |
| 486 SkMatrix sampleM; | 486 SkMatrix sampleM; |
| 487 sampleM.setIDiv(srcMask->width(), srcMask->height()); | 487 sampleM.setIDiv(srcMask->width(), srcMask->height()); |
| 488 | 488 |
| 489 pipelineBuilder->addCoverageFragmentProcessor( | 489 pipelineBuilder->addCoverageFragmentProcessor( |
| 490 GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager()
, | 490 GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager()
, |
| 491 srcMask, | 491 srcMask, |
| 492 sampleM, | 492 sampleM, |
| 493 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), | 493 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), |
| 494 GrTextureDomain::kDecal_Mode, | 494 GrTextureDomain::kDecal_Mode, |
| 495 GrTextureParams::kNone_FilterMode))->unref
(); | 495 GrTextureParams::kNone_FilterMode))->unref
(); |
| 496 | 496 |
| 497 // The color passed in here does not matter since the coverageSetOpXP won't
read it. | 497 // The color passed in here does not matter since the coverageSetOpXP won't
read it. |
| 498 fClipTarget->drawNonAARect(*pipelineBuilder, | 498 fDrawTarget->drawNonAARect(*pipelineBuilder, |
| 499 GrColor_WHITE, | 499 GrColor_WHITE, |
| 500 SkMatrix::I(), | 500 SkMatrix::I(), |
| 501 SkRect::Make(dstBound)); | 501 SkRect::Make(dstBound)); |
| 502 } | 502 } |
| 503 | 503 |
| 504 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { | 504 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { |
| 505 GrSurfaceDesc desc; | 505 GrSurfaceDesc desc; |
| 506 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 506 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 507 desc.fWidth = width; | 507 desc.fWidth = width; |
| 508 desc.fHeight = height; | 508 desc.fHeight = height; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 // space. | 579 // space. |
| 580 SkMatrix translate; | 580 SkMatrix translate; |
| 581 translate.setTranslate(clipToMaskOffset); | 581 translate.setTranslate(clipToMaskOffset); |
| 582 | 582 |
| 583 // The texture may be larger than necessary, this rect represents the part o
f the texture | 583 // The texture may be larger than necessary, this rect represents the part o
f the texture |
| 584 // we populate with a rasterization of the clip. | 584 // we populate with a rasterization of the clip. |
| 585 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 585 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
| 586 | 586 |
| 587 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 587 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
| 588 // clear the part that we care about. | 588 // clear the part that we care about. |
| 589 fClipTarget->clear(&maskSpaceIBounds, | 589 fDrawTarget->clear(&maskSpaceIBounds, |
| 590 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, | 590 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, |
| 591 true, | 591 true, |
| 592 result->asRenderTarget()); | 592 result->asRenderTarget()); |
| 593 | 593 |
| 594 // When we use the stencil in the below loop it is important to have this cl
ip installed. | 594 // When we use the stencil in the below loop it is important to have this cl
ip installed. |
| 595 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 595 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
| 596 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 596 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
| 597 // cleared. | 597 // cleared. |
| 598 GrClip clip(maskSpaceIBounds); | 598 GrClip clip(maskSpaceIBounds); |
| 599 SkAutoTUnref<GrTexture> temp; | 599 SkAutoTUnref<GrTexture> temp; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 628 if (!temp) { | 628 if (!temp) { |
| 629 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | 629 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, |
| 630 maskSpaceIBounds.fBottom)); | 630 maskSpaceIBounds.fBottom)); |
| 631 if (!temp) { | 631 if (!temp) { |
| 632 fAACache.reset(); | 632 fAACache.reset(); |
| 633 return nullptr; | 633 return nullptr; |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 dst = temp; | 636 dst = temp; |
| 637 // clear the temp target and set blend to replace | 637 // clear the temp target and set blend to replace |
| 638 fClipTarget->clear(&maskSpaceElementIBounds, | 638 fDrawTarget->clear(&maskSpaceElementIBounds, |
| 639 invert ? 0xffffffff : 0x00000000, | 639 invert ? 0xffffffff : 0x00000000, |
| 640 true, | 640 true, |
| 641 dst->asRenderTarget()); | 641 dst->asRenderTarget()); |
| 642 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); | 642 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); |
| 643 } else { | 643 } else { |
| 644 // draw directly into the result with the stencil set to make th
e pixels affected | 644 // draw directly into the result with the stencil set to make th
e pixels affected |
| 645 // by the clip shape be non-zero. | 645 // by the clip shape be non-zero. |
| 646 dst = result; | 646 dst = result; |
| 647 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 647 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
| 648 kReplace_StencilOp, | 648 kReplace_StencilOp, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 681 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
| 682 kZero_StencilOp, | 682 kZero_StencilOp, |
| 683 kZero_StencilOp, | 683 kZero_StencilOp, |
| 684 kEqual_StencilFunc, | 684 kEqual_StencilFunc, |
| 685 0xffff, | 685 0xffff, |
| 686 0x0000, | 686 0x0000, |
| 687 0xffff); | 687 0xffff); |
| 688 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 688 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); |
| 689 | 689 |
| 690 // The color passed in here does not matter since the coverageSe
tOpXP won't read it. | 690 // The color passed in here does not matter since the coverageSe
tOpXP won't read it. |
| 691 fClipTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH
ITE, translate, | 691 fDrawTarget->drawNonAARect(backgroundPipelineBuilder, GrColor_WH
ITE, translate, |
| 692 clipSpaceIBounds); | 692 clipSpaceIBounds); |
| 693 } | 693 } |
| 694 } else { | 694 } else { |
| 695 GrPipelineBuilder pipelineBuilder; | 695 GrPipelineBuilder pipelineBuilder; |
| 696 | 696 |
| 697 // all the remaining ops can just be directly draw into the accumula
tion buffer | 697 // all the remaining ops can just be directly draw into the accumula
tion buffer |
| 698 set_coverage_drawing_xpf(op, false, &pipelineBuilder); | 698 set_coverage_drawing_xpf(op, false, &pipelineBuilder); |
| 699 // The color passed in here does not matter since the coverageSetOpX
P won't read it. | 699 // The color passed in here does not matter since the coverageSetOpX
P won't read it. |
| 700 this->drawElement(&pipelineBuilder, translate, result, element); | 700 this->drawElement(&pipelineBuilder, translate, result, element); |
| 701 } | 701 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 | 734 |
| 735 // We set the current clip to the bounds so that our recursive draws are
scissored to them. | 735 // We set the current clip to the bounds so that our recursive draws are
scissored to them. |
| 736 SkIRect stencilSpaceIBounds(clipSpaceIBounds); | 736 SkIRect stencilSpaceIBounds(clipSpaceIBounds); |
| 737 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); | 737 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); |
| 738 GrClip clip(stencilSpaceIBounds); | 738 GrClip clip(stencilSpaceIBounds); |
| 739 | 739 |
| 740 int clipBit = stencilAttachment->bits(); | 740 int clipBit = stencilAttachment->bits(); |
| 741 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); | 741 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); |
| 742 clipBit = (1 << (clipBit-1)); | 742 clipBit = (1 << (clipBit-1)); |
| 743 | 743 |
| 744 fClipTarget->clearStencilClip(stencilSpaceIBounds, | 744 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, |
| 745 GrReducedClip::kAllIn_InitialState == init
ialState, | 745 GrReducedClip::kAllIn_InitialState == initialState, rt); |
| 746 rt); | |
| 747 | 746 |
| 748 // walk through each clip element and perform its set op | 747 // walk through each clip element and perform its set op |
| 749 // with the existing clip. | 748 // with the existing clip. |
| 750 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { | 749 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { |
| 751 const Element* element = iter.get(); | 750 const Element* element = iter.get(); |
| 752 | 751 |
| 753 GrPipelineBuilder pipelineBuilder; | 752 GrPipelineBuilder pipelineBuilder; |
| 754 pipelineBuilder.setClip(clip); | 753 pipelineBuilder.setClip(clip); |
| 755 pipelineBuilder.setRenderTarget(rt); | 754 pipelineBuilder.setRenderTarget(rt); |
| 756 | 755 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 776 SkPath clipPath; | 775 SkPath clipPath; |
| 777 if (Element::kRect_Type == element->getType()) { | 776 if (Element::kRect_Type == element->getType()) { |
| 778 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 777 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 779 fillInverted = false; | 778 fillInverted = false; |
| 780 } else { | 779 } else { |
| 781 element->asPath(&clipPath); | 780 element->asPath(&clipPath); |
| 782 fillInverted = clipPath.isInverseFillType(); | 781 fillInverted = clipPath.isInverseFillType(); |
| 783 if (fillInverted) { | 782 if (fillInverted) { |
| 784 clipPath.toggleInverseFillType(); | 783 clipPath.toggleInverseFillType(); |
| 785 } | 784 } |
| 786 pr = this->getContext()->getPathRenderer(fClipTarget, | 785 pr = this->getContext()->getPathRenderer(fDrawTarget, |
| 787 &pipelineBuilder, | 786 &pipelineBuilder, |
| 788 viewMatrix, | 787 viewMatrix, |
| 789 clipPath, | 788 clipPath, |
| 790 stroke, | 789 stroke, |
| 791 false, | 790 false, |
| 792 GrPathRendererChain::kS
tencilOnly_DrawType, | 791 GrPathRendererChain::kS
tencilOnly_DrawType, |
| 793 &stencilSupport); | 792 &stencilSupport); |
| 794 if (nullptr == pr) { | 793 if (nullptr == pr) { |
| 795 return false; | 794 return false; |
| 796 } | 795 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 818 kIncClamp_StencilOp, | 817 kIncClamp_StencilOp, |
| 819 kIncClamp_StencilOp, | 818 kIncClamp_StencilOp, |
| 820 kAlways_StencilFunc, | 819 kAlways_StencilFunc, |
| 821 0xffff, | 820 0xffff, |
| 822 0x0000, | 821 0x0000, |
| 823 0xffff); | 822 0xffff); |
| 824 if (Element::kRect_Type == element->getType()) { | 823 if (Element::kRect_Type == element->getType()) { |
| 825 *pipelineBuilder.stencil() = gDrawToStencil; | 824 *pipelineBuilder.stencil() = gDrawToStencil; |
| 826 | 825 |
| 827 // We need this AGP until everything is in GrBatch | 826 // We need this AGP until everything is in GrBatch |
| 828 fClipTarget->drawNonAARect(pipelineBuilder, | 827 fDrawTarget->drawNonAARect(pipelineBuilder, |
| 829 GrColor_WHITE, | 828 GrColor_WHITE, |
| 830 viewMatrix, | 829 viewMatrix, |
| 831 element->getRect()); | 830 element->getRect()); |
| 832 } else { | 831 } else { |
| 833 if (!clipPath.isEmpty()) { | 832 if (!clipPath.isEmpty()) { |
| 834 if (canRenderDirectToStencil) { | 833 if (canRenderDirectToStencil) { |
| 835 *pipelineBuilder.stencil() = gDrawToStencil; | 834 *pipelineBuilder.stencil() = gDrawToStencil; |
| 836 | 835 |
| 837 GrPathRenderer::DrawPathArgs args; | 836 GrPathRenderer::DrawPathArgs args; |
| 838 args.fTarget = fClipTarget; | 837 args.fTarget = fDrawTarget; |
| 839 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 838 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 840 args.fPipelineBuilder = &pipelineBuilder; | 839 args.fPipelineBuilder = &pipelineBuilder; |
| 841 args.fColor = GrColor_WHITE; | 840 args.fColor = GrColor_WHITE; |
| 842 args.fViewMatrix = &viewMatrix; | 841 args.fViewMatrix = &viewMatrix; |
| 843 args.fPath = &clipPath; | 842 args.fPath = &clipPath; |
| 844 args.fStroke = &stroke; | 843 args.fStroke = &stroke; |
| 845 args.fAntiAlias = false; | 844 args.fAntiAlias = false; |
| 846 pr->drawPath(args); | 845 pr->drawPath(args); |
| 847 } else { | 846 } else { |
| 848 GrPathRenderer::StencilPathArgs args; | 847 GrPathRenderer::StencilPathArgs args; |
| 849 args.fTarget = fClipTarget; | 848 args.fTarget = fDrawTarget; |
| 850 args.fResourceProvider = this->getContext()->resourc
eProvider(); | 849 args.fResourceProvider = this->getContext()->resourc
eProvider(); |
| 851 args.fPipelineBuilder = &pipelineBuilder; | 850 args.fPipelineBuilder = &pipelineBuilder; |
| 852 args.fViewMatrix = &viewMatrix; | 851 args.fViewMatrix = &viewMatrix; |
| 853 args.fPath = &clipPath; | 852 args.fPath = &clipPath; |
| 854 args.fStroke = &stroke; | 853 args.fStroke = &stroke; |
| 855 pr->stencilPath(args); | 854 pr->stencilPath(args); |
| 856 } | 855 } |
| 857 } | 856 } |
| 858 } | 857 } |
| 859 } | 858 } |
| 860 | 859 |
| 861 // now we modify the clip bit by rendering either the clip | 860 // now we modify the clip bit by rendering either the clip |
| 862 // element directly or a bounding rect of the entire clip. | 861 // element directly or a bounding rect of the entire clip. |
| 863 fClipMode = kModifyClip_StencilClipMode; | 862 fClipMode = kModifyClip_StencilClipMode; |
| 864 for (int p = 0; p < passes; ++p) { | 863 for (int p = 0; p < passes; ++p) { |
| 865 *pipelineBuilder.stencil() = stencilSettings[p]; | 864 *pipelineBuilder.stencil() = stencilSettings[p]; |
| 866 | 865 |
| 867 if (canDrawDirectToClip) { | 866 if (canDrawDirectToClip) { |
| 868 if (Element::kRect_Type == element->getType()) { | 867 if (Element::kRect_Type == element->getType()) { |
| 869 // We need this AGP until everything is in GrBatch | 868 // We need this AGP until everything is in GrBatch |
| 870 fClipTarget->drawNonAARect(pipelineBuilder, | 869 fDrawTarget->drawNonAARect(pipelineBuilder, |
| 871 GrColor_WHITE, | 870 GrColor_WHITE, |
| 872 viewMatrix, | 871 viewMatrix, |
| 873 element->getRect()); | 872 element->getRect()); |
| 874 } else { | 873 } else { |
| 875 GrPathRenderer::DrawPathArgs args; | 874 GrPathRenderer::DrawPathArgs args; |
| 876 args.fTarget = fClipTarget; | 875 args.fTarget = fDrawTarget; |
| 877 args.fResourceProvider = this->getContext()->resourcePro
vider(); | 876 args.fResourceProvider = this->getContext()->resourcePro
vider(); |
| 878 args.fPipelineBuilder = &pipelineBuilder; | 877 args.fPipelineBuilder = &pipelineBuilder; |
| 879 args.fColor = GrColor_WHITE; | 878 args.fColor = GrColor_WHITE; |
| 880 args.fViewMatrix = &viewMatrix; | 879 args.fViewMatrix = &viewMatrix; |
| 881 args.fPath = &clipPath; | 880 args.fPath = &clipPath; |
| 882 args.fStroke = &stroke; | 881 args.fStroke = &stroke; |
| 883 args.fAntiAlias = false; | 882 args.fAntiAlias = false; |
| 884 pr->drawPath(args); | 883 pr->drawPath(args); |
| 885 } | 884 } |
| 886 } else { | 885 } else { |
| 887 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 886 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 888 // draw rect in clip space. | 887 // draw rect in clip space. |
| 889 fClipTarget->drawNonAARect(pipelineBuilder, | 888 fDrawTarget->drawNonAARect(pipelineBuilder, |
| 890 GrColor_WHITE, | 889 GrColor_WHITE, |
| 891 viewMatrix, | 890 viewMatrix, |
| 892 SkRect::Make(clipSpaceIBounds)); | 891 SkRect::Make(clipSpaceIBounds)); |
| 893 } | 892 } |
| 894 } | 893 } |
| 895 } | 894 } |
| 896 } | 895 } |
| 897 // set this last because recursive draws may overwrite it back to kNone. | 896 // set this last because recursive draws may overwrite it back to kNone. |
| 898 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 897 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 899 fCurrClipMaskType = kStencil_ClipMaskType; | 898 fCurrClipMaskType = kStencil_ClipMaskType; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 settings = pipelineBuilder.getStencil(); | 975 settings = pipelineBuilder.getStencil(); |
| 977 } | 976 } |
| 978 | 977 |
| 979 int stencilBits = 0; | 978 int stencilBits = 0; |
| 980 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 979 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| 981 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); | 980 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); |
| 982 if (stencilAttachment) { | 981 if (stencilAttachment) { |
| 983 stencilBits = stencilAttachment->bits(); | 982 stencilBits = stencilAttachment->bits(); |
| 984 } | 983 } |
| 985 | 984 |
| 986 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); | 985 SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); |
| 987 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); | 986 SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); |
| 988 this->adjustStencilParams(&settings, fClipMode, stencilBits); | 987 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
| 989 ars->set(&pipelineBuilder); | 988 ars->set(&pipelineBuilder); |
| 990 ars->setStencil(settings); | 989 ars->setStencil(settings); |
| 991 } | 990 } |
| 992 | 991 |
| 993 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 992 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
| 994 StencilClipMode mode, | 993 StencilClipMode mode, |
| 995 int stencilBitCnt) { | 994 int stencilBitCnt) { |
| 996 SkASSERT(stencilBitCnt > 0); | 995 SkASSERT(stencilBitCnt > 0); |
| 997 | 996 |
| 998 if (kModifyClip_StencilClipMode == mode) { | 997 if (kModifyClip_StencilClipMode == mode) { |
| 999 // We assume that this clip manager itself is drawing to the GrGpu and | 998 // We assume that this clip manager itself is drawing to the GrGpu and |
| 1000 // has already setup the correct values. | 999 // has already setup the correct values. |
| 1001 return; | 1000 return; |
| 1002 } | 1001 } |
| 1003 | 1002 |
| 1004 unsigned int clipBit = (1 << (stencilBitCnt - 1)); | 1003 unsigned int clipBit = (1 << (stencilBitCnt - 1)); |
| 1005 unsigned int userBits = clipBit - 1; | 1004 unsigned int userBits = clipBit - 1; |
| 1006 | 1005 |
| 1007 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | 1006 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; |
| 1008 bool twoSided = fClipTarget->caps()->twoSidedStencilSupport(); | 1007 bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport(); |
| 1009 | 1008 |
| 1010 bool finished = false; | 1009 bool finished = false; |
| 1011 while (!finished) { | 1010 while (!finished) { |
| 1012 GrStencilFunc func = settings->func(face); | 1011 GrStencilFunc func = settings->func(face); |
| 1013 uint16_t writeMask = settings->writeMask(face); | 1012 uint16_t writeMask = settings->writeMask(face); |
| 1014 uint16_t funcMask = settings->funcMask(face); | 1013 uint16_t funcMask = settings->funcMask(face); |
| 1015 uint16_t funcRef = settings->funcRef(face); | 1014 uint16_t funcRef = settings->funcRef(face); |
| 1016 | 1015 |
| 1017 SkASSERT((unsigned) func < kStencilFuncCount); | 1016 SkASSERT((unsigned) func < kStencilFuncCount); |
| 1018 | 1017 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 fAACache.purgeResources(); | 1147 fAACache.purgeResources(); |
| 1149 } | 1148 } |
| 1150 | 1149 |
| 1151 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1150 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1152 GrStencilSettings* settings) { | 1151 GrStencilSettings* settings) { |
| 1153 if (stencilAttachment) { | 1152 if (stencilAttachment) { |
| 1154 int stencilBits = stencilAttachment->bits(); | 1153 int stencilBits = stencilAttachment->bits(); |
| 1155 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1154 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1156 } | 1155 } |
| 1157 } | 1156 } |
| OLD | NEW |