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

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

Issue 1424853002: Disable gpu-side clip mask merging in the clip mask manager (Closed) Base URL: https://skia.googlesource.com/skia.git@mdb-cosmetic
Patch Set: Add comment linking to bug 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') | no next file » | 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 } 47 }
48 48
49 // Does the path in 'element' require SW rendering? If so, return true (and, 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 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). 51 // 'prOut' to the non-SW path renderer that will do the job).
52 static bool path_needs_SW_renderer(GrContext* context, 52 static bool path_needs_SW_renderer(GrContext* context,
53 const GrPipelineBuilder& pipelineBuilder, 53 const GrPipelineBuilder& pipelineBuilder,
54 const SkMatrix& viewMatrix, 54 const SkMatrix& viewMatrix,
55 const Element* element, 55 const Element* element,
56 GrPathRenderer** prOut, 56 GrPathRenderer** prOut,
57 bool tryStencilFirst) { 57 bool needsStencil) {
58 if (Element::kRect_Type == element->getType()) { 58 if (Element::kRect_Type == element->getType()) {
59 // rects can always be drawn directly w/o using the software path 59 // rects can always be drawn directly w/o using the software path
60 // TODO: skip rrects once we're drawing them directly. 60 // TODO: skip rrects once we're drawing them directly.
61 if (prOut) { 61 if (prOut) {
62 *prOut = nullptr; 62 *prOut = nullptr;
63 } 63 }
64 return false; 64 return false;
65 } else { 65 } else {
66 // We shouldn't get here with an empty clip element. 66 // We shouldn't get here with an empty clip element.
67 SkASSERT(Element::kEmpty_Type != element->getType()); 67 SkASSERT(Element::kEmpty_Type != element->getType());
68 68
69 // the gpu alpha mask will draw the inverse paths as non-inverse to a te mp buffer 69 // the gpu alpha mask will draw the inverse paths as non-inverse to a te mp buffer
70 SkPath path; 70 SkPath path;
71 element->asPath(&path); 71 element->asPath(&path);
72 if (path.isInverseFillType()) { 72 if (path.isInverseFillType()) {
73 path.toggleInverseFillType(); 73 path.toggleInverseFillType();
74 } 74 }
75 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle); 75 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
76 76
77 GrPathRendererChain::DrawType type; 77 GrPathRendererChain::DrawType type;
78 78
79 if (tryStencilFirst) { 79 if (needsStencil) {
80 type = element->isAA() 80 type = element->isAA()
81 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra wType 81 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra wType
82 : GrPathRendererChain::kStencilAndColor_DrawType; 82 : GrPathRendererChain::kStencilAndColor_DrawType;
83 } else { 83 } else {
84 type = element->isAA() 84 type = element->isAA()
85 ? GrPathRendererChain::kColorAntiAlias_DrawType 85 ? GrPathRendererChain::kColorAntiAlias_DrawType
86 : GrPathRendererChain::kColor_DrawType; 86 : GrPathRendererChain::kColor_DrawType;
87 } 87 }
88 88
89 // the 'false' parameter disallows use of the SW path renderer 89 // the 'false' parameter disallows use of the SW path renderer
90 GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatri x, path, 90 GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatri x, path,
91 stroke, false, type); 91 stroke, false, type);
92 if (tryStencilFirst && !pr) {
93 // If the path can't be stenciled, createAlphaClipMask falls back to color rendering
94 // it into a temporary buffer. If that fails then SW is truly requir ed.
95 type = element->isAA()
96 ? GrPathRendererChain::kColorAntiAlias_DrawType
97 : GrPathRendererChain::kColor_DrawType;
98
99 pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path, str oke, false, type);
100 }
101
102 if (prOut) { 92 if (prOut) {
103 *prOut = pr; 93 *prOut = pr;
104 } 94 }
105 return SkToBool(!pr); 95 return SkToBool(!pr);
106 } 96 }
107 } 97 }
108 98
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
101 // also returned.
102 static bool can_stencil_and_draw_element(GrContext* context,
103 GrPipelineBuilder* pipelineBuilder,
104 GrTexture* texture,
105 const SkMatrix& viewMatrix,
106 const SkClipStack::Element* element,
107 GrPathRenderer** pr) {
108 pipelineBuilder->setRenderTarget(texture->asRenderTarget());
109
110 static const bool kNeedsStencil = true;
111 return !path_needs_SW_renderer(context,
112 *pipelineBuilder,
113 viewMatrix,
114 element,
115 pr,
116 kNeedsStencil);
117 }
118
109 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) 119 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
110 : fDrawTarget(drawTarget) 120 : fDrawTarget(drawTarget)
111 , fClipMode(kIgnoreClip_StencilClipMode) { 121 , fClipMode(kIgnoreClip_StencilClipMode) {
112 } 122 }
113 123
114 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); } 124 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); }
115 125
116 /* 126 /*
117 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 127 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
118 * will be used on any element. If so, it returns true to indicate that the 128 * will be used on any element. If so, it returns true to indicate that the
119 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 129 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
120 */ 130 */
121 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, 131 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
122 const SkVector& clipToMaskOffset, 132 const SkVector& clipToMaskOffset,
123 const GrReducedClip::ElementList& elements ) { 133 const GrReducedClip::ElementList& elements ) {
124 // TODO: generalize this function so that when 134 // TODO: generalize this function so that when
125 // a clip gets complex enough it can just be done in SW regardless 135 // a clip gets complex enough it can just be done in SW regardless
126 // of whether it would invoke the GrSoftwarePathRenderer. 136 // of whether it would invoke the GrSoftwarePathRenderer.
127 137
128 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 138 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
129 // space. 139 // space.
130 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 140 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
131 141
132 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 142 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
133 const Element* element = iter.get(); 143 const Element* element = iter.get();
134 144
135 SkRegion::Op op = element->getOp(); 145 SkRegion::Op op = element->getOp();
136 bool invert = element->isInverseFilled(); 146 bool invert = element->isInverseFilled();
137 bool tryStencilFirst = invert || 147 bool needsStencil = invert ||
138 SkRegion::kIntersect_Op == op || 148 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op;
139 SkRegion::kReverseDifference_Op == op;
140 149
141 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translat e, 150 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translat e,
142 element, nullptr, tryStencilFirst)) { 151 element, nullptr, needsStencil)) {
143 return true; 152 return true;
144 } 153 }
145 } 154 }
146 return false; 155 return false;
147 } 156 }
148 157
149 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 158 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements,
150 bool abortIfAA, 159 bool abortIfAA,
151 SkVector& clipToRTOffset, 160 SkVector& clipToRTOffset,
152 const SkRect* drawBounds, 161 const SkRect* drawBounds,
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 args.fPath = &path; 476 args.fPath = &path;
468 args.fStroke = &stroke; 477 args.fStroke = &stroke;
469 args.fAntiAlias = element->isAA(); 478 args.fAntiAlias = element->isAA();
470 pr->drawPath(args); 479 pr->drawPath(args);
471 break; 480 break;
472 } 481 }
473 } 482 }
474 return true; 483 return true;
475 } 484 }
476 485
477 bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuil der,
478 GrTexture* target,
479 GrPathRenderer** pr,
480 const SkClipStack::Element* ele ment) {
481 pipelineBuilder->setRenderTarget(target->asRenderTarget());
482
483 if (Element::kRect_Type == element->getType()) {
484 return true;
485 } else {
486 // We shouldn't get here with an empty clip element.
487 SkASSERT(Element::kEmpty_Type != element->getType());
488 SkPath path;
489 element->asPath(&path);
490 if (path.isInverseFillType()) {
491 path.toggleInverseFillType();
492 }
493 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
494 GrPathRendererChain::DrawType type = element->isAA() ?
495 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
496 GrPathRendererChain::kStencilAndColor_DrawType;
497 *pr = this->getContext()->getPathRenderer(*pipelineBuilder, SkMatrix::I( ), path,
498 stroke, false, type);
499 return SkToBool(*pr);
500 }
501 }
502
503 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder, 486 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder,
504 GrTexture* dstMask, 487 GrTexture* dstMask,
505 GrTexture* srcMask, 488 GrTexture* srcMask,
506 SkRegion::Op op, 489 SkRegion::Op op,
507 const SkIRect& dstBound, 490 const SkIRect& dstBound,
508 const SkIRect& srcBound) { 491 const SkIRect& srcBound) {
509 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget()); 492 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget());
510 493
511 // We want to invert the coverage here 494 // We want to invert the coverage here
512 set_coverage_drawing_xpf(op, false, pipelineBuilder); 495 set_coverage_drawing_xpf(op, false, pipelineBuilder);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 // walk through each clip element and perform its set op 601 // walk through each clip element and perform its set op
619 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 602 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
620 const Element* element = iter.get(); 603 const Element* element = iter.get();
621 SkRegion::Op op = element->getOp(); 604 SkRegion::Op op = element->getOp();
622 bool invert = element->isInverseFilled(); 605 bool invert = element->isInverseFilled();
623 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 606 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
624 GrPipelineBuilder pipelineBuilder; 607 GrPipelineBuilder pipelineBuilder;
625 608
626 pipelineBuilder.setClip(clip); 609 pipelineBuilder.setClip(clip);
627 GrPathRenderer* pr = nullptr; 610 GrPathRenderer* pr = nullptr;
628 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, tex ture, &pr, element); 611 bool useTemp = !can_stencil_and_draw_element(this->getContext(), &pi pelineBuilder,
612 texture, translate, ele ment, &pr);
613
614 // useSWOnlyPath should now filter out all cases where gpu-side mask merging is
615 // performed. See skbug.com/4519 for rationale and details.
616 SkASSERT(!useTemp);
617
629 GrTexture* dst; 618 GrTexture* dst;
630 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 619 // This is the bounds of the clip element in the space of the alpha- mask. The temporary
631 // mask buffer can be substantially larger than the actually clip st ack element. We 620 // mask buffer can be substantially larger than the actually clip st ack element. We
632 // touch the minimum number of pixels necessary and use decal mode t o combine it with 621 // touch the minimum number of pixels necessary and use decal mode t o combine it with
633 // the accumulator. 622 // the accumulator.
634 SkIRect maskSpaceElementIBounds; 623 SkIRect maskSpaceElementIBounds;
635 624
636 if (useTemp) { 625 if (useTemp) {
637 if (invert) { 626 if (invert) {
638 maskSpaceElementIBounds = maskSpaceIBounds; 627 maskSpaceElementIBounds = maskSpaceIBounds;
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 1143
1155 //////////////////////////////////////////////////////////////////////////////// 1144 ////////////////////////////////////////////////////////////////////////////////
1156 1145
1157 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, 1146 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1158 GrStencilSettings* settings) { 1147 GrStencilSettings* settings) {
1159 if (stencilAttachment) { 1148 if (stencilAttachment) {
1160 int stencilBits = stencilAttachment->bits(); 1149 int stencilBits = stencilAttachment->bits();
1161 this->adjustStencilParams(settings, fClipMode, stencilBits); 1150 this->adjustStencilParams(settings, fClipMode, stencilBits);
1162 } 1151 }
1163 } 1152 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698