Improve handling of clip stack ID

Change-Id: I1d5cf06d9b50c370f969a8778181fe94f7d35844
Reviewed-on: https://skia-review.googlesource.com/21061
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index ecc9304..dc5b93d 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -243,7 +243,7 @@
     reducedClip.drawStencilClipMask(ctx, rtc);
 
     // Now visualize the stencil mask by covering the entire render target. The regions inside
-    // window rectangless or outside the scissor should still have the initial checkerboard intact.
+    // window rectangles or outside the scissor should still have the initial checkerboard intact.
     // (This verifies we didn't spend any time modifying those pixels in the mask.)
     rtc->drawPaint(StencilOnlyClip(), std::move(paint), SkMatrix::I());
 }
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 8da54e1..d4a9867 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -924,12 +924,15 @@
     return false;
 }
 
-int32_t SkClipStack::GetNextGenID() {
-    // TODO: handle overflow.
-    return sk_atomic_inc(&gGenID);
+uint32_t SkClipStack::GetNextGenID() {
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gGenID));
+    } while (id < kFirstUnreservedGenID);
+    return id;
 }
 
-int32_t SkClipStack::getTopmostGenID() const {
+uint32_t SkClipStack::getTopmostGenID() const {
     if (fDeque.empty()) {
         return kWideOpenGenID;
     }
diff --git a/src/core/SkClipStack.h b/src/core/SkClipStack.h
index 4502ecd..70f812a 100644
--- a/src/core/SkClipStack.h
+++ b/src/core/SkClipStack.h
@@ -129,7 +129,7 @@
             stack not to the element itself. That is the same clip path in different stacks will
             have a different ID since the elements produce different clip result in the context of
             their stacks. */
-        int32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }
+        uint32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }
 
         /**
          * Gets the bounds of the clip element, either the rect or path bounds. (Whether the shape
@@ -241,7 +241,7 @@
         // equivalent to a single rect intersection? IIOW, is the clip effectively a rectangle.
         bool fIsIntersectionOfRects;
 
-        int fGenID;
+        uint32_t fGenID;
 #if SK_SUPPORT_GPU
         mutable SkTArray<std::unique_ptr<GrUniqueKeyInvalidatedMessage>> fMessages;
 #endif
@@ -430,13 +430,13 @@
      * The generation ID has three reserved values to indicate special
      * (potentially ignorable) cases
      */
-    static const int32_t kInvalidGenID = 0;     //!< Invalid id that is never returned by
-                                                //!< SkClipStack. Useful when caching clips
-                                                //!< based on GenID.
-    static const int32_t kEmptyGenID = 1;       // no pixels writeable
-    static const int32_t kWideOpenGenID = 2;    // all pixels writeable
+    static const uint32_t kInvalidGenID  = 0;    //!< Invalid id that is never returned by
+                                                 //!< SkClipStack. Useful when caching clips
+                                                 //!< based on GenID.
+    static const uint32_t kEmptyGenID    = 1;    // no pixels writeable
+    static const uint32_t kWideOpenGenID = 2;    // all pixels writeable
 
-    int32_t getTopmostGenID() const;
+    uint32_t getTopmostGenID() const;
 
 #ifdef SK_DEBUG
     /**
@@ -567,7 +567,7 @@
     /**
      * Return the next unique generation ID.
      */
-    static int32_t GetNextGenID();
+    static uint32_t GetNextGenID();
 };
 
 #endif
diff --git a/src/gpu/GrAppliedClip.h b/src/gpu/GrAppliedClip.h
index 4181f43..a389d74 100644
--- a/src/gpu/GrAppliedClip.h
+++ b/src/gpu/GrAppliedClip.h
@@ -53,7 +53,7 @@
         fClipCoverageFP = fp;
     }
 
-    void addStencilClip(int32_t clipStackID) {
+    void addStencilClip(uint32_t clipStackID) {
         SkASSERT(SkClipStack::kInvalidGenID == fClipStackID);
         fClipStackID = clipStackID;
     }
@@ -83,7 +83,7 @@
     GrScissorState             fScissorState;
     GrWindowRectsState         fWindowRectsState;
     sk_sp<GrFragmentProcessor> fClipCoverageFP;
-    int32_t                    fClipStackID = SkClipStack::kInvalidGenID;
+    uint32_t                   fClipStackID = SkClipStack::kInvalidGenID;
 };
 
 #endif
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index ecc6252..9a93687 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -364,7 +364,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Create a 8-bit clip mask in alpha
 
