ClipStackTest.cpp revision 51a6286c241c1dc750d263ed9676079c898148b0
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "Test.h" 951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com#include "GrClipMaskManager.h" 10bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "SkClipStack.h" 111e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org#include "SkPath.h" 1251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com#include "SkRandom.h" 131e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org#include "SkRect.h" 1451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com#include "SkRegion.h" 1580214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 171e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.orgstatic void test_assign_and_comparison(skiatest::Reporter* reporter) { 181e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack s; 19d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com bool doAA = false; 201e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 2180214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == s.getSaveCount()); 2280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 231e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Build up a clip stack with a path, an empty clip, and a rect. 241e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 2580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 2680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 271e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkPath p; 281e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.moveTo(5, 6); 291e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.lineTo(7, 8); 301e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.lineTo(5, 9); 311e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.close(); 32d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 331e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 341e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 3580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 3680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 371e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkRect r = SkRect::MakeLTRB(1, 2, 3, 4); 38d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 391e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(10, 11, 12, 13); 40d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 411e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 421e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 4380214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 4480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 451e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 46d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 471e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 481e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that assignment works. 491e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack copy = s; 501e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 511e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 521e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different save levels triggers not equal. 531e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 5480214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 551e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 561e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 571e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that an equal, but not copied version is equal. 581e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 5980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 6080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 611e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 62d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 631e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 641e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 651e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that a different op on one level triggers not equal. 661e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 6780214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 681e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 6980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 7080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 711e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 72d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 731e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 741e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 751e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different state (clip type) triggers not equal. 764c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // NO LONGER VALID: if a path contains only a rect, we turn 774c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // it into a bare rect for performance reasons (working 784c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // around Chromium/JavaScript bad pattern). 794c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com/* 801e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 811e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 821e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkPath rp; 831e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org rp.addRect(r); 84d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(rp, SkRegion::kUnion_Op, doAA); 851e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 864c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com*/ 871e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 881e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different rects triggers not equal. 891e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 9080214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 911e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 9280214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 9380214e26c57c5fea954006400852e8999e201923robertphillips@google.com 941e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(24, 25, 26, 27); 95d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 961e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 971e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 981e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Sanity check 991e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 10080214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 10180214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1021e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org copy.restore(); 10380214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == copy.getSaveCount()); 1041e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 1051e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 10680214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 1071e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org copy.restore(); 10880214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == copy.getSaveCount()); 1091e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 1101e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 1111e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different paths triggers not equal. 1121e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 11380214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == s.getSaveCount()); 1141e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 11580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 11680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1171e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.addRect(r); 118d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 1191e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 1201e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org} 121bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 122bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack, 123bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com int count) { 12480214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 125bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com int counter = 0; 126bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com while (iter.next()) { 127bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com counter += 1; 128bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 129bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, count == counter); 130bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 131bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 13208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Exercise the SkClipStack's bottom to top and bidirectional iterators 13308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// (including the skipToTopmost functionality) 13480214e26c57c5fea954006400852e8999e201923robertphillips@google.comstatic void test_iterators(skiatest::Reporter* reporter) { 13580214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack stack; 13680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 13780214e26c57c5fea954006400852e8999e201923robertphillips@google.com static const SkRect gRects[] = { 13880214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 0, 0, 40, 40 }, 13980214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 60, 0, 100, 40 }, 14080214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 0, 60, 40, 100 }, 14180214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 60, 60, 100, 100 } 14280214e26c57c5fea954006400852e8999e201923robertphillips@google.com }; 14380214e26c57c5fea954006400852e8999e201923robertphillips@google.com 14480214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 14580214e26c57c5fea954006400852e8999e201923robertphillips@google.com // the union op will prevent these from being fused together 14680214e26c57c5fea954006400852e8999e201923robertphillips@google.com stack.clipDevRect(gRects[i], SkRegion::kUnion_Op, false); 14780214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 14880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 14980214e26c57c5fea954006400852e8999e201923robertphillips@google.com assert_count(reporter, stack, 4); 15080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15180214e26c57c5fea954006400852e8999e201923robertphillips@google.com // bottom to top iteration 15280214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 15380214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::B2TIter::Clip* clip = NULL; 15480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15580214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 15680214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 15780214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15880214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (i = 0, clip = iter.next(); clip; ++i, clip = iter.next()) { 15980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[i]); 16080214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16180214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16280214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == 4); 16380214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16580214e26c57c5fea954006400852e8999e201923robertphillips@google.com // top to bottom iteration 16680214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 16780214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::Iter::Clip* clip = NULL; 16880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16980214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 17080214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 17180214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17280214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (i = 3, clip = iter.prev(); clip; --i, clip = iter.prev()) { 17380214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[i]); 17480214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 17580214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17680214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == -1); 17780214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 17880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17980214e26c57c5fea954006400852e8999e201923robertphillips@google.com // skipToTopmost 18080214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 18180214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::Iter::Clip*clip = NULL; 18280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18380214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 18480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18580214e26c57c5fea954006400852e8999e201923robertphillips@google.com clip = iter.skipToTopmost(SkRegion::kUnion_Op); 18680214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[3]); 18780214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 18880214e26c57c5fea954006400852e8999e201923robertphillips@google.com} 18980214e26c57c5fea954006400852e8999e201923robertphillips@google.com 19008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Exercise the SkClipStack's getConservativeBounds computation 1914c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.comstatic void test_bounds(skiatest::Reporter* reporter, bool useRects) { 192607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 193607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const int gNumCases = 20; 194607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRect gAnswerRectsBW[gNumCases] = { 195607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op B 196607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 197607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 198607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 199607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 200607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 201607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 202607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op B 203607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 204607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 205607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 206607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 207607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 208607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 209607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op invB 210607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 211607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 212607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 213607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 214607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 215607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 216607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op invB 217607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 218607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 219607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 220607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 221607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 222607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 223607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 224607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRegion::Op gOps[] = { 225607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kIntersect_Op, 226607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kDifference_Op, 227607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kUnion_Op, 228607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kXOR_Op, 229607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kReverseDifference_Op 230607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 231607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 232607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRect rectA, rectB; 233607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 234607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectA.iset(10, 10, 50, 50); 235607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectB.iset(40, 40, 80, 80); 236607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 237607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath clipA, clipB; 238607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 239607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 240607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 241607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 242607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkClipStack stack; 2437b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkRect devClipBound; 2444c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool isIntersectionOfRects = false; 245607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 246607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int testCase = 0; 2474c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com int numBitTests = useRects ? 1 : 4; 2484c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com for (int invBits = 0; invBits < numBitTests; ++invBits) { 249607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 250607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 251607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.save(); 252607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvA = SkToBool(invBits & 1); 253607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvB = SkToBool(invBits & 2); 254607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 255607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 256607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 257607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 258607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 259607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 2604c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 2614c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectA, SkRegion::kIntersect_Op, false); 2624c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectB, gOps[op], false); 2634c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2644c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipA, SkRegion::kIntersect_Op, false); 2654c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipB, gOps[op], false); 2664c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 267607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 268cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 269cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 2707b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com stack.getConservativeBounds(0, 0, 100, 100, &devClipBound, 2714c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com &isIntersectionOfRects); 2724c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com 2734c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 274d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects == 2754c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com (gOps[op] == SkRegion::kIntersect_Op)); 2764c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2774c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 2784c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 279607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 280607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkASSERT(testCase < gNumCases); 2817b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]); 282607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com ++testCase; 283607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 284607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.restore(); 285607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 286607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 287607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com} 288607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 289cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com// Test out 'isWideOpen' entry point 290cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.comstatic void test_isWideOpen(skiatest::Reporter* reporter) { 291cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 292cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect rectA, rectB; 293cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 294cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectA.iset(10, 10, 40, 40); 295cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectB.iset(50, 50, 80, 80); 296cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 297cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Stack should initially be wide open 298cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 299cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 300cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 301cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 302cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 303cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 304cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out case where the user specifies a union that includes everything 305cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 306cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 307cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 308cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkPath clipA, clipB; 309cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 310cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 311cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.setFillType(SkPath::kInverseEvenOdd_FillType); 312cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 313cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 314cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.setFillType(SkPath::kInverseEvenOdd_FillType); 315cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 316cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipA, SkRegion::kReplace_Op, false); 317cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipB, SkRegion::kUnion_Op, false); 318cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 319cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 320cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 321cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 322cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out union w/ a wide open clip 323cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 324cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 325cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 326cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kUnion_Op, false); 327cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 328cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 329cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 330cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 331cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out empty difference from a wide open clip 332cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 333cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 334cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 335cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect emptyRect; 336cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com emptyRect.setEmpty(); 337cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 338cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(emptyRect, SkRegion::kDifference_Op, false); 339cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 340cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 341cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 342cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 343cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out return to wide open 344cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 345cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 346cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 347cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.save(); 348cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 349cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kReplace_Op, false); 350cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 351cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 352cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 353cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.restore(); 354cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 355cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 356cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 357cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com} 358cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 359100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.comstatic int count(const SkClipStack& stack) { 36008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 36208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com const SkClipStack::Iter::Clip* clip = NULL; 36408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com int count = 0; 36508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com for (clip = iter.prev(); clip; clip = iter.prev(), ++count) { 36708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com ; 36808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 36908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com return count; 37108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 37208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Test out SkClipStack's merging of rect clips. In particular exercise 37408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// merging of aa vs. bw rects. 37508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.comstatic void test_rect_merging(skiatest::Reporter* reporter) { 37608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 37808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 37908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 38108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 38208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect bound; 38408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::BoundsType type; 38508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com bool isIntersectionOfRects; 38608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all bw overlapping - should merge 38808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 38908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 39008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, false); 39208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 39408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 39608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 39808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 40008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 40108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all aa overlapping - should merge 40308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 40408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 40508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 40708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); 40908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 41108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 41308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 41508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 41608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed overlapping - should _not_ merge 41808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 41908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 42008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 42208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 42408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 42608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 42808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 43008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 43108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (bw inside aa) - should merge 43308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 43408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 43508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, true); 43708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); 43908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 44108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 44308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 44508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 44608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (aa inside bw) - should merge 44808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 44908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 45008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, false); 45208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); 45408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 45608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 45808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 46008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 46108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // reverse nested (aa inside bw) - should _not_ merge 46308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 46408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 46508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kReplace_Op, false); 46708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); 46908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 47108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 47308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 47508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 47608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 477cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 478e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 479e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// This is similar to the above test but tests the iterator's ability to merge rects in the 480e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// middle of a clip stack's sequence using nextCombined(). There is a save after every clip 481e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// element to prevent the clip stack from merging the rectangles as they are added. 482e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.comstatic void test_iter_rect_merging(skiatest::Reporter* reporter) { 483e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 484e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 485e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 486e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 487e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 488e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 489e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 490e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect farAway = SkRect::MakeLTRB(1000, 1000, 1010, 1010); 491e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 492e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapIntersect; 493e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com overlapIntersect.intersect(overlapLeft, overlapRight); 494e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 495e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkPath path1, path2; 496e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com path1.addCircle(SkIntToScalar(30), SkIntToScalar(30), SkIntToScalar(1000)); 497e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com path2.addOval(SkRect::MakeWH(500, 600)); 498e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 499e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com const SkClipStack::Iter::Clip* clip; 500e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 501e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // call nextCombined with an empty clip stack 502e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 503e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 504e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 505e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == iter.nextCombined()); 506e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 507e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 508e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // two bw overlapping - should merge, bracketed by paths 509e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 510e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 511e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save(); 512e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 513e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save(); 514e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 515e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 516e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 517e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path2, SkRegion::kIntersect_Op, false); stack.save(); 518e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 519e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 520e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 521e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 522e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA); 523e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 524e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 525e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapIntersect); 526e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 527e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 528e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path2 && !clip->fDoAA); 529e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 530e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 531e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 532e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 533e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 534e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // same as above but rects are aa and no final path. 535e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 536e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 537e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save(); 538e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 539e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 540e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 541e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save(); 542e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 543e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 544e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 545e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 546e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA); 547e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 548e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 549e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect); 550e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 551e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 552e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 553e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 554e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 555e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed overlapping - no paths - should _not_ merge 556e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 557e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 558e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 559e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 560e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 561e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 562e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 563e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 564e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 565e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapLeft); 566e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 567e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 568e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapRight); 569e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 570e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 571e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 572e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 573e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 574e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // three rects in a row where the third rect uses a non-intersect op. 575e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 576e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 577e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 578e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 579e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save(); 580e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kXOR_Op, true); stack.save(); 581e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 582e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 583e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 584e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 585e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect); 586e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 587e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedParent); 588e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 589e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 590e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 591e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 592e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed nested (bw inside aa) - should merge 593e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 594e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 595e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, false); stack.save(); 596e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 597e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); stack.save(); 598e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 599e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 60072b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 601e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 602e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedChild); 603e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 604e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 605e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 606e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 607e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 608e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed nested (aa inside bw) - should merge 609e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 610e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 611e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); stack.save(); 612e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 613e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); stack.save(); 614e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 615e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 61672b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 617e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 618e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == nestedChild); 619e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 620e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 621e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 622e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 623e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 624e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // three rect intersects in a row where result is empty after the second. 625e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 626e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 627e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 628e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save(); 629e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(farAway, SkRegion::kIntersect_Op, false); stack.save(); 630e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 631e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 632e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 633e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 634e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 635e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fRect->isEmpty()); 636e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 637e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 638e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fRect == overlapRight); 639e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 640e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 641e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 642e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 643e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com} 644e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 64551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 64651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 64751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comtypedef void (*AddElementFunc) (const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack); 64851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 64951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_round_rect(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 65051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 65151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar rx = rect.width() / 10; 65251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar ry = rect.width() / 20; 65351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRoundRect(rect, rx, ry); 65451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(path, op, aa); 65551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 65651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 65751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_rect(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 65851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevRect(rect, op, aa); 65951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 66051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 66151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_oval(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 66251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 66351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addOval(rect); 66451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(path, op, aa); 66551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 66651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 66751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_elem_to_stack(const SkClipStack::Iter::Clip& clip, SkClipStack* stack) { 66851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (NULL != clip.fPath) { 66951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(*clip.fPath, clip.fOp, clip.fDoAA); 67051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else if (NULL != clip.fRect) { 67151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevRect(*clip.fRect, clip.fOp, clip.fDoAA); 67251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 67351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 67451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 67551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_elem_to_region(const SkClipStack::Iter::Clip& clip, 67651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkIRect& bounds, 67751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion* region) { 67851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion elemRegion; 67951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion boundsRgn(bounds); 68051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 68151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (NULL != clip.fPath) { 68251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com elemRegion.setPath(*clip.fPath, boundsRgn); 68351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else if (NULL != clip.fRect) { 68451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 68551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRect(*clip.fRect); 68651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com elemRegion.setPath(path, boundsRgn); 68751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 68851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // TODO: Figure out why we sometimes get here in the reduced clip stack. 68951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region->setEmpty(); 69051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com return; 69151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 69251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region->op(elemRegion, clip.fOp); 69351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 69451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 69551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com// This can assist with debugging the clip stack reduction code when the test below fails. 69651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void print_clip(const SkClipStack::Iter::Clip& clip) { 69751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const char* kOpStrs[] = { 69851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "DF", 69951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "IS", 70051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "UN", 70151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "XR", 70251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RD", 70351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RP", 70451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 70551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (clip.fRect || clip.fPath) { 70651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkRect& bounds = clip.getBounds(); 70751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("%s %s [%f %f] x [%f %f]\n", 70851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kOpStrs[clip.fOp], 70951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com (clip.fRect ? "R" : "P"), 71051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bounds.fLeft, bounds.fRight, bounds.fTop, bounds.fBottom); 71151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 71251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("EM\n"); 71351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 71451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 71551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 71651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void test_reduced_clip_stack(skiatest::Reporter* reporter) { 71751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // We construct random clip stacks, reduce them, and then rasterize both versions to verify that 71851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // they are equal. 71951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // All the clip elements will be contained within these bounds. 72151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRect kBounds = SkRect::MakeWH(100, 100); 72251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com enum { 72451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kNumTests = 200, 72551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMinElemsPerTest = 1, 72651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMaxElemsPerTest = 50, 72751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 72851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // min/max size of a clip element as a fraction of kBounds. 73051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5; 73151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMaxElemSizeFrac = SK_Scalar1; 73251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 73351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRegion::Op kOps[] = { 73451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kDifference_Op, 73551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kIntersect_Op, 73651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kUnion_Op, 73751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kXOR_Op, 73851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReverseDifference_Op, 73951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReplace_Op, 74051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 74151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 74251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Replace operations short-circuit the optimizer. We want to make sure that we test this code 74351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // path a little bit but we don't want it to prevent us from testing many longer traversals in 74451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // the optimizer. 74551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const int kReplaceDiv = 4 * kMaxElemsPerTest; 74651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 74751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const AddElementFunc kElementFuncs[] = { 74851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_rect, 74951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_round_rect, 75051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_oval, 75151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 75251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 75351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRandom r; 75451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 75551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int i = 0; i < kNumTests; ++i) { 75651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Randomly generate a clip stack. 75751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack stack; 75851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest); 75951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int e = 0; e < numElems; ++e) { 76051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::Op op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))]; 76151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (op == SkRegion::kReplace_Op) { 76251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (r.nextU() % kReplaceDiv) { 76351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com --e; 76451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com continue; 76551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 76651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 76751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 76851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // saves can change the clip stack behavior when an element is added. 76951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool doSave = r.nextBool(); 77051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 77151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkSize size = SkSize::Make( 77251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.width(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac))), 77351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.height(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac)))); 77451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 77551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPoint xy = {SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth)), 77651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight))}; 77751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 77851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect rect = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight); 77951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // AA is always disabled. The optimizer can cause changes in aa rasterization of the 78151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // clip stack. A fractional edge repeated in different elements may be rasterized fewer 78251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // times using the reduced stack. 78351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kElementFuncs[r.nextULessThan(SK_ARRAY_COUNT(kElementFuncs))](rect, false, op, &stack); 78451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (doSave) { 78551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack.save(); 78651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 78751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 78851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Get the reduced version of the stack. 79051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkTDArray<SkClipStack::Iter::Clip> reducedClips; 79151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect resultBounds; 79251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool bounded; 79351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::InitialState initial; 79451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::GrReduceClipStack(stack, &reducedClips, &resultBounds, &bounded, &initial); 79551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 79651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Build a new clip stack based on the reduced clip elements 79751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack reducedStack; 79851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (GrReducedClip::kAllOut_InitialState == initial) { 79951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // whether the result is bounded or not, the whole plane should start outside the clip. 80051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipEmpty(); 80151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 80251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int c = 0; c < reducedClips.count(); ++c) { 80351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_stack(reducedClips[c], &reducedStack); 80451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 80551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (bounded) { 80651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // GrReduceClipStack() assumes that there is an implicit clip to the bounds 80751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipDevRect(resultBounds, SkRegion::kIntersect_Op, true); 80851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 80951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 81051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // convert both the original stack and reduced stack to SkRegions and see if they're equal 81151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect inflatedBounds = kBounds; 81251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com inflatedBounds.outset(kBounds.width() / 2, kBounds.height() / 2); 81351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkIRect inflatedIBounds; 81451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com inflatedBounds.roundOut(&inflatedIBounds); 81551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 81651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion region; 81751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion reducedRegion; 81851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 81951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region.setRect(inflatedIBounds); 82051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkClipStack::Iter::Clip* clip; 82151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 82251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com while ((clip = iter.next())) { 82351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_region(*clip, inflatedIBounds, ®ion); 82451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 82551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 82651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedRegion.setRect(inflatedIBounds); 82751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com iter.reset(reducedStack, SkClipStack::Iter::kBottom_IterStart); 82851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com while ((clip = iter.next())) { 82951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_region(*clip, inflatedIBounds, &reducedRegion); 83051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 83151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 83251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com REPORTER_ASSERT(reporter, region == reducedRegion); 83351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 83451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 83551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 83651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 83751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 838bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void TestClipStack(skiatest::Reporter* reporter) { 839bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com SkClipStack stack; 840bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 84180214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 842bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 843bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 844bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com static const SkIRect gRects[] = { 845bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 100, 100 }, 846bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 25, 25, 125, 125 }, 847bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 1000, 1000 }, 848bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 75, 75 } 849bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com }; 850bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 851d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com stack.clipDevRect(gRects[i], SkRegion::kIntersect_Op); 852bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 853bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 854bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // all of the above rects should have been intersected, leaving only 1 rect 85580214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 85680214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::B2TIter::Clip* clip = iter.next(); 8572047f00e4698f83499ab91911999a65c21a951c9epoger@google.com SkRect answer; 8582047f00e4698f83499ab91911999a65c21a951c9epoger@google.com answer.iset(25, 25, 75, 75); 859bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 860bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, clip); 861bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, clip->fRect); 862bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !clip->fPath); 863bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == clip->fOp); 864bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, *clip->fRect == answer); 865bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // now check that we only had one in our iterator 866bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !iter.next()); 867bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 868bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com stack.reset(); 86980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 870bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 8711e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 8721e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org test_assign_and_comparison(reporter); 87380214e26c57c5fea954006400852e8999e201923robertphillips@google.com test_iterators(reporter); 87408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, true); // once with rects 87508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, false); // once with paths 876cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com test_isWideOpen(reporter); 87708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_rect_merging(reporter); 878e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com test_iter_rect_merging(reporter); 87951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com test_reduced_clip_stack(reporter); 880bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 881bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 882bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "TestClassDef.h" 883bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comDEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack) 884