| 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 "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
| 10 #include "GrAAHairLinePathRenderer.h" | 10 #include "GrAAHairLinePathRenderer.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer | 66 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer |
| 67 SkTCopyOnFirstWrite<SkPath> path(origPath); | 67 SkTCopyOnFirstWrite<SkPath> path(origPath); |
| 68 if (path->isInverseFillType()) { | 68 if (path->isInverseFillType()) { |
| 69 path.writable()->toggleInverseFillType(); | 69 path.writable()->toggleInverseFillType(); |
| 70 } | 70 } |
| 71 // last (false) parameter disallows use of the SW path renderer | 71 // last (false) parameter disallows use of the SW path renderer |
| 72 GrPathRendererChain::DrawType type = doAA ? | 72 GrPathRendererChain::DrawType type = doAA ? |
| 73 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 73 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 74 GrPathRendererChain::kColor_DrawType; | 74 GrPathRendererChain::kColor_DrawType; |
| 75 | 75 |
| 76 return NULL == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix, *
path, stroke, | 76 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix
, *path, stroke, |
| 77 false, type); | 77 false, type); |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget) | 81 GrClipMaskManager::GrClipMaskManager(GrClipTarget* clipTarget) |
| 82 : fCurrClipMaskType(kNone_ClipMaskType) | 82 : fCurrClipMaskType(kNone_ClipMaskType) |
| 83 , fAACache(clipTarget->getContext()->resourceProvider()) | 83 , fAACache(clipTarget->getContext()->resourceProvider()) |
| 84 , fClipTarget(clipTarget) | 84 , fClipTarget(clipTarget) |
| 85 , fClipMode(kIgnoreClip_StencilClipMode) { | 85 , fClipMode(kIgnoreClip_StencilClipMode) { |
| 86 } | 86 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 arfps->addCoverageFragmentProcessor(fp); | 203 arfps->addCoverageFragmentProcessor(fp); |
| 204 } else { | 204 } else { |
| 205 failed = true; | 205 failed = true; |
| 206 break; | 206 break; |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 iter.next(); | 209 iter.next(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 if (failed) { | 212 if (failed) { |
| 213 arfps->set(NULL); | 213 arfps->set(nullptr); |
| 214 } | 214 } |
| 215 return !failed; | 215 return !failed; |
| 216 } | 216 } |
| 217 | 217 |
| 218 //////////////////////////////////////////////////////////////////////////////// | 218 //////////////////////////////////////////////////////////////////////////////// |
| 219 // sort out what kind of clip mask needs to be created: alpha, stencil, | 219 // sort out what kind of clip mask needs to be created: alpha, stencil, |
| 220 // scissor, or entirely software | 220 // scissor, or entirely software |
| 221 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, | 221 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, |
| 222 GrPipelineBuilder::AutoRestoreFragmentProc
essorState* arfps, | 222 GrPipelineBuilder::AutoRestoreFragmentProc
essorState* arfps, |
| 223 GrPipelineBuilder::AutoRestoreStencil* ars
, | 223 GrPipelineBuilder::AutoRestoreStencil* ars
, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 // configuration's relative costs of switching RTs to generate a mask vs | 291 // configuration's relative costs of switching RTs to generate a mask vs |
| 292 // longer shaders. | 292 // longer shaders. |
| 293 if (elements.count() <= 4) { | 293 if (elements.count() <= 4) { |
| 294 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), | 294 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), |
| 295 SkIntToScalar(-clip.origin().fY) }; | 295 SkIntToScalar(-clip.origin().fY) }; |
| 296 if (elements.isEmpty() || | 296 if (elements.isEmpty() || |
| 297 (requiresAA && this->installClipEffects(pipelineBuilder, arfps, elem
ents, clipToRTOffset, | 297 (requiresAA && this->installClipEffects(pipelineBuilder, arfps, elem
ents, clipToRTOffset, |
| 298 devBounds))) { | 298 devBounds))) { |
| 299 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 299 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
| 300 scissorSpaceIBounds.offset(-clip.origin()); | 300 scissorSpaceIBounds.offset(-clip.origin()); |
| 301 if (NULL == devBounds || | 301 if (nullptr == devBounds || |
| 302 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { | 302 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { |
| 303 scissorState->set(scissorSpaceIBounds); | 303 scissorState->set(scissorSpaceIBounds); |
| 304 } | 304 } |
| 305 this->setPipelineBuilderStencil(pipelineBuilder, ars); | 305 this->setPipelineBuilderStencil(pipelineBuilder, ars); |
| 306 return true; | 306 return true; |
| 307 } | 307 } |
| 308 } | 308 } |
| 309 | 309 |
| 310 // If MSAA is enabled we can do everything in the stencil buffer. | 310 // If MSAA is enabled we can do everything in the stencil buffer. |
| 311 if (0 == rt->numColorSamples() && requiresAA) { | 311 if (0 == rt->numColorSamples() && requiresAA) { |
| 312 GrTexture* result = NULL; | 312 GrTexture* result = nullptr; |
| 313 | 313 |
| 314 // The top-left of the mask corresponds to the top-left corner of the bo
unds. | 314 // The top-left of the mask corresponds to the top-left corner of the bo
unds. |
| 315 SkVector clipToMaskOffset = { | 315 SkVector clipToMaskOffset = { |
| 316 SkIntToScalar(-clipSpaceIBounds.fLeft), | 316 SkIntToScalar(-clipSpaceIBounds.fLeft), |
| 317 SkIntToScalar(-clipSpaceIBounds.fTop) | 317 SkIntToScalar(-clipSpaceIBounds.fTop) |
| 318 }; | 318 }; |
| 319 | 319 |
| 320 if (this->useSWOnlyPath(pipelineBuilder, clipToMaskOffset, elements)) { | 320 if (this->useSWOnlyPath(pipelineBuilder, clipToMaskOffset, elements)) { |
| 321 // The clip geometry is complex enough that it will be more efficien
t to create it | 321 // The clip geometry is complex enough that it will be more efficien
t to create it |
| 322 // entirely in software | 322 // entirely in software |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 415 } |
| 416 return true; | 416 return true; |
| 417 default: { | 417 default: { |
| 418 SkPath path; | 418 SkPath path; |
| 419 element->asPath(&path); | 419 element->asPath(&path); |
| 420 path.setIsVolatile(true); | 420 path.setIsVolatile(true); |
| 421 if (path.isInverseFillType()) { | 421 if (path.isInverseFillType()) { |
| 422 path.toggleInverseFillType(); | 422 path.toggleInverseFillType(); |
| 423 } | 423 } |
| 424 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 424 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 425 if (NULL == pr) { | 425 if (nullptr == pr) { |
| 426 GrPathRendererChain::DrawType type; | 426 GrPathRendererChain::DrawType type; |
| 427 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : | 427 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 428 GrPathRendererChain::kColor_DrawType; | 428 GrPathRendererChain::kColor_DrawType; |
| 429 pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBu
ilder, viewMatrix, | 429 pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBu
ilder, viewMatrix, |
| 430 path, stroke, false, ty
pe); | 430 path, stroke, false, ty
pe); |
| 431 } | 431 } |
| 432 if (NULL == pr) { | 432 if (nullptr == pr) { |
| 433 return false; | 433 return false; |
| 434 } | 434 } |
| 435 GrPathRenderer::DrawPathArgs args; | 435 GrPathRenderer::DrawPathArgs args; |
| 436 args.fTarget = fClipTarget; | 436 args.fTarget = fClipTarget; |
| 437 args.fResourceProvider = this->getContext()->resourceProvider(); | 437 args.fResourceProvider = this->getContext()->resourceProvider(); |
| 438 args.fPipelineBuilder = pipelineBuilder; | 438 args.fPipelineBuilder = pipelineBuilder; |
| 439 args.fColor = color; | 439 args.fColor = color; |
| 440 args.fViewMatrix = &viewMatrix; | 440 args.fViewMatrix = &viewMatrix; |
| 441 args.fPath = &path; | 441 args.fPath = &path; |
| 442 args.fStroke = &stroke; | 442 args.fStroke = &stroke; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { | 511 if (this->getContext()->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, f
alse)) { |
| 512 desc.fConfig = kAlpha_8_GrPixelConfig; | 512 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 513 } else { | 513 } else { |
| 514 desc.fConfig = kRGBA_8888_GrPixelConfig; | 514 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 515 } | 515 } |
| 516 | 516 |
| 517 return this->getContext()->textureProvider()->createApproxTexture(desc); | 517 return this->getContext()->textureProvider()->createApproxTexture(desc); |
| 518 } | 518 } |
| 519 | 519 |
| 520 //////////////////////////////////////////////////////////////////////////////// | 520 //////////////////////////////////////////////////////////////////////////////// |
| 521 // Return the texture currently in the cache if it exists. Otherwise, return NUL
L | 521 // Return the texture currently in the cache if it exists. Otherwise, return nul
lptr |
| 522 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, | 522 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, |
| 523 const SkIRect& clipSpaceIBoun
ds) { | 523 const SkIRect& clipSpaceIBoun
ds) { |
| 524 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); | 524 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); |
| 525 if (!cached) { | 525 if (!cached) { |
| 526 return NULL; | 526 return nullptr; |
| 527 } | 527 } |
| 528 | 528 |
| 529 return fAACache.getLastMask(); | 529 return fAACache.getLastMask(); |
| 530 } | 530 } |
| 531 | 531 |
| 532 //////////////////////////////////////////////////////////////////////////////// | 532 //////////////////////////////////////////////////////////////////////////////// |
| 533 // Allocate a texture in the texture cache. This function returns the texture | 533 // Allocate a texture in the texture cache. This function returns the texture |
| 534 // allocated (or NULL on error). | 534 // allocated (or nullptr on error). |
| 535 GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID, | 535 GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID, |
| 536 const SkIRect& clipSpaceIBounds, | 536 const SkIRect& clipSpaceIBounds, |
| 537 bool willUpload) { | 537 bool willUpload) { |
| 538 // Since we are setting up the cache we should free up the | 538 // Since we are setting up the cache we should free up the |
| 539 // currently cached mask so it can be reused. | 539 // currently cached mask so it can be reused. |
| 540 fAACache.reset(); | 540 fAACache.reset(); |
| 541 | 541 |
| 542 GrSurfaceDesc desc; | 542 GrSurfaceDesc desc; |
| 543 desc.fFlags = willUpload ? kNone_GrSurfaceFlags : kRenderTarget_GrSurfaceFla
g; | 543 desc.fFlags = willUpload ? kNone_GrSurfaceFlags : kRenderTarget_GrSurfaceFla
g; |
| 544 desc.fWidth = clipSpaceIBounds.width(); | 544 desc.fWidth = clipSpaceIBounds.width(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 565 | 565 |
| 566 // First, check for cached texture | 566 // First, check for cached texture |
| 567 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); | 567 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); |
| 568 if (result) { | 568 if (result) { |
| 569 fCurrClipMaskType = kAlpha_ClipMaskType; | 569 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 570 return result; | 570 return result; |
| 571 } | 571 } |
| 572 | 572 |
| 573 // There's no texture in the cache. Let's try to allocate it then. | 573 // There's no texture in the cache. Let's try to allocate it then. |
| 574 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); | 574 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); |
| 575 if (NULL == result) { | 575 if (nullptr == result) { |
| 576 fAACache.reset(); | 576 fAACache.reset(); |
| 577 return NULL; | 577 return nullptr; |
| 578 } | 578 } |
| 579 | 579 |
| 580 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 580 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
| 581 // space. | 581 // space. |
| 582 SkMatrix translate; | 582 SkMatrix translate; |
| 583 translate.setTranslate(clipToMaskOffset); | 583 translate.setTranslate(clipToMaskOffset); |
| 584 | 584 |
| 585 // The texture may be larger than necessary, this rect represents the part o
f the texture | 585 // The texture may be larger than necessary, this rect represents the part o
f the texture |
| 586 // we populate with a rasterization of the clip. | 586 // we populate with a rasterization of the clip. |
| 587 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 587 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 602 | 602 |
| 603 // walk through each clip element and perform its set op | 603 // walk through each clip element and perform its set op |
| 604 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { | 604 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { |
| 605 const Element* element = iter.get(); | 605 const Element* element = iter.get(); |
| 606 SkRegion::Op op = element->getOp(); | 606 SkRegion::Op op = element->getOp(); |
| 607 bool invert = element->isInverseFilled(); | 607 bool invert = element->isInverseFilled(); |
| 608 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 608 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
| 609 GrPipelineBuilder pipelineBuilder; | 609 GrPipelineBuilder pipelineBuilder; |
| 610 | 610 |
| 611 pipelineBuilder.setClip(clip); | 611 pipelineBuilder.setClip(clip); |
| 612 GrPathRenderer* pr = NULL; | 612 GrPathRenderer* pr = nullptr; |
| 613 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, res
ult, &pr, element); | 613 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, res
ult, &pr, element); |
| 614 GrTexture* dst; | 614 GrTexture* dst; |
| 615 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 615 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
| 616 // mask buffer can be substantially larger than the actually clip st
ack element. We | 616 // mask buffer can be substantially larger than the actually clip st
ack element. We |
| 617 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 617 // touch the minimum number of pixels necessary and use decal mode t
o combine it with |
| 618 // the accumulator. | 618 // the accumulator. |
| 619 SkIRect maskSpaceElementIBounds; | 619 SkIRect maskSpaceElementIBounds; |
| 620 | 620 |
| 621 if (useTemp) { | 621 if (useTemp) { |
| 622 if (invert) { | 622 if (invert) { |
| 623 maskSpaceElementIBounds = maskSpaceIBounds; | 623 maskSpaceElementIBounds = maskSpaceIBounds; |
| 624 } else { | 624 } else { |
| 625 SkRect elementBounds = element->getBounds(); | 625 SkRect elementBounds = element->getBounds(); |
| 626 elementBounds.offset(clipToMaskOffset); | 626 elementBounds.offset(clipToMaskOffset); |
| 627 elementBounds.roundOut(&maskSpaceElementIBounds); | 627 elementBounds.roundOut(&maskSpaceElementIBounds); |
| 628 } | 628 } |
| 629 | 629 |
| 630 if (!temp) { | 630 if (!temp) { |
| 631 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, | 631 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, |
| 632 maskSpaceIBounds.fBottom)); | 632 maskSpaceIBounds.fBottom)); |
| 633 if (!temp) { | 633 if (!temp) { |
| 634 fAACache.reset(); | 634 fAACache.reset(); |
| 635 return NULL; | 635 return nullptr; |
| 636 } | 636 } |
| 637 } | 637 } |
| 638 dst = temp; | 638 dst = temp; |
| 639 // clear the temp target and set blend to replace | 639 // clear the temp target and set blend to replace |
| 640 fClipTarget->clear(&maskSpaceElementIBounds, | 640 fClipTarget->clear(&maskSpaceElementIBounds, |
| 641 invert ? 0xffffffff : 0x00000000, | 641 invert ? 0xffffffff : 0x00000000, |
| 642 true, | 642 true, |
| 643 dst->asRenderTarget()); | 643 dst->asRenderTarget()); |
| 644 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); | 644 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin
eBuilder); |
| 645 } else { | 645 } else { |
| 646 // draw directly into the result with the stencil set to make th
e pixels affected | 646 // draw directly into the result with the stencil set to make th
e pixels affected |
| 647 // by the clip shape be non-zero. | 647 // by the clip shape be non-zero. |
| 648 dst = result; | 648 dst = result; |
| 649 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, | 649 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, |
| 650 kReplace_StencilOp, | 650 kReplace_StencilOp, |
| 651 kReplace_StencilOp, | 651 kReplace_StencilOp, |
| 652 kAlways_StencilFunc, | 652 kAlways_StencilFunc, |
| 653 0xffff, | 653 0xffff, |
| 654 0xffff, | 654 0xffff, |
| 655 0xffff); | 655 0xffff); |
| 656 pipelineBuilder.setStencil(kStencilInElement); | 656 pipelineBuilder.setStencil(kStencilInElement); |
| 657 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); | 657 set_coverage_drawing_xpf(op, invert, &pipelineBuilder); |
| 658 } | 658 } |
| 659 | 659 |
| 660 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { | 660 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr
)) { |
| 661 fAACache.reset(); | 661 fAACache.reset(); |
| 662 return NULL; | 662 return nullptr; |
| 663 } | 663 } |
| 664 | 664 |
| 665 if (useTemp) { | 665 if (useTemp) { |
| 666 GrPipelineBuilder backgroundPipelineBuilder; | 666 GrPipelineBuilder backgroundPipelineBuilder; |
| 667 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget
()); | 667 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget
()); |
| 668 | 668 |
| 669 // Now draw into the accumulator using the real operation and th
e temp buffer as a | 669 // Now draw into the accumulator using the real operation and th
e temp buffer as a |
| 670 // texture | 670 // texture |
| 671 this->mergeMask(&backgroundPipelineBuilder, | 671 this->mergeMask(&backgroundPipelineBuilder, |
| 672 result, | 672 result, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, | 713 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, |
| 714 int32_t elementsGenID, | 714 int32_t elementsGenID, |
| 715 GrReducedClip::InitialState initia
lState, | 715 GrReducedClip::InitialState initia
lState, |
| 716 const GrReducedClip::ElementList&
elements, | 716 const GrReducedClip::ElementList&
elements, |
| 717 const SkIRect& clipSpaceIBounds, | 717 const SkIRect& clipSpaceIBounds, |
| 718 const SkIPoint& clipSpaceToStencil
Offset) { | 718 const SkIPoint& clipSpaceToStencil
Offset) { |
| 719 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 719 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 720 SkASSERT(rt); | 720 SkASSERT(rt); |
| 721 | 721 |
| 722 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); | 722 GrStencilAttachment* stencilAttachment = rt->renderTargetPriv().attachStenci
lAttachment(); |
| 723 if (NULL == stencilAttachment) { | 723 if (nullptr == stencilAttachment) { |
| 724 return false; | 724 return false; |
| 725 } | 725 } |
| 726 | 726 |
| 727 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { | 727 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS
paceToStencilOffset)) { |
| 728 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); | 728 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac
eToStencilOffset); |
| 729 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. | 729 // Set the matrix so that rendered clip elements are transformed from cl
ip to stencil space. |
| 730 SkVector translate = { | 730 SkVector translate = { |
| 731 SkIntToScalar(clipSpaceToStencilOffset.fX), | 731 SkIntToScalar(clipSpaceToStencilOffset.fX), |
| 732 SkIntToScalar(clipSpaceToStencilOffset.fY) | 732 SkIntToScalar(clipSpaceToStencilOffset.fY) |
| 733 }; | 733 }; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 // enabled at bottom of loop | 767 // enabled at bottom of loop |
| 768 fClipMode = kIgnoreClip_StencilClipMode; | 768 fClipMode = kIgnoreClip_StencilClipMode; |
| 769 | 769 |
| 770 // This will be used to determine whether the clip shape can be rend
ered into the | 770 // This will be used to determine whether the clip shape can be rend
ered into the |
| 771 // stencil with arbitrary stencil settings. | 771 // stencil with arbitrary stencil settings. |
| 772 GrPathRenderer::StencilSupport stencilSupport; | 772 GrPathRenderer::StencilSupport stencilSupport; |
| 773 | 773 |
| 774 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); | 774 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); |
| 775 SkRegion::Op op = element->getOp(); | 775 SkRegion::Op op = element->getOp(); |
| 776 | 776 |
| 777 GrPathRenderer* pr = NULL; | 777 GrPathRenderer* pr = nullptr; |
| 778 SkPath clipPath; | 778 SkPath clipPath; |
| 779 if (Element::kRect_Type == element->getType()) { | 779 if (Element::kRect_Type == element->getType()) { |
| 780 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 780 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 781 fillInverted = false; | 781 fillInverted = false; |
| 782 } else { | 782 } else { |
| 783 element->asPath(&clipPath); | 783 element->asPath(&clipPath); |
| 784 fillInverted = clipPath.isInverseFillType(); | 784 fillInverted = clipPath.isInverseFillType(); |
| 785 if (fillInverted) { | 785 if (fillInverted) { |
| 786 clipPath.toggleInverseFillType(); | 786 clipPath.toggleInverseFillType(); |
| 787 } | 787 } |
| 788 pr = this->getContext()->getPathRenderer(fClipTarget, | 788 pr = this->getContext()->getPathRenderer(fClipTarget, |
| 789 &pipelineBuilder, | 789 &pipelineBuilder, |
| 790 viewMatrix, | 790 viewMatrix, |
| 791 clipPath, | 791 clipPath, |
| 792 stroke, | 792 stroke, |
| 793 false, | 793 false, |
| 794 GrPathRendererChain::kS
tencilOnly_DrawType, | 794 GrPathRendererChain::kS
tencilOnly_DrawType, |
| 795 &stencilSupport); | 795 &stencilSupport); |
| 796 if (NULL == pr) { | 796 if (nullptr == pr) { |
| 797 return false; | 797 return false; |
| 798 } | 798 } |
| 799 } | 799 } |
| 800 | 800 |
| 801 int passes; | 801 int passes; |
| 802 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; | 802 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; |
| 803 | 803 |
| 804 bool canRenderDirectToStencil = | 804 bool canRenderDirectToStencil = |
| 805 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; | 805 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; |
| 806 bool canDrawDirectToClip; // Given the renderer, the element, | 806 bool canDrawDirectToClip; // Given the renderer, the element, |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1128 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
| 1129 } else { | 1129 } else { |
| 1130 SkPath path; | 1130 SkPath path; |
| 1131 element->asPath(&path); | 1131 element->asPath(&path); |
| 1132 helper.draw(path, stroke, op, element->isAA(), 0xFF); | 1132 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
| 1133 } | 1133 } |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 // Allocate clip mask texture | 1136 // Allocate clip mask texture |
| 1137 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true); | 1137 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true); |
| 1138 if (NULL == result) { | 1138 if (nullptr == result) { |
| 1139 fAACache.reset(); | 1139 fAACache.reset(); |
| 1140 return NULL; | 1140 return nullptr; |
| 1141 } | 1141 } |
| 1142 helper.toTexture(result); | 1142 helper.toTexture(result); |
| 1143 | 1143 |
| 1144 fCurrClipMaskType = kAlpha_ClipMaskType; | 1144 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 1145 return result; | 1145 return result; |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 //////////////////////////////////////////////////////////////////////////////// | 1148 //////////////////////////////////////////////////////////////////////////////// |
| 1149 void GrClipMaskManager::purgeResources() { | 1149 void GrClipMaskManager::purgeResources() { |
| 1150 fAACache.purgeResources(); | 1150 fAACache.purgeResources(); |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, | 1153 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc
ilAttachment, |
| 1154 GrStencilSettings* settings) { | 1154 GrStencilSettings* settings) { |
| 1155 if (stencilAttachment) { | 1155 if (stencilAttachment) { |
| 1156 int stencilBits = stencilAttachment->bits(); | 1156 int stencilBits = stencilAttachment->bits(); |
| 1157 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1157 this->adjustStencilParams(settings, fClipMode, stencilBits); |
| 1158 } | 1158 } |
| 1159 } | 1159 } |
| OLD | NEW |