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