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/ganesh/PathRendererChain.h" 10 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" 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<ganesh::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 !defined(SK_ENABLE_OPTIMIZE_SIZE) 53 if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) { 54 fChain.push_back(sk_make_sp<SmallPathRenderer>()); 55 } 56 if (options.fGpuPathRenderers & GpuPathRenderers::kTriangulating) { 57 fChain.push_back(sk_make_sp<TriangulatingPathRenderer>()); 58 } 59 #endif 60 if (options.fGpuPathRenderers & GpuPathRenderers::kTessellation) { 61 if (TessellationPathRenderer::IsSupported(caps)) { 62 auto tess = sk_make_sp<TessellationPathRenderer>(); 63 fTessellationPathRenderer = tess.get(); 64 fChain.push_back(std::move(tess)); 65 } 66 } 67 68 // We always include the default path renderer (as well as SW), so we can draw any path 69 fChain.push_back(sk_make_sp<DefaultPathRenderer>()); 70 } 71 getPathRenderer(const PathRenderer::CanDrawPathArgs & args,DrawType drawType,PathRenderer::StencilSupport * stencilSupport)72PathRenderer* PathRendererChain::getPathRenderer(const PathRenderer::CanDrawPathArgs& args, 73 DrawType drawType, 74 PathRenderer::StencilSupport* stencilSupport) { 75 static_assert(PathRenderer::kNoSupport_StencilSupport < 76 PathRenderer::kStencilOnly_StencilSupport); 77 static_assert(PathRenderer::kStencilOnly_StencilSupport < 78 PathRenderer::kNoRestriction_StencilSupport); 79 PathRenderer::StencilSupport minStencilSupport; 80 if (DrawType::kStencil == drawType) { 81 minStencilSupport = PathRenderer::kStencilOnly_StencilSupport; 82 } else if (DrawType::kStencilAndColor == drawType) { 83 minStencilSupport = PathRenderer::kNoRestriction_StencilSupport; 84 } else { 85 minStencilSupport = PathRenderer::kNoSupport_StencilSupport; 86 } 87 if (minStencilSupport != PathRenderer::kNoSupport_StencilSupport) { 88 // We don't support (and shouldn't need) stenciling of non-fill paths. 89 if (!args.fShape->style().isSimpleFill()) { 90 return nullptr; 91 } 92 } 93 94 PathRenderer* bestPathRenderer = nullptr; 95 for (const sk_sp<PathRenderer>& pr : fChain) { 96 PathRenderer::StencilSupport support = PathRenderer::kNoSupport_StencilSupport; 97 if (PathRenderer::kNoSupport_StencilSupport != minStencilSupport) { 98 support = pr->getStencilSupport(*args.fShape); 99 if (support < minStencilSupport) { 100 continue; 101 } 102 } 103 PathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args); 104 if (PathRenderer::CanDrawPath::kNo == canDrawPath) { 105 continue; 106 } 107 if (PathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) { 108 continue; 109 } 110 if (stencilSupport) { 111 *stencilSupport = support; 112 } 113 bestPathRenderer = pr.get(); 114 if (PathRenderer::CanDrawPath::kYes == canDrawPath) { 115 break; 116 } 117 } 118 return bestPathRenderer; 119 } 120 121 } // namespace skgpu::v1 122