aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/src/GrPathRenderer.h
blob: c2d30c0bd58c2afddda51e64219c65240dec7a33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
    Copyright 2011 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

#ifndef GrPathRenderer_DEFINED
#define GrPathRenderer_DEFINED

#include "GrDrawTarget.h"

class GrPathIter;
struct GrPoint;

/**
 *  Base class for drawing paths into a GrDrawTarget.
 */
class GrPathRenderer {
public:
    /**
     * Draws a path into the draw target. The target will already have its draw
     * state configured for the draw.
     * @param target                the target to draw into.
     * @param stages                indicates which stages the are already
     *                              in use. All enabled stages expect positions
     *                              as texture coordinates. The path renderer
     *                              use the remaining stages for its path
     *                              filling algorithm.
     * @param path                  the path to draw.
     * @param fill                  the fill rule to apply.
     * @param translate             optional additional translation to apply to
     *                              the path. NULL means (0,0).
     */
    virtual void drawPath(GrDrawTarget* target,
                          GrDrawTarget::StageBitfield stages,
                          GrPathIter* path,
                          GrPathFill fill,
                          const GrPoint* translate) = 0;

    void drawPath(GrDrawTarget* target,
                  GrDrawTarget::StageBitfield stages,
                  const GrPath& path,
                  GrPathFill fill,
                  const GrPoint* translate) {
            GrPath::Iter iter(path);
            this->drawPath(target, stages, &iter, fill, translate);
    }

    /**
     * For complex clips Gr uses the stencil buffer. The path renderer must be
     * able to render paths into the stencil buffer. However, the path renderer
     * itself may require the stencil buffer to resolve the path fill rule. This
     * function queries whether the path render needs its own stencil
     * pass. If this returns false then drawPath() should not modify the
     * the target's stencil settings but use those already set on target.
     *
     * @param target target that the path will be rendered to
     * @param path   the path that will be drawn
     * @param fill   the fill rule that will be used
     *
     * @return false if this path renderer can generate interior-only fragments
     *         without changing the stencil settings on the target. If it
     *         returns true the drawPathToStencil will be used when rendering
     *         clips.
     */
    virtual bool requiresStencilPass(const GrDrawTarget* target,
                                     GrPathIter* path,
                                     GrPathFill fill) const { return false; }

    bool requiresStencilPass(const GrDrawTarget* target,
                             const GrPath& path,
                             GrPathFill fill) const {
        GrPath::Iter iter(path);
        return requiresStencilPass(target, &iter, fill);
    }

    /**
     * Draws a path to the stencil buffer. Assume the writable stencil bits
     * are already initialized to zero. Fill will always be either
     * kWinding_PathFill or kEvenOdd_PathFill.
     *
     * Only called if requiresStencilPass returns true for the same combo of
     * target, path, and fill (or inverse of the fill).
     *
     * The default implementation assumes the path filling algorithm doesn't
     * require a separate stencil pass and so crashes.
     *
     *
     * @param target                the target to draw into.
     * @param path                  the path to draw.
     * @param fill                  the fill rule to apply.
     * @param translate             optional additional translation to apply to
     *                              the path. NULL means (0,0).
     */
    virtual void drawPathToStencil(GrDrawTarget* target,
                                   GrPathIter* path,
                                   GrPathFill fill,
                                   const GrPoint* translate) {
        GrCrash("Unexpected call to drawPathToStencil.");
    }

    void drawPathToStencil(GrDrawTarget* target,
                           const GrPath& path,
                           GrPathFill fill,
                           const GrPoint* translate) {
        GrPath::Iter iter(path);
        this->drawPathToStencil(target, &iter, fill, translate);
    }
};

/**
 *  Subclass that renders the path using the stencil buffer to resolve fill
 *  rules (e.g. winding, even-odd)
 */
class GrDefaultPathRenderer : public GrPathRenderer {
public:
    GrDefaultPathRenderer(bool separateStencilSupport,
                          bool stencilWrapOpsSupport);

    virtual void drawPath(GrDrawTarget* target,
                          GrDrawTarget::StageBitfield stages,
                          GrPathIter* path,
                          GrPathFill fill,
                          const GrPoint* translate);
    virtual bool requiresStencilPass(const GrDrawTarget* target,
                                     GrPathIter* path,
                                     GrPathFill fill) const;
    virtual void drawPathToStencil(GrDrawTarget* target,
                                   GrPathIter* path,
                                   GrPathFill fill,
                                   const GrPoint* translate);
private:

    void drawPathHelper(GrDrawTarget* target,
                        GrDrawTarget::StageBitfield stages,
                        GrPathIter* path,
                        GrPathFill fill,
                        const GrPoint* translate,
                        bool stencilOnly);

    bool    fSeparateStencil;
    bool    fStencilWrapOps;
};

#endif