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 |