|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "GrPathRendererChain.h" |
|
11 |
|
12 #include "GrContext.h" |
|
13 #include "GrDefaultPathRenderer.h" |
|
14 #include "GrDrawTargetCaps.h" |
|
15 #include "GrGpu.h" |
|
16 |
|
17 GrPathRendererChain::GrPathRendererChain(GrContext* context) |
|
18 : fInit(false) |
|
19 , fOwner(context) { |
|
20 } |
|
21 |
|
22 GrPathRendererChain::~GrPathRendererChain() { |
|
23 for (int i = 0; i < fChain.count(); ++i) { |
|
24 fChain[i]->unref(); |
|
25 } |
|
26 } |
|
27 |
|
28 GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) { |
|
29 fChain.push_back() = pr; |
|
30 pr->ref(); |
|
31 return pr; |
|
32 } |
|
33 |
|
34 GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path, |
|
35 const SkStrokeRec& stroke, |
|
36 const GrDrawTarget* target, |
|
37 DrawType drawType, |
|
38 StencilSupport* stencilSupport) { |
|
39 if (!fInit) { |
|
40 this->init(); |
|
41 } |
|
42 bool antiAlias = (kColorAntiAlias_DrawType == drawType || |
|
43 kStencilAndColorAntiAlias_DrawType == drawType); |
|
44 |
|
45 GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport < |
|
46 GrPathRenderer::kStencilOnly_StencilSupport); |
|
47 GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport < |
|
48 GrPathRenderer::kNoRestriction_StencilSupport); |
|
49 GrPathRenderer::StencilSupport minStencilSupport; |
|
50 if (kStencilOnly_DrawType == drawType) { |
|
51 minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport; |
|
52 } else if (kStencilAndColor_DrawType == drawType || |
|
53 kStencilAndColorAntiAlias_DrawType == drawType) { |
|
54 minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
|
55 } else { |
|
56 minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport; |
|
57 } |
|
58 |
|
59 |
|
60 for (int i = 0; i < fChain.count(); ++i) { |
|
61 if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) { |
|
62 if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { |
|
63 GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path, |
|
64 stroke, |
|
65 target); |
|
66 if (support < minStencilSupport) { |
|
67 continue; |
|
68 } else if (NULL != stencilSupport) { |
|
69 *stencilSupport = support; |
|
70 } |
|
71 } |
|
72 return fChain[i]; |
|
73 } |
|
74 } |
|
75 return NULL; |
|
76 } |
|
77 |
|
78 void GrPathRendererChain::init() { |
|
79 SkASSERT(!fInit); |
|
80 GrGpu* gpu = fOwner->getGpu(); |
|
81 bool twoSided = gpu->caps()->twoSidedStencilSupport(); |
|
82 bool wrapOp = gpu->caps()->stencilWrapOpsSupport(); |
|
83 GrPathRenderer::AddPathRenderers(fOwner, this); |
|
84 this->addPathRenderer(SkNEW_ARGS(GrDefaultPathRenderer, |
|
85 (twoSided, wrapOp)))->unref(); |
|
86 fInit = true; |
|
87 } |