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 30 GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& options) { 31 using GpuPathRenderers = GrContextOptions::GpuPathRenderers; 32 const GrCaps& caps = *context->caps(); 33 if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) { 34 fChain.push_back(sk_make_sp<GrDashLinePathRenderer>()); 35 } 36 if (options.fGpuPathRenderers & GpuPathRenderers::kStencilAndCover) { 37 sk_sp<GrPathRenderer> pr( 38 GrStencilAndCoverPathRenderer::Create(context->resourceProvider(), caps)); 39 if (pr) { 40 fChain.push_back(std::move(pr)); 41 } 42 } 43 #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK 44 if (options.fGpuPathRenderers & GpuPathRenderers::kMSAA) { 45 if (caps.sampleShadingSupport()) { 46 fChain.push_back(sk_make_sp<GrMSAAPathRenderer>()); 47 } 48 } 49 #endif 50 if (options.fGpuPathRenderers & GpuPathRenderers::kAAHairline) { 51 fChain.push_back(sk_make_sp<GrAAHairLinePathRenderer>()); 52 } 53 if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) { 54 fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>()); 55 } 56 if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) { 57 fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>()); 58 } 59 if (options.fGpuPathRenderers & GpuPathRenderers::kSmall) { 60 fChain.push_back(sk_make_sp<GrSmallPathRenderer>()); 61 } 62 if (options.fGpuPathRenderers & Options::GpuPathRenderers::kCoverageCounting) { 63 if (auto ccpr = GrCoverageCountingPathRenderer::CreateIfSupported(*context->caps())) { 64 context->contextPriv().addOnFlushCallbackObject(ccpr.get()); 65 fChain.push_back(std::move(ccpr)); 66 } 67 } 68 if (options.fGpuPathRenderers & GpuPathRenderers::kTessellating) { 69 fChain.push_back(sk_make_sp<GrTessellatingPathRenderer>()); 70 } 71 if (options.fGpuPathRenderers & GpuPathRenderers::kDefault) { 72 fChain.push_back(sk_make_sp<GrDefaultPathRenderer>()); 73 } 74 } 75 76 GrPathRenderer* GrPathRendererChain::getPathRenderer( 77 const GrPathRenderer::CanDrawPathArgs& args, 78 DrawType drawType, 79 GrPathRenderer::StencilSupport* stencilSupport) { 80 GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport < 81 GrPathRenderer::kStencilOnly_StencilSupport); 82 GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport < 83 GrPathRenderer::kNoRestriction_StencilSupport); 84 GrPathRenderer::StencilSupport minStencilSupport; 85 if (DrawType::kStencil == drawType) { 86 minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport; 87 } else if (DrawType::kStencilAndColor == drawType) { 88 minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 89 } else { 90 minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport; 91 } 92 if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) { 93 // We don't support (and shouldn't need) stenciling of non-fill paths. 94 if (!args.fShape->style().isSimpleFill()) { 95 return nullptr; 96 } 97 } 98 99 for (int i = 0; i < fChain.count(); ++i) { 100 if (fChain[i]->canDrawPath(args)) { 101 if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { 102 GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(*args.fShape); 103 if (support < minStencilSupport) { 104 continue; 105 } else if (stencilSupport) { 106 *stencilSupport = support; 107 } 108 } 109 return fChain[i].get(); 110 } 111 } 112 return nullptr; 113 } 114