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     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