1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "GrPathRendererChain.h"
11
12#include "GrCaps.h"
13#include "gl/GrGLCaps.h"
14#include "glsl/GrGLSLCaps.h"
15#include "GrContext.h"
16#include "GrGpu.h"
17
18#include "batches/GrAAConvexPathRenderer.h"
19#include "batches/GrAADistanceFieldPathRenderer.h"
20#include "batches/GrAAHairLinePathRenderer.h"
21#include "batches/GrAALinearizingConvexPathRenderer.h"
22#include "batches/GrDashLinePathRenderer.h"
23#include "batches/GrDefaultPathRenderer.h"
24#include "batches/GrStencilAndCoverPathRenderer.h"
25#include "batches/GrTessellatingPathRenderer.h"
26#include "batches/GrPLSPathRenderer.h"
27
28GrPathRendererChain::GrPathRendererChain(GrContext* context) {
29    const GrCaps& caps = *context->caps();
30    this->addPathRenderer(new GrDashLinePathRenderer)->unref();
31
32    if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(context->resourceProvider(),
33                                                                   caps)) {
34        this->addPathRenderer(pr)->unref();
35    }
36    this->addPathRenderer(new GrTessellatingPathRenderer)->unref();
37    this->addPathRenderer(new GrAAHairLinePathRenderer)->unref();
38    this->addPathRenderer(new GrAAConvexPathRenderer)->unref();
39    this->addPathRenderer(new GrAALinearizingConvexPathRenderer)->unref();
40    if (caps.shaderCaps()->plsPathRenderingSupport()) {
41        this->addPathRenderer(new GrPLSPathRenderer)->unref();
42    }
43    this->addPathRenderer(new GrAADistanceFieldPathRenderer)->unref();
44    this->addPathRenderer(new GrDefaultPathRenderer(caps.twoSidedStencilSupport(),
45                                                    caps.stencilWrapOpsSupport()))->unref();
46}
47
48GrPathRendererChain::~GrPathRendererChain() {
49    for (int i = 0; i < fChain.count(); ++i) {
50        fChain[i]->unref();
51    }
52}
53
54GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
55    fChain.push_back() = pr;
56    pr->ref();
57    return pr;
58}
59
60GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
61                                                     DrawType drawType,
62                                                     GrPathRenderer::StencilSupport* stencilSupport) {
63    GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
64                     GrPathRenderer::kStencilOnly_StencilSupport);
65    GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
66                     GrPathRenderer::kNoRestriction_StencilSupport);
67    GrPathRenderer::StencilSupport minStencilSupport;
68    if (kStencilOnly_DrawType == drawType) {
69        minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
70    } else if (kStencilAndColor_DrawType == drawType ||
71               kStencilAndColorAntiAlias_DrawType == drawType) {
72        minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
73    } else {
74        minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
75    }
76
77    for (int i = 0; i < fChain.count(); ++i) {
78        if (fChain[i]->canDrawPath(args)) {
79            if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
80                GrPathRenderer::StencilSupport support =
81                                        fChain[i]->getStencilSupport(*args.fPath, *args.fStroke);
82                if (support < minStencilSupport) {
83                    continue;
84                } else if (stencilSupport) {
85                    *stencilSupport = support;
86                }
87            }
88            return fChain[i];
89        }
90    }
91    return nullptr;
92}
93