| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "GrStencilAndCoverPathRenderer.h" | 10 #include "GrStencilAndCoverPathRenderer.h" |
| 11 #include "GrCaps.h" | 11 #include "GrCaps.h" |
| 12 #include "GrContext.h" | 12 #include "GrContext.h" |
| 13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
| 14 #include "GrPath.h" | 14 #include "GrPath.h" |
| 15 #include "GrRenderTarget.h" | 15 #include "GrRenderTarget.h" |
| 16 #include "GrResourceProvider.h" | 16 #include "GrResourceProvider.h" |
| 17 #include "GrStrokeInfo.h" | 17 #include "GrStrokeInfo.h" |
| 18 | 18 |
| 19 /* | |
| 20 * For now paths only natively support winding and even odd fill types | |
| 21 */ | |
| 22 static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill)
{ | |
| 23 switch (fill) { | |
| 24 default: | |
| 25 SkFAIL("Incomplete Switch\n"); | |
| 26 case SkPath::kWinding_FillType: | |
| 27 case SkPath::kInverseWinding_FillType: | |
| 28 return GrPathRendering::kWinding_FillType; | |
| 29 case SkPath::kEvenOdd_FillType: | |
| 30 case SkPath::kInverseEvenOdd_FillType: | |
| 31 return GrPathRendering::kEvenOdd_FillType; | |
| 32 } | |
| 33 } | |
| 34 | |
| 35 GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resour
ceProvider, | 19 GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resour
ceProvider, |
| 36 const GrCaps& caps) { | 20 const GrCaps& caps) { |
| 37 if (caps.shaderCaps()->pathRenderingSupport()) { | 21 if (caps.shaderCaps()->pathRenderingSupport()) { |
| 38 return new GrStencilAndCoverPathRenderer(resourceProvider); | 22 return new GrStencilAndCoverPathRenderer(resourceProvider); |
| 39 } else { | 23 } else { |
| 40 return nullptr; | 24 return nullptr; |
| 41 } | 25 } |
| 42 } | 26 } |
| 43 | 27 |
| 44 GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
resourceProvider) | 28 GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
resourceProvider) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 73 } | 57 } |
| 74 } else { | 58 } else { |
| 75 SkASSERT(path->isEqualTo(skPath, stroke)); | 59 SkASSERT(path->isEqualTo(skPath, stroke)); |
| 76 } | 60 } |
| 77 return path.detach(); | 61 return path.detach(); |
| 78 } | 62 } |
| 79 | 63 |
| 80 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { | 64 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) { |
| 81 SkASSERT(!args.fPath->isInverseFillType()); | 65 SkASSERT(!args.fPath->isInverseFillType()); |
| 82 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, *args.fSt
roke)); | 66 SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, *args.fSt
roke)); |
| 83 args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, | 67 args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, p->g
etFillType()); |
| 84 convert_skpath_filltype(args.fPath->getFillType())
); | |
| 85 } | 68 } |
| 86 | 69 |
| 87 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { | 70 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) { |
| 88 SkASSERT(!args.fStroke->isHairlineStyle()); | 71 SkASSERT(!args.fStroke->isHairlineStyle()); |
| 89 const SkPath& path = *args.fPath; | 72 const SkPath& path = *args.fPath; |
| 90 GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder; | 73 GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder; |
| 91 const SkMatrix& viewMatrix = *args.fViewMatrix; | 74 const SkMatrix& viewMatrix = *args.fViewMatrix; |
| 92 | 75 |
| 93 SkASSERT(pipelineBuilder->getStencil().isDisabled()); | 76 SkASSERT(pipelineBuilder->getStencil().isDisabled()); |
| 94 | 77 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 107 // outside the clip. So we can't just fill where the user bits are 0
. We also need to | 90 // outside the clip. So we can't just fill where the user bits are 0
. We also need to |
| 108 // check that the clip bit is set. | 91 // check that the clip bit is set. |
| 109 kEqualIfInClip_StencilFunc, | 92 kEqualIfInClip_StencilFunc, |
| 110 0xffff, | 93 0xffff, |
| 111 0x0000, | 94 0x0000, |
| 112 0xffff); | 95 0xffff); |
| 113 | 96 |
| 114 pipelineBuilder->setStencil(kInvertedStencilPass); | 97 pipelineBuilder->setStencil(kInvertedStencilPass); |
| 115 | 98 |
| 116 // fake inverse with a stencil and cover | 99 // fake inverse with a stencil and cover |
| 117 args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, | 100 args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, p->getFillTyp
e()); |
| 118 convert_skpath_filltype(path.getFillType())); | |
| 119 | 101 |
| 120 SkMatrix invert = SkMatrix::I(); | 102 SkMatrix invert = SkMatrix::I(); |
| 121 SkRect bounds = | 103 SkRect bounds = |
| 122 SkRect::MakeLTRB(0, 0, SkIntToScalar(pipelineBuilder->getRenderTarge
t()->width()), | 104 SkRect::MakeLTRB(0, 0, SkIntToScalar(pipelineBuilder->getRenderTarge
t()->width()), |
| 123 SkIntToScalar(pipelineBuilder->getRenderTarget()->h
eight())); | 105 SkIntToScalar(pipelineBuilder->getRenderTarget()->h
eight())); |
| 124 SkMatrix vmi; | 106 SkMatrix vmi; |
| 125 // mapRect through persp matrix may not be correct | 107 // mapRect through persp matrix may not be correct |
| 126 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { | 108 if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) { |
| 127 vmi.mapRect(&bounds); | 109 vmi.mapRect(&bounds); |
| 128 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion | 110 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion |
| (...skipping 13 matching lines...) Expand all Loading... |
| 142 } else { | 124 } else { |
| 143 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, | 125 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, |
| 144 kZero_StencilOp, | 126 kZero_StencilOp, |
| 145 kKeep_StencilOp, | 127 kKeep_StencilOp, |
| 146 kNotEqual_StencilFunc, | 128 kNotEqual_StencilFunc, |
| 147 0xffff, | 129 0xffff, |
| 148 0x0000, | 130 0x0000, |
| 149 0xffff); | 131 0xffff); |
| 150 | 132 |
| 151 pipelineBuilder->setStencil(kStencilPass); | 133 pipelineBuilder->setStencil(kStencilPass); |
| 152 args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p, | 134 args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p, p->
getFillType()); |
| 153 convert_skpath_filltype(path.getFillType())); | |
| 154 } | 135 } |
| 155 | 136 |
| 156 pipelineBuilder->stencil()->setDisabled(); | 137 pipelineBuilder->stencil()->setDisabled(); |
| 157 return true; | 138 return true; |
| 158 } | 139 } |
| OLD | NEW |