ClipStackTest.cpp revision 8ccf590b89cec1a5974b6f4b7b49ca67cc5036cf
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 10a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com #include "GrClipMaskManager.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 { 15580214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::B2TIter::Clip* clip = NULL; 15680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 15780214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 15880214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 15980214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16080214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (i = 0, clip = iter.next(); clip; ++i, clip = iter.next()) { 16180214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[i]); 16280214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16380214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16480214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == 4); 16580214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 16680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 16780214e26c57c5fea954006400852e8999e201923robertphillips@google.com // top to bottom iteration 16880214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 16980214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::Iter::Clip* clip = NULL; 17080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17180214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 17280214e26c57c5fea954006400852e8999e201923robertphillips@google.com int i; 17380214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17480214e26c57c5fea954006400852e8999e201923robertphillips@google.com for (i = 3, clip = iter.prev(); clip; --i, clip = iter.prev()) { 17580214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[i]); 17680214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 17780214e26c57c5fea954006400852e8999e201923robertphillips@google.com 17880214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkASSERT(i == -1); 17980214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 18080214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18180214e26c57c5fea954006400852e8999e201923robertphillips@google.com // skipToTopmost 18280214e26c57c5fea954006400852e8999e201923robertphillips@google.com { 18380214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::Iter::Clip*clip = NULL; 18480214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18580214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 18680214e26c57c5fea954006400852e8999e201923robertphillips@google.com 18780214e26c57c5fea954006400852e8999e201923robertphillips@google.com clip = iter.skipToTopmost(SkRegion::kUnion_Op); 18880214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, *clip->fRect == gRects[3]); 18980214e26c57c5fea954006400852e8999e201923robertphillips@google.com } 19080214e26c57c5fea954006400852e8999e201923robertphillips@google.com} 19180214e26c57c5fea954006400852e8999e201923robertphillips@google.com 19208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Exercise the SkClipStack's getConservativeBounds computation 1934c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.comstatic void test_bounds(skiatest::Reporter* reporter, bool useRects) { 194607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 195607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const int gNumCases = 20; 196607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRect gAnswerRectsBW[gNumCases] = { 197607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op B 198607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 199607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 200607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 201607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 202607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 203607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 204607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op B 205607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 206607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 207607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 208607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 209607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 210607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 211607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // A op invB 212607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 213607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 50, 50 }, 214607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 215607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 216607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 217607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 218607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com // invA op invB 219607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 220607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 40, 40, 80, 80 }, 221607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 0, 0, 100, 100 }, 222607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 80, 80 }, 223607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com { 10, 10, 50, 50 }, 224607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 225607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 226607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com static const SkRegion::Op gOps[] = { 227607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kIntersect_Op, 228607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kDifference_Op, 229607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kUnion_Op, 230607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kXOR_Op, 231607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRegion::kReverseDifference_Op 232607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com }; 233607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 234607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkRect rectA, rectB; 235607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 236607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectA.iset(10, 10, 50, 50); 237607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com rectB.iset(40, 40, 80, 80); 238607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 239607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath clipA, clipB; 240607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 241607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 242607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 243607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 244607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkClipStack stack; 2457b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com SkRect devClipBound; 2464c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com bool isIntersectionOfRects = false; 247607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 248607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com int testCase = 0; 2494c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com int numBitTests = useRects ? 1 : 4; 2504c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com for (int invBits = 0; invBits < numBitTests; ++invBits) { 251607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 252607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 253607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.save(); 254607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvA = SkToBool(invBits & 1); 255607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com bool doInvB = SkToBool(invBits & 2); 256607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 257607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 258607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 259607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 260607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkPath::kEvenOdd_FillType); 261607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 2624c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 2634c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectA, SkRegion::kIntersect_Op, false); 2644c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevRect(rectB, gOps[op], false); 2654c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2664c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipA, SkRegion::kIntersect_Op, false); 2674c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com stack.clipDevPath(clipB, gOps[op], false); 2684c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 269607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 270cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 271cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 2727b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com stack.getConservativeBounds(0, 0, 100, 100, &devClipBound, 2734c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com &isIntersectionOfRects); 2744c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com 2754c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com if (useRects) { 276d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects == 2774c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com (gOps[op] == SkRegion::kIntersect_Op)); 2784c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } else { 2794c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 2804c2a2f7c5e8ec77771153f94c454adf21fd33805robertphillips@google.com } 281607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 282607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com SkASSERT(testCase < gNumCases); 2837b11289b4e4d117bbcee6d2460b057d0fcf6e437robertphillips@google.com REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]); 284607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com ++testCase; 285607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 286607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com stack.restore(); 287607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 288607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com } 289607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com} 290607fe077c893fdb230e29631be096de614a14e2arobertphillips@google.com 291cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com// Test out 'isWideOpen' entry point 292cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.comstatic void test_isWideOpen(skiatest::Reporter* reporter) { 293cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 294cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect rectA, rectB; 295cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 296cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectA.iset(10, 10, 40, 40); 297cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com rectB.iset(50, 50, 80, 80); 298cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 299cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Stack should initially be wide open 300cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 301cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 302cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 303cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 304cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 305cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 306cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out case where the user specifies a union that includes everything 307cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 308cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 309cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 310cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkPath clipA, clipB; 311cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 312cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 313cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipA.setFillType(SkPath::kInverseEvenOdd_FillType); 314cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 315cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 316cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com clipB.setFillType(SkPath::kInverseEvenOdd_FillType); 317cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 318cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipA, SkRegion::kReplace_Op, false); 319cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevPath(clipB, SkRegion::kUnion_Op, false); 320cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 321cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 322cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 323cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 324cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out union w/ a wide open clip 325cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 326cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 327cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 328cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kUnion_Op, false); 329cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 330cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 331cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 332cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 333cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out empty difference from a wide open clip 334cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 335cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 336cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 337cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkRect emptyRect; 338cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com emptyRect.setEmpty(); 339cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 340cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(emptyRect, SkRegion::kDifference_Op, false); 341cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 342cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 343cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 344cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 345cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com // Test out return to wide open 346cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com { 347cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com SkClipStack stack; 348cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 349cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.save(); 350cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 351cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.clipDevRect(rectA, SkRegion::kReplace_Op, false); 352cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 353cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, !stack.isWideOpen()); 354cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 355cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com stack.restore(); 356cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 357cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com REPORTER_ASSERT(reporter, stack.isWideOpen()); 358cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com } 359cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com} 360cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 361100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.comstatic int count(const SkClipStack& stack) { 36208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 36408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com const SkClipStack::Iter::Clip* clip = NULL; 36608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com int count = 0; 36708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 36808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com for (clip = iter.prev(); clip; clip = iter.prev(), ++count) { 36908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com ; 37008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 37108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com return count; 37308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 37408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// Test out SkClipStack's merging of rect clips. In particular exercise 37608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com// merging of aa vs. bw rects. 37708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.comstatic void test_rect_merging(skiatest::Reporter* reporter) { 37808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 37908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 38008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 38108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 38308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 38408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkRect bound; 38608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack::BoundsType type; 38708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com bool isIntersectionOfRects; 38808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 38908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all bw overlapping - should merge 39008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 39108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 39208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, false); 39408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 39608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 39808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 39908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 40008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 40208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 40308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // all aa overlapping - should merge 40508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 40608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 40708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 40808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 40908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); 41108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 41308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 41508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 41708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 41808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 41908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed overlapping - should _not_ merge 42008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 42108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 42208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 42408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 42608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 42808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 42908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 43008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 43208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 43308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (bw inside aa) - should merge 43508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 43608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 43708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 43808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, true); 43908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); 44108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 44308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 44508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 44708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 44808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 44908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // mixed nested (aa inside bw) - should merge 45008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 45108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 45208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, false); 45408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); 45608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 1 == count(stack)); 45808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 45908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 46008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, isIntersectionOfRects); 46208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 46308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com // reverse nested (aa inside bw) - should _not_ merge 46508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com { 46608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com SkClipStack stack; 46708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 46808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedChild, SkRegion::kReplace_Op, false); 46908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); 47108eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, 2 == count(stack)); 47308eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47408eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com stack.getBounds(&bound, &type, &isIntersectionOfRects); 47508eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com 47608eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com REPORTER_ASSERT(reporter, !isIntersectionOfRects); 47708eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com } 47808eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com} 479cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com 480e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 481e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// This is similar to the above test but tests the iterator's ability to merge rects in the 482e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// middle of a clip stack's sequence using nextCombined(). There is a save after every clip 483e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com// element to prevent the clip stack from merging the rectangles as they are added. 484e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.comstatic void test_iter_rect_merging(skiatest::Reporter* reporter) { 485e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 486e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 487e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 488e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 489e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 490e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 491e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 492e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect farAway = SkRect::MakeLTRB(1000, 1000, 1010, 1010); 493e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 494e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkRect overlapIntersect; 495e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com overlapIntersect.intersect(overlapLeft, overlapRight); 496e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 497e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkPath path1, path2; 498e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com path1.addCircle(SkIntToScalar(30), SkIntToScalar(30), SkIntToScalar(1000)); 499e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com path2.addOval(SkRect::MakeWH(500, 600)); 500e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 501e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com const SkClipStack::Iter::Clip* clip; 502e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 503e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // call nextCombined with an empty clip stack 504e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 505e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 506e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 507e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == iter.nextCombined()); 508e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 509e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 510e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // two bw overlapping - should merge, bracketed by paths 511e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 512e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 513e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save(); 514e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 515e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save(); 516e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 517e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 518e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 519e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path2, SkRegion::kIntersect_Op, false); stack.save(); 520e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 521e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 522e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 523e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 524e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA); 525e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 526e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 527e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapIntersect); 528e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 529e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 530e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path2 && !clip->fDoAA); 531e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 532e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 533e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 534e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 535e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 536e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // same as above but rects are aa and no final path. 537e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 538e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 539e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save(); 540e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 541e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 542e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 543e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save(); 544e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 545e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 546e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 547e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 548e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA); 549e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 550e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 551e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect); 552e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 553e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 554e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 555e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 556e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 557e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed overlapping - no paths - should _not_ merge 558e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 559e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 560e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 561e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 562e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 563e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 564e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 565e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 566e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 567e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapLeft); 568e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 569e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 570e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapRight); 571e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 572e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 573e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 574e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 575e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 576e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // three rects in a row where the third rect uses a non-intersect op. 577e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 578e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 579e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 580e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save(); 581e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save(); 582e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kXOR_Op, true); stack.save(); 583e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 584e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 585e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 586e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 587e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect); 588e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 589e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedParent); 590e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 591e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 592e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 593e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 594e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed nested (bw inside aa) - should merge 595e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 596e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 597e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, false); stack.save(); 598e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 599e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); stack.save(); 600e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 601e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 60272b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 603e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 604e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedChild); 605e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 606e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 607e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 608e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 609e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 610e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // mixed nested (aa inside bw) - should merge 611e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 612e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 613e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); stack.save(); 614e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 615e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); stack.save(); 616e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 617e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 61872b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 619e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 620e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == nestedChild); 621e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 622e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 623e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 624e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 625e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 626e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com // three rect intersects in a row where result is empty after the second. 627e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com { 628e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack stack; 629e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 630e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save(); 631e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(farAway, SkRegion::kIntersect_Op, false); stack.save(); 632e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save(); 633e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 634e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 635e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 636e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 637e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, clip->fRect->isEmpty()); 638e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 639e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 640e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, *clip->fRect == overlapRight); 641e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 642e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com clip = iter.nextCombined(); 643e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com REPORTER_ASSERT(reporter, NULL == clip); 644e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com } 645e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com} 646e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com 64751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 64851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 649a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#if SK_SUPPORT_GPU 650a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com 65151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comtypedef void (*AddElementFunc) (const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack); 65251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 65351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_round_rect(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 65451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 65551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar rx = rect.width() / 10; 65651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalar ry = rect.width() / 20; 65751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRoundRect(rect, rx, ry); 65851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(path, op, aa); 65951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 66051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 66151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_rect(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 66251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevRect(rect, op, aa); 66351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 66451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 66551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_oval(const SkRect& rect, bool aa, SkRegion::Op op, SkClipStack* stack) { 66651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 66751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addOval(rect); 66851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(path, op, aa); 66951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com}; 67051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 67151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_elem_to_stack(const SkClipStack::Iter::Clip& clip, SkClipStack* stack) { 67251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (NULL != clip.fPath) { 67351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevPath(*clip.fPath, clip.fOp, clip.fDoAA); 67451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else if (NULL != clip.fRect) { 67551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack->clipDevRect(*clip.fRect, clip.fOp, clip.fDoAA); 67651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 67751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 67851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 67951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void add_elem_to_region(const SkClipStack::Iter::Clip& clip, 68051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkIRect& bounds, 68151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion* region) { 68251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion elemRegion; 68351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion boundsRgn(bounds); 68451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 68551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (NULL != clip.fPath) { 68651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com elemRegion.setPath(*clip.fPath, boundsRgn); 68751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else if (NULL != clip.fRect) { 68851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPath path; 68951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com path.addRect(*clip.fRect); 69051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com elemRegion.setPath(path, boundsRgn); 69151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 69251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // TODO: Figure out why we sometimes get here in the reduced clip stack. 69351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region->setEmpty(); 69451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com return; 69551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 69651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region->op(elemRegion, clip.fOp); 69751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 69851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 69951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com// This can assist with debugging the clip stack reduction code when the test below fails. 70051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void print_clip(const SkClipStack::Iter::Clip& clip) { 70151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const char* kOpStrs[] = { 70251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "DF", 70351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "IS", 70451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "UN", 70551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "XR", 70651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RD", 70751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com "RP", 70851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 70951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (clip.fRect || clip.fPath) { 71051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkRect& bounds = clip.getBounds(); 71151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("%s %s [%f %f] x [%f %f]\n", 71251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kOpStrs[clip.fOp], 71351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com (clip.fRect ? "R" : "P"), 71451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bounds.fLeft, bounds.fRight, bounds.fTop, bounds.fBottom); 71551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } else { 71651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkDebugf("EM\n"); 71751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 71851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 71951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.comstatic void test_reduced_clip_stack(skiatest::Reporter* reporter) { 72151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // We construct random clip stacks, reduce them, and then rasterize both versions to verify that 7228ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com // they are equal. 72351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // All the clip elements will be contained within these bounds. 72551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRect kBounds = SkRect::MakeWH(100, 100); 72651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 72751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com enum { 72851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kNumTests = 200, 72951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMinElemsPerTest = 1, 73051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kMaxElemsPerTest = 50, 73151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 73251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 73351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // min/max size of a clip element as a fraction of kBounds. 73451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5; 73551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkScalar kMaxElemSizeFrac = SK_Scalar1; 73651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 73751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const SkRegion::Op kOps[] = { 73851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kDifference_Op, 73951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kIntersect_Op, 74051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kUnion_Op, 74151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kXOR_Op, 74251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReverseDifference_Op, 74351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::kReplace_Op, 74451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 74551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 74651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Replace operations short-circuit the optimizer. We want to make sure that we test this code 74751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // path a little bit but we don't want it to prevent us from testing many longer traversals in 74851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // the optimizer. 74951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const int kReplaceDiv = 4 * kMaxElemsPerTest; 75051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 75151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com static const AddElementFunc kElementFuncs[] = { 75251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_rect, 75351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_round_rect, 75451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_oval, 75551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com }; 75651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 75751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRandom r; 75851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 75951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int i = 0; i < kNumTests; ++i) { 76051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Randomly generate a clip stack. 76151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack stack; 76251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest); 76351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int e = 0; e < numElems; ++e) { 76451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion::Op op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))]; 76551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (op == SkRegion::kReplace_Op) { 76651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (r.nextU() % kReplaceDiv) { 76751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com --e; 76851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com continue; 76951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 77051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 7718ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 77251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // saves can change the clip stack behavior when an element is added. 77351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool doSave = r.nextBool(); 7748ccf590b89cec1a5974b6f4b7b49ca67cc5036cfskia.committer@gmail.com 77551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkSize size = SkSize::Make( 77651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.width(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac))), 77751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(SkScalarMul(kBounds.height(), r.nextRangeScalar(kMinElemSizeFrac, kMaxElemSizeFrac)))); 77851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 77951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkPoint xy = {SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth)), 78051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkScalarFloorToScalar(r.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight))}; 78151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect rect = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight); 78351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 78451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // AA is always disabled. The optimizer can cause changes in aa rasterization of the 78551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // clip stack. A fractional edge repeated in different elements may be rasterized fewer 78651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // times using the reduced stack. 78751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com kElementFuncs[r.nextULessThan(SK_ARRAY_COUNT(kElementFuncs))](rect, false, op, &stack); 78851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (doSave) { 78951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com stack.save(); 79051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 79151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 79251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 79351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Get the reduced version of the stack. 79451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkTDArray<SkClipStack::Iter::Clip> reducedClips; 79551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect resultBounds; 79651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com bool bounded; 79751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::InitialState initial; 79851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com GrReducedClip::GrReduceClipStack(stack, &reducedClips, &resultBounds, &bounded, &initial); 79951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 80051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // Build a new clip stack based on the reduced clip elements 80151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack reducedStack; 80251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (GrReducedClip::kAllOut_InitialState == initial) { 80351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // whether the result is bounded or not, the whole plane should start outside the clip. 80451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipEmpty(); 80551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 80651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com for (int c = 0; c < reducedClips.count(); ++c) { 80751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_stack(reducedClips[c], &reducedStack); 80851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 80951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com if (bounded) { 81051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // GrReduceClipStack() assumes that there is an implicit clip to the bounds 81151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedStack.clipDevRect(resultBounds, SkRegion::kIntersect_Op, true); 81251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 81351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 81451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com // convert both the original stack and reduced stack to SkRegions and see if they're equal 81551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRect inflatedBounds = kBounds; 81651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com inflatedBounds.outset(kBounds.width() / 2, kBounds.height() / 2); 81751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkIRect inflatedIBounds; 81851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com inflatedBounds.roundOut(&inflatedIBounds); 81951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 82051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion region; 82151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkRegion reducedRegion; 82251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 82351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com region.setRect(inflatedIBounds); 82451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com const SkClipStack::Iter::Clip* clip; 82551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 82651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com while ((clip = iter.next())) { 82751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_region(*clip, inflatedIBounds, ®ion); 82851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 82951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 83051a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com reducedRegion.setRect(inflatedIBounds); 83151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com iter.reset(reducedStack, SkClipStack::Iter::kBottom_IterStart); 83251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com while ((clip = iter.next())) { 83351a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com add_elem_to_region(*clip, inflatedIBounds, &reducedRegion); 83451a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 83551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 83651a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com REPORTER_ASSERT(reporter, region == reducedRegion); 83751a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com } 83851a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com} 83951a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 840a4e13c85b23fe7530ae89a84ef671ebd5e451e80bsalomon@google.com#endif 84151a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 84251a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com 843bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comstatic void TestClipStack(skiatest::Reporter* reporter) { 844bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com SkClipStack stack; 845bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 84680214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 847bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 848bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 849bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com static const SkIRect gRects[] = { 850bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 100, 100 }, 851bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 25, 25, 125, 125 }, 852bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 1000, 1000 }, 853bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com { 0, 0, 75, 75 } 854bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com }; 855bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 856d9f2dea5328c9ab455852f2e4928cca7c71c6b05reed@google.com stack.clipDevRect(gRects[i], SkRegion::kIntersect_Op); 857bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com } 858bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 859bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // all of the above rects should have been intersected, leaving only 1 rect 86080214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(stack); 86180214e26c57c5fea954006400852e8999e201923robertphillips@google.com const SkClipStack::B2TIter::Clip* clip = iter.next(); 8622047f00e4698f83499ab91911999a65c21a951c9epoger@google.com SkRect answer; 8632047f00e4698f83499ab91911999a65c21a951c9epoger@google.com answer.iset(25, 25, 75, 75); 864bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 865bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, clip); 866bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, clip->fRect); 867bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !clip->fPath); 868bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == clip->fOp); 869bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, *clip->fRect == answer); 870bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com // now check that we only had one in our iterator 871bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com REPORTER_ASSERT(reporter, !iter.next()); 872bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 873bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com stack.reset(); 87480214e26c57c5fea954006400852e8999e201923robertphillips@google.com REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 875bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com assert_count(reporter, stack, 0); 8761e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org 8771e1c36f4f89ad39e1d248edb745919e493242c68vandebo@chromium.org test_assign_and_comparison(reporter); 87880214e26c57c5fea954006400852e8999e201923robertphillips@google.com test_iterators(reporter); 87908eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, true); // once with rects 88008eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_bounds(reporter, false); // once with paths 881cc6493bbef7c9c2adf4b1ed8701e2ed015ae745drobertphillips@google.com test_isWideOpen(reporter); 88208eacc144711cd5d33513b2fba7a635ad28b7208robertphillips@google.com test_rect_merging(reporter); 883e8ca6c6e3a55634ac76efe5aceafaf8d669f43babsalomon@google.com test_iter_rect_merging(reporter); 884e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#if SK_SUPPORT_GPU 88551a6286c241c1dc750d263ed9676079c898148b0bsalomon@google.com test_reduced_clip_stack(reporter); 886e7b3d29a1289e64130dd0ec905d94feedc9d1064bsalomon@google.com#endif 887bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com} 888bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com 889bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.com#include "TestClassDef.h" 890bdee9fc778d4387d805d717f2cd7fc7074991fdbreed@google.comDEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack) 891