|  | /* | 
|  | * 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 |