1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci
9cb93a386Sopenharmony_ci#include "src/gpu/v1/PathRendererChain.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h"
12cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
15cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrShaderCaps.h"
18cb93a386Sopenharmony_ci#include "src/gpu/geometry/GrStyledShape.h"
19cb93a386Sopenharmony_ci#include "src/gpu/ops/AAConvexPathRenderer.h"
20cb93a386Sopenharmony_ci#include "src/gpu/ops/AAHairLinePathRenderer.h"
21cb93a386Sopenharmony_ci#include "src/gpu/ops/AALinearizingConvexPathRenderer.h"
22cb93a386Sopenharmony_ci#include "src/gpu/ops/AtlasPathRenderer.h"
23cb93a386Sopenharmony_ci#include "src/gpu/ops/DashLinePathRenderer.h"
24cb93a386Sopenharmony_ci#include "src/gpu/ops/DefaultPathRenderer.h"
25cb93a386Sopenharmony_ci#include "src/gpu/ops/SmallPathRenderer.h"
26cb93a386Sopenharmony_ci#include "src/gpu/ops/TessellationPathRenderer.h"
27cb93a386Sopenharmony_ci#include "src/gpu/ops/TriangulatingPathRenderer.h"
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_cinamespace skgpu::v1 {
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ciPathRendererChain::PathRendererChain(GrRecordingContext* context, const Options& options) {
32cb93a386Sopenharmony_ci    const GrCaps& caps = *context->priv().caps();
33cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) {
34cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<DashLinePathRenderer>());
35cb93a386Sopenharmony_ci    }
36cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) {
37cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<AAConvexPathRenderer>());
38cb93a386Sopenharmony_ci    }
39cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kAAHairline) {
40cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<AAHairLinePathRenderer>());
41cb93a386Sopenharmony_ci    }
42cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) {
43cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<AALinearizingConvexPathRenderer>());
44cb93a386Sopenharmony_ci    }
45cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kAtlas) {
46cb93a386Sopenharmony_ci        if (auto atlasPathRenderer = AtlasPathRenderer::Make(context)) {
47cb93a386Sopenharmony_ci            fAtlasPathRenderer = atlasPathRenderer.get();
48cb93a386Sopenharmony_ci            context->priv().addOnFlushCallbackObject(atlasPathRenderer.get());
49cb93a386Sopenharmony_ci            fChain.push_back(std::move(atlasPathRenderer));
50cb93a386Sopenharmony_ci        }
51cb93a386Sopenharmony_ci    }
52cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) {
53cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<SmallPathRenderer>());
54cb93a386Sopenharmony_ci    }
55cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kTriangulating) {
56cb93a386Sopenharmony_ci        fChain.push_back(sk_make_sp<TriangulatingPathRenderer>());
57cb93a386Sopenharmony_ci    }
58cb93a386Sopenharmony_ci    if (options.fGpuPathRenderers & GpuPathRenderers::kTessellation) {
59cb93a386Sopenharmony_ci        if (TessellationPathRenderer::IsSupported(caps)) {
60cb93a386Sopenharmony_ci            auto tess = sk_make_sp<TessellationPathRenderer>();
61cb93a386Sopenharmony_ci            fTessellationPathRenderer = tess.get();
62cb93a386Sopenharmony_ci            fChain.push_back(std::move(tess));
63cb93a386Sopenharmony_ci        }
64cb93a386Sopenharmony_ci    }
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    // We always include the default path renderer (as well as SW), so we can draw any path
67cb93a386Sopenharmony_ci    fChain.push_back(sk_make_sp<DefaultPathRenderer>());
68cb93a386Sopenharmony_ci}
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ciPathRenderer* PathRendererChain::getPathRenderer(const PathRenderer::CanDrawPathArgs& args,
71cb93a386Sopenharmony_ci                                                 DrawType drawType,
72cb93a386Sopenharmony_ci                                                 PathRenderer::StencilSupport* stencilSupport) {
73cb93a386Sopenharmony_ci    static_assert(PathRenderer::kNoSupport_StencilSupport <
74cb93a386Sopenharmony_ci                  PathRenderer::kStencilOnly_StencilSupport);
75cb93a386Sopenharmony_ci    static_assert(PathRenderer::kStencilOnly_StencilSupport <
76cb93a386Sopenharmony_ci                  PathRenderer::kNoRestriction_StencilSupport);
77cb93a386Sopenharmony_ci    PathRenderer::StencilSupport minStencilSupport;
78cb93a386Sopenharmony_ci    if (DrawType::kStencil == drawType) {
79cb93a386Sopenharmony_ci        minStencilSupport = PathRenderer::kStencilOnly_StencilSupport;
80cb93a386Sopenharmony_ci    } else if (DrawType::kStencilAndColor == drawType) {
81cb93a386Sopenharmony_ci        minStencilSupport = PathRenderer::kNoRestriction_StencilSupport;
82cb93a386Sopenharmony_ci    } else {
83cb93a386Sopenharmony_ci        minStencilSupport = PathRenderer::kNoSupport_StencilSupport;
84cb93a386Sopenharmony_ci    }
85cb93a386Sopenharmony_ci    if (minStencilSupport != PathRenderer::kNoSupport_StencilSupport) {
86cb93a386Sopenharmony_ci        // We don't support (and shouldn't need) stenciling of non-fill paths.
87cb93a386Sopenharmony_ci        if (!args.fShape->style().isSimpleFill()) {
88cb93a386Sopenharmony_ci            return nullptr;
89cb93a386Sopenharmony_ci        }
90cb93a386Sopenharmony_ci    }
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci    PathRenderer* bestPathRenderer = nullptr;
93cb93a386Sopenharmony_ci    for (const sk_sp<PathRenderer>& pr : fChain) {
94cb93a386Sopenharmony_ci        PathRenderer::StencilSupport support = PathRenderer::kNoSupport_StencilSupport;
95cb93a386Sopenharmony_ci        if (PathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
96cb93a386Sopenharmony_ci            support = pr->getStencilSupport(*args.fShape);
97cb93a386Sopenharmony_ci            if (support < minStencilSupport) {
98cb93a386Sopenharmony_ci                continue;
99cb93a386Sopenharmony_ci            }
100cb93a386Sopenharmony_ci        }
101cb93a386Sopenharmony_ci        PathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args);
102cb93a386Sopenharmony_ci        if (PathRenderer::CanDrawPath::kNo == canDrawPath) {
103cb93a386Sopenharmony_ci            continue;
104cb93a386Sopenharmony_ci        }
105cb93a386Sopenharmony_ci        if (PathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) {
106cb93a386Sopenharmony_ci            continue;
107cb93a386Sopenharmony_ci        }
108cb93a386Sopenharmony_ci        if (stencilSupport) {
109cb93a386Sopenharmony_ci            *stencilSupport = support;
110cb93a386Sopenharmony_ci        }
111cb93a386Sopenharmony_ci        bestPathRenderer = pr.get();
112cb93a386Sopenharmony_ci        if (PathRenderer::CanDrawPath::kYes == canDrawPath) {
113cb93a386Sopenharmony_ci            break;
114cb93a386Sopenharmony_ci        }
115cb93a386Sopenharmony_ci    }
116cb93a386Sopenharmony_ci    return bestPathRenderer;
117cb93a386Sopenharmony_ci}
118cb93a386Sopenharmony_ci
119cb93a386Sopenharmony_ci} // namespace skgpu::v1
120