aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SGTest.cpp
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2018-01-03 16:17:29 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-04 00:59:20 +0000
commitc75e2401a82640c35b0b5f80a5684d0892904530 (patch)
tree0742a71071c9b92399a1182ec20ebfc69f8918f9 /tests/SGTest.cpp
parent5a59c26193272825e814b50f7d9856c1b122531f (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/SGTest.cpp')
-rw-r--r--tests/SGTest.cpp119
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);
+ }
+}