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