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 "src/gpu/v1/PathRendererChain.h" 10 11 #include "include/gpu/GrDirectContext.h" 12 #include "include/gpu/GrRecordingContext.h" 13 #include "src/gpu/GrCaps.h" 14 #include "src/gpu/GrDirectContextPriv.h" 15 #include "src/gpu/GrGpu.h" 16 #include "src/gpu/GrRecordingContextPriv.h" 17 #include "src/gpu/GrShaderCaps.h" 18 #include "src/gpu/geometry/GrStyledShape.h" 19 #include "src/gpu/ops/AAConvexPathRenderer.h" 20 #include "src/gpu/ops/AAHairLinePathRenderer.h" 21 #include "src/gpu/ops/AALinearizingConvexPathRenderer.h" 22 #include "src/gpu/ops/AtlasPathRenderer.h" 23 #include "src/gpu/ops/DashLinePathRenderer.h" 24 #include "src/gpu/ops/DefaultPathRenderer.h" 25 #include "src/gpu/ops/SmallPathRenderer.h" 26 #include "src/gpu/ops/TessellationPathRenderer.h" 27 #include "src/gpu/ops/TriangulatingPathRenderer.h" 28 29 namespace skgpu::v1 { 30 PathRendererChain(GrRecordingContext * context,const Options & options)31PathRendererChain::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>()); 35 } 36 if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) { 37 fChain.push_back(sk_make_sp<AAConvexPathRenderer>()); 38 } 39 if (options.fGpuPathRenderers & GpuPathRenderers::kAAHairline) { 40 fChain.push_back(sk_make_sp<AAHairLinePathRenderer>()); 41 } 42 if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) { 43 fChain.push_back(sk_make_sp<AALinearizingConvexPathRenderer>()); 44 } 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)); 50 } 51 } 52 if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) { 53 fChain.push_back(sk_make_sp<SmallPathRenderer>()); 54 } 55 if (options.fGpuPathRenderers & GpuPathRenderers::kTriangulating) { 56 fChain.push_back(sk_make_sp<TriangulatingPathRenderer>()); 57 } 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)); 63 } 64 } 65 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>()); 68 } 69 getPathRenderer(const PathRenderer::CanDrawPathArgs & args,DrawType drawType,PathRenderer::StencilSupport * stencilSupport)70PathRenderer* PathRendererChain::getPathRenderer(const PathRenderer::CanDrawPathArgs& args, 71 DrawType drawType, 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; 82 } else { 83 minStencilSupport = PathRenderer::kNoSupport_StencilSupport; 84 } 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()) { 88 return nullptr; 89 } 90 } 91 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) { 98 continue; 99 } 100 } 101 PathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args); 102 if (PathRenderer::CanDrawPath::kNo == canDrawPath) { 103 continue; 104 } 105 if (PathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) { 106 continue; 107 } 108 if (stencilSupport) { 109 *stencilSupport = support; 110 } 111 bestPathRenderer = pr.get(); 112 if (PathRenderer::CanDrawPath::kYes == canDrawPath) { 113 break; 114 } 115 } 116 return bestPathRenderer; 117 } 118 119 } // namespace skgpu::v1 120