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 "GrPathRendererChain.h" 10 11 #include "GrCaps.h" 12 #include "GrShaderCaps.h" 13 #include "gl/GrGLCaps.h" 14 #include "GrContext.h" 15 #include "GrContextPriv.h" 16 #include "GrGpu.h" 17 18 #include "ccpr/GrCoverageCountingPathRenderer.h" 19 20 #include "ops/GrAAConvexPathRenderer.h" 21 #include "ops/GrAAHairLinePathRenderer.h" 22 #include "ops/GrAALinearizingConvexPathRenderer.h" 23 #include "ops/GrSmallPathRenderer.h" 24 #include "ops/GrDashLinePathRenderer.h" 25 #include "ops/GrDefaultPathRenderer.h" 26 #include "ops/GrMSAAPathRenderer.h" 27 #include "ops/GrStencilAndCoverPathRenderer.h" 28 #include "ops/GrTessellatingPathRenderer.h" 29 GrPathRendererChain(GrContext * context,const Options & options)30GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) { 31 const GrCaps& caps = *context->caps(); 32 if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) { 33 fChain.push_back(sk_make_sp<GrDashLinePathRenderer>()); 34 } 35 if (options.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) { 36 sk_sp<GrPathRenderer> pr( 37 GrStencilAndCoverPathRenderer::Create(context->contextPriv().resourceProvider(), caps)); 38 if (pr) { 39 fChain.push_back(std::move(pr)); 40 } 41 } 42 #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK 43 if (options.fGpuPathRenderers & GpuPathRenderers::kMSAA) { 44 if (caps.sampleShadingSupport()) { 45 fChain.push_back(sk_make_sp<GrMSAAPathRenderer>()); 46 } 47 } 48 #endif 49 50 // AA hairline path renderer is very specialized - no other renderer can do this job well 51 fChain.push_back(sk_make_sp<GrAAHairLinePathRenderer>()); 52 53 if (options.fGpuPathRenderers & GpuPathRenderers::kCoverageCounting) { 54 bool drawCachablePaths = !options.fAllowPathMaskCaching; 55 if (auto ccpr = GrCoverageCountingPathRenderer::CreateIfSupported(*context->caps(), 56 drawCachablePaths)) { 57 fCoverageCountingPathRenderer = ccpr.get(); 58 context->contextPriv().addOnFlushCallbackObject(fCoverageCountingPathRenderer); 59 fChain.push_back(std::move(ccpr)); 60 } 61 } 62 if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) { 63 fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>()); 64 } 65 if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) { 66 fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>()); 67 } 68 if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) { 69 auto spr = sk_make_sp<GrSmallPathRenderer>(); 70 context->contextPriv().addOnFlushCallbackObject(spr.get()); 71 fChain.push_back(std::move(spr)); 72 } 73 if (options.fGpuPathRenderers & GpuPathRenderers::kTessellating) { 74 fChain.push_back(sk_make_sp<GrTessellatingPathRenderer>()); 75 } 76 77 // We always include the default path renderer (as well as SW), so we can draw any path 78 fChain.push_back(sk_make_sp<GrDefaultPathRenderer>()); 79 } 80 getPathRenderer(const GrPathRenderer::CanDrawPathArgs & args,DrawType drawType,GrPathRenderer::StencilSupport * stencilSupport)81GrPathRenderer* GrPathRendererChain::getPathRenderer( 82 const GrPathRenderer::CanDrawPathArgs& args, 83 DrawType drawType, 84 GrPathRenderer::StencilSupport* stencilSupport) { 85 GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport < 86 GrPathRenderer::kStencilOnly_StencilSupport); 87 GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport < 88 GrPathRenderer::kNoRestriction_StencilSupport); 89 GrPathRenderer::StencilSupport minStencilSupport; 90 if (DrawType::kStencil == drawType) { 91 minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport; 92 } else if (DrawType::kStencilAndColor == drawType) { 93 minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 94 } else { 95 minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport; 96 } 97 if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) { 98 // We don't support (and shouldn't need) stenciling of non-fill paths. 99 if (!args.fShape->style().isSimpleFill()) { 100 return nullptr; 101 } 102 } 103 104 GrPathRenderer* bestPathRenderer = nullptr; 105 for (const sk_sp<GrPathRenderer>& pr : fChain) { 106 GrPathRenderer::StencilSupport support = GrPathRenderer::kNoSupport_StencilSupport; 107 if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { 108 support = pr->getStencilSupport(*args.fShape); 109 if (support < minStencilSupport) { 110 continue; 111 } 112 } 113 GrPathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args); 114 if (GrPathRenderer::CanDrawPath::kNo == canDrawPath) { 115 continue; 116 } 117 if (GrPathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) { 118 continue; 119 } 120 if (stencilSupport) { 121 *stencilSupport = support; 122 } 123 bestPathRenderer = pr.get(); 124 if (GrPathRenderer::CanDrawPath::kYes == canDrawPath) { 125 break; 126 } 127 } 128 return bestPathRenderer; 129 } 130