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 "GrContextPriv.h"
16 #include "GrGpu.h"
17 
18 #include "ccpr/GrCoverageCountingPathRenderer.h"
19 
20 #include "ops/GrAAConvexPathRenderer.h"
21 #include "ops/GrAAHairLinePathRenderer.h"
22 #include "ops/GrAALinearizingConvexPathRenderer.h"
23 #include "ops/GrSmallPathRenderer.h"
24 #include "ops/GrDashLinePathRenderer.h"
25 #include "ops/GrDefaultPathRenderer.h"
26 #include "ops/GrMSAAPathRenderer.h"
27 #include "ops/GrStencilAndCoverPathRenderer.h"
28 #include "ops/GrTessellatingPathRenderer.h"
29 
30 GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) {
31     const GrCaps& caps = *context->caps();
32     if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) {
33         fChain.push_back(sk_make_sp<GrDashLinePathRenderer>());
34     }
35     if (options.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) {
36         sk_sp<GrPathRenderer> pr(
37            GrStencilAndCoverPathRenderer::Create(context->contextPriv().resourceProvider(), caps));
38         if (pr) {
39             fChain.push_back(std::move(pr));
40         }
41     }
42 #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
43     if (options.fGpuPathRenderers & GpuPathRenderers::kMSAA) {
44         if (caps.sampleShadingSupport()) {
45             fChain.push_back(sk_make_sp<GrMSAAPathRenderer>());
46         }
47     }
48 #endif
49 
50     // AA hairline path renderer is very specialized - no other renderer can do this job well
51     fChain.push_back(sk_make_sp<GrAAHairLinePathRenderer>());
52 
53     if (options.fGpuPathRenderers & GpuPathRenderers::kCoverageCounting) {
54         bool drawCachablePaths = !options.fAllowPathMaskCaching;
55         if (auto ccpr = GrCoverageCountingPathRenderer::CreateIfSupported(*context->caps(),
56                                                                           drawCachablePaths)) {
57             fCoverageCountingPathRenderer = ccpr.get();
58             context->contextPriv().addOnFlushCallbackObject(fCoverageCountingPathRenderer);
59             fChain.push_back(std::move(ccpr));
60         }
61     }
62     if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) {
63         fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>());
64     }
65     if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) {
66         fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>());
67     }
68     if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) {
69         auto spr = sk_make_sp<GrSmallPathRenderer>();
70         context->contextPriv().addOnFlushCallbackObject(spr.get());
71         fChain.push_back(std::move(spr));
72     }
73     if (options.fGpuPathRenderers & GpuPathRenderers::kTessellating) {
74         fChain.push_back(sk_make_sp<GrTessellatingPathRenderer>());
75     }
76 
77     // We always include the default path renderer (as well as SW), so we can draw any path
78     fChain.push_back(sk_make_sp<GrDefaultPathRenderer>());
79 }
80 
81 GrPathRenderer* GrPathRendererChain::getPathRenderer(
82         const GrPathRenderer::CanDrawPathArgs& args,
83         DrawType drawType,
84         GrPathRenderer::StencilSupport* stencilSupport) {
85     GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
86                      GrPathRenderer::kStencilOnly_StencilSupport);
87     GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
88                      GrPathRenderer::kNoRestriction_StencilSupport);
89     GrPathRenderer::StencilSupport minStencilSupport;
90     if (DrawType::kStencil == drawType) {
91         minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
92     } else if (DrawType::kStencilAndColor == drawType) {
93         minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
94     } else {
95         minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
96     }
97     if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) {
98         // We don't support (and shouldn't need) stenciling of non-fill paths.
99         if (!args.fShape->style().isSimpleFill()) {
100             return nullptr;
101         }
102     }
103 
104     GrPathRenderer* bestPathRenderer = nullptr;
105     for (const sk_sp<GrPathRenderer>& pr : fChain) {
106         GrPathRenderer::StencilSupport support = GrPathRenderer::kNoSupport_StencilSupport;
107         if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
108             support = pr->getStencilSupport(*args.fShape);
109             if (support < minStencilSupport) {
110                 continue;
111             }
112         }
113         GrPathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args);
114         if (GrPathRenderer::CanDrawPath::kNo == canDrawPath) {
115             continue;
116         }
117         if (GrPathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) {
118             continue;
119         }
120         if (stencilSupport) {
121             *stencilSupport = support;
122         }
123         bestPathRenderer = pr.get();
124         if (GrPathRenderer::CanDrawPath::kYes == canDrawPath) {
125             break;
126         }
127     }
128     return bestPathRenderer;
129 }
130