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