-static void create_clip_mask_key(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey* key) {
+static void create_clip_mask_key(uint32_t clipGenID, const SkIRect& bounds, GrUniqueKey* key) {
     static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     GrUniqueKey::Builder builder(key, kDomain, 3, GrClipStackClip::kMaskTestTag);
     builder[0] = clipGenID;
@@ -374,7 +374,7 @@
     builder[2] = SkToS16(bounds.fTop) | (SkToS16(bounds.fBottom) << 16);
 }
 
-static void add_invalidate_on_pop_message(const SkClipStack& stack, int32_t clipGenID,
+static void add_invalidate_on_pop_message(const SkClipStack& stack, uint32_t clipGenID,
                                           const GrUniqueKey& clipMaskKey) {
     SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
     while (const Element* element = iter.prev()) {
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index dfa4166..e6cea3e 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -662,7 +662,7 @@
 
 class StencilClip final : public GrClip {
 public:
-    StencilClip(const SkIRect& scissorRect, int32_t clipStackID)
+    StencilClip(const SkIRect& scissorRect, uint32_t clipStackID)
         : fFixedClip(scissorRect)
         , fClipStackID(clipStackID) {
     }
@@ -694,7 +694,7 @@
     }
 
     GrFixedClip fFixedClip;
-    int32_t     fClipStackID;
+    uint32_t    fClipStackID;
 
     typedef GrClip INHERITED;
 };
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index 6dceb00..c9cce36 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -56,7 +56,7 @@
      * If elements() are nonempty, uniquely identifies the list of elements within ibounds().
      * Otherwise undefined.
      */
-    int32_t elementsGenID() const { SkASSERT(!fElements.isEmpty()); return fElementsGenID; }
+    uint32_t elementsGenID() const { SkASSERT(!fElements.isEmpty()); return fElementsGenID; }
 
     /**
      * Indicates whether antialiasing is required to process any of the clip elements.
@@ -83,7 +83,7 @@
     bool                 fHasIBounds;
     GrWindowRectangles   fWindowRects;
     ElementList          fElements;
-    int32_t              fElementsGenID;
+    uint32_t             fElementsGenID;
     bool                 fRequiresAA;
     InitialState         fInitialState;
 };
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index 3312a8f..ed1b40b 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -27,7 +27,7 @@
 
     // called to note the last clip drawn to the stencil buffer.
     // TODO: remove after clipping overhaul.
-    void setLastClip(int32_t clipStackGenID, const SkIRect& devClipBounds) {
+    void setLastClip(uint32_t clipStackGenID, const SkIRect& devClipBounds) {
         GrRenderTargetOpList* opList = fRenderTargetContext->getRTOpList();
         opList->fLastClipStackGenID = clipStackGenID;
         opList->fLastDevClipBounds = devClipBounds;
@@ -35,7 +35,7 @@
 
     // called to determine if we have to render the clip into SB.
     // TODO: remove after clipping overhaul.
-    bool mustRenderClip(int32_t clipStackGenID, const SkIRect& devClipBounds) const {
+    bool mustRenderClip(uint32_t clipStackGenID, const SkIRect& devClipBounds) const {
         GrRenderTargetOpList* opList = fRenderTargetContext->getRTOpList();
         return opList->fLastClipStackGenID != clipStackGenID ||
                !opList->fLastDevClipBounds.contains(devClipBounds);
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 668e94d..7a26a05 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -143,7 +143,7 @@
 
     std::unique_ptr<gr_instanced::InstancedRendering> fInstancedRendering;
 
-    int32_t                        fLastClipStackGenID;
+    uint32_t                       fLastClipStackGenID;
     SkIRect                        fLastDevClipBounds;
 
     // For ops/opList we have mean: 5 stdDev: 28
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index af57f9e..e1aa148 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -1107,16 +1107,16 @@
 
         stack.clipRect(SkRect::MakeXYWH(0, 0, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
                        kReplace_SkClipOp, true);
-        int32_t genIDA = stack.getTopmostGenID();
+        uint32_t genIDA = stack.getTopmostGenID();
         stack.clipRect(SkRect::MakeXYWH(50, 0, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
                        kUnion_SkClipOp, true);
-        int32_t genIDB = stack.getTopmostGenID();
+        uint32_t genIDB = stack.getTopmostGenID();
         stack.clipRect(SkRect::MakeXYWH(0, 50, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
                        kUnion_SkClipOp, true);
-        int32_t genIDC = stack.getTopmostGenID();
+        uint32_t genIDC = stack.getTopmostGenID();
         stack.clipRect(SkRect::MakeXYWH(50, 50, SkScalar(25.3), SkScalar(25.3)), SkMatrix::I(),
                        kUnion_SkClipOp, true);
-        int32_t genIDD = stack.getTopmostGenID();
+        uint32_t genIDD = stack.getTopmostGenID();
 
 
 #define IXYWH SkIRect::MakeXYWH
@@ -1135,7 +1135,7 @@
         static const struct SUPPRESS_VISIBILITY_WARNING {
             SkRect testBounds;
             int reducedClipCount;
-            int32_t reducedGenID;
+            uint32_t reducedGenID;
             InitialState initialState;
             SkIRect clipIRect;
             // parameter.