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 "GrCaps.h"
13 #include "gl/GrGLCaps.h"
14 #include "glsl/GrGLSLCaps.h"
15 #include "GrContext.h"
16 #include "GrGpu.h"
17 
18 #include "batches/GrAAConvexPathRenderer.h"
19 #include "batches/GrAADistanceFieldPathRenderer.h"
20 #include "batches/GrAAHairLinePathRenderer.h"
21 #include "batches/GrAALinearizingConvexPathRenderer.h"
22 #include "batches/GrDashLinePathRenderer.h"
23 #include "batches/GrDefaultPathRenderer.h"
24 #include "batches/GrStencilAndCoverPathRenderer.h"
25 #include "batches/GrTessellatingPathRenderer.h"
26 #include "batches/GrPLSPathRenderer.h"
27 
GrPathRendererChain(GrContext * context)28 GrPathRendererChain::GrPathRendererChain(GrContext* context) {
29     const GrCaps& caps = *context->caps();
30     this->addPathRenderer(new GrDashLinePathRenderer)->unref();
31 
32     if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(context->resourceProvider(),
33                                                                    caps)) {
34         this->addPathRenderer(pr)->unref();
35     }
36     this->addPathRenderer(new GrTessellatingPathRenderer)->unref();
37     this->addPathRenderer(new GrAAHairLinePathRenderer)->unref();
38     this->addPathRenderer(new GrAAConvexPathRenderer)->unref();
39     this->addPathRenderer(new GrAALinearizingConvexPathRenderer)->unref();
40     if (caps.shaderCaps()->plsPathRenderingSupport()) {
41         this->addPathRenderer(new GrPLSPathRenderer)->unref();
42     }
43     this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref();
44     this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(),
45                                                     caps.stencilWrapOpsSupport()))->unref();
46 }
47 
~GrPathRendererChain()48 GrPathRendererChain::~GrPathRendererChain() {
49     for (int i = 0; i < fChain.count(); ++i) {
50         fChain[i]->unref();
51     }
52 }
53 
addPathRenderer(GrPathRenderer * pr)54 GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
55     fChain.push_back() = pr;
56     pr->ref();
57     return pr;
58 }
59 
getPathRenderer(const GrPathRenderer::CanDrawPathArgs & args,DrawType drawType,GrPathRenderer::StencilSupport * stencilSupport)60 GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
61                                                      DrawType drawType,
62                                                      GrPathRenderer::StencilSupport* stencilSupport) {
63     GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
64                      GrPathRenderer::kStencilOnly_StencilSupport);
65     GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
66                      GrPathRenderer::kNoRestriction_StencilSupport);
67     GrPathRenderer::StencilSupport minStencilSupport;
68     if (kStencilOnly_DrawType == drawType) {
69         minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
70     } else if (kStencilAndColor_DrawType == drawType ||
71                kStencilAndColorAntiAlias_DrawType == drawType) {
72         minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
73     } else {
74         minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
75     }
76 
77     for (int i = 0; i < fChain.count(); ++i) {
78         if (fChain[i]->canDrawPath(args)) {
79             if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
80                 GrPathRenderer::StencilSupport support =
81                                         fChain[i]->getStencilSupport(*args.fPath, *args.fStroke);
82                 if (support < minStencilSupport) {
83                     continue;
84                 } else if (stencilSupport) {
85                     *stencilSupport = support;
86                 }
87             }
88             return fChain[i];
89         }
90     }
91     return nullptr;
92 }
93