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" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrGpu* gpu) { | 43 GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrGpu* gpu) { |
44 SkASSERT(gpu->caps()->pathRenderingSupport()); | 44 SkASSERT(gpu->caps()->pathRenderingSupport()); |
45 fGpu = gpu; | 45 fGpu = gpu; |
46 gpu->ref(); | 46 gpu->ref(); |
47 } | 47 } |
48 | 48 |
49 GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { | 49 GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { |
50 fGpu->unref(); | 50 fGpu->unref(); |
51 } | 51 } |
52 | 52 |
53 bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, | 53 bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 54 const GrDrawState* drawState, |
| 55 const SkPath& path, |
54 const SkStrokeRec& stroke, | 56 const SkStrokeRec& stroke, |
55 const GrDrawTarget* target, | |
56 bool antiAlias) const { | 57 bool antiAlias) const { |
57 return !stroke.isHairlineStyle() && | 58 return !stroke.isHairlineStyle() && |
58 !antiAlias && // doesn't do per-path AA, relies on the target having
MSAA | 59 !antiAlias && // doesn't do per-path AA, relies on the target having
MSAA |
59 target->getDrawState().getRenderTarget()->getStencilBuffer() && | 60 drawState->getRenderTarget()->getStencilBuffer() && |
60 target->getDrawState().getStencil().isDisabled(); | 61 drawState->getStencil().isDisabled(); |
61 } | 62 } |
62 | 63 |
63 GrPathRenderer::StencilSupport | 64 GrPathRenderer::StencilSupport |
64 GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&, | 65 GrStencilAndCoverPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
65 const SkStrokeRec& , | 66 const GrDrawState*, |
66 const GrDrawTarget*) const { | 67 const SkPath&, |
| 68 const SkStrokeRec&) const { |
67 return GrPathRenderer::kStencilOnly_StencilSupport; | 69 return GrPathRenderer::kStencilOnly_StencilSupport; |
68 } | 70 } |
69 | 71 |
70 static GrPath* get_gr_path(GrGpu* gpu, const SkPath& skPath, const SkStrokeRec&
stroke) { | 72 static GrPath* get_gr_path(GrGpu* gpu, const SkPath& skPath, const SkStrokeRec&
stroke) { |
71 GrContext* ctx = gpu->getContext(); | 73 GrContext* ctx = gpu->getContext(); |
72 GrResourceKey resourceKey = GrPath::ComputeKey(skPath, stroke); | 74 GrResourceKey resourceKey = GrPath::ComputeKey(skPath, stroke); |
73 SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource
(resourceKey))); | 75 SkAutoTUnref<GrPath> path(static_cast<GrPath*>(ctx->findAndRefCachedResource
(resourceKey))); |
74 if (NULL == path || !path->isEqualTo(skPath, stroke)) { | 76 if (NULL == path || !path->isEqualTo(skPath, stroke)) { |
75 path.reset(gpu->pathRendering()->createPath(skPath, stroke)); | 77 path.reset(gpu->pathRendering()->createPath(skPath, stroke)); |
76 ctx->addResourceToCache(resourceKey, path); | 78 ctx->addResourceToCache(resourceKey, path); |
77 } | 79 } |
78 return path.detach(); | 80 return path.detach(); |
79 } | 81 } |
80 | 82 |
81 void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, | 83 void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target, |
82 const SkStrokeRec& stroke, | 84 GrDrawState* drawState, |
83 GrDrawTarget* target) { | 85 const SkPath& path, |
| 86 const SkStrokeRec& stroke) { |
84 SkASSERT(!path.isInverseFillType()); | 87 SkASSERT(!path.isInverseFillType()); |
85 SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); | 88 SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); |
86 target->stencilPath(p, convert_skpath_filltype(path.getFillType())); | 89 target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()
)); |
87 } | 90 } |
88 | 91 |
89 bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, | 92 bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target, |
| 93 GrDrawState* drawState, |
| 94 const SkPath& path, |
90 const SkStrokeRec& stroke, | 95 const SkStrokeRec& stroke, |
91 GrDrawTarget* target, | |
92 bool antiAlias) { | 96 bool antiAlias) { |
93 SkASSERT(!antiAlias); | 97 SkASSERT(!antiAlias); |
94 SkASSERT(!stroke.isHairlineStyle()); | 98 SkASSERT(!stroke.isHairlineStyle()); |
95 | 99 |
96 GrDrawState* drawState = target->drawState(); | |
97 SkASSERT(drawState->getStencil().isDisabled()); | 100 SkASSERT(drawState->getStencil().isDisabled()); |
98 | 101 |
99 SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); | 102 SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke)); |
100 | 103 |
101 if (path.isInverseFillType()) { | 104 if (path.isInverseFillType()) { |
102 GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, | 105 GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, |
103 kZero_StencilOp, | 106 kZero_StencilOp, |
104 kZero_StencilOp, | 107 kZero_StencilOp, |
105 // We know our rect will hit pixels outside the clip and the user bi
ts will be 0 | 108 // We know our rect will hit pixels outside the clip and the user bi
ts will be 0 |
106 // outside the clip. So we can't just fill where the user bits are 0
. We also need to | 109 // outside the clip. So we can't just fill where the user bits are 0
. We also need to |
107 // check that the clip bit is set. | 110 // check that the clip bit is set. |
108 kEqualIfInClip_StencilFunc, | 111 kEqualIfInClip_StencilFunc, |
109 0xffff, | 112 0xffff, |
110 0x0000, | 113 0x0000, |
111 0xffff); | 114 0xffff); |
112 | 115 |
113 drawState->setStencil(kInvertedStencilPass); | 116 drawState->setStencil(kInvertedStencilPass); |
114 | 117 |
115 // fake inverse with a stencil and cover | 118 // fake inverse with a stencil and cover |
116 target->stencilPath(p, convert_skpath_filltype(path.getFillType())); | 119 target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillTy
pe())); |
117 | 120 |
118 GrDrawState::AutoViewMatrixRestore avmr; | 121 GrDrawState::AutoViewMatrixRestore avmr; |
119 SkRect bounds = SkRect::MakeLTRB(0, 0, | 122 SkRect bounds = SkRect::MakeLTRB(0, 0, |
120 SkIntToScalar(drawState->getRenderTarge
t()->width()), | 123 SkIntToScalar(drawState->getRenderTarge
t()->width()), |
121 SkIntToScalar(drawState->getRenderTarge
t()->height())); | 124 SkIntToScalar(drawState->getRenderTarge
t()->height())); |
122 SkMatrix vmi; | 125 SkMatrix vmi; |
123 // mapRect through persp matrix may not be correct | 126 // mapRect through persp matrix may not be correct |
124 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { | 127 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { |
125 vmi.mapRect(&bounds); | 128 vmi.mapRect(&bounds); |
126 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion | 129 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion |
127 // precision. | 130 // precision. |
128 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
rHalf; | 131 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
rHalf; |
129 bounds.outset(bloat, bloat); | 132 bounds.outset(bloat, bloat); |
130 } else { | 133 } else { |
131 avmr.setIdentity(drawState); | 134 avmr.setIdentity(drawState); |
132 } | 135 } |
133 target->drawSimpleRect(bounds); | 136 target->drawSimpleRect(drawState, bounds); |
134 } else { | 137 } else { |
135 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, | 138 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, |
136 kZero_StencilOp, | 139 kZero_StencilOp, |
137 kZero_StencilOp, | 140 kZero_StencilOp, |
138 kNotEqual_StencilFunc, | 141 kNotEqual_StencilFunc, |
139 0xffff, | 142 0xffff, |
140 0x0000, | 143 0x0000, |
141 0xffff); | 144 0xffff); |
142 | 145 |
143 drawState->setStencil(kStencilPass); | 146 drawState->setStencil(kStencilPass); |
144 target->drawPath(p, convert_skpath_filltype(path.getFillType())); | 147 target->drawPath(drawState, p, convert_skpath_filltype(path.getFillType(
))); |
145 } | 148 } |
146 | 149 |
147 target->drawState()->stencil()->setDisabled(); | 150 drawState->stencil()->setDisabled(); |
148 return true; | 151 return true; |
149 } | 152 } |
OLD | NEW |