| Index: tests/ClipStackTest.cpp | 
| diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp | 
| index f6edb8ce5b1f773610a9b7e5e827c2cae0c1a873..a6b636271ab3da50909edc79945bceea9fd9240b 100644 | 
| --- a/tests/ClipStackTest.cpp | 
| +++ b/tests/ClipStackTest.cpp | 
| @@ -1006,57 +1006,47 @@ static void test_reduced_clip_stack(skiatest::Reporter* reporter) { | 
| } | 
| } | 
|  | 
| +        // Get the reduced version of the stack. | 
| SkRect queryBounds = kBounds; | 
| queryBounds.outset(kBounds.width() / 2, kBounds.height() / 2); | 
| +        const GrReducedClip reduced(stack, queryBounds); | 
|  | 
| -        // Get the reduced version of the stack. | 
| -        ElementList reducedClips; | 
| -        int32_t reducedGenID; | 
| -        SkIRect clipIBounds; | 
| -        bool requiresAA; | 
| -        InitialState initial = GrReducedClip::ReduceClipStack(stack, | 
| -                                                              queryBounds, | 
| -                                                              &reducedClips, | 
| -                                                              &reducedGenID, | 
| -                                                              &clipIBounds, | 
| -                                                              &requiresAA); | 
| - | 
| -        REPORTER_ASSERT_MESSAGE(reporter, SkClipStack::kInvalidGenID != reducedGenID, | 
| +        REPORTER_ASSERT_MESSAGE(reporter, SkClipStack::kInvalidGenID != reduced.genID(), | 
| testCase.c_str()); | 
|  | 
| -        if (!reducedClips.isEmpty()) { | 
| +        if (!reduced.elements().isEmpty()) { | 
| SkRect stackBounds; | 
| SkClipStack::BoundsType stackBoundsType; | 
| stack.getBounds(&stackBounds, &stackBoundsType); | 
| if (SkClipStack::kNormal_BoundsType == stackBoundsType) { | 
| // Unless GrReducedClip starts doing some heroic tightening of the clip bounds, this | 
| // will be true since the stack bounds are completely contained inside the query. | 
| -                REPORTER_ASSERT_MESSAGE(reporter, GrClip::IsInsideClip(clipIBounds, stackBounds), | 
| +                REPORTER_ASSERT_MESSAGE(reporter, GrClip::IsInsideClip(reduced.iBounds(), stackBounds), | 
| testCase.c_str()); | 
| } | 
| -            REPORTER_ASSERT_MESSAGE(reporter, requiresAA == doAA, testCase.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, reduced.requiresAA() == doAA, testCase.c_str()); | 
| } | 
|  | 
| // Build a new clip stack based on the reduced clip elements | 
| SkClipStack reducedStack; | 
| -        if (GrReducedClip::kAllOut_InitialState == initial) { | 
| +        if (GrReducedClip::InitialState::kAllOut == reduced.initialState()) { | 
| // whether the result is bounded or not, the whole plane should start outside the clip. | 
| reducedStack.clipEmpty(); | 
| } | 
| -        for (ElementList::Iter iter = reducedClips.headIter(); iter.get(); iter.next()) { | 
| +        for (ElementList::Iter iter(reduced.elements()); iter.get(); iter.next()) { | 
| add_elem_to_stack(*iter.get(), &reducedStack); | 
| } | 
|  | 
| // GrReducedClipStack assumes that the final result is clipped to the returned bounds | 
| -        reducedStack.clipDevRect(clipIBounds, SkRegion::kIntersect_Op); | 
| -        stack.clipDevRect(clipIBounds, SkRegion::kIntersect_Op); | 
| +        reducedStack.clipDevRect(reduced.iBounds(), SkRegion::kIntersect_Op); | 
| +        stack.clipDevRect(reduced.iBounds(), SkRegion::kIntersect_Op); | 
|  | 
| // convert both the original stack and reduced stack to SkRegions and see if they're equal | 
| SkRegion region; | 
| -        set_region_to_stack(stack, clipIBounds, ®ion); | 
| +        set_region_to_stack(stack, reduced.iBounds(), ®ion); | 
|  | 
| SkRegion reducedRegion; | 
| -        set_region_to_stack(reducedStack, clipIBounds, &reducedRegion); | 
| +        set_region_to_stack(reducedStack, reduced.iBounds(), &reducedRegion); | 
|  | 
| REPORTER_ASSERT_MESSAGE(reporter, region == reducedRegion, testCase.c_str()); | 
| } | 
| @@ -1075,21 +1065,11 @@ static void test_reduced_clip_stack_genid(skiatest::Reporter* reporter) { | 
| stack.clipDevRect(SkRect::MakeXYWH(0, 0, SkScalar(50.3), SkScalar(50.3)), SkRegion::kReplace_Op, true); | 
| SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100); | 
|  | 
| -        ElementList reducedClips; | 
| -        int32_t reducedGenID; | 
| -        SkIRect tightBounds; | 
| -        bool requiresAA; | 
| - | 
| -        GrReducedClip::ReduceClipStack(stack, | 
| -                                       bounds, | 
| -                                       &reducedClips, | 
| -                                       &reducedGenID, | 
| -                                       &tightBounds, | 
| -                                       &requiresAA); | 
| +        const GrReducedClip reduced(stack, bounds); | 
|  | 
| -        REPORTER_ASSERT(reporter, reducedClips.count() == 1); | 
| +        REPORTER_ASSERT(reporter, reduced.elements().count() == 1); | 
| // Clips will be cached based on the generation id. Make sure the gen id is valid. | 
| -        REPORTER_ASSERT(reporter, SkClipStack::kInvalidGenID != reducedGenID); | 
| +        REPORTER_ASSERT(reporter, SkClipStack::kInvalidGenID != reduced.genID()); | 
| } | 
| { | 
| SkClipStack stack; | 
| @@ -1129,60 +1109,50 @@ static void test_reduced_clip_stack_genid(skiatest::Reporter* reporter) { | 
| SkIRect clipIRect; | 
| // parameter. | 
| } testCases[] = { | 
| + | 
| // Rect A. | 
| -            { XYWH(0, 0, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(0, 0, 25, 25) }, | 
| -            { XYWH(0.1f, 0.1f, 25.1f, 25.1f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(0, 0, 26, 26) }, | 
| -            { XYWH(0, 0, 27, 27), 1, genIDA, GrReducedClip::kAllOut_InitialState, IXYWH(0, 0, 27, 27)}, | 
| +            { XYWH(0, 0, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 0, 25, 25) }, | 
| +            { XYWH(0.1f, 0.1f, 25.1f, 25.1f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 0, 26, 26) }, | 
| +            { XYWH(0, 0, 27, 27), 1, genIDA, GrReducedClip::InitialState::kAllOut, IXYWH(0, 0, 27, 27)}, | 
|  | 
| // Rect B. | 
| -            { XYWH(50, 0, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(50, 0, 25, 25) }, | 
| -            { XYWH(50, 0, 25.3f, 25.3f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(50, 0, 26, 26) }, | 
| -            { XYWH(50, 0, 27, 27), 1, genIDB, GrReducedClip::kAllOut_InitialState, IXYWH(50, 0, 26, 27) }, | 
| +            { XYWH(50, 0, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 0, 25, 25) }, | 
| +            { XYWH(50, 0, 25.3f, 25.3f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 0, 26, 26) }, | 
| +            { XYWH(50, 0, 27, 27), 1, genIDB, GrReducedClip::InitialState::kAllOut, IXYWH(50, 0, 26, 27) }, | 
|  | 
| // Rect C. | 
| -            { XYWH(0, 50, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(0, 50, 25, 25) }, | 
| -            { XYWH(0.2f, 50.1f, 25.1f, 25.2f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(0, 50, 26, 26) }, | 
| -            { XYWH(0, 50, 27, 27), 1, genIDC, GrReducedClip::kAllOut_InitialState, IXYWH(0, 50, 27, 26) }, | 
| +            { XYWH(0, 50, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 50, 25, 25) }, | 
| +            { XYWH(0.2f, 50.1f, 25.1f, 25.2f), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(0, 50, 26, 26) }, | 
| +            { XYWH(0, 50, 27, 27), 1, genIDC, GrReducedClip::InitialState::kAllOut, IXYWH(0, 50, 27, 26) }, | 
|  | 
| // Rect D. | 
| -            { XYWH(50, 50, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(50, 50, 25, 25)}, | 
| -            { XYWH(50.3f, 50.3f, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::kAllIn_InitialState, IXYWH(50, 50, 26, 26)}, | 
| -            { XYWH(50, 50, 27, 27), 1, genIDD, GrReducedClip::kAllOut_InitialState,  IXYWH(50, 50, 26, 26)}, | 
| +            { XYWH(50, 50, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 50, 25, 25)}, | 
| +            { XYWH(50.3f, 50.3f, 25, 25), 0, SkClipStack::kWideOpenGenID, GrReducedClip::InitialState::kAllIn, IXYWH(50, 50, 26, 26)}, | 
| +            { XYWH(50, 50, 27, 27), 1, genIDD, GrReducedClip::InitialState::kAllOut,  IXYWH(50, 50, 26, 26)}, | 
|  | 
| // Other tests: | 
| -            { XYWH(0, 0, 100, 100), 4, genIDD, GrReducedClip::kAllOut_InitialState, stackBounds }, | 
| +            { XYWH(0, 0, 100, 100), 4, genIDD, GrReducedClip::InitialState::kAllOut, stackBounds }, | 
|  | 
| // Rect in the middle, touches none. | 
| -            { XYWH(26, 26, 24, 24), 0, SkClipStack::kEmptyGenID, GrReducedClip::kAllOut_InitialState, IXYWH(26, 26, 24, 24) }, | 
| +            { XYWH(26, 26, 24, 24), 0, SkClipStack::kEmptyGenID, GrReducedClip::InitialState::kAllOut, IXYWH(26, 26, 24, 24) }, | 
|  | 
| // Rect in the middle, touches all the rects. GenID is the last rect. | 
| -            { XYWH(24, 24, 27, 27), 4, genIDD, GrReducedClip::kAllOut_InitialState, IXYWH(24, 24, 27, 27) }, | 
| +            { XYWH(24, 24, 27, 27), 4, genIDD, GrReducedClip::InitialState::kAllOut, IXYWH(24, 24, 27, 27) }, | 
| }; | 
|  | 
| #undef XYWH | 
| #undef IXYWH | 
|  | 
| for (size_t i = 0; i < SK_ARRAY_COUNT(testCases); ++i) { | 
| -            ElementList reducedClips; | 
| -            int32_t reducedGenID; | 
| -            SkIRect clipIRect; | 
| -            bool requiresAA; | 
| - | 
| -            InitialState initial = GrReducedClip::ReduceClipStack(stack, | 
| -                                                                  testCases[i].testBounds, | 
| -                                                                  &reducedClips, | 
| -                                                                  &reducedGenID, | 
| -                                                                  &clipIRect, | 
| -                                                                  &requiresAA); | 
| - | 
| -            REPORTER_ASSERT(reporter, reducedClips.count() == testCases[i].reducedClipCount); | 
| -            SkASSERT(reducedClips.count() == testCases[i].reducedClipCount); | 
| -            REPORTER_ASSERT(reporter, reducedGenID == testCases[i].reducedGenID); | 
| -            SkASSERT(reducedGenID == testCases[i].reducedGenID); | 
| -            REPORTER_ASSERT(reporter, initial == testCases[i].initialState); | 
| -            SkASSERT(initial == testCases[i].initialState); | 
| -            REPORTER_ASSERT(reporter, clipIRect == testCases[i].clipIRect); | 
| -            SkASSERT(clipIRect == testCases[i].clipIRect); | 
| +            const GrReducedClip reduced(stack, testCases[i].testBounds); | 
| +            REPORTER_ASSERT(reporter, reduced.elements().count() == testCases[i].reducedClipCount); | 
| +            SkASSERT(reduced.elements().count() == testCases[i].reducedClipCount); | 
| +            REPORTER_ASSERT(reporter, reduced.genID() == testCases[i].reducedGenID); | 
| +            SkASSERT(reduced.genID() == testCases[i].reducedGenID); | 
| +            REPORTER_ASSERT(reporter, reduced.initialState() == testCases[i].initialState); | 
| +            SkASSERT(reduced.initialState() == testCases[i].initialState); | 
| +            REPORTER_ASSERT(reporter, reduced.iBounds() == testCases[i].clipIRect); | 
| +            SkASSERT(reduced.iBounds() == testCases[i].clipIRect); | 
| } | 
| } | 
| } | 
| @@ -1193,20 +1163,9 @@ static void test_reduced_clip_stack_no_aa_crash(skiatest::Reporter* reporter) { | 
| stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 50, 50), SkRegion::kReplace_Op); | 
| SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100); | 
|  | 
| -    ElementList reducedClips; | 
| -    int32_t reducedGenID; | 
| -    SkIRect tightBounds; | 
| -    bool requiresAA; | 
| - | 
| // At the time, this would crash. | 
| -    GrReducedClip::ReduceClipStack(stack, | 
| -                                   bounds, | 
| -                                   &reducedClips, | 
| -                                   &reducedGenID, | 
| -                                   &tightBounds, | 
| -                                   &requiresAA); | 
| - | 
| -    REPORTER_ASSERT(reporter, 0 == reducedClips.count()); | 
| +    const GrReducedClip reduced(stack, bounds); | 
| +    REPORTER_ASSERT(reporter, reduced.elements().isEmpty()); | 
| } | 
|  | 
| enum class ClipMethod { | 
| @@ -1220,20 +1179,9 @@ static void test_aa_query(skiatest::Reporter* reporter, const SkString& testName | 
| const SkClipStack& stack, const SkMatrix& queryXform, | 
| const SkRect& preXformQuery, ClipMethod expectedMethod, | 
| int numExpectedElems = 0) { | 
| -    ElementList reducedElems; | 
| -    int32_t reducedGenID; | 
| -    SkIRect clipIBounds; | 
| -    bool requiresAA; | 
| - | 
| SkRect queryBounds; | 
| queryXform.mapRect(&queryBounds, preXformQuery); | 
| - | 
| -    InitialState initialState = GrReducedClip::ReduceClipStack(stack, | 
| -                                                               queryBounds, | 
| -                                                               &reducedElems, | 
| -                                                               &reducedGenID, | 
| -                                                               &clipIBounds, | 
| -                                                               &requiresAA); | 
| +    const GrReducedClip reduced(stack, queryBounds); | 
|  | 
| SkClipStack::BoundsType stackBoundsType; | 
| SkRect stackBounds; | 
| @@ -1242,16 +1190,18 @@ static void test_aa_query(skiatest::Reporter* reporter, const SkString& testName | 
| switch (expectedMethod) { | 
| case ClipMethod::kSkipDraw: | 
| SkASSERT(0 == numExpectedElems); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, reducedElems.isEmpty(), testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, GrReducedClip::kAllOut_InitialState == initialState, | 
| +            REPORTER_ASSERT_MESSAGE(reporter, reduced.elements().isEmpty(), testName.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, | 
| +                                    GrReducedClip::InitialState::kAllOut == reduced.initialState(), | 
| testName.c_str()); | 
| return; | 
| case ClipMethod::kIgnoreClip: | 
| SkASSERT(0 == numExpectedElems); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, reducedElems.isEmpty(), testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, GrClip::IsInsideClip(clipIBounds, queryBounds), | 
| +            REPORTER_ASSERT_MESSAGE(reporter, GrClip::IsInsideClip(reduced.iBounds(), queryBounds), | 
| testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, GrReducedClip::kAllIn_InitialState == initialState, | 
| +            REPORTER_ASSERT_MESSAGE(reporter, reduced.elements().isEmpty(), testName.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, | 
| +                                    GrReducedClip::InitialState::kAllIn == reduced.initialState(), | 
| testName.c_str()); | 
| return; | 
| case ClipMethod::kScissor: { | 
| @@ -1259,9 +1209,11 @@ static void test_aa_query(skiatest::Reporter* reporter, const SkString& testName | 
| SkASSERT(0 == numExpectedElems); | 
| SkIRect expectedScissor; | 
| stackBounds.round(&expectedScissor); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, reducedElems.isEmpty(), testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, expectedScissor == clipIBounds, testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, GrReducedClip::kAllIn_InitialState == initialState, | 
| +            REPORTER_ASSERT_MESSAGE(reporter, reduced.elements().isEmpty(), testName.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, expectedScissor == reduced.iBounds(), | 
| +                                    testName.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, | 
| +                                    GrReducedClip::InitialState::kAllIn == reduced.initialState(), | 
| testName.c_str()); | 
| return; | 
| } | 
| @@ -1270,10 +1222,11 @@ static void test_aa_query(skiatest::Reporter* reporter, const SkString& testName | 
| if (SkClipStack::kNormal_BoundsType == stackBoundsType) { | 
| SkAssertResult(expectedClipIBounds.intersect(GrClip::GetPixelIBounds(stackBounds))); | 
| } | 
| -            REPORTER_ASSERT_MESSAGE(reporter, numExpectedElems == reducedElems.count(), | 
| +            REPORTER_ASSERT_MESSAGE(reporter, numExpectedElems == reduced.elements().count(), | 
| +                                    testName.c_str()); | 
| +            REPORTER_ASSERT_MESSAGE(reporter, expectedClipIBounds == reduced.iBounds(), | 
| testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, expectedClipIBounds == clipIBounds, testName.c_str()); | 
| -            REPORTER_ASSERT_MESSAGE(reporter, requiresAA == !reducedElems.isEmpty(), | 
| +            REPORTER_ASSERT_MESSAGE(reporter, reduced.requiresAA() == !reduced.elements().isEmpty(), | 
| testName.c_str()); | 
| break; | 
| } | 
| @@ -1306,8 +1259,7 @@ static void test_reduced_clip_stack_aa(skiatest::Reporter* reporter) { | 
| stack.clipDevRect(alignedRect, SkRegion::kIntersect_Op, true); | 
| test_aa_query(reporter, name, stack, m, {IL, IT, IR, IB}, ClipMethod::kIgnoreClip); | 
| test_aa_query(reporter, name, stack, m, {IL, IT-1, IR, IT}, ClipMethod::kSkipDraw); | 
| -        test_aa_query(reporter, name, stack, m, {IL, IT, IR, IB}, ClipMethod::kScissor); | 
| -        test_aa_query(reporter, name, stack, m, {IL, IT+2, IR, IB-3}, ClipMethod::kScissor); | 
| +        test_aa_query(reporter, name, stack, m, {IL, IT-2, IR, IB}, ClipMethod::kScissor); | 
|  | 
| // Rect (iior=true). | 
| name.printf("Rect test, iter %i", i); | 
|  |