| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 68 |
| 69 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { | 69 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { |
| 70 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 70 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
| 71 "GrStencilAndCoverPathRenderer::onStencilPath"); | 71 "GrStencilAndCoverPathRenderer::onStencilPath"); |
| 72 SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled()); | 72 SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled()); |
| 73 | 73 |
| 74 GrPaint paint; | 74 GrPaint paint; |
| 75 SkSafeUnref(paint.setXPFactory(GrDisableColorXPFactory::Create())); | 75 SkSafeUnref(paint.setXPFactory(GrDisableColorXPFactory::Create())); |
| 76 paint.setAntiAlias(args.fIsAA); | 76 paint.setAntiAlias(args.fIsAA); |
| 77 | 77 |
| 78 GrPipelineBuilder pipelineBuilder(paint, args.fDrawContext->isUnifiedMultisa
mpled()); | 78 const GrPipelineBuilder pipelineBuilder(paint, args.fIsAA); |
| 79 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, args.fIsAA); | |
| 80 | 79 |
| 81 SkASSERT(!args.fPath->isInverseFillType()); | 80 SkASSERT(!args.fPath->isInverseFillType()); |
| 82 SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyl
e::SimpleFill())); | 81 SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyl
e::SimpleFill())); |
| 83 args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, | 82 args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, |
| 84 *args.fClip, | 83 *args.fClip, |
| 85 *args.fViewMatrix, | 84 *args.fViewMatrix, |
| 86 path, | 85 path, |
| 87 path->getFillType()); | 86 path->getFillType()); |
| 88 } | 87 } |
| 89 | 88 |
| 90 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { | 89 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { |
| 91 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), | 90 GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(), |
| 92 "GrStencilAndCoverPathRenderer::onDrawPath"); | 91 "GrStencilAndCoverPathRenderer::onDrawPath"); |
| 92 SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMu
ltisampled()); |
| 93 SkASSERT(!args.fStyle->strokeRec().isHairlineStyle()); | 93 SkASSERT(!args.fStyle->strokeRec().isHairlineStyle()); |
| 94 const SkPath& path = *args.fPath; | 94 const SkPath& path = *args.fPath; |
| 95 const SkMatrix& viewMatrix = *args.fViewMatrix; | 95 const SkMatrix& viewMatrix = *args.fViewMatrix; |
| 96 | 96 |
| 97 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle)); | 97 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle)); |
| 98 | 98 |
| 99 if (path.isInverseFillType()) { | 99 if (path.isInverseFillType()) { |
| 100 static constexpr GrUserStencilSettings kInvertedCoverPass( | 100 static constexpr GrUserStencilSettings kInvertedCoverPass( |
| 101 GrUserStencilSettings::StaticInit< | 101 GrUserStencilSettings::StaticInit< |
| 102 0x0000, | 102 0x0000, |
| 103 // We know our rect will hit pixels outside the clip and the use
r bits will be 0 | 103 // We know our rect will hit pixels outside the clip and the use
r bits will be 0 |
| 104 // outside the clip. So we can't just fill where the user bits a
re 0. We also need | 104 // outside the clip. So we can't just fill where the user bits a
re 0. We also need |
| 105 // to check that the clip bit is set. | 105 // to check that the clip bit is set. |
| 106 GrUserStencilTest::kEqualIfInClip, | 106 GrUserStencilTest::kEqualIfInClip, |
| 107 0xffff, | 107 0xffff, |
| 108 GrUserStencilOp::kKeep, | 108 GrUserStencilOp::kKeep, |
| 109 GrUserStencilOp::kZero, | 109 GrUserStencilOp::kZero, |
| 110 0xffff>() | 110 0xffff>() |
| 111 ); | 111 ); |
| 112 | 112 |
| 113 // fake inverse with a stencil and cover | 113 // fake inverse with a stencil and cover |
| 114 { | 114 { |
| 115 GrPipelineBuilder pipelineBuilder(*args.fPaint, | 115 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fPaint->isAntiA
lias()); |
| 116 args.fDrawContext->isUnifiedMultis
ampled()); | |
| 117 pipelineBuilder.setUserStencil(&kInvertedCoverPass); | 116 pipelineBuilder.setUserStencil(&kInvertedCoverPass); |
| 118 if (args.fAntiAlias) { | |
| 119 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); | |
| 120 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag
); | |
| 121 } | |
| 122 | 117 |
| 123 args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *a
rgs.fClip, | 118 args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *a
rgs.fClip, |
| 124 viewMatrix, p, p->g
etFillType()); | 119 viewMatrix, p, p->g
etFillType()); |
| 125 } | 120 } |
| 126 | 121 |
| 127 SkMatrix invert = SkMatrix::I(); | 122 SkMatrix invert = SkMatrix::I(); |
| 128 SkRect bounds = | 123 SkRect bounds = |
| 129 SkRect::MakeLTRB(0, 0, | 124 SkRect::MakeLTRB(0, 0, |
| 130 SkIntToScalar(args.fDrawContext->width()), | 125 SkIntToScalar(args.fDrawContext->width()), |
| 131 SkIntToScalar(args.fDrawContext->height())); | 126 SkIntToScalar(args.fDrawContext->height())); |
| 132 SkMatrix vmi; | 127 SkMatrix vmi; |
| 133 // mapRect through persp matrix may not be correct | 128 // mapRect through persp matrix may not be correct |
| 134 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { | 129 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { |
| 135 vmi.mapRect(&bounds); | 130 vmi.mapRect(&bounds); |
| 136 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion | 131 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion |
| 137 // precision. | 132 // precision. |
| 138 SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; | 133 SkScalar bloat = viewMatrix.getMaxScale() * SK_ScalarHalf; |
| 139 bounds.outset(bloat, bloat); | 134 bounds.outset(bloat, bloat); |
| 140 } else { | 135 } else { |
| 141 if (!viewMatrix.invert(&invert)) { | 136 if (!viewMatrix.invert(&invert)) { |
| 142 return false; | 137 return false; |
| 143 } | 138 } |
| 144 } | 139 } |
| 145 const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : vi
ewMatrix; | 140 const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : vi
ewMatrix; |
| 146 | 141 |
| 147 SkAutoTUnref<GrDrawBatch> batch( | 142 SkAutoTUnref<GrDrawBatch> coverBatch( |
| 148 GrRectBatchFactory::CreateNonAAFill(args.fColor, viewM, bounds,
nullptr, | 143 GrRectBatchFactory::CreateNonAAFill(args.fColor, viewM, bounds,
nullptr, |
| 149 &invert)); | 144 &invert)); |
| 150 | 145 |
| 151 { | 146 { |
| 152 GrPipelineBuilder pipelineBuilder(*args.fPaint, | 147 GrPipelineBuilder pipelineBuilder(*args.fPaint, |
| 153 args.fDrawContext->isUnifiedMultis
ampled()); | 148 args.fPaint->isAntiAlias() && |
| 149 !args.fDrawContext->hasMixedSample
s()); |
| 154 pipelineBuilder.setUserStencil(&kInvertedCoverPass); | 150 pipelineBuilder.setUserStencil(&kInvertedCoverPass); |
| 155 if (args.fAntiAlias) { | |
| 156 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); | |
| 157 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag
); | |
| 158 } | |
| 159 if (args.fDrawContext->hasMixedSamples()) { | |
| 160 pipelineBuilder.disableState(GrPipelineBuilder::kHWAntialias_Fla
g); | |
| 161 } | |
| 162 | 151 |
| 163 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); | 152 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, coverBatc
h); |
| 164 } | 153 } |
| 165 } else { | 154 } else { |
| 166 static constexpr GrUserStencilSettings kCoverPass( | 155 static constexpr GrUserStencilSettings kCoverPass( |
| 167 GrUserStencilSettings::StaticInit< | 156 GrUserStencilSettings::StaticInit< |
| 168 0x0000, | 157 0x0000, |
| 169 GrUserStencilTest::kNotEqual, | 158 GrUserStencilTest::kNotEqual, |
| 170 0xffff, | 159 0xffff, |
| 171 GrUserStencilOp::kZero, | 160 GrUserStencilOp::kZero, |
| 172 GrUserStencilOp::kKeep, | 161 GrUserStencilOp::kKeep, |
| 173 0xffff>() | 162 0xffff>() |
| 174 ); | 163 ); |
| 175 | 164 |
| 176 SkAutoTUnref<GrDrawBatch> batch( | 165 SkAutoTUnref<GrDrawBatch> batch( |
| 177 GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(
), p)); | 166 GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(
), p)); |
| 178 | 167 |
| 179 GrPipelineBuilder pipelineBuilder(*args.fPaint, | 168 GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fPaint->isAntiAlias
()); |
| 180 args.fDrawContext->isUnifiedMultisampl
ed()); | |
| 181 pipelineBuilder.setUserStencil(&kCoverPass); | 169 pipelineBuilder.setUserStencil(&kCoverPass); |
| 182 if (args.fAntiAlias) { | 170 if (args.fAntiAlias) { |
| 183 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); | 171 SkASSERT(args.fDrawContext->isStencilBufferMultisampled()); |
| 184 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag); | 172 pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag); |
| 185 } | 173 } |
| 186 | 174 |
| 187 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); | 175 args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch); |
| 188 } | 176 } |
| 189 | 177 |
| 190 return true; | 178 return true; |
| 191 } | 179 } |
| OLD | NEW |