1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #include "GrPathRendererChain.h"
10 
11 #include "GrCaps.h"
12 #include "gl/GrGLCaps.h"
13 #include "glsl/GrGLSLCaps.h"
14 #include "GrContext.h"
15 #include "GrGpu.h"
16 
17 #include "batches/GrAAConvexPathRenderer.h"
18 #include "batches/GrAADistanceFieldPathRenderer.h"
19 #include "batches/GrAAHairLinePathRenderer.h"
20 #include "batches/GrAALinearizingConvexPathRenderer.h"
21 #include "batches/GrDashLinePathRenderer.h"
22 #include "batches/GrDefaultPathRenderer.h"
23 #include "batches/GrMSAAPathRenderer.h"
24 #include "batches/GrPLSPathRenderer.h"
25 #include "batches/GrStencilAndCoverPathRenderer.h"
26 #include "batches/GrTessellatingPathRenderer.h"
27 
GrPathRendererChain(GrContext * context,const Options & options)28 GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) {
29     if (!options.fDisableAllPathRenderers) {
30         const GrCaps& caps = *context->caps();
31         this->addPathRenderer(new GrDashLinePathRenderer)->unref();
32 
33         if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(context->resourceProvider(),
34                                                                        caps)) {
35             this->addPathRenderer(pr)->unref();
36         }
37     #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
38         if (caps.sampleShadingSupport()) {
39             this->addPathRenderer(new GrMSAAPathRenderer)->unref();
40         }
41     #endif
42         this->addPathRenderer(new GrAAHairLinePathRenderer)->unref();
43         this->addPathRenderer(new GrAAConvexPathRenderer)->unref();
44         this->addPathRenderer(new GrAALinearizingConvexPathRenderer)->unref();
45         if (caps.shaderCaps()->plsPathRenderingSupport()) {
46             this->addPathRenderer(new GrPLSPathRenderer)->unref();
47         }
48         if (!options.fDisableDistanceFieldRenderer) {
49             this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref();
50         }
51         this->addPathRenderer(new GrTessellatingPathRenderer)->unref();
52         this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(),
53                                                         caps.stencilWrapOpsSupport()))->unref();
54     }
55 }
56 
~GrPathRendererChain()57 GrPathRendererChain::~GrPathRendererChain() {
58     for (int i = 0; i < fChain.count(); ++i) {
59         fChain[i]->unref();
60     }
61 }
62 
addPathRenderer(GrPathRenderer * pr)63 GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
64     fChain.push_back() = pr;
65     pr->ref();
66     return pr;
67 }
68 
getPathRenderer(const GrPathRenderer::CanDrawPathArgs & args,DrawType drawType,GrPathRenderer::StencilSupport * stencilSupport)69 GrPathRenderer* GrPathRendererChain::getPathRenderer(
70         const GrPathRenderer::CanDrawPathArgs& args,
71         DrawType drawType,
72         GrPathRenderer::StencilSupport* stencilSupport) {
73     GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
74                      GrPathRenderer::kStencilOnly_StencilSupport);
75     GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
76                      GrPathRenderer::kNoRestriction_StencilSupport);
77     GrPathRenderer::StencilSupport minStencilSupport;
78     if (kStencilOnly_DrawType == drawType) {
79         minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
80     } else if (kStencilAndColor_DrawType == drawType ||
81                kStencilAndColorAntiAlias_DrawType == drawType) {
82         minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
83     } else {
84         minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
85     }
86     if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) {
87         // We don't support (and shouldn't need) stenciling of non-fill paths.
88         if (!args.fShape->style().isSimpleFill()) {
89             return nullptr;
90         }
91     }
92 
93     for (int i = 0; i < fChain.count(); ++i) {
94         if (fChain[i]->canDrawPath(args)) {
95             if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
96                 GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(*args.fShape);
97                 if (support < minStencilSupport) {
98                     continue;
99                 } else if (stencilSupport) {
100                     *stencilSupport = support;
101                 }
102             }
103             return fChain[i];
104         }
105     }
106     return nullptr;
107 }
108