Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Unified Diff: src/gpu/GrStencil.cpp

Issue 1969693003: Revert of Separate user and raw stencil settings (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrStencil.h ('k') | src/gpu/GrStencilSettings.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrStencil.cpp
diff --git a/src/gpu/GrStencil.cpp b/src/gpu/GrStencil.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94559ab68eb6333ccd09692eb7e2df4acf8535ba
--- /dev/null
+++ b/src/gpu/GrStencil.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "GrStencil.h"
+
+#include "GrProcessor.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Stencil Rules for Merging user stencil space into clip
+
+// We can't include the clip bit in the ref or mask values because the division
+// between user and clip bits in the stencil depends on the number of stencil
+// bits in the runtime. Comments below indicate what the code should do to
+// incorporate the clip bit into these settings.
+
+///////
+// Replace
+
+// set the ref to be the clip bit, but mask it out for the test
+static constexpr GrStencilSettings gUserToClipReplace(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+static constexpr GrStencilSettings gInvUserToClipReplace(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+///////
+// Intersect
+static constexpr GrStencilSettings gUserToClipIsect(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+static constexpr GrStencilSettings gInvUserToClipIsect(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+///////
+// Difference
+static constexpr GrStencilSettings gUserToClipDiff(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+static constexpr GrStencilSettings gInvUserToClipDiff(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+///////
+// Union
+
+// first pass makes all the passing cases >= just clip bit set.
+static constexpr GrStencilSettings gUserToClipUnionPass0(
+ kReplace_StencilOp,
+ kKeep_StencilOp,
+ kLEqual_StencilFunc,
+ 0xffff,
+ 0x0001, // set clip bit
+ 0xffff);
+
+// second pass allows anything greater than just clip bit set to pass
+static constexpr GrStencilSettings gUserToClipUnionPass1(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+// first pass finds zeros in the user bits and if found sets
+// the clip bit to 1
+static constexpr GrStencilSettings gInvUserToClipUnionPass0(
+ kReplace_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clip bit
+);
+
+// second pass zeros the user bits
+static constexpr GrStencilSettings gInvUserToClipUnionPass1(
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff // unset clip bit
+);
+
+///////
+// Xor
+static constexpr GrStencilSettings gUserToClipXorPass0(
+ kInvert_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000,
+ 0xffff);
+
+static constexpr GrStencilSettings gUserToClipXorPass1(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kGreater_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+static constexpr GrStencilSettings gInvUserToClipXorPass0(
+ kInvert_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000,
+ 0xffff);
+
+static constexpr GrStencilSettings gInvUserToClipXorPass1(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+///////
+// Reverse Diff
+static constexpr GrStencilSettings gUserToClipRDiffPass0(
+ kInvert_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+static constexpr GrStencilSettings gUserToClipRDiffPass1(
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0x0000, // set clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+// We are looking for stencil values that are all zero. The first pass sets the
+// clip bit if the stencil is all zeros. The second pass clears the user bits.
+static constexpr GrStencilSettings gInvUserToClipRDiffPass0(
+ kInvert_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
+
+static constexpr GrStencilSettings gInvUserToClipRDiffPass1(
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff // unset clip bit
+);
+
+///////
+// Direct to Stencil
+
+// We can render a clip element directly without first writing to the client
+// portion of the clip when the fill is not inverse and the set operation will
+// only modify the in/out status of samples covered by the clip element.
+
+// this one only works if used right after stencil clip was cleared.
+// Our clip mask creation code doesn't allow midstream replace ops.
+static constexpr GrStencilSettings gReplaceClip(
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clipBit
+);
+
+static constexpr GrStencilSettings gUnionClip(
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clip bit
+);
+
+static constexpr GrStencilSettings gXorClip(
+ kInvert_StencilOp,
+ kInvert_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
+
+static constexpr GrStencilSettings gDiffClip(
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
+
+bool GrStencilSettings::GetClipPasses(
+ SkRegion::Op op,
+ bool canBeDirect,
+ unsigned int stencilClipMask,
+ bool invertedFill,
+ int* numPasses,
+ GrStencilSettings settings[kMaxStencilClipPasses]) {
+ if (canBeDirect && !invertedFill) {
+ *numPasses = 0;
+ switch (op) {
+ case SkRegion::kReplace_Op:
+ *numPasses = 1;
+ settings[0] = gReplaceClip;
+ break;
+ case SkRegion::kUnion_Op:
+ *numPasses = 1;
+ settings[0] = gUnionClip;
+ break;
+ case SkRegion::kXOR_Op:
+ *numPasses = 1;
+ settings[0] = gXorClip;
+ break;
+ case SkRegion::kDifference_Op:
+ *numPasses = 1;
+ settings[0] = gDiffClip;
+ break;
+ default: // suppress warning
+ break;
+ }
+ if (1 == *numPasses) {
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+ settings[0].fWriteMasks[kBack_Face] =
+ settings[0].fWriteMasks[kFront_Face];
+ return true;
+ }
+ }
+ switch (op) {
+ // if we make the path renderer go to stencil we always give it a
+ // non-inverted fill and we use the stencil rules on the client->clipbit
+ // pass to select either the zeros or nonzeros.
+ case SkRegion::kReplace_Op:
+ *numPasses= 1;
+ settings[0] = invertedFill ? gInvUserToClipReplace :
+ gUserToClipReplace;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+ break;
+ case SkRegion::kIntersect_Op:
+ *numPasses = 1;
+ settings[0] = invertedFill ? gInvUserToClipIsect : gUserToClipIsect;
+ settings[0].fFuncRefs[kFront_Face] = stencilClipMask;
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+ break;
+ case SkRegion::kUnion_Op:
+ *numPasses = 2;
+ if (invertedFill) {
+ settings[0] = gInvUserToClipUnionPass0;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+ settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
+ settings[0].fWriteMasks[kBack_Face] =
+ settings[0].fWriteMasks[kFront_Face];
+
+ settings[1] = gInvUserToClipUnionPass1;
+ settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
+ settings[1].fWriteMasks[kBack_Face] &=
+ settings[1].fWriteMasks[kFront_Face];
+
+ } else {
+ settings[0] = gUserToClipUnionPass0;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+
+ settings[1] = gUserToClipUnionPass1;
+ settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[1].fFuncRefs[kBack_Face] =
+ settings[1].fFuncRefs[kFront_Face];
+ }
+ break;
+ case SkRegion::kXOR_Op:
+ *numPasses = 2;
+ if (invertedFill) {
+ settings[0] = gInvUserToClipXorPass0;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+
+ settings[1] = gInvUserToClipXorPass1;
+ settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[1].fFuncRefs[kBack_Face] =
+ settings[1].fFuncRefs[kFront_Face];
+ } else {
+ settings[0] = gUserToClipXorPass0;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+
+ settings[1] = gUserToClipXorPass1;
+ settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[1].fFuncRefs[kBack_Face] =
+ settings[1].fFuncRefs[kFront_Face];
+ }
+ break;
+ case SkRegion::kDifference_Op:
+ *numPasses = 1;
+ settings[0] = invertedFill ? gInvUserToClipDiff : gUserToClipDiff;
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+ break;
+ case SkRegion::kReverseDifference_Op:
+ if (invertedFill) {
+ *numPasses = 2;
+ settings[0] = gInvUserToClipRDiffPass0;
+ settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
+ settings[0].fWriteMasks[kBack_Face] =
+ settings[0].fWriteMasks[kFront_Face];
+ settings[1] = gInvUserToClipRDiffPass1;
+ settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
+ settings[1].fWriteMasks[kBack_Face] =
+ settings[1].fWriteMasks[kFront_Face];
+ } else {
+ *numPasses = 2;
+ settings[0] = gUserToClipRDiffPass0;
+ settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
+ settings[0].fFuncMasks[kBack_Face] =
+ settings[0].fFuncMasks[kFront_Face];
+ settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[0].fFuncRefs[kBack_Face] =
+ settings[0].fFuncRefs[kFront_Face];
+
+ settings[1] = gUserToClipRDiffPass1;
+ settings[1].fFuncMasks[kFront_Face] |= stencilClipMask;
+ settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
+ settings[1].fFuncMasks[kBack_Face] =
+ settings[1].fFuncMasks[kFront_Face];
+ settings[1].fFuncRefs[kBack_Face] =
+ settings[1].fFuncRefs[kFront_Face];
+ }
+ break;
+ default:
+ SkFAIL("Unknown set op");
+ }
+ return false;
+}
+
+void GrStencilSettings::genKey(GrProcessorKeyBuilder* b) const {
+ static const int kCount = sizeof(GrStencilSettings) / sizeof(uint32_t);
+ GR_STATIC_ASSERT(0 == sizeof(GrStencilSettings) % sizeof(uint32_t));
+ uint32_t* key = b->add32n(kCount);
+ memcpy(key, this, sizeof(GrStencilSettings));
+}
« no previous file with comments | « src/gpu/GrStencil.h ('k') | src/gpu/GrStencilSettings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698