ClipStackTest.cpp revision 8cdf0f52ff395d4053f7ed5c20861c42eba25d31
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" 9a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#if SK_SUPPORT_GPU 10170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com #include "GrReducedClip.h" 11a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#endif 12bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "SkClipStack.h" 131e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org#include "SkPath.h" 1451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com#include "SkRandom.h" 151e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org#include "SkRect.h" 1651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com#include "SkRegion.h" 1780214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 191e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.orgstatic void test_assign_and_comparison(skiatest::Reporter* reporter) { 201e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack s; 21d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com bool doAA = false; 221e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 2380214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == s.getSaveCount()); 2480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 251e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Build up a clip stack with a path, an empty clip, and a rect. 261e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 2780214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 2880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 291e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkPath p; 301e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.moveTo(5, 6); 311e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.lineTo(7, 8); 321e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.lineTo(5, 9); 331e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.close(); 34d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 351e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 361e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 3780214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 3880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 391e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkRect r = SkRect::MakeLTRB(1, 2, 3, 4); 40d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 411e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(10, 11, 12, 13); 42d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 431e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 441e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 4580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 4680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 471e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 48d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 491e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 501e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that assignment works. 511e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkClipStack copy = s; 521e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 531e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 541e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different save levels triggers not equal. 551e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 5680214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 571e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 581e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 591e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that an equal, but not copied version is equal. 601e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 6180214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 6280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 631e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 64d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 651e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 661e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 671e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that a different op on one level triggers not equal. 681e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 6980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 701e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 7180214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 7280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 731e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(14, 15, 16, 17); 74d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 751e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 761e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 771e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different state (clip type) triggers not equal. 784c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // NO LONGER VALID: if a path contains only a rect, we turn 794c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // it into a bare rect for performance reasons (working 804c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com // around Chromium/JavaScript bad pattern). 814c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com/* 821e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 831e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 841e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org SkPath rp; 851e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org rp.addRect(r); 86d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(rp, SkRegion::kUnion_Op, doAA); 871e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 884c4337291d873c4f27cb7903645863dc65b98a7btomhudson@google.com*/ 891e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 901e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different rects triggers not equal. 911e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 9280214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 931e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 9480214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 9580214e26c57c5fea954006400852e8999e201923robertphillips@google.com 961e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org r = SkRect::MakeLTRB(24, 25, 26, 27); 97d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 981e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 991e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 1001e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Sanity check 1011e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 10280214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 10380214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1041e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org copy.restore(); 10580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 2 == copy.getSaveCount()); 1061e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 1071e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 10880214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 1091e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org copy.restore(); 11080214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == copy.getSaveCount()); 1111e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s == copy); 1121e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 1131e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org // Test that different paths triggers not equal. 1141e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.restore(); 11580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == s.getSaveCount()); 1161e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org s.save(); 11780214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 11880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1191e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org p.addRect(r); 120d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 1211e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org REPORTER_ASSERT(reporter, s != copy); 1221e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org} 123bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 124bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack, 125bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com int count) { 12680214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 127bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com int counter = 0; 128bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com while (iter.next()) { 129bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com counter += 1; 130bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 131bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, count == counter); 132bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 133bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 13408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Exercise the SkClipStack's bottom to top and bidirectional iterators 13508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// (including the skipToTopmost functionality) 13680214e26c57c5fea954006400852e8999e201923robertphillips@google.comstatic void test_iterators(skiatest::Reporter* reporter) { 13780214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack stack; 13880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 13980214e26c57c5fea954006400852e8999e201923robertphillips@google.com static const SkRect gRects[] = { 14080214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 0, 0, 40, 40 }, 14180214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 60, 0, 100, 40 }, 14280214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 0, 60, 40, 100 }, 14380214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 60, 60, 100, 100 } 14480214e26c57c5fea954006400852e8999e201923robertphillips@google.com }; 14580214e26c57c5fea954006400852e8999e201923robertphillips@google.com 14680214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 14780214e26c57c5fea954006400852e8999e201923robertphillips@google.com // the union op will prevent these from being fused together 14880214e26c57c5fea954006400852e8999e201923robertphillips@google.com stack.clipDevRect(gRects[i], SkRegion::kUnion_Op, false); 14980214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 15080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15180214e26c57c5fea954006400852e8999e201923robertphillips@google.com assert_count(reporter, stack, 4); 15280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15380214e26c57c5fea954006400852e8999e201923robertphillips@google.com // bottom to top iteration 15480214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 1558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = NULL; 15680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15780214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 15880214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 15980214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1608182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com for (i = 0, element = iter.next(); element; ++i, element = iter.next()) { 1618182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType()); 1628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, element->getRect() == gRects[i]); 16380214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16580214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == 4); 16680214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16780214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16880214e26c57c5fea954006400852e8999e201923robertphillips@google.com // top to bottom iteration 16980214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 1708182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = NULL; 17180214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17280214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 17380214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 17480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1758182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com for (i = 3, element = iter.prev(); element; --i, element = iter.prev()) { 1768182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType()); 1778182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, element->getRect() == gRects[i]); 17880214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 17980214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18080214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == -1); 18180214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 18280214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18380214e26c57c5fea954006400852e8999e201923robertphillips@google.com // skipToTopmost 18480214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 1858182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = NULL; 18680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18780214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 18880214e26c57c5fea954006400852e8999e201923robertphillips@google.com 1898182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element = iter.skipToTopmost(SkRegion::kUnion_Op); 1908182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType()); 1918182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, element->getRect() == gRects[3]); 19280214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 19380214e26c57c5fea954006400852e8999e201923robertphillips@google.com} 19480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 19508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Exercise the SkClipStack's getConservativeBounds computation 1964c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.comstatic void test_bounds(skiatest::Reporter* reporter, bool useRects) { 197607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 198607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const int gNumCases = 20; 199607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRect gAnswerRectsBW[gNumCases] = { 200607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op B 201607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 202607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 203607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 204607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 205607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 206607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 207607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op B 208607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 209607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 210607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 211607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 212607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 213607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 214607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op invB 215607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 216607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 217607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 218607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 219607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 220607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 221607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op invB 222607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 223607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 224607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 225607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 226607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 227607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 228607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 229607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRegion::Op gOps[] = { 230607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kIntersect_Op, 231607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kDifference_Op, 232607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kUnion_Op, 233607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kXOR_Op, 234607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kReverseDifference_Op 235607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 236607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 237607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRect rectA, rectB; 238607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 239607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectA.iset(10, 10, 50, 50); 240607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectB.iset(40, 40, 80, 80); 241607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 242607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath clipA, clipB; 243607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 244607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 245607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 246607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 247607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkClipStack stack; 2487b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkRect devClipBound; 2494c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool isIntersectionOfRects = false; 250607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 251607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int testCase = 0; 2524c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com int numBitTests = useRects ? 1 : 4; 2534c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com for (int invBits = 0; invBits < numBitTests; ++invBits) { 254607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 255607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 256607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.save(); 257607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvA = SkToBool(invBits & 1); 258607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvB = SkToBool(invBits & 2); 259607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 260607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 261607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 262607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 263607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 264607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 2654c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 2664c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectA, SkRegion::kIntersect_Op, false); 2674c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectB, gOps[op], false); 2684c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2694c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipA, SkRegion::kIntersect_Op, false); 2704c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipB, gOps[op], false); 2714c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 272607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 273cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 274cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 2757b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com stack.getConservativeBounds(0, 0, 100, 100, &devClipBound, 2764c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com &isIntersectionOfRects); 2774c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com 2784c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 279d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects == 2804c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com (gOps[op] == SkRegion::kIntersect_Op)); 2814c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2824c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 2834c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 284607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 285607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkASSERT(testCase < gNumCases); 2867b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]); 287607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com ++testCase; 288607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 289607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.restore(); 290607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 291607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 292607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com} 293607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 294cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com// Test out 'isWideOpen' entry point 295cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.comstatic void test_isWideOpen(skiatest::Reporter* reporter) { 296cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 297cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect rectA, rectB; 298cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 299cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectA.iset(10, 10, 40, 40); 300cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectB.iset(50, 50, 80, 80); 301cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 302cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Stack should initially be wide open 303cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 304cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 305cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 306cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 307cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 308cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 309cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out case where the user specifies a union that includes everything 310cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 311cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 312cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 313cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkPath clipA, clipB; 314cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 315cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 316cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.setFillType(SkPath::kInverseEvenOdd_FillType); 317cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 318cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 319cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.setFillType(SkPath::kInverseEvenOdd_FillType); 320cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 321cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipA, SkRegion::kReplace_Op, false); 322cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipB, SkRegion::kUnion_Op, false); 323cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 324cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 325cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 326cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 327cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out union w/ a wide open clip 328cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 329cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 330cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 331cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kUnion_Op, false); 332cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 333cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 334cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 335cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 336cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out empty difference from a wide open clip 337cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 338cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 339cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 340cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect emptyRect; 341cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com emptyRect.setEmpty(); 342cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 343cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(emptyRect, SkRegion::kDifference_Op, false); 344cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 345cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 346cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 347cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 348cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out return to wide open 349cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 350cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 351cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 352cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.save(); 353cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 354cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kReplace_Op, false); 355cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 356cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 357cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 358cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.restore(); 359cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 360cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 361cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 362cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com} 363cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 364100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.comstatic int count(const SkClipStack& stack) { 36508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 36708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 3688182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = NULL; 36908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com int count = 0; 37008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 3718182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com for (element = iter.prev(); element; element = iter.prev(), ++count) { 37208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com ; 37308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 37408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com return count; 37608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 37708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 378edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.orgstatic void test_rect_inverse_fill(skiatest::Reporter* reporter) { 379edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org // non-intersecting rectangles 380edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org SkRect rect = SkRect::MakeLTRB(0, 0, 10, 10); 381edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org 382edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org SkPath path; 383edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org path.addRect(rect); 384edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org path.toggleInverseFillType(); 385edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org SkClipStack stack; 386edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 387edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org 388edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org SkRect bounds; 389edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org SkClipStack::BoundsType boundsType; 390edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org stack.getBounds(&bounds, &boundsType); 391edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org REPORTER_ASSERT(reporter, SkClipStack::kInsideOut_BoundsType == boundsType); 392edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org REPORTER_ASSERT(reporter, bounds == rect); 393edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org} 394edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org 39508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Test out SkClipStack's merging of rect clips. In particular exercise 39608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// merging of aa vs. bw rects. 39708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.comstatic void test_rect_merging(skiatest::Reporter* reporter) { 39808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 40008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 40108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 40308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 40408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect bound; 40608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::BoundsType type; 40708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com bool isIntersectionOfRects; 40808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all bw overlapping - should merge 41008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 41108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 41208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, false); 41408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 41608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 41808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 42008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 42208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 42308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all aa overlapping - should merge 42508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 42608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 42708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 42908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); 43108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 43308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 43508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 43708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 43808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed overlapping - should _not_ merge 44008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 44108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 44208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 44408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 44608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 44808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 45008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 45208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 45308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (bw inside aa) - should merge 45508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 45608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 45708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, true); 45908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); 46108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 46308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 46508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 46708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 46808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (aa inside bw) - should merge 47008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 47108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 47208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, false); 47408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); 47608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 47808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 48008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 48108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 48208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 48308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 48408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // reverse nested (aa inside bw) - should _not_ merge 48508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 48608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 48708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 48808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kReplace_Op, false); 48908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 49008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); 49108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 49208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 49308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 49408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 49508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 49608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 49708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 49808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 499cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 5008cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.orgstatic void test_quickContains(skiatest::Reporter* reporter) { 5018cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkRect testRect = SkRect::MakeLTRB(10, 10, 40, 40); 5028cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkRect insideRect = SkRect::MakeLTRB(20, 20, 30, 30); 5038cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkRect intersectingRect = SkRect::MakeLTRB(25, 25, 50, 50); 5048cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkRect outsideRect = SkRect::MakeLTRB(0, 0, 50, 50); 5058cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkRect nonIntersectingRect = SkRect::MakeLTRB(100, 100, 110, 110); 5068cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5078cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath insideCircle; 5088cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org insideCircle.addCircle(25, 25, 5); 5098cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath intersectingCircle; 5108cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org intersectingCircle.addCircle(25, 40, 10); 5118cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath outsideCircle; 5128cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org outsideCircle.addCircle(25, 25, 50); 5138cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath nonIntersectingCircle; 5148cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org nonIntersectingCircle.addCircle(100, 100, 5); 5158cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5168cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5178cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5188cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(outsideRect, SkRegion::kDifference_Op, false); 5198cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // return false because quickContains currently does not care for kDifference_Op 5208cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5218cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5228cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5238cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Replace Op tests 5248cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5258cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5268cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(outsideRect, SkRegion::kReplace_Op, false); 5278cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 5288cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5298cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5308cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5318cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5328cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 5338cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.save(); // To prevent in-place substitution by replace OP 5348cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(outsideRect, SkRegion::kReplace_Op, false); 5358cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 5368cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.restore(); 5378cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5388cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5398cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5408cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5418cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(outsideRect, SkRegion::kIntersect_Op, false); 5428cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.save(); // To prevent in-place substitution by replace OP 5438cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(insideRect, SkRegion::kReplace_Op, false); 5448cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5458cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.restore(); 5468cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5478cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5488cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Verify proper traversal of multi-element clip 5498cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5508cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5518cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 5528cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Use a path for second clip to prevent in-place intersection 5538cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(outsideCircle, SkRegion::kIntersect_Op, false); 5548cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5558cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5568cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5578cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Intersect Op tests with rectangles 5588cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5598cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5608cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(outsideRect, SkRegion::kIntersect_Op, false); 5618cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 5628cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5638cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5648cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5658cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5668cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 5678cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5688cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5698cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5708cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5718cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5728cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(intersectingRect, SkRegion::kIntersect_Op, false); 5738cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5748cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5758cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5768cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5778cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5788cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevRect(nonIntersectingRect, SkRegion::kIntersect_Op, false); 5798cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5808cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5818cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5828cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Intersect Op tests with circle paths 5838cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5848cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5858cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(outsideCircle, SkRegion::kIntersect_Op, false); 5868cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 5878cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5888cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5898cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5908cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5918cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(insideCircle, SkRegion::kIntersect_Op, false); 5928cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5938cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 5948cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 5958cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 5968cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 5978cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(intersectingCircle, SkRegion::kIntersect_Op, false); 5988cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 5998cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6008cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6018cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6028cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6038cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(nonIntersectingCircle, SkRegion::kIntersect_Op, false); 6048cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6058cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6068cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6078cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Intersect Op tests with inverse filled rectangles 6088cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6098cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6108cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path; 6118cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.addRect(outsideRect); 6128cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6138cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6148cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6158cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6168cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6178cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6188cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6198cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path; 6208cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.addRect(insideRect); 6218cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6228cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6238cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6248cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6258cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6268cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6278cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6288cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path; 6298cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.addRect(intersectingRect); 6308cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6318cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6328cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6338cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6348cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6358cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6368cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6378cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path; 6388cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.addRect(nonIntersectingRect); 6398cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6408cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6418cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 6428cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6438cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6448cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org // Intersect Op tests with inverse filled circles 6458cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6468cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6478cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path = outsideCircle; 6488cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6498cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6508cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6518cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6528cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6538cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6548cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6558cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path = insideCircle; 6568cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6578cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6588cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6598cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6608cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6618cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6628cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6638cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path = intersectingCircle; 6648cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6658cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6668cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 6678cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6688cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 6698cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org { 6708cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkClipStack stack; 6718cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org SkPath path = nonIntersectingCircle; 6728cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org path.toggleInverseFillType(); 6738cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 6748cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 6758cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org } 6768cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org} 6778cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org 67851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 67951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 680a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#if SK_SUPPORT_GPU 681705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// Functions that add a shape to the clip stack. The shape is computed from a rectangle. 682705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// AA is always disabled since the clip stack reducer can cause changes in aa rasterization of the 683705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// stack. A fractional edge repeated in different elements may be rasterized fewer times using the 684705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// reduced stack. 685705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comtypedef void (*AddElementFunc) (const SkRect& rect, 686705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com bool invert, 687705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkRegion::Op op, 688705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkClipStack* stack); 689705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com 690705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_round_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 69151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 69251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar rx = rect.width() / 10; 693705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkScalar ry = rect.height() / 20; 69451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRoundRect(rect, rx, ry); 695705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 696705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 697705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 698705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 69951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 70051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 701705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 702705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 703705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkPath path; 704705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.addRect(rect); 705705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 706705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 707705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } else { 708705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevRect(rect, op, false); 709705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 71051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 71151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 712705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_oval(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 71351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 71451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addOval(rect); 715705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 716705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 717705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 718705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 71951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 72051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 7218182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void add_elem_to_stack(const SkClipStack::Element& element, SkClipStack* stack) { 7228182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element.getType()) { 7238182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 7248182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipDevRect(element.getRect(), element.getOp(), element.isAA()); 7258182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 7268182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kPath_Type: 7278182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipDevPath(element.getPath(), element.getOp(), element.isAA()); 7288182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 7298182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 7308182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkDEBUGFAIL("Why did the reducer produce an explicit empty."); 7318182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipEmpty(); 7328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 73351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 73451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 73551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 7368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void add_elem_to_region(const SkClipStack::Element& element, 73751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkIRect& bounds, 73851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion* region) { 73951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion elemRegion; 74051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion boundsRgn(bounds); 74151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 7428182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element.getType()) { 7438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: { 7448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkPath path; 7458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com path.addRect(element.getRect()); 7468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com elemRegion.setPath(path, boundsRgn); 7478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 7488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 7498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kPath_Type: 7508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com elemRegion.setPath(element.getPath(), boundsRgn); 7518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 7528182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 75373b140a9f668c189b0682cc5f82d9fb57ff8bc15skia.committer@gmail.com // 7548182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com region->setEmpty(); 7558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return; 75651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 7578182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com region->op(elemRegion, element.getOp()); 75851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 75951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 76051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com// This can assist with debugging the clip stack reduction code when the test below fails. 7618182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void print_clip(const SkClipStack::Element& element) { 76251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const char* kOpStrs[] = { 76351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "DF", 76451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "IS", 76551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "UN", 76651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "XR", 76751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RD", 76851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RP", 76951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 7708182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com if (SkClipStack::Element::kEmpty_Type != element.getType()) { 7718182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkRect& bounds = element.getBounds(); 7728182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com bool isRect = SkClipStack::Element::kRect_Type == element.getType(); 773705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkDebugf("%s %s %s [%f %f] x [%f %f]\n", 7748182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com kOpStrs[element.getOp()], 7758182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com (isRect ? "R" : "P"), 7768182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com (element.isInverseFilled() ? "I" : " "), 77751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bounds.fLeft, bounds.fRight, bounds.fTop, bounds.fBottom); 77851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 77951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("EM\n"); 78051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 78151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 78251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void test_reduced_clip_stack(skiatest::Reporter* reporter) { 78451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // We construct random clip stacks, reduce them, and then rasterize both versions to verify that 7858ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com // they are equal. 78651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // All the clip elements will be contained within these bounds. 78851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRect kBounds = SkRect::MakeWH(100, 100); 78951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 79051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com enum { 79151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kNumTests = 200, 79251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMinElemsPerTest = 1, 79351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMaxElemsPerTest = 50, 79451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 79551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 79651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // min/max size of a clip element as a fraction of kBounds. 79751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5; 79851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMaxElemSizeFrac = SK_Scalar1; 79951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 80051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRegion::Op kOps[] = { 80151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kDifference_Op, 80251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kIntersect_Op, 80351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kUnion_Op, 80451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kXOR_Op, 80551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReverseDifference_Op, 80651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReplace_Op, 80751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 80851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 80951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Replace operations short-circuit the optimizer. We want to make sure that we test this code 81051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // path a little bit but we don't want it to prevent us from testing many longer traversals in 81151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // the optimizer. 81251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const int kReplaceDiv = 4 * kMaxElemsPerTest; 81351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 814705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com // We want to test inverse fills. However, they are quite rare in practice so don't over do it. 815705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com static const SkScalar kFractionInverted = SK_Scalar1 / kMaxElemsPerTest; 816705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com 81751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const AddElementFunc kElementFuncs[] = { 81851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_rect, 81951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_round_rect, 82051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_oval, 82151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 82251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 82351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRandom r; 82451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 82551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int i = 0; i < kNumTests; ++i) { 82651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Randomly generate a clip stack. 82751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack stack; 82851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest); 82951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int e = 0; e < numElems; ++e) { 83051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::Op op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))]; 83151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (op == SkRegion::kReplace_Op) { 83251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (r.nextU() % kReplaceDiv) { 83351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com --e; 83451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com continue; 83551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 83651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 8378ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 83851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // saves can change the clip stack behavior when an element is added. 83951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool doSave = r.nextBool(); 8408ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 84151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkSize size = SkSize::Make( 84251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.width(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac))), 84351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.height(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac)))); 84451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 84551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPoint xy = {SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth)), 84651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight))}; 84751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 84851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect rect = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight); 84951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 850705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com bool invert = r.nextBiasedBool(kFractionInverted); 851705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com kElementFuncs[r.nextULessThan(SK_ARRAY_COUNT(kElementFuncs))](rect, invert, op, &stack); 85251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (doSave) { 85351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack.save(); 85451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 85551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 85651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 857a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com SkRect inflatedBounds = kBounds; 858a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com inflatedBounds.outset(kBounds.width() / 2, kBounds.height() / 2); 859a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com SkIRect inflatedIBounds; 860a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com inflatedBounds.roundOut(&inflatedIBounds); 861a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com 8628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com typedef GrReducedClip::ElementList ElementList; 86351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Get the reduced version of the stack. 8648182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com ElementList reducedClips; 865a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com 86651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::InitialState initial; 86734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect tBounds; 86834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect* tightBounds = r.nextBool() ? &tBounds : NULL; 86934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com GrReducedClip::ReduceClipStack(stack, 87034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com inflatedIBounds, 87134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com &reducedClips, 87234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com &initial, 87334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com tightBounds); 87451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 87551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Build a new clip stack based on the reduced clip elements 87651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack reducedStack; 87751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (GrReducedClip::kAllOut_InitialState == initial) { 87851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // whether the result is bounded or not, the whole plane should start outside the clip. 87951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipEmpty(); 88051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 8818182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com for (ElementList::Iter iter = reducedClips.headIter(); NULL != iter.get(); iter.next()) { 8828182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_stack(*iter.get(), &reducedStack); 88351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 88451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 88534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // GrReducedClipStack assumes that the final result is clipped to the returned bounds 88634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tightBounds) { 88734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com reducedStack.clipDevRect(*tightBounds, SkRegion::kIntersect_Op); 88834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 88934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 89051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // convert both the original stack and reduced stack to SkRegions and see if they're equal 89151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion region; 89251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion reducedRegion; 89351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 89451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region.setRect(inflatedIBounds); 8958182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 89651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 8978182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next())) { 8988182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_region(*element, inflatedIBounds, ®ion); 89951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 90051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 90151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedRegion.setRect(inflatedIBounds); 90251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com iter.reset(reducedStack, SkClipStack::Iter::kBottom_IterStart); 9038182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next())) { 9048182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_region(*element, inflatedIBounds, &reducedRegion); 90551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 90651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 90751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com REPORTER_ASSERT(reporter, region == reducedRegion); 90851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 90951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 91051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 911a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#endif 91251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 91351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 914bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void TestClipStack(skiatest::Reporter* reporter) { 915bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com SkClipStack stack; 916bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 91780214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 918bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 919bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 920bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com static const SkIRect gRects[] = { 921bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 100, 100 }, 922bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 25, 25, 125, 125 }, 923bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 1000, 1000 }, 924bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 75, 75 } 925bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com }; 926bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 927d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com stack.clipDevRect(gRects[i], SkRegion::kIntersect_Op); 928bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 929bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 930bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // all of the above rects should have been intersected, leaving only 1 rect 93180214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 9328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = iter.next(); 9332047f00e4698f83499ab91911999a65c21a951c9epoger@google.com SkRect answer; 9342047f00e4698f83499ab91911999a65c21a951c9epoger@google.com answer.iset(25, 25, 75, 75); 935bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 9368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, NULL != element); 9378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType()); 9388182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == element->getOp()); 9398182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, element->getRect() == answer); 940bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // now check that we only had one in our iterator 941bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !iter.next()); 942bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 943bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com stack.reset(); 94480214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 945bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 9461e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 9471e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org test_assign_and_comparison(reporter); 94880214e26c57c5fea954006400852e8999e201923robertphillips@google.com test_iterators(reporter); 94908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, true); // once with rects 95008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, false); // once with paths 951cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com test_isWideOpen(reporter); 95208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_rect_merging(reporter); 953edf32d5b0e7694833287024e03da38521a0adf05junov@chromium.org test_rect_inverse_fill(reporter); 9548cdf0f52ff395d4053f7ed5c20861c42eba25d31junov@chromium.org test_quickContains(reporter); 955e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#if SK_SUPPORT_GPU 956edb26fdb8349a727b226e90cbeab06cd25f5cac0bsalomon@google.com test_reduced_clip_stack(reporter); 957e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#endif 958bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 959bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 960bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "TestClassDef.h" 961bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comDEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack) 962