• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrShaderCaps.h"
13 #include "gl/GrGLCaps.h"
14 #include "GrContext.h"
15 #include "GrGpu.h"
16 
17 #include "ops/GrAAConvexPathRenderer.h"
18 #include "ops/GrAAHairLinePathRenderer.h"
19 #include "ops/GrAALinearizingConvexPathRenderer.h"
20 #include "ops/GrSmallPathRenderer.h"
21 #include "ops/GrDashLinePathRenderer.h"
22 #include "ops/GrDefaultPathRenderer.h"
23 #include "ops/GrMSAAPathRenderer.h"
24 #include "ops/GrStencilAndCoverPathRenderer.h"
25 #include "ops/GrTessellatingPathRenderer.h"
26 
GrPathRendererChain(GrContext * context,const Options & options)27 GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) {
28     using GpuPathRenderers = GrContextOptions::GpuPathRenderers;
29     const GrCaps& caps = *context->caps();
30     if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) {
31         fChain.push_back(sk_make_sp<GrDashLinePathRenderer>());
32     }
33     if (options.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) {
34         sk_sp<GrPathRenderer> pr(
35             GrStencilAndCoverPathRenderer::Create(context->resourceProvider(), caps));
36         if (pr) {
37             fChain.push_back(std::move(pr));
38         }
39     }
40 #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
41     if (options.fGpuPathRenderers & GpuPathRenderers::kMSAA) {
42         if (caps.sampleShadingSupport()) {
43             fChain.push_back(sk_make_sp<GrMSAAPathRenderer>());
44         }
45     }
46 #endif
47     if (options.fGpuPathRenderers & GpuPathRenderers::kAAHairline) {
48         fChain.push_back(sk_make_sp<GrAAHairLinePathRenderer>());
49     }
50     if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) {
51         fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>());
52     }
53     if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) {
54         fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>());
55     }
56     if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) {
57         fChain.push_back(sk_make_sp<GrSmallPathRenderer>());
58     }
59     if (options.fGpuPathRenderers & GpuPathRenderers::kTessellating) {
60         fChain.push_back(sk_make_sp<GrTessellatingPathRenderer>());
61     }
62     if (options.fGpuPathRenderers & GpuPathRenderers::kDefault) {
63         fChain.push_back(sk_make_sp<GrDefaultPathRenderer>(caps.twoSidedStencilSupport(),
64                                                            caps.stencilWrapOpsSupport()));
65     }
66 }
67 
getPathRenderer(const GrPathRenderer::CanDrawPathArgs & args,DrawType drawType,GrPathRenderer::StencilSupport * stencilSupport)68 GrPathRenderer* GrPathRendererChain::getPathRenderer(
69         const GrPathRenderer::CanDrawPathArgs& args,
70         DrawType drawType,
71         GrPathRenderer::StencilSupport* stencilSupport) {
72     GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
73                      GrPathRenderer::kStencilOnly_StencilSupport);
74     GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
75                      GrPathRenderer::kNoRestriction_StencilSupport);
76     GrPathRenderer::StencilSupport minStencilSupport;
77     if (DrawType::kStencil == drawType) {
78         minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
79     } else if (DrawType::kStencilAndColor == drawType) {
80         minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
81     } else {
82         minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
83     }
84     if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) {
85         // We don't support (and shouldn't need) stenciling of non-fill paths.
86         if (!args.fShape->style().isSimpleFill()) {
87             return nullptr;
88         }
89     }
90 
91     for (int i = 0; i < fChain.count(); ++i) {
92         if (fChain[i]->canDrawPath(args)) {
93             if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
94                 GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(*args.fShape);
95                 if (support < minStencilSupport) {
96                     continue;
97                 } else if (stencilSupport) {
98                     *stencilSupport = support;
99                 }
100             }
101             return fChain[i].get();
102         }
103     }
104     return nullptr;
105 }
106