LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrStencilSettings.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 88 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2011 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : 
       9             : #include "GrStencilSettings.h"
      10             : 
      11             : #include "GrProcessor.h"
      12             : 
      13             : constexpr const GrUserStencilSettings gUnused(
      14             :     GrUserStencilSettings::StaticInit<
      15             :         0x0000,
      16             :         GrUserStencilTest::kAlwaysIfInClip,
      17             :         0xffff,
      18             :         GrUserStencilOp::kKeep,
      19             :         GrUserStencilOp::kKeep,
      20             :         0x0000>()
      21             : );
      22             : 
      23             : GR_STATIC_ASSERT(kAll_StencilFlags == (gUnused.fFrontFlags[0] & gUnused.fBackFlags[0]));
      24             : 
      25             : const GrUserStencilSettings& GrUserStencilSettings::kUnused = gUnused;
      26             : 
      27           0 : void GrStencilSettings::reset(const GrUserStencilSettings& user, bool hasStencilClip,
      28             :                               int numStencilBits) {
      29           0 :     uint16_t frontFlags = user.fFrontFlags[hasStencilClip];
      30           0 :     if (frontFlags & kSingleSided_StencilFlag) {
      31           0 :         SkASSERT(frontFlags == user.fBackFlags[hasStencilClip]);
      32           0 :         fFlags = frontFlags;
      33           0 :         if (!this->isDisabled()) {
      34           0 :             fFront.reset(user.fFront, hasStencilClip, numStencilBits);
      35             :         }
      36           0 :         return;
      37             :     }
      38             : 
      39           0 :     uint16_t backFlags = user.fBackFlags[hasStencilClip];
      40           0 :     fFlags = frontFlags & backFlags;
      41           0 :     if (this->isDisabled()) {
      42           0 :         return;
      43             :     }
      44           0 :     if (!(frontFlags & kDisabled_StencilFlag)) {
      45           0 :         fFront.reset(user.fFront, hasStencilClip, numStencilBits);
      46             :     } else {
      47           0 :         fFront.setDisabled();
      48             :     }
      49           0 :     if (!(backFlags & kDisabled_StencilFlag)) {
      50           0 :         fBack.reset(user.fBack, hasStencilClip, numStencilBits);
      51             :     } else {
      52           0 :         fBack.setDisabled();
      53             :     }
      54             : }
      55             : 
      56           0 : void GrStencilSettings::reset(const GrStencilSettings& that) {
      57           0 :     fFlags = that.fFlags;
      58           0 :     if ((kInvalid_PrivateFlag | kDisabled_StencilFlag) & fFlags) {
      59           0 :         return;
      60             :     }
      61           0 :     if (!this->isTwoSided()) {
      62           0 :         memcpy(&fFront, &that.fFront, sizeof(Face));
      63             :     } else {
      64           0 :         memcpy(&fFront, &that.fFront, 2 * sizeof(Face));
      65             :         GR_STATIC_ASSERT(sizeof(Face) ==
      66             :                          offsetof(GrStencilSettings, fBack) - offsetof(GrStencilSettings, fFront));
      67             :     }
      68             : }
      69             : 
      70           0 : bool GrStencilSettings::operator==(const GrStencilSettings& that) const {
      71           0 :     if ((kInvalid_PrivateFlag | kDisabled_StencilFlag) & (fFlags | that.fFlags)) {
      72             :         // At least one is invalid and/or disabled.
      73           0 :         if (kInvalid_PrivateFlag & (fFlags | that.fFlags)) {
      74           0 :             return false; // We never allow invalid stencils to be equal.
      75             :         }
      76             :         // They're only equal if both are disabled.
      77           0 :         return kDisabled_StencilFlag & (fFlags & that.fFlags);
      78             :     }
      79           0 :     if (kSingleSided_StencilFlag & (fFlags & that.fFlags)) {
      80           0 :         return 0 == memcmp(&fFront, &that.fFront, sizeof(Face)); // Both are single sided.
      81           0 :     } else if (kSingleSided_StencilFlag & (fFlags | that.fFlags)) {
      82           0 :         return false;
      83             :     } else {
      84           0 :         return 0 == memcmp(&fFront, &that.fFront, 2 * sizeof(Face));
      85             :         GR_STATIC_ASSERT(sizeof(Face) ==
      86             :                          offsetof(GrStencilSettings, fBack) - offsetof(GrStencilSettings, fFront));
      87             :     }
      88             :     // memcmp relies on GrStencilSettings::Face being tightly packed.
      89             :     GR_STATIC_ASSERT(0 == offsetof(Face, fRef));
      90             :     GR_STATIC_ASSERT(2 == sizeof(Face::fRef));
      91             :     GR_STATIC_ASSERT(2 == offsetof(Face, fTest));
      92             :     GR_STATIC_ASSERT(2 == sizeof(Face::fTest));
      93             :     GR_STATIC_ASSERT(4 == offsetof(Face, fTestMask));
      94             :     GR_STATIC_ASSERT(2 == sizeof(Face::fTestMask));
      95             :     GR_STATIC_ASSERT(6 == offsetof(Face, fPassOp));
      96             :     GR_STATIC_ASSERT(1 == sizeof(Face::fPassOp));
      97             :     GR_STATIC_ASSERT(7 == offsetof(Face, fFailOp));
      98             :     GR_STATIC_ASSERT(1 == sizeof(Face::fFailOp));
      99             :     GR_STATIC_ASSERT(8 == offsetof(Face, fWriteMask));
     100             :     GR_STATIC_ASSERT(2 == sizeof(Face::fWriteMask));
     101             :     GR_STATIC_ASSERT(10 == sizeof(Face));
     102             : }
     103             : 
     104             : static constexpr GrStencilTest gUserStencilTestToRaw[kGrUserStencilTestCount] = {
     105             :     // Tests that respect the clip.
     106             :     GrStencilTest::kAlways,  // kAlwaysIfInClip (This is only for when there is not a stencil clip).
     107             :     GrStencilTest::kEqual,   // kEqualIfInClip.
     108             :     GrStencilTest::kLess,    // kLessIfInClip.
     109             :     GrStencilTest::kLEqual,  // kLEqualIfInClip.
     110             : 
     111             :     // Tests that ignore the clip.
     112             :     GrStencilTest::kAlways,
     113             :     GrStencilTest::kNever,
     114             :     GrStencilTest::kGreater,
     115             :     GrStencilTest::kGEqual,
     116             :     GrStencilTest::kLess,
     117             :     GrStencilTest::kLEqual,
     118             :     GrStencilTest::kEqual,
     119             :     GrStencilTest::kNotEqual
     120             : };
     121             : 
     122             : GR_STATIC_ASSERT(0 == (int)GrUserStencilTest::kAlwaysIfInClip);
     123             : GR_STATIC_ASSERT(1 == (int)GrUserStencilTest::kEqualIfInClip);
     124             : GR_STATIC_ASSERT(2 == (int)GrUserStencilTest::kLessIfInClip);
     125             : GR_STATIC_ASSERT(3 == (int)GrUserStencilTest::kLEqualIfInClip);
     126             : GR_STATIC_ASSERT(4 == (int)GrUserStencilTest::kAlways);
     127             : GR_STATIC_ASSERT(5 == (int)GrUserStencilTest::kNever);
     128             : GR_STATIC_ASSERT(6 == (int)GrUserStencilTest::kGreater);
     129             : GR_STATIC_ASSERT(7 == (int)GrUserStencilTest::kGEqual);
     130             : GR_STATIC_ASSERT(8 == (int)GrUserStencilTest::kLess);
     131             : GR_STATIC_ASSERT(9 == (int)GrUserStencilTest::kLEqual);
     132             : GR_STATIC_ASSERT(10 == (int)GrUserStencilTest::kEqual);
     133             : GR_STATIC_ASSERT(11 == (int)GrUserStencilTest::kNotEqual);
     134             : 
     135             : static constexpr GrStencilOp gUserStencilOpToRaw[kGrUserStencilOpCount] = {
     136             :     GrStencilOp::kKeep,
     137             : 
     138             :     // Ops that only modify user bits.
     139             :     GrStencilOp::kZero,
     140             :     GrStencilOp::kReplace,
     141             :     GrStencilOp::kInvert,
     142             :     GrStencilOp::kIncWrap,
     143             :     GrStencilOp::kDecWrap,
     144             :     GrStencilOp::kIncClamp,  // kIncMaybeClamp.
     145             :     GrStencilOp::kDecClamp,  // kDecMaybeClamp.
     146             : 
     147             :     // Ops that only modify the clip bit.
     148             :     GrStencilOp::kZero,      // kZeroClipBit.
     149             :     GrStencilOp::kReplace,   // kSetClipBit.
     150             :     GrStencilOp::kInvert,    // kInvertClipBit.
     151             : 
     152             :     // Ops that modify clip and user bits.
     153             :     GrStencilOp::kReplace,   // kSetClipAndReplaceUserBits.
     154             :     GrStencilOp::kZero       // kZeroClipAndUserBits.
     155             : };
     156             : 
     157             : GR_STATIC_ASSERT(0 == (int)GrUserStencilOp::kKeep);
     158             : GR_STATIC_ASSERT(1 == (int)GrUserStencilOp::kZero);
     159             : GR_STATIC_ASSERT(2 == (int)GrUserStencilOp::kReplace);
     160             : GR_STATIC_ASSERT(3 == (int)GrUserStencilOp::kInvert);
     161             : GR_STATIC_ASSERT(4 == (int)GrUserStencilOp::kIncWrap);
     162             : GR_STATIC_ASSERT(5 == (int)GrUserStencilOp::kDecWrap);
     163             : GR_STATIC_ASSERT(6 == (int)GrUserStencilOp::kIncMaybeClamp);
     164             : GR_STATIC_ASSERT(7 == (int)GrUserStencilOp::kDecMaybeClamp);
     165             : GR_STATIC_ASSERT(8 == (int)GrUserStencilOp::kZeroClipBit);
     166             : GR_STATIC_ASSERT(9 == (int)GrUserStencilOp::kSetClipBit);
     167             : GR_STATIC_ASSERT(10 == (int)GrUserStencilOp::kInvertClipBit);
     168             : GR_STATIC_ASSERT(11 == (int)GrUserStencilOp::kSetClipAndReplaceUserBits);
     169             : GR_STATIC_ASSERT(12 == (int)GrUserStencilOp::kZeroClipAndUserBits);
     170             : 
     171           0 : void GrStencilSettings::Face::reset(const GrUserStencilSettings::Face& user, bool hasStencilClip,
     172             :                                     int numStencilBits) {
     173           0 :     SkASSERT(user.fTest < (GrUserStencilTest)kGrUserStencilTestCount);
     174           0 :     SkASSERT(user.fPassOp < (GrUserStencilOp)kGrUserStencilOpCount);
     175           0 :     SkASSERT(user.fFailOp < (GrUserStencilOp)kGrUserStencilOpCount);
     176           0 :     SkASSERT(numStencilBits > 0 && numStencilBits <= 16);
     177           0 :     int clipBit = 1 << (numStencilBits - 1);
     178           0 :     int userMask = clipBit - 1;
     179             : 
     180           0 :     GrUserStencilOp maxOp = SkTMax(user.fPassOp, user.fFailOp);
     181           0 :     SkDEBUGCODE(GrUserStencilOp otherOp = SkTMin(user.fPassOp, user.fFailOp);)
     182           0 :     if (maxOp <= kLastUserOnlyStencilOp) {
     183             :         // Ops that only modify user bits.
     184           0 :         fWriteMask = user.fWriteMask & userMask;
     185           0 :         SkASSERT(otherOp <= kLastUserOnlyStencilOp);
     186           0 :     } else if (maxOp <= kLastClipOnlyStencilOp) {
     187             :         // Ops that only modify the clip bit.
     188           0 :         fWriteMask = clipBit;
     189           0 :         SkASSERT(GrUserStencilOp::kKeep == otherOp ||
     190             :                  (otherOp > kLastUserOnlyStencilOp && otherOp <= kLastClipOnlyStencilOp));
     191             :     } else {
     192             :         // Ops that modify both clip and user bits.
     193           0 :         fWriteMask = clipBit | (user.fWriteMask & userMask);
     194           0 :         SkASSERT(GrUserStencilOp::kKeep == otherOp || otherOp > kLastClipOnlyStencilOp);
     195             :     }
     196             : 
     197           0 :     fFailOp = gUserStencilOpToRaw[(int)user.fFailOp];
     198           0 :     fPassOp = gUserStencilOpToRaw[(int)user.fPassOp];
     199             : 
     200           0 :     if (!hasStencilClip || user.fTest > kLastClippedStencilTest) {
     201             :         // Ignore the clip.
     202           0 :         fTestMask = user.fTestMask & userMask;
     203           0 :         fTest = gUserStencilTestToRaw[(int)user.fTest];
     204           0 :     } else if (GrUserStencilTest::kAlwaysIfInClip != user.fTest) {
     205             :         // Respect the clip.
     206           0 :         fTestMask = clipBit | (user.fTestMask & userMask);
     207           0 :         fTest = gUserStencilTestToRaw[(int)user.fTest];
     208             :     } else {
     209             :         // Test only for clip.
     210           0 :         fTestMask = clipBit;
     211           0 :         fTest = GrStencilTest::kEqual;
     212             :     }
     213             : 
     214           0 :     fRef = (clipBit | user.fRef) & (fTestMask | fWriteMask);
     215           0 : }
     216             : 
     217           0 : void GrStencilSettings::Face::setDisabled() {
     218           0 :     memset(this, 0, sizeof(*this));
     219             :     GR_STATIC_ASSERT(0 == (int)GrStencilTest::kAlways);
     220             :     GR_STATIC_ASSERT(0 == (int)GrStencilOp::kKeep);
     221           0 : }
     222             : 
     223             : ////////////////////////////////////////////////////////////////////////////////
     224             : // Stencil Rules for Merging user stencil space into clip
     225             : //
     226             : 
     227             : ///////
     228             : // Replace
     229             : static constexpr GrUserStencilSettings gUserToClipReplace(
     230             :     GrUserStencilSettings::StaticInit<
     231             :         0x0000,
     232             :         GrUserStencilTest::kNotEqual,
     233             :         0xffff,
     234             :         GrUserStencilOp::kSetClipAndReplaceUserBits,
     235             :         GrUserStencilOp::kZeroClipAndUserBits,
     236             :         0xffff>()
     237             : );
     238             : 
     239             : static constexpr GrUserStencilSettings gInvUserToClipReplace(
     240             :     GrUserStencilSettings::StaticInit<
     241             :         0x0000,
     242             :         GrUserStencilTest::kEqual,
     243             :         0xffff,
     244             :         GrUserStencilOp::kSetClipAndReplaceUserBits,
     245             :         GrUserStencilOp::kZeroClipAndUserBits,
     246             :         0xffff>()
     247             : );
     248             : 
     249             : ///////
     250             : // Intersect
     251             : static constexpr GrUserStencilSettings gUserToClipIsect(
     252             :     GrUserStencilSettings::StaticInit<
     253             :         0x0000,
     254             :         GrUserStencilTest::kLessIfInClip, // "0 < userBits" is equivalent to "0 != userBits".
     255             :         0xffff,
     256             :         GrUserStencilOp::kSetClipAndReplaceUserBits,
     257             :         GrUserStencilOp::kZeroClipAndUserBits,
     258             :         0xffff>()
     259             : );
     260             : 
     261             : ///////
     262             : // Difference
     263             : static constexpr GrUserStencilSettings gUserToClipDiff(
     264             :     GrUserStencilSettings::StaticInit<
     265             :         0x0000,
     266             :         GrUserStencilTest::kEqualIfInClip,
     267             :         0xffff,
     268             :         GrUserStencilOp::kSetClipAndReplaceUserBits,
     269             :         GrUserStencilOp::kZeroClipAndUserBits,
     270             :         0xffff>()
     271             : );
     272             : 
     273             : ///////
     274             : // Union
     275             : static constexpr GrUserStencilSettings gUserToClipUnion(
     276             :     GrUserStencilSettings::StaticInit<
     277             :         0x0000,
     278             :         GrUserStencilTest::kNotEqual,
     279             :         0xffff,
     280             :         GrUserStencilOp::kSetClipAndReplaceUserBits,
     281             :         GrUserStencilOp::kKeep,
     282             :         0xffff>()
     283             : );
     284             : 
     285             : static constexpr GrUserStencilSettings gInvUserToClipUnionPass0( // Does not zero user bits.
     286             :     GrUserStencilSettings::StaticInit<
     287             :         0x0000,
     288             :         GrUserStencilTest::kEqual,
     289             :         0xffff,
     290             :         GrUserStencilOp::kSetClipBit,
     291             :         GrUserStencilOp::kKeep,
     292             :         0x0000>()
     293             : );
     294             : 
     295             : ///////
     296             : // Xor
     297             : static constexpr GrUserStencilSettings gUserToClipXorPass0( // Does not zero user bits.
     298             :     GrUserStencilSettings::StaticInit<
     299             :         0x0000,
     300             :         GrUserStencilTest::kNotEqual,
     301             :         0xffff,
     302             :         GrUserStencilOp::kInvertClipBit,
     303             :         GrUserStencilOp::kKeep,
     304             :         0x0000>()
     305             : );
     306             : 
     307             : static constexpr GrUserStencilSettings gInvUserToClipXorPass0( // Does not zero user bits.
     308             :     GrUserStencilSettings::StaticInit<
     309             :         0x0000,
     310             :         GrUserStencilTest::kEqual,
     311             :         0xffff,
     312             :         GrUserStencilOp::kInvertClipBit,
     313             :         GrUserStencilOp::kKeep,
     314             :         0x0000>()
     315             : );
     316             : 
     317             : ///////
     318             : // Reverse Diff
     319             : static constexpr GrUserStencilSettings gUserToClipRDiffPass0( // Does not zero user bits.
     320             :     GrUserStencilSettings::StaticInit<
     321             :         0x0000,
     322             :         GrUserStencilTest::kNotEqual,
     323             :         0xffff,
     324             :         GrUserStencilOp::kInvertClipBit,
     325             :         GrUserStencilOp::kZeroClipBit,
     326             :         0x0000>()
     327             : );
     328             : 
     329             : static constexpr GrUserStencilSettings gInvUserToClipRDiffPass0( // Does not zero user bits.
     330             :     GrUserStencilSettings::StaticInit<
     331             :         0x0000,
     332             :         GrUserStencilTest::kEqual,
     333             :         0xffff,
     334             :         GrUserStencilOp::kInvertClipBit,
     335             :         GrUserStencilOp::kZeroClipBit,
     336             :         0x0000>()
     337             : );
     338             : 
     339             : ///////
     340             : // Second pass to clear user bits (only needed sometimes)
     341             : static constexpr GrUserStencilSettings gZeroUserBits(
     342             :     GrUserStencilSettings::StaticInit<
     343             :         0x0000,
     344             :         GrUserStencilTest::kNotEqual,
     345             :         0xffff,
     346             :         GrUserStencilOp::kZero,
     347             :         GrUserStencilOp::kKeep,
     348             :         0xffff>()
     349             : );
     350             : 
     351             : static constexpr const GrUserStencilSettings* gUserToClipTable[2][1 + SkRegion::kLastOp][3] = {
     352             :     {  /* Normal fill. */
     353             :         {&gUserToClipDiff,           nullptr,         nullptr},  // kDifference_Op.
     354             :         {&gUserToClipIsect,          nullptr,         nullptr},  // kIntersect_Op.
     355             :         {&gUserToClipUnion,          nullptr,         nullptr},  // kUnion_Op.
     356             :         {&gUserToClipXorPass0,       &gZeroUserBits,  nullptr},  // kXOR_Op.
     357             :         {&gUserToClipRDiffPass0,     &gZeroUserBits,  nullptr},  // kReverseDifference_Op.
     358             :         {&gUserToClipReplace,        nullptr,         nullptr}   // kReplace_Op.
     359             : 
     360             :     }, /* Inverse fill. */ {
     361             :         {&gUserToClipIsect,          nullptr,         nullptr},  // ~diff (aka isect).
     362             :         {&gUserToClipDiff,           nullptr,         nullptr},  // ~isect (aka diff).
     363             :         {&gInvUserToClipUnionPass0,  &gZeroUserBits,  nullptr},  // ~union.
     364             :         {&gInvUserToClipXorPass0,    &gZeroUserBits,  nullptr},  // ~xor.
     365             :         {&gInvUserToClipRDiffPass0,  &gZeroUserBits,  nullptr},  // ~reverse diff.
     366             :         {&gInvUserToClipReplace,     nullptr,         nullptr}   // ~replace.
     367             :     }
     368             : };
     369             : 
     370             : GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
     371             : GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
     372             : GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
     373             : GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
     374             : GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
     375             : GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
     376             : 
     377             : ///////
     378             : // Direct to Stencil
     379             : 
     380             : // We can render a clip element directly without first writing to the client
     381             : // portion of the clip when the fill is not inverse and the set operation will
     382             : // only modify the in/out status of samples covered by the clip element.
     383             : 
     384             : // this one only works if used right after stencil clip was cleared.
     385             : // Our clip mask creation code doesn't allow midstream replace ops.
     386             : static constexpr GrUserStencilSettings gReplaceClip(
     387             :     GrUserStencilSettings::StaticInit<
     388             :         0x0000,
     389             :         GrUserStencilTest::kAlways,
     390             :         0xffff,
     391             :         GrUserStencilOp::kSetClipBit,
     392             :         GrUserStencilOp::kSetClipBit,
     393             :         0x0000>()
     394             : );
     395             : 
     396             : static constexpr GrUserStencilSettings gUnionClip(
     397             :     GrUserStencilSettings::StaticInit<
     398             :         0x0000,
     399             :         GrUserStencilTest::kAlwaysIfInClip,
     400             :         0xffff,
     401             :         GrUserStencilOp::kKeep,
     402             :         GrUserStencilOp::kSetClipBit,
     403             :         0x0000>()
     404             : );
     405             : 
     406             : static constexpr GrUserStencilSettings gXorClip(
     407             :     GrUserStencilSettings::StaticInit<
     408             :         0x0000,
     409             :         GrUserStencilTest::kAlways,
     410             :         0xffff,
     411             :         GrUserStencilOp::kInvertClipBit,
     412             :         GrUserStencilOp::kInvertClipBit,
     413             :         0x0000>()
     414             : );
     415             : 
     416             : static constexpr GrUserStencilSettings gDiffClip(
     417             :     GrUserStencilSettings::StaticInit<
     418             :         0x0000,
     419             :         GrUserStencilTest::kAlwaysIfInClip,
     420             :         0xffff,
     421             :         GrUserStencilOp::kZeroClipBit,
     422             :         GrUserStencilOp::kKeep,
     423             :         0x0000>()
     424             : );
     425             : 
     426             : static constexpr const GrUserStencilSettings* gDirectDrawTable[1 + SkRegion::kLastOp][2] = {
     427             :     {&gDiffClip,     nullptr},  // kDifference_Op.
     428             :     {nullptr,        nullptr},  // kIntersect_Op.
     429             :     {&gUnionClip,    nullptr},  // kUnion_Op.
     430             :     {&gXorClip,      nullptr},  // kXOR_Op.
     431             :     {nullptr,        nullptr},  // kReverseDifference_Op.
     432             :     {&gReplaceClip,  nullptr}   // kReplace_Op.
     433             : };
     434             : 
     435             : GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
     436             : GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
     437             : GR_STATIC_ASSERT(2 == SkRegion::kUnion_Op);
     438             : GR_STATIC_ASSERT(3 == SkRegion::kXOR_Op);
     439             : GR_STATIC_ASSERT(4 == SkRegion::kReverseDifference_Op);
     440             : GR_STATIC_ASSERT(5 == SkRegion::kReplace_Op);
     441             : 
     442           0 : GrUserStencilSettings const* const* GrStencilSettings::GetClipPasses(SkRegion::Op op,
     443             :                                                                      bool canBeDirect,
     444             :                                                                      bool invertedFill,
     445             :                                                                      bool* drawDirectToClip) {
     446           0 :     SkASSERT((unsigned)op <= SkRegion::kLastOp);
     447           0 :     if (canBeDirect && !invertedFill) { // TODO: inverse fill + intersect op can be direct.
     448           0 :         GrUserStencilSettings const* const* directPass = gDirectDrawTable[op];
     449           0 :         if (directPass[0]) {
     450           0 :             *drawDirectToClip = true;
     451           0 :             return directPass;
     452             :         }
     453             :     }
     454           0 :     *drawDirectToClip = false;
     455           0 :     return gUserToClipTable[invertedFill][op];
     456             : }
     457             : 
     458           0 : void GrStencilSettings::genKey(GrProcessorKeyBuilder* b) const {
     459           0 :     b->add32(fFlags);
     460           0 :     if (this->isDisabled()) {
     461           0 :         return;
     462             :     }
     463           0 :     if (!this->isTwoSided()) {
     464           0 :         constexpr int kCount16 = sizeof(Face) / sizeof(uint16_t);
     465             :         GR_STATIC_ASSERT(0 == sizeof(Face) % sizeof(uint16_t));
     466           0 :         uint16_t* key = reinterpret_cast<uint16_t*>(b->add32n((kCount16 + 1) / 2));
     467           0 :         memcpy(key, &fFront, sizeof(Face));
     468           0 :         key[kCount16] = 0;
     469             :         GR_STATIC_ASSERT(1 == kCount16 % 2);
     470             :     } else {
     471           0 :         constexpr int kCount32 = (2 * sizeof(Face)) / sizeof(uint32_t);
     472             :         GR_STATIC_ASSERT(0 == (2 * sizeof(Face)) % sizeof(uint32_t));
     473           0 :         uint32_t* key = b->add32n(kCount32);
     474           0 :         memcpy(key, &fFront, 2 * sizeof(Face));
     475             :         GR_STATIC_ASSERT(sizeof(Face) ==
     476             :                          offsetof(GrStencilSettings, fBack) - offsetof(GrStencilSettings, fFront));
     477             :     }
     478             :     // We rely on GrStencilSettings::Face being tightly packed for the key to be reliable.
     479             :     GR_STATIC_ASSERT(0 == offsetof(Face, fRef));
     480             :     GR_STATIC_ASSERT(2 == sizeof(Face::fRef));
     481             :     GR_STATIC_ASSERT(2 == offsetof(Face, fTest));
     482             :     GR_STATIC_ASSERT(2 == sizeof(Face::fTest));
     483             :     GR_STATIC_ASSERT(4 == offsetof(Face, fTestMask));
     484             :     GR_STATIC_ASSERT(2 == sizeof(Face::fTestMask));
     485             :     GR_STATIC_ASSERT(6 == offsetof(Face, fPassOp));
     486             :     GR_STATIC_ASSERT(1 == sizeof(Face::fPassOp));
     487             :     GR_STATIC_ASSERT(7 == offsetof(Face, fFailOp));
     488             :     GR_STATIC_ASSERT(1 == sizeof(Face::fFailOp));
     489             :     GR_STATIC_ASSERT(8 == offsetof(Face, fWriteMask));
     490             :     GR_STATIC_ASSERT(2 == sizeof(Face::fWriteMask));
     491             :     GR_STATIC_ASSERT(10 == sizeof(Face));
     492             : }

Generated by: LCOV version 1.13