| 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 if (prOut) { | 92 if (prOut) { |
| 93 *prOut = pr; | 93 *prOut = pr; |
| 94 } | 94 } |
| 95 return SkToBool(!pr); | 95 return SkToBool(!pr); |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 // Determines whether it is possible to draw the element to both the stencil buf
fer and the | 99 // Determines whether it is possible to draw the element to both the stencil buf
fer and the |
| 100 // alpha mask simultaneously. If so and the element is a path a compatible path
renderer is | 100 // alpha mask simultaneously. If so and the element is a path a compatible path
renderer is |
| 101 // also returned. | 101 // also returned. |
| 102 static bool can_stencil_and_draw_element(GrContext* context, | 102 static GrPathRenderer* get_path_renderer(GrContext* context, |
| 103 GrPipelineBuilder* pipelineBuilder, | 103 GrPipelineBuilder* pipelineBuilder, |
| 104 GrTexture* texture, | |
| 105 const SkMatrix& viewMatrix, | 104 const SkMatrix& viewMatrix, |
| 106 const SkClipStack::Element* element, | 105 const SkClipStack::Element* element) { |
| 107 GrPathRenderer** pr) { | 106 GrPathRenderer* pr; |
| 108 pipelineBuilder->setRenderTarget(texture->asRenderTarget()); | |
| 109 | |
| 110 static const bool kNeedsStencil = true; | 107 static const bool kNeedsStencil = true; |
| 111 return !path_needs_SW_renderer(context, | 108 path_needs_SW_renderer(context, *pipelineBuilder, viewMatrix, element, &pr,
kNeedsStencil); |
| 112 *pipelineBuilder, | 109 return pr; |
| 113 viewMatrix, | |
| 114 element, | |
| 115 pr, | |
| 116 kNeedsStencil); | |
| 117 } | 110 } |
| 118 | 111 |
| 119 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) | 112 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) |
| 120 : fDrawTarget(drawTarget) | 113 : fDrawTarget(drawTarget) |
| 121 , fClipMode(kIgnoreClip_StencilClipMode) { | 114 , fClipMode(kIgnoreClip_StencilClipMode) { |
| 122 } | 115 } |
| 123 | 116 |
| 124 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con
text(); } | 117 GrContext* GrClipMaskManager::getContext() { |
| 118 return fDrawTarget->cmmAccess().context(); |
| 119 } |
| 125 | 120 |
| 121 const GrCaps* GrClipMaskManager::caps() const { |
| 122 return fDrawTarget->caps(); |
| 123 } |
| 124 |
| 125 GrResourceProvider* GrClipMaskManager::resourceProvider() { |
| 126 return fDrawTarget->cmmAccess().resourceProvider(); |
| 127 } |
| 126 /* | 128 /* |
| 127 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 129 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
| 128 * will be used on any element. If so, it returns true to indicate that the | 130 * will be used on any element. If so, it returns true to indicate that the |
| 129 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 131 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
| 130 */ | 132 */ |
| 131 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, | 133 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, |
| 132 const SkVector& clipToMaskOffset, | 134 const SkVector& clipToMaskOffset, |
| 133 const GrReducedClip::ElementList& elements
) { | 135 const GrReducedClip::ElementList& elements
) { |
| 134 // TODO: generalize this function so that when | 136 // TODO: generalize this function so that when |
| 135 // a clip gets complex enough it can just be done in SW regardless | 137 // a clip gets complex enough it can just be done in SW regardless |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 args.fPath = &path; | 477 args.fPath = &path; |
| 476 args.fStroke = &stroke; | 478 args.fStroke = &stroke; |
| 477 args.fAntiAlias = element->isAA(); | 479 args.fAntiAlias = element->isAA(); |
| 478 pr->drawPath(args); | 480 pr->drawPath(args); |
| 479 break; | 481 break; |
| 480 } | 482 } |
| 481 } | 483 } |
| 482 return true; | 484 return true; |
| 483 } | 485 } |
| 484 | 486 |
| 485 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, | |
| 486 GrTexture* dstMask, | |
| 487 GrTexture* srcMask, | |
| 488 SkRegion::Op op, | |
| 489 const SkIRect& dstBound, | |
| 490 const SkIRect& srcBound) { | |
| 491 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); | |
| 492 | |
| 493 // We want to invert the coverage here | |
| 494 set_coverage_drawing_xpf(op, false, pipelineBuilder); | |
| 495 | |
| 496 SkMatrix sampleM; | |
| 497 sampleM.setIDiv(srcMask->width(), srcMask->height()); | |
| 498 | |
| 499 pipelineBuilder->addCoverageFragmentProcessor( | |
| 500 GrTextureDomainEffect::Create(srcMask, | |
| 501 sampleM, | |
| 502 GrTextureDomain::MakeTexelDomain(srcMask,
srcBound), | |
| 503 GrTextureDomain::kDecal_Mode, | |
| 504 GrTextureParams::kNone_FilterMode))->unref
(); | |
| 505 | |
| 506 // The color passed in here does not matter since the coverageSetOpXP won't
read it. | |
| 507 fDrawTarget->drawNonAARect(*pipelineBuilder, | |
| 508 GrColor_WHITE, | |
| 509 SkMatrix::I(), | |
| 510 SkRect::Make(dstBound)); | |
| 511 } | |
| 512 | |
| 513 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { | |
| 514 GrSurfaceDesc desc; | |
| 515 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
| 516 desc.fWidth = width; | |
| 517 desc.fHeight = height; | |
| 518 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { | |
| 519 desc.fConfig = kAlpha_8_GrPixelConfig; | |
| 520 } else { | |
| 521 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
| 522 } | |
| 523 | |
| 524 return this->getContext()->textureProvider()->createApproxTexture(desc); | |
| 525 } | |
| 526 | |
| 527 //////////////////////////////////////////////////////////////////////////////// | 487 //////////////////////////////////////////////////////////////////////////////// |
| 528 // Create a 8-bit clip mask in alpha | 488 // Create a 8-bit clip mask in alpha |
| 529 | 489 |
| 530 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { | 490 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { |
| 531 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 491 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
| 532 GrUniqueKey::Builder builder(key, kDomain, 3); | 492 GrUniqueKey::Builder builder(key, kDomain, 3); |
| 533 builder[0] = clipGenID; | 493 builder[0] = clipGenID; |
| 534 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); | 494 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); |
| 535 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); | 495 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); |
| 536 } | 496 } |
| 537 | 497 |
| 538 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
iqueKey& key, | 498 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn
iqueKey& key, |
| 539 bool renderTarget) { | 499 bool renderTarget) { |
| 540 GrSurfaceDesc desc; | 500 GrSurfaceDesc desc; |
| 541 desc.fWidth = width; | 501 desc.fWidth = width; |
| 542 desc.fHeight = height; | 502 desc.fHeight = height; |
| 543 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl
ags; | 503 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl
ags; |
| 544 if (!renderTarget || fDrawTarget->caps()->isConfigRenderable(kAlpha_8_GrPixe
lConfig, false)) { | 504 if (!renderTarget || this->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig
, false)) { |
| 545 desc.fConfig = kAlpha_8_GrPixelConfig; | 505 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 546 } else { | 506 } else { |
| 547 desc.fConfig = kRGBA_8888_GrPixelConfig; | 507 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 548 } | 508 } |
| 549 | 509 |
| 550 GrTexture* texture = fDrawTarget->cmmAccess().resourceProvider()->createAppr
oxTexture(desc, 0); | 510 GrTexture* texture = this->resourceProvider()->createApproxTexture(desc, 0); |
| 551 if (!texture) { | 511 if (!texture) { |
| 552 return nullptr; | 512 return nullptr; |
| 553 } | 513 } |
| 554 texture->resourcePriv().setUniqueKey(key); | 514 texture->resourcePriv().setUniqueKey(key); |
| 555 return texture; | 515 return texture; |
| 556 } | 516 } |
| 557 | 517 |
| 558 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 518 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
| 559 GrReducedClip::InitialState in
itialState, | 519 GrReducedClip::InitialState in
itialState, |
| 560 const GrReducedClip::ElementLi
st& elements, | 520 const GrReducedClip::ElementLi
st& elements, |
| 561 const SkVector& clipToMaskOffs
et, | 521 const SkVector& clipToMaskOffs
et, |
| 562 const SkIRect& clipSpaceIBound
s) { | 522 const SkIRect& clipSpaceIBound
s) { |
| 563 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); | 523 GrResourceProvider* resourceProvider = this->resourceProvider(); |
| 564 GrUniqueKey key; | 524 GrUniqueKey key; |
| 565 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 525 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
| 566 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { | 526 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
| 567 return texture; | 527 return texture; |
| 568 } | 528 } |
| 569 | 529 |
| 530 // There's no texture in the cache. Let's try to allocate it then. |
| 570 SkAutoTUnref<GrTexture> texture(this->createCachedMask( | 531 SkAutoTUnref<GrTexture> texture(this->createCachedMask( |
| 571 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); | 532 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); |
| 572 | |
| 573 // There's no texture in the cache. Let's try to allocate it then. | |
| 574 if (!texture) { | 533 if (!texture) { |
| 575 return nullptr; | 534 return nullptr; |
| 576 } | 535 } |
| 577 | 536 |
| 578 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 537 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
| 579 // space. | 538 // space. |
| 580 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); | 539 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa
skOffset.fY); |
| 581 | 540 |
| 582 // The texture may be larger than necessary, this rect represents the part o
f the texture | 541 // The texture may be larger than necessary, this rect represents the part o
f the texture |
| 583 // we populate with a rasterization of the clip. | 542 // we populate with a rasterization of the clip. |
| 584 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 543 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
| 585 | 544 |
| 586 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 545 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
| 587 // clear the part that we care about. | 546 // clear the part that we care about. |
| 588 fDrawTarget->clear(&maskSpaceIBounds, | 547 fDrawTarget->clear(&maskSpaceIBounds, |
| 589 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, | 548 GrReducedClip::kAllIn_InitialState == initialState ? 0xff
ffffff : 0x00000000, |
| 590 true, | 549 true, |
| 591 texture->asRenderTarget()); | 550 texture->asRenderTarget()); |
| 592 | 551 |
| 593 // When we use the stencil in the below loop it is important to have this cl
ip installed. | 552 // When we use the stencil in the below loop it is important to have this cl
ip installed. |
| 594 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 553 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
| 595 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 554 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
| 596 // cleared. | 555 // cleared. |
| 597 GrClip clip(maskSpaceIBounds); | 556 const GrClip clip(maskSpaceIBounds); |
| 598 SkAutoTUnref<GrTexture> temp; | |
| 599 | 557 |
| 600 // walk through each clip element and perform its set op | 558 // walk through each clip element and perform its set op |
| 601 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { | 559 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { |
| 602 const Element* element = iter.get(); | 560 const Element* element = iter.get(); |
| 603 SkRegion::Op op = element->getOp(); | 561 SkRegion::Op op = element->getOp(); |
| 604 bool invert = element->isInverseFilled(); | 562 bool invert = element->isInverseFilled(); |
| 605 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 563 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
| 606 GrPipelineBuilder pipelineBuilder; | 564 GrPipelineBuilder pipelineBuilder; |
| 607 | 565 |
| 608 pipelineBuilder.setClip(clip); | 566 pipelineBuilder.setClip(clip); |
| 609 GrPathRenderer* pr = nullptr; | 567 pipelineBuilder.setRenderTarget(texture->asRenderTarget()); |
| 610 bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pi
pelineBuilder, | |
| 611 texture, translate, ele
ment, &pr); | |
| 612 | 568 |
| 613 // useSWOnlyPath should now filter out all cases where gpu-side mask
merging is | 569 GrPathRenderer* pr = get_path_renderer(this->getContext(), &pipeline
Builder, |
| 614 // performed. See skbug.com/4519 for rationale and details. | 570 translate, element); |
| 615 SkASSERT(!useTemp); | 571 if (Element::kRect_Type != element->getType() && !pr) { |
| 616 | 572 // useSWOnlyPath should now filter out all cases where gpu-side
mask merging would |
| 617 GrTexture* dst; | 573 // be performed (i.e., pr would be NULL for a non-rect path). Se
e skbug.com/4519 |
| 618 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 574 // for rationale and details. |
| 619 // mask buffer can be substantially larger than the actually clip st
ack element. We | 575 SkASSERT(0); |
| 620 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 576 continue; |
| 621 // the accumulator. | |
| 622 SkIRect maskSpaceElementIBounds; | |
| 623 | |
| 624 if (useTemp) { | |
| 625 if (invert) { | |
| 626 maskSpaceElementIBounds = maskSpaceIBounds; | |
| 627 } else { | |
| 628 SkRect elementBounds = element->getBounds(); | |
| 629 elementBounds.offset(clipToMaskOffset); | |
| 630 elementBounds.roundOut(&maskSpaceElementIBounds); | |
| 631 } | |
| 632 | |
| 633 if (!temp) { | |
| 634 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | |
| 635 maskSpaceIBounds.fBottom)); | |
| 636 if (!temp) { | |
| 637 texture->resourcePriv().removeUniqueKey(); | |
| 638 return nullptr; | |
| 639 } | |
| 640 } | |
| 641 dst = temp; | |
| 642 // clear the temp target and set blend to replace | |
| 643 fDrawTarget->clear(&maskSpaceElementIBounds, | |
| 644 invert ? 0xffffffff : 0x00000000, | |
| 645 true, | |
| 646 dst->asRenderTarget()); | |
| 647 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); | |
| 648 } else { | |
| 649 // draw directly into the result with the stencil set to make th
e pixels affected | |
| 650 // by the clip shape be non-zero. | |
| 651 dst = texture; | |
| 652 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | |
| 653 kReplace_StencilOp, | |
| 654 kReplace_StencilOp, | |
| 655 kAlways_StencilFunc, | |
| 656 0xffff, | |
| 657 0xffff, | |
| 658 0xffff); | |
| 659 pipelineBuilder.setStencil(kStencilInElement); | |
| 660 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | |
| 661 } | 577 } |
| 662 | 578 |
| 663 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { | 579 // draw directly into the result with the stencil set to make the pi
xels affected |
| 580 // by the clip shape be non-zero. |
| 581 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
| 582 kReplace_StencilOp, |
| 583 kReplace_StencilOp, |
| 584 kAlways_StencilFunc, |
| 585 0xffff, |
| 586 0xffff, |
| 587 0xffff); |
| 588 pipelineBuilder.setStencil(kStencilInElement); |
| 589 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); |
| 590 |
| 591 if (!this->drawElement(&pipelineBuilder, translate, texture, element
, pr)) { |
| 664 texture->resourcePriv().removeUniqueKey(); | 592 texture->resourcePriv().removeUniqueKey(); |
| 665 return nullptr; | 593 return nullptr; |
| 666 } | 594 } |
| 667 | 595 |
| 668 if (useTemp) { | 596 { |
| 669 GrPipelineBuilder backgroundPipelineBuilder; | 597 GrPipelineBuilder backgroundPipelineBuilder; |
| 670 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); | 598 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); |
| 671 | 599 |
| 672 // Now draw into the accumulator using the real operation and th
e temp buffer as a | |
| 673 // texture | |
| 674 this->mergeMask(&backgroundPipelineBuilder, | |
| 675 texture, | |
| 676 temp, | |
| 677 op, | |
| 678 maskSpaceIBounds, | |
| 679 maskSpaceElementIBounds); | |
| 680 } else { | |
| 681 GrPipelineBuilder backgroundPipelineBuilder; | |
| 682 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge
t()); | |
| 683 | |
| 684 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); | 600 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder
); |
| 685 // Draw to the exterior pixels (those with a zero stencil value)
. | 601 // Draw to the exterior pixels (those with a zero stencil value)
. |
| 686 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 602 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
| 687 kZero_StencilOp, | 603 kZero_StencilOp, |
| 688 kZero_StencilOp, | 604 kZero_StencilOp, |
| 689 kEqual_StencilFunc, | 605 kEqual_StencilFunc, |
| 690 0xffff, | 606 0xffff, |
| 691 0x0000, | 607 0x0000, |
| 692 0xffff); | 608 0xffff); |
| 693 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); | 609 backgroundPipelineBuilder.setStencil(kDrawOutsideElement); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 713 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 629 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
| 714 // (as opposed to canvas) coordinates | 630 // (as opposed to canvas) coordinates |
| 715 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, | 631 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, |
| 716 int32_t elementsGenID, | 632 int32_t elementsGenID, |
| 717 GrReducedClip::InitialState initia
lState, | 633 GrReducedClip::InitialState initia
lState, |
| 718 const GrReducedClip::ElementList&
elements, | 634 const GrReducedClip::ElementList&
elements, |
| 719 const SkIRect& clipSpaceIBounds, | 635 const SkIRect& clipSpaceIBounds, |
| 720 const SkIPoint& clipSpaceToStencil
Offset) { | 636 const SkIPoint& clipSpaceToStencil
Offset) { |
| 721 SkASSERT(rt); | 637 SkASSERT(rt); |
| 722 | 638 |
| 723 GrStencilAttachment* stencilAttachment = | 639 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); |
| 724 fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt)
; | |
| 725 if (nullptr == stencilAttachment) { | 640 if (nullptr == stencilAttachment) { |
| 726 return false; | 641 return false; |
| 727 } | 642 } |
| 728 | 643 |
| 729 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { | 644 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { |
| 730 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); | 645 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); |
| 731 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. | 646 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. |
| 732 SkVector translate = { | 647 SkVector translate = { |
| 733 SkIntToScalar(clipSpaceToStencilOffset.fX), | 648 SkIntToScalar(clipSpaceToStencilOffset.fX), |
| 734 SkIntToScalar(clipSpaceToStencilOffset.fY) | 649 SkIntToScalar(clipSpaceToStencilOffset.fY) |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 settings = basic_apply_stencil_clip_settings(); | 885 settings = basic_apply_stencil_clip_settings(); |
| 971 } else { | 886 } else { |
| 972 return; | 887 return; |
| 973 } | 888 } |
| 974 } else { | 889 } else { |
| 975 settings = pipelineBuilder.getStencil(); | 890 settings = pipelineBuilder.getStencil(); |
| 976 } | 891 } |
| 977 | 892 |
| 978 int stencilBits = 0; | 893 int stencilBits = 0; |
| 979 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 894 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| 980 GrStencilAttachment* stencilAttachment = | 895 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte
ncilAttachment(rt); |
| 981 fDrawTarget->cmmAccess().resourceProvider()->attachStencilAttachment(rt)
; | |
| 982 if (stencilAttachment) { | 896 if (stencilAttachment) { |
| 983 stencilBits = stencilAttachment->bits(); | 897 stencilBits = stencilAttachment->bits(); |
| 984 } | 898 } |
| 985 | 899 |
| 986 SkASSERT(fDrawTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO
p()); | 900 SkASSERT(this->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); |
| 987 SkASSERT(fDrawTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid
ed()); | 901 SkASSERT(this->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); |
| 988 this->adjustStencilParams(&settings, fClipMode, stencilBits); | 902 this->adjustStencilParams(&settings, fClipMode, stencilBits); |
| 989 ars->set(&pipelineBuilder); | 903 ars->set(&pipelineBuilder); |
| 990 ars->setStencil(settings); | 904 ars->setStencil(settings); |
| 991 } | 905 } |
| 992 | 906 |
| 993 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, | 907 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, |
| 994 StencilClipMode mode, | 908 StencilClipMode mode, |
| 995 int stencilBitCnt) { | 909 int stencilBitCnt) { |
| 996 SkASSERT(stencilBitCnt > 0); | 910 SkASSERT(stencilBitCnt > 0); |
| 997 | 911 |
| 998 if (kModifyClip_StencilClipMode == mode) { | 912 if (kModifyClip_StencilClipMode == mode) { |
| 999 // We assume that this clip manager itself is drawing to the GrGpu and | 913 // We assume that this clip manager itself is drawing to the GrGpu and |
| 1000 // has already setup the correct values. | 914 // has already setup the correct values. |
| 1001 return; | 915 return; |
| 1002 } | 916 } |
| 1003 | 917 |
| 1004 unsigned int clipBit = (1 << (stencilBitCnt - 1)); | 918 unsigned int clipBit = (1 << (stencilBitCnt - 1)); |
| 1005 unsigned int userBits = clipBit - 1; | 919 unsigned int userBits = clipBit - 1; |
| 1006 | 920 |
| 1007 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; | 921 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; |
| 1008 bool twoSided = fDrawTarget->caps()->twoSidedStencilSupport(); | 922 bool twoSided = this->caps()->twoSidedStencilSupport(); |
| 1009 | 923 |
| 1010 bool finished = false; | 924 bool finished = false; |
| 1011 while (!finished) { | 925 while (!finished) { |
| 1012 GrStencilFunc func = settings->func(face); | 926 GrStencilFunc func = settings->func(face); |
| 1013 uint16_t writeMask = settings->writeMask(face); | 927 uint16_t writeMask = settings->writeMask(face); |
| 1014 uint16_t funcMask = settings->funcMask(face); | 928 uint16_t funcMask = settings->funcMask(face); |
| 1015 uint16_t funcRef = settings->funcRef(face); | 929 uint16_t funcRef = settings->funcRef(face); |
| 1016 | 930 |
| 1017 SkASSERT((unsigned) func < kStencilFuncCount); | 931 SkASSERT((unsigned) func < kStencilFuncCount); |
| 1018 | 932 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1070 } | 984 } |
| 1071 | 985 |
| 1072 //////////////////////////////////////////////////////////////////////////////// | 986 //////////////////////////////////////////////////////////////////////////////// |
| 1073 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 987 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
| 1074 GrReducedClip::InitialState
initialState, | 988 GrReducedClip::InitialState
initialState, |
| 1075 const GrReducedClip::Elemen
tList& elements, | 989 const GrReducedClip::Elemen
tList& elements, |
| 1076 const SkVector& clipToMaskO
ffset, | 990 const SkVector& clipToMaskO
ffset, |
| 1077 const SkIRect& clipSpaceIBo
unds) { | 991 const SkIRect& clipSpaceIBo
unds) { |
| 1078 GrUniqueKey key; | 992 GrUniqueKey key; |
| 1079 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); | 993 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); |
| 1080 GrResourceProvider* resourceProvider = fDrawTarget->cmmAccess().resourceProv
ider(); | 994 GrResourceProvider* resourceProvider = this->resourceProvider(); |
| 1081 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { | 995 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
| 1082 return texture; | 996 return texture; |
| 1083 } | 997 } |
| 1084 | 998 |
| 1085 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin | 999 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin |
| 1086 // the top left corner of the resulting rect to the top left of the texture. | 1000 // the top left corner of the resulting rect to the top left of the texture. |
| 1087 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 1001 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
| 1088 | 1002 |
| 1089 GrSWMaskHelper helper(this->getContext()); | 1003 GrSWMaskHelper helper(this->getContext()); |
| 1090 | 1004 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 | 1056 |
| 1143 //////////////////////////////////////////////////////////////////////////////// | 1057 //////////////////////////////////////////////////////////////////////////////// |
| 1144 | 1058 |
| 1145 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1059 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1146 GrStencilSettings* settings) { | 1060 GrStencilSettings* settings) { |
| 1147 if (stencilAttachment) { | 1061 if (stencilAttachment) { |
| 1148 int stencilBits = stencilAttachment->bits(); | 1062 int stencilBits = stencilAttachment->bits(); |
| 1149 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1063 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1150 } | 1064 } |
| 1151 } | 1065 } |
| OLD | NEW |