1d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com */
8d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com#include "GrStencil.h"
11d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
12d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
13d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Stencil Rules for Merging user stencil space into clip
14d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
15d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// We can't include the clip bit in the ref or mask values because the division
16d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// between user and clip bits in the stencil depends on the number of stencil
17d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// bits in the runtime. Comments below indicate what the code should do to
18d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// incorporate the clip bit into these settings.
19d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
20d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
21d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Replace
22d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
23d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// set the ref to be the clip bit, but mask it out for the test
246b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipReplace,
256b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
266b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
276b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
286b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,           // unset clip bit
296b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
306b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
316b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
326b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipReplace,
336b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
346b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
356b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
366b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,           // unset clip bit
376b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
386b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
39d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
40d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
41d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Intersect
426b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipIsect,
436b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
446b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
456b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
466b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
476b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
486b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
496b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
506b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipIsect,
516b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
526b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
536b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
546b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
556b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
566b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
57d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
58d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
59d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Difference
606b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipDiff,
616b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
626b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
636b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
646b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
656b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
666b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
676b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
686b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipDiff,
696b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
706b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
716b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
726b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
736b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
746b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
75d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
76d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
77d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Union
78d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
79d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// first pass makes all the passing cases >= just clip bit set.
806b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass0,
816b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
826b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kKeep_StencilOp,
836b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLEqual_StencilFunc,
846b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
856b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0001,           // set clip bit
866b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
87d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
88d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// second pass allows anything greater than just clip bit set to pass
896b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass1,
906b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
916b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
926b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLEqual_StencilFunc,
936b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
946b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
956b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
96d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
976b20c2ded4bc546853719c88d1cf13b36fd89bcbbsalomon@google.com// first pass finds zeros in the user bits and if found sets
986b20c2ded4bc546853719c88d1cf13b36fd89bcbbsalomon@google.com// the clip bit to 1
996b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass0,
1006b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
1016b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kKeep_StencilOp,
1026b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
1036b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
1046b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
1056b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000            // set clip bit
1066b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
107d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
1086b20c2ded4bc546853719c88d1cf13b36fd89bcbbsalomon@google.com// second pass zeros the user bits
1096b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass1,
1106b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1116b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1126b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
1136b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
1146b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
1156b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff            // unset clip bit
1166b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
117d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
118d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
119d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Xor
1206b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass0,
1216b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
1226b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kKeep_StencilOp,
1236b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
1246b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,           // unset clip bit
1256b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
1266b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
1276b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
1286b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass1,
1296b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
1306b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1316b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kGreater_StencilFunc,
1326b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
1336b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,          // set clip bit
1346b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
1356b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
1366b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass0,
1376b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
1386b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kKeep_StencilOp,
1396b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
1406b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,           // unset clip bit
1416b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
1426b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
1436b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
1446b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass1,
1456b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
1466b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1476b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
1486b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
1496b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,          // set clip bit
1506b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
151d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
152d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
153d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Reverse Diff
1546b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass0,
1556b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
1566b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1576b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kLess_StencilFunc,
1586b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,         // unset clip bit
1596b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,         // set clip bit
1606b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
1616b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
1626b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass1,
1636b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
1646b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1656b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
1666b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,          // set clip bit
1676b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,          // set clip bit
1686b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff);
1696b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
17070fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com// We are looking for stencil values that are all zero. The first pass sets the
17170fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com// clip bit if the stencil is all zeros. The second pass clears the user bits.
17270fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipRDiffPass0,
1736b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
1746b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
1756b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kEqual_StencilFunc,
1766b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
1776b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
1786b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000           // set clip bit
1796b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
18070fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com
18170fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gInvUserToClipRDiffPass1,
18270fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    kZero_StencilOp,
18370fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    kZero_StencilOp,
18470fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    kAlways_StencilFunc,
18570fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    0xffff,
18670fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    0x0000,
18770fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com    0xffff           // unset clip bit
18870fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com);
18970fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com
190d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com///////
191d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// Direct to Stencil
192d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
193d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// We can render a clip element directly without first writing to the client
194d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// portion of the clip when the fill is not inverse and the set operation will
195d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// only modify the in/out status of samples covered by the clip element.
196d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
197d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com// this one only works if used right after stencil clip was cleared.
198a2d71482db8b6d752a51c96da74768d7dfc27932robertphillips@google.com// Our clip mask creation code doesn't allow midstream replace ops.
1996b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gReplaceClip,
2006b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
2016b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
2026b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kAlways_StencilFunc,
2036b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
2046b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
2056b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000            // set clipBit
2066b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
2076b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
2086b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gUnionClip,
2096b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
2106b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kReplace_StencilOp,
2116b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kAlways_StencilFunc,
2126b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
2136b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,           // set clip bit
2146b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000            // set clip bit
2156b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
2166b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
2176b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gXorClip,
2186b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
2196b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kInvert_StencilOp,
2206b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kAlways_StencilFunc,
2216b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
2226b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
2236b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000            // set clip bit
2246b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
2256b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com
2266b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.comGR_STATIC_CONST_SAME_STENCIL(gDiffClip,
2276b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
2286b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kZero_StencilOp,
2296b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    kAlways_StencilFunc,
2306b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0xffff,
2316b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000,
2326b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com    0x0000            // set clip bit
2336b2445eb154d71517b1ed6811f3f77eec592963absalomon@google.com);
234d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
235a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.combool GrStencilSettings::GetClipPasses(
236fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                            SkRegion::Op op,
237a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                            bool canBeDirect,
238a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                            unsigned int stencilClipMask,
239a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                            bool invertedFill,
240a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                            int* numPasses,
241a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                            GrStencilSettings settings[kMaxStencilClipPasses]) {
2427f5875d33462f0f1b96a36ac530fb1f2edb1d535bsalomon@google.com    if (canBeDirect && !invertedFill) {
2435aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        *numPasses = 0;
2445aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        switch (op) {
2450f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com            case SkRegion::kReplace_Op:
2465aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                *numPasses = 1;
2475aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                settings[0] = gReplaceClip;
2485aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                break;
2490f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com            case SkRegion::kUnion_Op:
2505aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                *numPasses = 1;
2515aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                settings[0] = gUnionClip;
2525aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                break;
2530f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com            case SkRegion::kXOR_Op:
2545aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                *numPasses = 1;
2555aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                settings[0] = gXorClip;
2565aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                break;
2570f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com            case SkRegion::kDifference_Op:
2585aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                *numPasses = 1;
2595aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                settings[0] = gDiffClip;
2605aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                break;
2615aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            default: // suppress warning
2625aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com                break;
2635aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        }
2645aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        if (1 == *numPasses) {
265a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kFront_Face]   |= stencilClipMask;
266a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
267a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kBack_Face] =
268a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face];
269a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fWriteMasks[kBack_Face] =
270a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fWriteMasks[kFront_Face];
2715aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            return true;
272d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        }
273d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    }
274d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    switch (op) {
2755aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        // if we make the path renderer go to stencil we always give it a
2765aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        // non-inverted fill and we use the stencil rules on the client->clipbit
2775aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com        // pass to select either the zeros or nonzeros.
2780f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kReplace_Op:
279d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            *numPasses= 1;
280a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0] = invertedFill ? gInvUserToClipReplace :
281a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                                         gUserToClipReplace;
282a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
283a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
284a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncMasks[kBack_Face] =
285a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face];
286a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kBack_Face] =
287a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face];
2885aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            break;
2890f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kIntersect_Op:
290d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            *numPasses = 1;
2915aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            settings[0] = invertedFill ? gInvUserToClipIsect : gUserToClipIsect;
292a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kFront_Face] = stencilClipMask;
293a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kBack_Face] =
294a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face];
295d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            break;
2960f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kUnion_Op:
297d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            *numPasses = 2;
2985aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            if (invertedFill) {
299d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[0] = gInvUserToClipUnionPass0;
300a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
301a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kBack_Face] =
302a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncMasks[kFront_Face];
303a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
304a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kBack_Face] =
305a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncRefs[kFront_Face];
306a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
307a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fWriteMasks[kBack_Face] =
308a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fWriteMasks[kFront_Face];
309d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
310d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[1] = gInvUserToClipUnionPass1;
311a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
312a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fWriteMasks[kBack_Face] &=
313a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fWriteMasks[kFront_Face];
314d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
315d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            } else {
316d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[0] = gUserToClipUnionPass0;
317a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
318a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
319a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kBack_Face] =
320a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncMasks[kFront_Face];
321a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kBack_Face] =
322a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncRefs[kFront_Face];
323d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
324d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[1] = gUserToClipUnionPass1;
325a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
326a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kBack_Face] =
327a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fFuncRefs[kFront_Face];
328d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            }
329d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            break;
3300f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kXOR_Op:
331d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            *numPasses = 2;
3325aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            if (invertedFill) {
333d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[0] = gInvUserToClipXorPass0;
334a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
335a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kBack_Face] =
336a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncMasks[kFront_Face];
337d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
338d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[1] = gInvUserToClipXorPass1;
339a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
340a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kBack_Face] =
341a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fFuncRefs[kFront_Face];
342d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            } else {
343d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[0] = gUserToClipXorPass0;
344a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
345a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kBack_Face] =
346a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncMasks[kFront_Face];
347d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
348d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[1] = gUserToClipXorPass1;
349a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
350a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kBack_Face] =
351a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fFuncRefs[kFront_Face];
352d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            }
353d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            break;
3540f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kDifference_Op:
355d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            *numPasses = 1;
3565aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            settings[0] = invertedFill ? gInvUserToClipDiff : gUserToClipDiff;
357a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
358a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com            settings[0].fFuncRefs[kBack_Face] =
359a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face];
360d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            break;
3610f191f30af7c067883c97b034baf70bfd92f5ea0robertphillips@google.com        case SkRegion::kReverseDifference_Op:
3625aaa69e4339e229adfb05e96084a8ec0a590238bbsalomon@google.com            if (invertedFill) {
36370fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                *numPasses = 2;
36470fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                settings[0] = gInvUserToClipRDiffPass0;
365a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
366a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fWriteMasks[kBack_Face] =
367a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fWriteMasks[kFront_Face];
36870fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                settings[1] = gInvUserToClipRDiffPass1;
36970fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
37070fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                settings[1].fWriteMasks[kBack_Face] =
37170fc152576d3e7e1405e8234a097054c609eeb77bsalomon@google.com                    settings[1].fWriteMasks[kFront_Face];
372d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            } else {
373d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                *numPasses = 2;
374d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[0] = gUserToClipRDiffPass0;
375a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
376a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncMasks[kBack_Face] =
377a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncMasks[kFront_Face];
378a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
379a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[0].fFuncRefs[kBack_Face] =
380a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[0].fFuncRefs[kFront_Face];
381d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
382d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                settings[1] = gUserToClipRDiffPass1;
383a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncMasks[kFront_Face] |= stencilClipMask;
384a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
385a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncMasks[kBack_Face] =
386a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fFuncMasks[kFront_Face];
387a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                settings[1].fFuncRefs[kBack_Face] =
388a320194e4242ef0e5e758aea896bfd52bcb3dac7bsalomon@google.com                    settings[1].fFuncRefs[kFront_Face];
389d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            }
390d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            break;
391d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        default:
39288cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unknown set op");
393d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    }
394d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    return false;
395d5683e2caac8dcfc6328547077ff9dc965d172e8ctguil@chromium.org}
396