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 | 8 |
9 #include "GrStencilAndCoverPathRenderer.h" | 9 #include "GrStencilAndCoverPathRenderer.h" |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 } | 69 } |
70 | 70 |
71 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { | 71 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { |
72 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 72 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
73 "GrStencilAndCoverPathRenderer::onStencilPath"); | 73 "GrStencilAndCoverPathRenderer::onStencilPath"); |
74 SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled()); | 74 SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled()); |
75 SkPath path; | 75 SkPath path; |
76 args.fShape->asPath(&path); | 76 args.fShape->asPath(&path); |
77 | 77 |
78 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleF
ill())); | 78 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleF
ill())); |
79 args.fDrawContext->drawContextPriv().stencilPath(*args.fClip, nullptr, args.
fIsAA, | 79 args.fDrawContext->drawContextPriv().stencilPath(*args.fClip, args.fIsAA, *a
rgs.fViewMatrix, p); |
80 *args.fViewMatrix, p); | |
81 } | 80 } |
82 | 81 |
83 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { | 82 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { |
84 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 83 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
85 "GrStencilAndCoverPathRenderer::onDrawPath"); | 84 "GrStencilAndCoverPathRenderer::onDrawPath"); |
86 SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMu
ltisampled()); | 85 SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMu
ltisampled()); |
87 SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle()); | 86 SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle()); |
88 | 87 |
89 const SkMatrix& viewMatrix = *args.fViewMatrix; | 88 const SkMatrix& viewMatrix = *args.fViewMatrix; |
90 | 89 |
91 SkPath path; | 90 SkPath path; |
92 args.fShape->asPath(&path); | 91 args.fShape->asPath(&path); |
93 | 92 |
94 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, args.fShape->sty
le())); | 93 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, args.fShape->sty
le())); |
95 | 94 |
96 if (path.isInverseFillType()) { | 95 if (path.isInverseFillType()) { |
97 static constexpr GrUserStencilSettings kInvertedCoverPass( | |
98 GrUserStencilSettings::StaticInit< | |
99 0x0000, | |
100 // We know our rect will hit pixels outside the clip and the use
r bits will be 0 | |
101 // outside the clip. So we can't just fill where the user bits a
re 0. We also need | |
102 // to check that the clip bit is set. | |
103 GrUserStencilTest::kEqualIfInClip, | |
104 0xffff, | |
105 GrUserStencilOp::kKeep, | |
106 GrUserStencilOp::kZero, | |
107 0xffff>() | |
108 ); | |
109 | |
110 // fake inverse with a stencil and cover | |
111 args.fDrawContext->drawContextPriv().stencilPath(*args.fClip, | |
112 &kInvertedCoverPass, | |
113 args.fPaint->isAntiAlia
s(), | |
114 viewMatrix, p); | |
115 | |
116 SkMatrix invert = SkMatrix::I(); | 96 SkMatrix invert = SkMatrix::I(); |
117 SkRect bounds = | 97 SkRect bounds = |
118 SkRect::MakeLTRB(0, 0, | 98 SkRect::MakeLTRB(0, 0, |
119 SkIntToScalar(args.fDrawContext->width()), | 99 SkIntToScalar(args.fDrawContext->width()), |
120 SkIntToScalar(args.fDrawContext->height())); | 100 SkIntToScalar(args.fDrawContext->height())); |
121 SkMatrix vmi; | 101 SkMatrix vmi; |
122 // mapRect through persp matrix may not be correct | 102 // mapRect through persp matrix may not be correct |
123 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { | 103 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { |
124 vmi.mapRect(&bounds); | 104 vmi.mapRect(&bounds); |
125 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion | 105 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion |
126 // precision. | 106 // precision. |
127 SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; | 107 SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; |
128 bounds.outset(bloat, bloat); | 108 bounds.outset(bloat, bloat); |
129 } else { | 109 } else { |
130 if (!viewMatrix.invert(&invert)) { | 110 if (!viewMatrix.invert(&invert)) { |
131 return false; | 111 return false; |
132 } | 112 } |
133 } | 113 } |
134 const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : vi
ewMatrix; | 114 const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : vi
ewMatrix; |
135 | 115 |
136 SkAutoTUnref<GrDrawBatch> coverBatch( | 116 SkAutoTUnref<GrDrawBatch> coverBatch( |
137 GrRectBatchFactory::CreateNonAAFill(args.fPaint->getColor(), vie
wM, bounds, | 117 GrRectBatchFactory::CreateNonAAFill(args.fPaint->getColor(), vie
wM, bounds, |
138 nullptr, &invert)); | 118 nullptr, &invert)); |
139 | 119 |
| 120 // fake inverse with a stencil and cover |
| 121 args.fDrawContext->drawContextPriv().stencilPath(*args.fClip, args.fPain
t->isAntiAlias(), |
| 122 viewMatrix, p); |
| 123 |
140 { | 124 { |
| 125 static constexpr GrUserStencilSettings kInvertedCoverPass( |
| 126 GrUserStencilSettings::StaticInit< |
| 127 0x0000, |
| 128 // We know our rect will hit pixels outside the clip and the
user bits will |
| 129 // be 0 outside the clip. So we can't just fill where the us
er bits are 0. We |
| 130 // also need to check that the clip bit is set. |
| 131 GrUserStencilTest::kEqualIfInClip, |
| 132 0xffff, |
| 133 GrUserStencilOp::kKeep, |
| 134 GrUserStencilOp::kZero, |
| 135 0xffff>() |
| 136 ); |
| 137 |
141 GrPipelineBuilder pipelineBuilder(*args.fPaint, | 138 GrPipelineBuilder pipelineBuilder(*args.fPaint, |
142 args.fPaint->isAntiAlias() && | 139 args.fPaint->isAntiAlias() && |
143 !args.fDrawContext->hasMixedSample
s()); | 140 !args.fDrawContext->hasMixedSample
s()); |
144 pipelineBuilder.setUserStencil(&kInvertedCoverPass); | 141 pipelineBuilder.setUserStencil(&kInvertedCoverPass); |
145 | 142 |
146 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, coverBatc
h); | 143 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, coverBatc
h); |
147 } | 144 } |
148 } else { | 145 } else { |
149 static constexpr GrUserStencilSettings kCoverPass( | 146 static constexpr GrUserStencilSettings kCoverPass( |
150 GrUserStencilSettings::StaticInit< | 147 GrUserStencilSettings::StaticInit< |
(...skipping 13 matching lines...) Expand all Loading... |
164 if (args.fAntiAlias) { | 161 if (args.fAntiAlias) { |
165 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); | 162 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); |
166 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag); | 163 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag); |
167 } | 164 } |
168 | 165 |
169 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); | 166 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); |
170 } | 167 } |
171 | 168 |
172 return true; | 169 return true; |
173 } | 170 } |
OLD | NEW |