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

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

Issue 1412883005: Fix ClipMaskManager's SW-fallback logic (take 2) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up 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 | « no previous file | 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 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).
49 static bool path_needs_SW_renderer(GrContext* context, 52 static bool path_needs_SW_renderer(GrContext* context,
50 const GrPipelineBuilder& pipelineBuilder, 53 const GrPipelineBuilder& pipelineBuilder,
51 const SkMatrix& viewMatrix, 54 const SkMatrix& viewMatrix,
52 const SkPath& origPath, 55 const Element* element,
53 const GrStrokeInfo& stroke, 56 GrPathRenderer** prOut,
54 bool doAA) { 57 bool tryStencilFirst) {
55 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer 58 if (Element::kRect_Type == element->getType()) {
56 SkTCopyOnFirstWrite<SkPath> path(origPath); 59 // rects can always be drawn directly w/o using the software path
57 if (path->isInverseFillType()) { 60 // TODO: skip rrects once we're drawing them directly.
58 path.writable()->toggleInverseFillType(); 61 if (prOut) {
62 *prOut = nullptr;
63 }
64 return false;
65 } else {
66 // We shouldn't get here with an empty clip element.
67 SkASSERT(Element::kEmpty_Type != element->getType());
68
69 // the gpu alpha mask will draw the inverse paths as non-inverse to a te mp buffer
70 SkPath path;
71 element->asPath(&path);
72 if (path.isInverseFillType()) {
73 path.toggleInverseFillType();
74 }
75 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
76
77 GrPathRendererChain::DrawType type;
78
79 if (tryStencilFirst) {
80 type = element->isAA()
81 ? GrPathRendererChain::kStencilAndColorAntiAlias_Dra wType
82 : GrPathRendererChain::kStencilAndColor_DrawType;
83 } else {
84 type = element->isAA()
85 ? GrPathRendererChain::kColorAntiAlias_DrawType
86 : GrPathRendererChain::kColor_DrawType;
87 }
88
89 // the 'false' parameter disallows use of the SW path renderer
90 GrPathRenderer* pr = context->getPathRenderer(&pipelineBuilder, viewMatr ix, path,
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, st roke, false, type);
100 }
101
102 if (prOut) {
103 *prOut = pr;
104 }
105 return SkToBool(!pr);
59 } 106 }
60 // last (false) parameter disallows use of the SW path renderer
61 GrPathRendererChain::DrawType type = doAA ?
62 GrPathRendererChain::kColorAntiAlias_Dr awType :
63 GrPathRendererChain::kColor_DrawType;
64
65 return nullptr == context->getPathRenderer(&pipelineBuilder, viewMatrix, *pa th, stroke,
66 false, type);
67 } 107 }
68 108
69 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) 109 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
70 : fDrawTarget(drawTarget) 110 : fDrawTarget(drawTarget)
71 , fClipMode(kIgnoreClip_StencilClipMode) { 111 , fClipMode(kIgnoreClip_StencilClipMode) {
72 } 112 }
73 113
74 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); } 114 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); }
75 115
76 /* 116 /*
77 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 117 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
78 * will be used on any element. If so, it returns true to indicate that the 118 * will be used on any element. If so, it returns true to indicate that the
79 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 119 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
80 */ 120 */
81 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, 121 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder,
82 const SkVector& clipToMaskOffset, 122 const SkVector& clipToMaskOffset,
83 const GrReducedClip::ElementList& elements ) { 123 const GrReducedClip::ElementList& elements ) {
84 // TODO: generalize this function so that when 124 // TODO: generalize this function so that when
85 // a clip gets complex enough it can just be done in SW regardless 125 // a clip gets complex enough it can just be done in SW regardless
86 // of whether it would invoke the GrSoftwarePathRenderer. 126 // of whether it would invoke the GrSoftwarePathRenderer.
87 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
88 127
89 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 128 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
90 // space. 129 // space.
91 SkMatrix translate; 130 SkMatrix translate;
92 translate.setTranslate(clipToMaskOffset); 131 translate.setTranslate(clipToMaskOffset);
93 132
94 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 133 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
95 const Element* element = iter.get(); 134 const Element* element = iter.get();
96 // rects can always be drawn directly w/o using the software path 135
97 // Skip rrects once we're drawing them directly. 136 SkRegion::Op op = element->getOp();
98 if (Element::kRect_Type != element->getType()) { 137 bool invert = element->isInverseFilled();
99 SkPath path; 138 bool tryStencilFirst = invert ||
100 element->asPath(&path); 139 SkRegion::kIntersect_Op == op ||
101 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, tran slate, 140 SkRegion::kReverseDifference_Op == op;
102 path, stroke, element->isAA())) { 141
103 return true; 142 if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translat e,
104 } 143 element, nullptr, tryStencilFirst)) {
144 return true;
105 } 145 }
106 } 146 }
107 return false; 147 return false;
108 } 148 }
109 149
110 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 150 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements,
111 bool abortIfAA, 151 bool abortIfAA,
112 SkVector& clipToRTOffset, 152 SkVector& clipToRTOffset,
113 const SkRect* drawBounds, 153 const SkRect* drawBounds,
114 const GrFragmentProcessor** res ultFP) { 154 const GrFragmentProcessor** res ultFP) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 initialState, 358 initialState,
319 elements, 359 elements,
320 clipToMaskOffset, 360 clipToMaskOffset,
321 clipSpaceIBounds)); 361 clipSpaceIBounds));
322 } else { 362 } else {
323 result.reset(this->createAlphaClipMask(genID, 363 result.reset(this->createAlphaClipMask(genID,
324 initialState, 364 initialState,
325 elements, 365 elements,
326 clipToMaskOffset, 366 clipToMaskOffset,
327 clipSpaceIBounds)); 367 clipSpaceIBounds));
368 // If createAlphaClipMask fails it means useSWOnlyPath has a bug
369 SkASSERT(result);
328 } 370 }
329 371
330 if (result) { 372 if (result) {
331 // The mask's top left coord should be pinned to the rounded-out top left corner of 373 // The mask's top left coord should be pinned to the rounded-out top left corner of
332 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 374 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
333 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 375 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
334 rtSpaceMaskBounds.offset(-clip.origin()); 376 rtSpaceMaskBounds.offset(-clip.origin());
335 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds)); 377 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds));
336 this->setPipelineBuilderStencil(pipelineBuilder, ars); 378 this->setPipelineBuilderStencil(pipelineBuilder, ars);
337 return true; 379 return true;
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 1156
1115 //////////////////////////////////////////////////////////////////////////////// 1157 ////////////////////////////////////////////////////////////////////////////////
1116 1158
1117 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, 1159 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1118 GrStencilSettings* settings) { 1160 GrStencilSettings* settings) {
1119 if (stencilAttachment) { 1161 if (stencilAttachment) {
1120 int stencilBits = stencilAttachment->bits(); 1162 int stencilBits = stencilAttachment->bits();
1121 this->adjustStencilParams(settings, fClipMode, stencilBits); 1163 this->adjustStencilParams(settings, fClipMode, stencilBits);
1122 } 1164 }
1123 } 1165 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698