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 "GrContext.h"
13#include "GrDefaultPathRenderer.h"
14#include "GrDrawTargetCaps.h"
15#include "GrGpu.h"
16
17GrPathRendererChain::GrPathRendererChain(GrContext* context)
18    : fInit(false)
19    , fOwner(context) {
20}
21
22GrPathRendererChain::~GrPathRendererChain() {
23    for (int i = 0; i < fChain.count(); ++i) {
24        fChain[i]->unref();
25    }
26}
27
28GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
29    fChain.push_back() = pr;
30    pr->ref();
31    return pr;
32}
33
34GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path,
35                                                     const SkStrokeRec& stroke,
36                                                     const GrDrawTarget* target,
37                                                     DrawType drawType,
38                                                     StencilSupport* stencilSupport) {
39    if (!fInit) {
40        this->init();
41    }
42    bool antiAlias = (kColorAntiAlias_DrawType == drawType ||
43                      kStencilAndColorAntiAlias_DrawType == drawType);
44
45    GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport <
46                     GrPathRenderer::kStencilOnly_StencilSupport);
47    GR_STATIC_ASSERT(GrPathRenderer::kStencilOnly_StencilSupport <
48                     GrPathRenderer::kNoRestriction_StencilSupport);
49    GrPathRenderer::StencilSupport minStencilSupport;
50    if (kStencilOnly_DrawType == drawType) {
51        minStencilSupport = GrPathRenderer::kStencilOnly_StencilSupport;
52    } else if (kStencilAndColor_DrawType == drawType ||
53               kStencilAndColorAntiAlias_DrawType == drawType) {
54        minStencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
55    } else {
56        minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport;
57    }
58
59
60    for (int i = 0; i < fChain.count(); ++i) {
61        if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) {
62            if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
63                GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path,
64                                                                                      stroke,
65                                                                                      target);
66                if (support < minStencilSupport) {
67                    continue;
68                } else if (stencilSupport) {
69                    *stencilSupport = support;
70                }
71            }
72            return fChain[i];
73        }
74    }
75    return NULL;
76}
77
78void GrPathRendererChain::init() {
79    SkASSERT(!fInit);
80    GrGpu* gpu = fOwner->getGpu();
81    bool twoSided = gpu->caps()->twoSidedStencilSupport();
82    bool wrapOp = gpu->caps()->stencilWrapOpsSupport();
83    GrPathRenderer::AddPathRenderers(fOwner, this);
84    this->addPathRenderer(SkNEW_ARGS(GrDefaultPathRenderer,
85                                     (twoSided, wrapOp)))->unref();
86    fInit = true;
87}
88