diff options
author | 2018-01-03 16:17:29 -0500 | |
---|---|---|
committer | 2018-01-04 00:59:20 +0000 | |
commit | c75e2401a82640c35b0b5f80a5684d0892904530 (patch) | |
tree | 0742a71071c9b92399a1182ec20ebfc69f8918f9 /tests | |
parent | 5a59c26193272825e814b50f7d9856c1b122531f (diff) |
[sksg] Refine invalidation logic
We need to discriminate between nodes whose bounds updates contribute to the dirty
region, and nodes whose bounds changes do not.
E.g. animated shape in a group: the animated shape node bounds should yield damage,
but the ancestor group bounds should not.
To accomplish this, we refine the invalidation state:
1) self invalidation == the node itself was invalidated, and its bounds updates
yield damage.
2) descendant invalidation == the node has some (self-)invalidated descendant,
but its own bounds are not contributing damage.
Also:
* hoist the bounding box invalidation logic into the base class (Node::revalidate)
and update to respect the states described above.
* remove (now-redundant) GeometryNode bbox logic.
* update revalidation methods to return the node bbox instead of void
TBR=
Change-Id: I8023d1793fb501c945a53f2dc2d2983e5b620ade
Reviewed-on: https://skia-review.googlesource.com/90581
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/SGTest.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/SGTest.cpp b/tests/SGTest.cpp new file mode 100644 index 0000000000..b0cad5b8f3 --- /dev/null +++ b/tests/SGTest.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkRect.h" +#include "SkSGColor.h" +#include "SkSGDraw.h" +#include "SkSGGroup.h" +#include "SkSGInvalidationController.h" +#include "SkSGRect.h" +#include "SkSGTransform.h" + +#include "Test.h" + +#include <vector> + +static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root, + const SkRect& expected_bounds, + const SkRect& expected_inval_bounds, + const std::vector<SkRect>* expected_damage) { + sksg::InvalidationController ic; + const auto bbox = root->revalidate(&ic, SkMatrix::I()); + + if (0) { + printf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n", + bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom, + ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom()); + } + + REPORTER_ASSERT(reporter, bbox == expected_bounds); + REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds); + + if (expected_damage) { + REPORTER_ASSERT(reporter, expected_damage->size() == SkTo<size_t>(ic.end() - ic.begin())); + for (size_t i = 0; i < expected_damage->size(); ++i) { + const auto r1 = (*expected_damage)[i], + r2 = ic.begin()[i]; + if (0) { + printf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n", + r1.left(), r1.top(), r1.right(), r1.bottom(), + r2.left(), r2.top(), r2.right(), r2.bottom()); + } + REPORTER_ASSERT(reporter, r1 == r2); + } + } +} + +DEF_TEST(SGInvalidation, reporter) { + auto color = sksg::Color::Make(0xff000000); + auto r1 = sksg::Rect::Make(SkRect::MakeWH(100, 100)), + r2 = sksg::Rect::Make(SkRect::MakeWH(100, 100)); + auto grp = sksg::Group::Make(); + auto tr = sksg::Transform::Make(grp, SkMatrix::I()); + + grp->addChild(sksg::Draw::Make(r1, color)); + grp->addChild(sksg::Draw::Make(r2, color)); + + { + // Initial revalidation. + check_inval(reporter, tr, + SkRect::MakeWH(100, 100), + SkRect::MakeLargestS32(), + nullptr); + } + + { + // Move r2 to (200 100). + r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200); + std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} }; + check_inval(reporter, tr, + SkRect::MakeWH(300, 200), + SkRect::MakeWH(300, 200), + &damage); + } + + { + // Update the common color. + // TODO: this doesn't work ATM as expected; fix and enable. +// color->setColor(0xffff0000); +// std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} }; +// check_inval(reporter, tr, +// SkRect::MakeWH(300, 200), +// SkRect::MakeWH(300, 200), +// &damage); + } + + { + // Shrink r1. + r1->setR(50); + std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} }; + check_inval(reporter, tr, + SkRect::MakeWH(300, 200), + SkRect::MakeWH(100, 100), + &damage); + } + + { + // Update transform. + tr->setMatrix(SkMatrix::MakeScale(2, 2)); + std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} }; + check_inval(reporter, tr, + SkRect::MakeWH(600, 400), + SkRect::MakeWH(600, 400), + &damage); + } + + { + // Shrink r2 under transform. + r2->setR(250); + std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} }; + check_inval(reporter, tr, + SkRect::MakeWH(500, 400), + SkRect::MakeLTRB(400, 200, 600, 400), + &damage); + } +} |