aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops/GrPathStencilSettings.h
blob: f37d1b2f18074a3909155fc748363937d0c4a59c (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
156
157
158
159
160
/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrPathStencilSettings_DEFINED
#define GrPathStencilSettings_DEFINED

#include "GrUserStencilSettings.h"

////////////////////////////////////////////////////////////////////////////////
// Stencil rules for paths

////// Even/Odd

static constexpr GrUserStencilSettings gEOStencilPass(
    GrUserStencilSettings::StaticInit<
        0xffff,
        GrUserStencilTest::kAlwaysIfInClip,
        0xffff,
        GrUserStencilOp::kInvert,
        GrUserStencilOp::kKeep,
        0xffff>()
);

// ok not to check clip b/c stencil pass only wrote inside clip
static constexpr GrUserStencilSettings gEOColorPass(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kNotEqual,
        0xffff,
        GrUserStencilOp::kZero,
        GrUserStencilOp::kZero,
        0xffff>()
);

// have to check clip b/c outside clip will always be zero.
static constexpr GrUserStencilSettings gInvEOColorPass(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kEqualIfInClip,
        0xffff,
        GrUserStencilOp::kZero,
        GrUserStencilOp::kZero,
        0xffff>()
);

////// Winding

// when we have separate stencil we increment front faces / decrement back faces
// when we don't have wrap incr and decr we use the stencil test to simulate
// them.

static constexpr GrUserStencilSettings gWindStencilSeparateWithWrap(
    GrUserStencilSettings::StaticInitSeparate<
        0xffff,                                0xffff,
        GrUserStencilTest::kAlwaysIfInClip,    GrUserStencilTest::kAlwaysIfInClip,
        0xffff,                                0xffff,
        GrUserStencilOp::kIncWrap,             GrUserStencilOp::kDecWrap,
        GrUserStencilOp::kKeep,                GrUserStencilOp::kKeep,
        0xffff,                                0xffff>()
);

// if inc'ing the max value, invert to make 0
// if dec'ing zero invert to make all ones.
// we can't avoid touching the stencil on both passing and
// failing, so we can't resctrict ourselves to the clip.
static constexpr GrUserStencilSettings gWindStencilSeparateNoWrap(
    GrUserStencilSettings::StaticInitSeparate<
        0xffff,                                0x0000,
        GrUserStencilTest::kEqual,             GrUserStencilTest::kEqual,
        0xffff,                                0xffff,
        GrUserStencilOp::kInvert,              GrUserStencilOp::kInvert,
        GrUserStencilOp::kIncMaybeClamp,       GrUserStencilOp::kDecMaybeClamp,
        0xffff,                                0xffff>()
);

// When there are no separate faces we do two passes to setup the winding rule
// stencil. First we draw the front faces and inc, then we draw the back faces
// and dec. These are same as the above two split into the incrementing and
// decrementing passes.
static constexpr GrUserStencilSettings gWindSingleStencilWithWrapInc(
    GrUserStencilSettings::StaticInit<
        0xffff,
        GrUserStencilTest::kAlwaysIfInClip,
        0xffff,
        GrUserStencilOp::kIncWrap,
        GrUserStencilOp::kKeep,
        0xffff>()
);

static constexpr GrUserStencilSettings gWindSingleStencilWithWrapDec(
    GrUserStencilSettings::StaticInit<
        0xffff,
        GrUserStencilTest::kAlwaysIfInClip,
        0xffff,
        GrUserStencilOp::kDecWrap,
        GrUserStencilOp::kKeep,
        0xffff>()
);

static constexpr GrUserStencilSettings gWindSingleStencilNoWrapInc(
    GrUserStencilSettings::StaticInit<
        0xffff,
        GrUserStencilTest::kEqual,
        0xffff,
        GrUserStencilOp::kInvert,
        GrUserStencilOp::kIncMaybeClamp,
        0xffff>()
);

static constexpr GrUserStencilSettings gWindSingleStencilNoWrapDec(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kEqual,
        0xffff,
        GrUserStencilOp::kInvert,
        GrUserStencilOp::kDecMaybeClamp,
        0xffff>()
);

// Color passes are the same whether we use the two-sided stencil or two passes

static constexpr GrUserStencilSettings gWindColorPass(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kLessIfInClip, // "0 < stencil" is equivalent to "0 != stencil".
        0xffff,
        GrUserStencilOp::kZero,
        GrUserStencilOp::kZero,
        0xffff>()
);

static constexpr GrUserStencilSettings gInvWindColorPass(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kEqualIfInClip,
        0xffff,
        GrUserStencilOp::kZero,
        GrUserStencilOp::kZero,
        0xffff>()
);

////// Normal render to stencil

// Sometimes the default path renderer can draw a path directly to the stencil
// buffer without having to first resolve the interior / exterior.
static constexpr GrUserStencilSettings gDirectToStencil(
    GrUserStencilSettings::StaticInit<
        0x0000,
        GrUserStencilTest::kAlwaysIfInClip,
        0xffff,
        GrUserStencilOp::kZero,
        GrUserStencilOp::kIncMaybeClamp,
        0xffff>()
);

#endif