Home | History | Annotate | Download | only in gpu
      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     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 
     81 GrPathRenderer* 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