ClipStackTest.cpp revision 34cd70a5810b3cf37b44de1ce080a911a8b342c8
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 37808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Test out SkClipStack's merging of rect clips. In particular exercise 37908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// merging of aa vs. bw rects. 38008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.comstatic void test_rect_merging(skiatest::Reporter* reporter) { 38108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 38308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 38408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 38608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 38708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect bound; 38908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::BoundsType type; 39008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com bool isIntersectionOfRects; 39108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all bw overlapping - should merge 39308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 39408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 39508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, false); 39708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 39908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 40108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 40308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 40508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 40608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all aa overlapping - should merge 40808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 40908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 41008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 41208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); 41408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 41608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 41808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 42008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 42108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed overlapping - should _not_ merge 42308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 42408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 42508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 42708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 42908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 43108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 43308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 43508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 43608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (bw inside aa) - should merge 43808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 43908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 44008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, true); 44208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); 44408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 44608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 44808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 45008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 45108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (aa inside bw) - should merge 45308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 45408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 45508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, false); 45708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); 45908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 46108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 46308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 46508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 46608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // reverse nested (aa inside bw) - should _not_ merge 46808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 46908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 47008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kReplace_Op, false); 47208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); 47408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 47608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 47808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 48008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 48108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 482cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 48351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 48451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 485a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#if SK_SUPPORT_GPU 486705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// Functions that add a shape to the clip stack. The shape is computed from a rectangle. 487705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// AA is always disabled since the clip stack reducer can cause changes in aa rasterization of the 488705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// stack. A fractional edge repeated in different elements may be rasterized fewer times using the 489705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com// reduced stack. 490705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comtypedef void (*AddElementFunc) (const SkRect& rect, 491705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com bool invert, 492705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkRegion::Op op, 493705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkClipStack* stack); 494705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com 495705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_round_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 49651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 49751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar rx = rect.width() / 10; 498705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkScalar ry = rect.height() / 20; 49951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRoundRect(rect, rx, ry); 500705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 501705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 502705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 503705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 50451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 50551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 506705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 507705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 508705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkPath path; 509705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.addRect(rect); 510705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 511705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 512705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } else { 513705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevRect(rect, op, false); 514705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 51551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 51651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 517705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.comstatic void add_oval(const SkRect& rect, bool invert, SkRegion::Op op, SkClipStack* stack) { 51851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 51951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addOval(rect); 520705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com if (invert) { 521705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com path.setFillType(SkPath::kInverseWinding_FillType); 522705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com } 523705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com stack->clipDevPath(path, op, false); 52451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 52551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 5268182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void add_elem_to_stack(const SkClipStack::Element& element, SkClipStack* stack) { 5278182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element.getType()) { 5288182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 5298182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipDevRect(element.getRect(), element.getOp(), element.isAA()); 5308182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 5318182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kPath_Type: 5328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipDevPath(element.getPath(), element.getOp(), element.isAA()); 5338182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 5348182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 5358182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkDEBUGFAIL("Why did the reducer produce an explicit empty."); 5368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com stack->clipEmpty(); 5378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 53851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 53951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 54051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 5418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void add_elem_to_region(const SkClipStack::Element& element, 54251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkIRect& bounds, 54351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion* region) { 54451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion elemRegion; 54551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion boundsRgn(bounds); 54651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 5478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element.getType()) { 5488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: { 5498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com SkPath path; 5508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com path.addRect(element.getRect()); 5518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com elemRegion.setPath(path, boundsRgn); 5528182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 5538182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com } 5548182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kPath_Type: 5558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com elemRegion.setPath(element.getPath(), boundsRgn); 5568182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 5578182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 55873b140a9f668c189b0682cc5f82d9fb57ff8bc15skia.committer@gmail.com // 5598182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com region->setEmpty(); 5608182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com return; 56151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 5628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com region->op(elemRegion, element.getOp()); 56351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 56451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 56551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com// This can assist with debugging the clip stack reduction code when the test below fails. 5668182fa0cac76e7e6d583aebba060229230516887bsalomon@google.comstatic void print_clip(const SkClipStack::Element& element) { 56751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const char* kOpStrs[] = { 56851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "DF", 56951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "IS", 57051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "UN", 57151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "XR", 57251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RD", 57351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RP", 57451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 5758182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com if (SkClipStack::Element::kEmpty_Type != element.getType()) { 5768182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkRect& bounds = element.getBounds(); 5778182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com bool isRect = SkClipStack::Element::kRect_Type == element.getType(); 578705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com SkDebugf("%s %s %s [%f %f] x [%f %f]\n", 5798182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com kOpStrs[element.getOp()], 5808182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com (isRect ? "R" : "P"), 5818182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com (element.isInverseFilled() ? "I" : " "), 58251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bounds.fLeft, bounds.fRight, bounds.fTop, bounds.fBottom); 58351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 58451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("EM\n"); 58551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 58651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 58751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 58851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void test_reduced_clip_stack(skiatest::Reporter* reporter) { 58951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // We construct random clip stacks, reduce them, and then rasterize both versions to verify that 5908ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com // they are equal. 59151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 59251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // All the clip elements will be contained within these bounds. 59351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRect kBounds = SkRect::MakeWH(100, 100); 59451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 59551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com enum { 59651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kNumTests = 200, 59751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMinElemsPerTest = 1, 59851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMaxElemsPerTest = 50, 59951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 60051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 60151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // min/max size of a clip element as a fraction of kBounds. 60251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5; 60351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMaxElemSizeFrac = SK_Scalar1; 60451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 60551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRegion::Op kOps[] = { 60651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kDifference_Op, 60751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kIntersect_Op, 60851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kUnion_Op, 60951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kXOR_Op, 61051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReverseDifference_Op, 61151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReplace_Op, 61251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 61351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 61451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Replace operations short-circuit the optimizer. We want to make sure that we test this code 61551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // path a little bit but we don't want it to prevent us from testing many longer traversals in 61651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // the optimizer. 61751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const int kReplaceDiv = 4 * kMaxElemsPerTest; 61851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 619705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com // We want to test inverse fills. However, they are quite rare in practice so don't over do it. 620705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com static const SkScalar kFractionInverted = SK_Scalar1 / kMaxElemsPerTest; 621705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com 62251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const AddElementFunc kElementFuncs[] = { 62351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_rect, 62451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_round_rect, 62551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_oval, 62651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 62751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 62851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRandom r; 62951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 63051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int i = 0; i < kNumTests; ++i) { 63151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Randomly generate a clip stack. 63251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack stack; 63351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest); 63451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int e = 0; e < numElems; ++e) { 63551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::Op op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))]; 63651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (op == SkRegion::kReplace_Op) { 63751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (r.nextU() % kReplaceDiv) { 63851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com --e; 63951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com continue; 64051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 64151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 6428ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 64351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // saves can change the clip stack behavior when an element is added. 64451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool doSave = r.nextBool(); 6458ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 64651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkSize size = SkSize::Make( 64751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.width(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac))), 64851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.height(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac)))); 64951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 65051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPoint xy = {SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth)), 65151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight))}; 65251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 65351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect rect = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight); 65451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 655705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com bool invert = r.nextBiasedBool(kFractionInverted); 656705e84094494613a4659fcabe29f76eb003f9809bsalomon@google.com kElementFuncs[r.nextULessThan(SK_ARRAY_COUNT(kElementFuncs))](rect, invert, op, &stack); 65751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (doSave) { 65851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack.save(); 65951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 66051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 66151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 662a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com SkRect inflatedBounds = kBounds; 663a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com inflatedBounds.outset(kBounds.width() / 2, kBounds.height() / 2); 664a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com SkIRect inflatedIBounds; 665a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com inflatedBounds.roundOut(&inflatedIBounds); 666a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com 6678182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com typedef GrReducedClip::ElementList ElementList; 66851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Get the reduced version of the stack. 6698182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com ElementList reducedClips; 670a444430281ea35cb76fb42516978b4a93221c2c7bsalomon@google.com 67151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::InitialState initial; 67234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect tBounds; 67334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect* tightBounds = r.nextBool() ? &tBounds : NULL; 67434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com GrReducedClip::ReduceClipStack(stack, 67534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com inflatedIBounds, 67634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com &reducedClips, 67734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com &initial, 67834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com tightBounds); 67951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 68051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Build a new clip stack based on the reduced clip elements 68151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack reducedStack; 68251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (GrReducedClip::kAllOut_InitialState == initial) { 68351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // whether the result is bounded or not, the whole plane should start outside the clip. 68451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipEmpty(); 68551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 6868182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com for (ElementList::Iter iter = reducedClips.headIter(); NULL != iter.get(); iter.next()) { 6878182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_stack(*iter.get(), &reducedStack); 68851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 68951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 69034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // GrReducedClipStack assumes that the final result is clipped to the returned bounds 69134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tightBounds) { 69234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com reducedStack.clipDevRect(*tightBounds, SkRegion::kIntersect_Op); 69334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 69434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 69551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // convert both the original stack and reduced stack to SkRegions and see if they're equal 69651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion region; 69751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion reducedRegion; 69851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 69951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region.setRect(inflatedIBounds); 7008182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 70151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 7028182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next())) { 7038182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_region(*element, inflatedIBounds, ®ion); 70451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 70551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 70651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedRegion.setRect(inflatedIBounds); 70751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com iter.reset(reducedStack, SkClipStack::Iter::kBottom_IterStart); 7088182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next())) { 7098182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com add_elem_to_region(*element, inflatedIBounds, &reducedRegion); 71051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 71151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 71251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com REPORTER_ASSERT(reporter, region == reducedRegion); 71351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 71451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 71551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 716a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#endif 71751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 71851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 719bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void TestClipStack(skiatest::Reporter* reporter) { 720bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com SkClipStack stack; 721bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 72280214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 723bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 724bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 725bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com static const SkIRect gRects[] = { 726bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 100, 100 }, 727bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 25, 25, 125, 125 }, 728bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 1000, 1000 }, 729bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 75, 75 } 730bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com }; 731bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 732d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com stack.clipDevRect(gRects[i], SkRegion::kIntersect_Op); 733bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 734bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 735bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // all of the above rects should have been intersected, leaving only 1 rect 73680214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 7378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element = iter.next(); 7382047f00e4698f83499ab91911999a65c21a951c9epoger@google.com SkRect answer; 7392047f00e4698f83499ab91911999a65c21a951c9epoger@google.com answer.iset(25, 25, 75, 75); 740bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 7418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, NULL != element); 7428182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getType()); 7438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == element->getOp()); 7448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com REPORTER_ASSERT(reporter, element->getRect() == answer); 745bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // now check that we only had one in our iterator 746bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !iter.next()); 747bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 748bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com stack.reset(); 74980214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 750bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 7511e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 7521e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org test_assign_and_comparison(reporter); 75380214e26c57c5fea954006400852e8999e201923robertphillips@google.com test_iterators(reporter); 75408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, true); // once with rects 75508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, false); // once with paths 756cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com test_isWideOpen(reporter); 75708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_rect_merging(reporter); 758e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#if SK_SUPPORT_GPU 759edb26fdb8349a727b226e90cbeab06cd25f5cac0bsalomon@google.com test_reduced_clip_stack(reporter); 760e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#endif 761bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 762bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 763bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "TestClassDef.h" 764bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comDEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack) 765