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