Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: src/gpu/GrClipMaskManager.cpp

Issue 1426443008: Revert of Fix ClipMaskManager's SW-fallback logic (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
39 39
40 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); 40 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
41 return GrTextureDomainEffect::Create(result, 41 return GrTextureDomainEffect::Create(result,
42 mat, 42 mat,
43 GrTextureDomain::MakeTexelDomain(result , domainTexels), 43 GrTextureDomain::MakeTexelDomain(result , domainTexels),
44 GrTextureDomain::kDecal_Mode, 44 GrTextureDomain::kDecal_Mode,
45 GrTextureParams::kNone_FilterMode, 45 GrTextureParams::kNone_FilterMode,
46 kDevice_GrCoordSet); 46 kDevice_GrCoordSet);
47 } 47 }
48 48
49 // Does the path in 'element' require SW rendering? If so, return true (and,
50 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
51 // 'prOut' to the non-SW path renderer that will do the job).
52 static bool path_needs_SW_renderer(GrContext* context, 49 static bool path_needs_SW_renderer(GrContext* context,
53 const GrPipelineBuilder& pipelineBuilder, 50 const GrPipelineBuilder& pipelineBuilder,
54 const SkMatrix& viewMatrix, 51 const SkMatrix& viewMatrix,
55 const Element* element, 52 const SkPath& origPath,
56 GrPathRenderer** prOut, 53 const GrStrokeInfo& stroke,
57 bool needsStencil) { 54 bool doAA) {
58 if (Element::kRect_Type == element->getType()) { 55 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer
59 // rects can always be drawn directly w/o using the software path 56 SkTCopyOnFirstWrite<SkPath> path(origPath);
60 // TODO: skip rrects once we're drawing them directly. 57 if (path->isInverseFillType()) {
61 return false; 58 path.writable()->toggleInverseFillType();
62 } else { 59 }
63 // We shouldn't get here with an empty clip element. 60 // last (false) parameter disallows use of the SW path renderer
64 SkASSERT(Element::kEmpty_Type != element->getType()); 61 GrPathRendererChain::DrawType type = doAA ?
62 GrPathRendererChain::kColorAntiAlias_Dr awType :
63 GrPathRendererChain::kColor_DrawType;
65 64
66 // the gpu alpha mask will draw the inverse paths as non-inverse to a te mp buffer 65 return nullptr == context->getPathRenderer(&pipelineBuilder, viewMatrix, *pa th, stroke,
67 SkPath path; 66 false, type);
68 element->asPath(&path);
69 if (path.isInverseFillType()) {
70 path.toggleInverseFillType();
71 }
72 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
73
74 GrPathRendererChain::DrawType type;
75
76 if (needsStencil) {
77 type = element->isAA()
78 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra wType
79 : GrPathRendererChain::kStencilAndColor_DrawType;
80 } else {
81 type = element->isAA()
82 ? GrPathRendererChain::kColorAntiAlias_DrawType
83 : GrPathRendererChain::kColor_DrawType;
84 }
85
86 // the 'false' parameter disallows use of the SW path renderer
87 GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatri x, path,
88 stroke, false, type);
89 if (prOut) {
90 *prOut = pr;
91 }
92 return SkToBool(!pr);
93 }
94 }
95
96 // Determines whether it is possible to draw the element to both the stencil buf fer and the
97 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is
98 // also returned.
99 static bool can_stencil_and_draw_element(GrContext* context,
100 GrPipelineBuilder* pipelineBuilder,
101 GrTexture* texture,
102 const SkMatrix& viewMatrix,
103 const SkClipStack::Element* element,
104 GrPathRenderer** pr) {
105 pipelineBuilder->setRenderTarget(texture->asRenderTarget());
106
107 static const bool kNeedsStencil = true;
108 return !path_needs_SW_renderer(context,
109 *pipelineBuilder,
110 viewMatrix,
111 element,
112 pr,
113 kNeedsStencil);
114 } 67 }
115 68
116 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) 69 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
117 : fDrawTarget(drawTarget) 70 : fDrawTarget(drawTarget)
118 , fClipMode(kIgnoreClip_StencilClipMode) { 71 , fClipMode(kIgnoreClip_StencilClipMode) {
119 } 72 }
120 73
121 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); } 74 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); }
122 75
123 /* 76 /*
124 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 77 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
125 * will be used on any element. If so, it returns true to indicate that the 78 * will be used on any element. If so, it returns true to indicate that the
126 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 79 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
127 */ 80 */
128 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, 81 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
129 const SkVector& clipToMaskOffset, 82 const SkVector& clipToMaskOffset,
130 const GrReducedClip::ElementList& elements ) { 83 const GrReducedClip::ElementList& elements ) {
131 // TODO: generalize this function so that when 84 // TODO: generalize this function so that when
132 // a clip gets complex enough it can just be done in SW regardless 85 // a clip gets complex enough it can just be done in SW regardless
133 // of whether it would invoke the GrSoftwarePathRenderer. 86 // of whether it would invoke the GrSoftwarePathRenderer.
87 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
134 88
135 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 89 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
136 // space. 90 // space.
137 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 91 SkMatrix translate;
92 translate.setTranslate(clipToMaskOffset);
138 93
139 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 94 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
140 const Element* element = iter.get(); 95 const Element* element = iter.get();
141 96 // rects can always be drawn directly w/o using the software path
142 SkRegion::Op op = element->getOp(); 97 // Skip rrects once we're drawing them directly.
143 bool invert = element->isInverseFilled(); 98 if (Element::kRect_Type != element->getType()) {
144 bool needsStencil = invert || 99 SkPath path;
145 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op; 100 element->asPath(&path);
146 101 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, tran slate,
147 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translat e, 102 path, stroke, element->isAA())) {
148 element, nullptr, needsStencil)) { 103 return true;
149 return true; 104 }
150 } 105 }
151 } 106 }
152 return false; 107 return false;
153 } 108 }
154 109
155 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 110 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements,
156 bool abortIfAA, 111 bool abortIfAA,
157 SkVector& clipToRTOffset, 112 SkVector& clipToRTOffset,
158 const SkRect* drawBounds, 113 const SkRect* drawBounds,
159 const GrFragmentProcessor** res ultFP) { 114 const GrFragmentProcessor** res ultFP) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 element->asPath(&path); 405 element->asPath(&path);
451 path.setIsVolatile(true); 406 path.setIsVolatile(true);
452 if (path.isInverseFillType()) { 407 if (path.isInverseFillType()) {
453 path.toggleInverseFillType(); 408 path.toggleInverseFillType();
454 } 409 }
455 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); 410 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
456 if (nullptr == pr) { 411 if (nullptr == pr) {
457 GrPathRendererChain::DrawType type; 412 GrPathRendererChain::DrawType type;
458 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : 413 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
459 GrPathRendererChain::kColor_DrawType; 414 GrPathRendererChain::kColor_DrawType;
460 pr = this->getContext()->getPathRenderer(*pipelineBuilder, viewM atrix, 415 pr = this->getContext()->getPathRenderer(pipelineBuilder, viewMa trix,
461 path, stroke, false, ty pe); 416 path, stroke, false, ty pe);
462 } 417 }
463 if (nullptr == pr) { 418 if (nullptr == pr) {
464 return false; 419 return false;
465 } 420 }
466 GrPathRenderer::DrawPathArgs args; 421 GrPathRenderer::DrawPathArgs args;
467 args.fTarget = fDrawTarget; 422 args.fTarget = fDrawTarget;
468 args.fResourceProvider = this->getContext()->resourceProvider(); 423 args.fResourceProvider = this->getContext()->resourceProvider();
469 args.fPipelineBuilder = pipelineBuilder; 424 args.fPipelineBuilder = pipelineBuilder;
470 args.fColor = color; 425 args.fColor = color;
471 args.fViewMatrix = &viewMatrix; 426 args.fViewMatrix = &viewMatrix;
472 args.fPath = &path; 427 args.fPath = &path;
473 args.fStroke = &stroke; 428 args.fStroke = &stroke;
474 args.fAntiAlias = element->isAA(); 429 args.fAntiAlias = element->isAA();
475 pr->drawPath(args); 430 pr->drawPath(args);
476 break; 431 break;
477 } 432 }
478 } 433 }
479 return true; 434 return true;
480 } 435 }
481 436
437 bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuil der,
438 GrTexture* target,
439 GrPathRenderer** pr,
440 const SkClipStack::Element* ele ment) {
441 pipelineBuilder->setRenderTarget(target->asRenderTarget());
442
443 if (Element::kRect_Type == element->getType()) {
444 return true;
445 } else {
446 // We shouldn't get here with an empty clip element.
447 SkASSERT(Element::kEmpty_Type != element->getType());
448 SkPath path;
449 element->asPath(&path);
450 if (path.isInverseFillType()) {
451 path.toggleInverseFillType();
452 }
453 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
454 GrPathRendererChain::DrawType type = element->isAA() ?
455 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
456 GrPathRendererChain::kStencilAndColor_DrawType;
457 *pr = this->getContext()->getPathRenderer(pipelineBuilder, SkMatrix::I() , path,
458 stroke, false, type);
459 return SkToBool(*pr);
460 }
461 }
462
482 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, 463 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder,
483 GrTexture* dstMask, 464 GrTexture* dstMask,
484 GrTexture* srcMask, 465 GrTexture* srcMask,
485 SkRegion::Op op, 466 SkRegion::Op op,
486 const SkIRect& dstBound, 467 const SkIRect& dstBound,
487 const SkIRect& srcBound) { 468 const SkIRect& srcBound) {
488 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); 469 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget());
489 470
490 // We want to invert the coverage here 471 // We want to invert the coverage here
491 set_coverage_drawing_xpf(op, false, pipelineBuilder); 472 set_coverage_drawing_xpf(op, false, pipelineBuilder);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 SkAutoTUnref<GrTexture> texture(this->createCachedMask( 548 SkAutoTUnref<GrTexture> texture(this->createCachedMask(
568 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); 549 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true));
569 550
570 // There's no texture in the cache. Let's try to allocate it then. 551 // There's no texture in the cache. Let's try to allocate it then.
571 if (!texture) { 552 if (!texture) {
572 return nullptr; 553 return nullptr;
573 } 554 }
574 555
575 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 556 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
576 // space. 557 // space.
577 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 558 SkMatrix translate;
559 translate.setTranslate(clipToMaskOffset);
578 560
579 // The texture may be larger than necessary, this rect represents the part o f the texture 561 // The texture may be larger than necessary, this rect represents the part o f the texture
580 // we populate with a rasterization of the clip. 562 // we populate with a rasterization of the clip.
581 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 563 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
582 564
583 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 565 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
584 // clear the part that we care about. 566 // clear the part that we care about.
585 fDrawTarget->clear(&maskSpaceIBounds, 567 fDrawTarget->clear(&maskSpaceIBounds,
586 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000, 568 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000,
587 true, 569 true,
588 texture->asRenderTarget()); 570 texture->asRenderTarget());
589 571
590 // When we use the stencil in the below loop it is important to have this cl ip installed. 572 // When we use the stencil in the below loop it is important to have this cl ip installed.
591 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 573 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
592 // pass must not set values outside of this bounds or stencil values outside the rect won't be 574 // pass must not set values outside of this bounds or stencil values outside the rect won't be
593 // cleared. 575 // cleared.
594 GrClip clip(maskSpaceIBounds); 576 GrClip clip(maskSpaceIBounds);
595 SkAutoTUnref<GrTexture> temp; 577 SkAutoTUnref<GrTexture> temp;
596 578
597 // walk through each clip element and perform its set op 579 // walk through each clip element and perform its set op
598 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 580 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
599 const Element* element = iter.get(); 581 const Element* element = iter.get();
600 SkRegion::Op op = element->getOp(); 582 SkRegion::Op op = element->getOp();
601 bool invert = element->isInverseFilled(); 583 bool invert = element->isInverseFilled();
602 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 584 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
603 GrPipelineBuilder pipelineBuilder; 585 GrPipelineBuilder pipelineBuilder;
604 586
605 pipelineBuilder.setClip(clip); 587 pipelineBuilder.setClip(clip);
606 GrPathRenderer* pr = nullptr; 588 GrPathRenderer* pr = nullptr;
607 bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pi pelineBuilder, 589 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, tex ture, &pr, element);
608 texture, translate, ele ment, &pr);
609 GrTexture* dst; 590 GrTexture* dst;
610 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 591 // This is the bounds of the clip element in the space of the alpha- mask. The temporary
611 // mask buffer can be substantially larger than the actually clip st ack element. We 592 // mask buffer can be substantially larger than the actually clip st ack element. We
612 // touch the minimum number of pixels necessary and use decal mode t o combine it with 593 // touch the minimum number of pixels necessary and use decal mode t o combine it with
613 // the accumulator. 594 // the accumulator.
614 SkIRect maskSpaceElementIBounds; 595 SkIRect maskSpaceElementIBounds;
615 596
616 SkASSERT(!useTemp);
617
618 if (useTemp) { 597 if (useTemp) {
619 if (invert) { 598 if (invert) {
620 maskSpaceElementIBounds = maskSpaceIBounds; 599 maskSpaceElementIBounds = maskSpaceIBounds;
621 } else { 600 } else {
622 SkRect elementBounds = element->getBounds(); 601 SkRect elementBounds = element->getBounds();
623 elementBounds.offset(clipToMaskOffset); 602 elementBounds.offset(clipToMaskOffset);
624 elementBounds.roundOut(&maskSpaceElementIBounds); 603 elementBounds.roundOut(&maskSpaceElementIBounds);
625 } 604 }
626 605
627 if (!temp) { 606 if (!temp) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 SkPath clipPath; 752 SkPath clipPath;
774 if (Element::kRect_Type == element->getType()) { 753 if (Element::kRect_Type == element->getType()) {
775 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 754 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
776 fillInverted = false; 755 fillInverted = false;
777 } else { 756 } else {
778 element->asPath(&clipPath); 757 element->asPath(&clipPath);
779 fillInverted = clipPath.isInverseFillType(); 758 fillInverted = clipPath.isInverseFillType();
780 if (fillInverted) { 759 if (fillInverted) {
781 clipPath.toggleInverseFillType(); 760 clipPath.toggleInverseFillType();
782 } 761 }
783 pr = this->getContext()->getPathRenderer(pipelineBuilder, 762 pr = this->getContext()->getPathRenderer(&pipelineBuilder,
784 viewMatrix, 763 viewMatrix,
785 clipPath, 764 clipPath,
786 stroke, 765 stroke,
787 false, 766 false,
788 GrPathRendererChain::kS tencilOnly_DrawType, 767 GrPathRendererChain::kS tencilOnly_DrawType,
789 &stencilSupport); 768 &stencilSupport);
790 if (nullptr == pr) { 769 if (nullptr == pr) {
791 return false; 770 return false;
792 } 771 }
793 } 772 }
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1115
1137 //////////////////////////////////////////////////////////////////////////////// 1116 ////////////////////////////////////////////////////////////////////////////////
1138 1117
1139 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, 1118 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1140 GrStencilSettings* settings) { 1119 GrStencilSettings* settings) {
1141 if (stencilAttachment) { 1120 if (stencilAttachment) {
1142 int stencilBits = stencilAttachment->bits(); 1121 int stencilBits = stencilAttachment->bits();
1143 this->adjustStencilParams(settings, fClipMode, stencilBits); 1122 this->adjustStencilParams(settings, fClipMode, stencilBits);
1144 } 1123 }
1145 } 1124 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698