aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar senorblanco <senorblanco@chromium.org>2015-08-04 10:01:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-04 10:01:58 -0700
commit84cd621670a357484e1674e06d3d8d6f929a4ab2 (patch)
treea4ab6bce0dd381065a2e2b33df7ccf4b20863c27 /tests
parent846b022f6b469cfde285372f26e0d5c593d122ac (diff)
Implement caching of filled paths in the tessellated path renderer.
Paths are cached as tessellated triangle meshes in vertex buffers on the GPU. Stroked paths are not (yet) cached. Paths containing no curved segments (linear paths) are reused at all scales. Paths containing curved segments are reused within a scale tolerance threshold. In order to invalidate the cache when an SkPath is changed or deleted, this required implementing genID change notification in SkPath. This is modelled almost exactly on SkPixelRef::GenIDChangeListener. However, It does not currently implement the check for unique genIDs, so notifiers will fire when the first instance of an SkPathRef using a given genID is destroyed. Another caveat is that you cannot successfully add a change notifier to an empty path, since it uses the "canonical" empty path which is never modified or destroyed. For this reason, we prevent adding listeners to it. BUG=skia:4121,skia:4122, 497403 DOCS_PREVIEW= https://skia.org/?cl=1114353004 Committed: https://skia.googlesource.com/skia/+/468dfa72eb6694145487be17876804dfca3b7adb Review URL: https://codereview.chromium.org/1114353004
Diffstat (limited to 'tests')
-rw-r--r--tests/PathTest.cpp60
-rw-r--r--tests/ResourceCacheTest.cpp31
2 files changed, 91 insertions, 0 deletions
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 8272692167..b0bd66726d 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -3715,6 +3715,21 @@ static void test_dump(skiatest::Reporter* reporter) {
"path.lineTo(3, 4);\n");
}
+namespace {
+
+class ChangeListener : public SkPathRef::GenIDChangeListener {
+public:
+ ChangeListener(bool *changed) : fChanged(changed) { *fChanged = false; }
+ virtual ~ChangeListener() {}
+ void onChange() override {
+ *fChanged = true;
+ }
+private:
+ bool* fChanged;
+};
+
+}
+
class PathTest_Private {
public:
static void TestPathTo(skiatest::Reporter* reporter) {
@@ -3734,6 +3749,50 @@ public:
SkRect reverseExpected = {-4, -4, 8, 8};
REPORTER_ASSERT(reporter, p.getBounds() == reverseExpected);
}
+
+ static void TestPathrefListeners(skiatest::Reporter* reporter) {
+ SkPath p;
+
+ bool changed = false;
+ p.moveTo(0, 0);
+
+ // Check that listener is notified on moveTo().
+
+ SkPathPriv::AddGenIDChangeListener(p, SkNEW(ChangeListener(&changed)));
+ REPORTER_ASSERT(reporter, !changed);
+ p.moveTo(10, 0);
+ REPORTER_ASSERT(reporter, changed);
+
+ // Check that listener is notified on lineTo().
+ SkPathPriv::AddGenIDChangeListener(p, SkNEW(ChangeListener(&changed)));
+ REPORTER_ASSERT(reporter, !changed);
+ p.lineTo(20, 0);
+ REPORTER_ASSERT(reporter, changed);
+
+ // Check that listener is notified on reset().
+ SkPathPriv::AddGenIDChangeListener(p, SkNEW(ChangeListener(&changed)));
+ REPORTER_ASSERT(reporter, !changed);
+ p.reset();
+ REPORTER_ASSERT(reporter, changed);
+
+ p.moveTo(0, 0);
+
+ // Check that listener is notified on rewind().
+ SkPathPriv::AddGenIDChangeListener(p, SkNEW(ChangeListener(&changed)));
+ REPORTER_ASSERT(reporter, !changed);
+ p.rewind();
+ REPORTER_ASSERT(reporter, changed);
+
+ // Check that listener is notified when pathref is deleted.
+ {
+ SkPath q;
+ q.moveTo(10, 10);
+ SkPathPriv::AddGenIDChangeListener(q, SkNEW(ChangeListener(&changed)));
+ REPORTER_ASSERT(reporter, !changed);
+ }
+ // q went out of scope.
+ REPORTER_ASSERT(reporter, changed);
+ }
};
DEF_TEST(Paths, reporter) {
@@ -3880,6 +3939,7 @@ DEF_TEST(Paths, reporter) {
test_contains(reporter);
PathTest_Private::TestPathTo(reporter);
PathRefTest_Private::TestPathRef(reporter);
+ PathTest_Private::TestPathrefListeners(reporter);
test_dump(reporter);
test_path_crbug389050(reporter);
test_path_crbugskia2820(reporter);
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index b795b01b24..43f087004f 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -845,6 +845,21 @@ static void test_duplicate_unique_key(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
+
+ {
+ GrUniqueKey key2;
+ make_unique_key<0>(&key2, 0);
+ SkAutoTUnref<TestResource> d(SkNEW_ARGS(TestResource, (context->getGpu())));
+ int foo = 4132;
+ SkAutoTUnref<SkData> data(SkData::NewWithCopy(&foo, sizeof(foo)));
+ key2.setCustomData(data.get());
+ d->resourcePriv().setUniqueKey(key2);
+ }
+
+ GrUniqueKey key3;
+ make_unique_key<0>(&key3, 0);
+ SkAutoTUnref<GrGpuResource> d2(cache->findAndRefUniqueResource(key3));
+ REPORTER_ASSERT(reporter, *(int*) d2->getUniqueKey().getCustomData()->data() == 4132);
}
static void test_purge_invalidated(skiatest::Reporter* reporter) {
@@ -1223,6 +1238,21 @@ static void test_large_resource_count(skiatest::Reporter* reporter) {
}
}
+static void test_custom_data(skiatest::Reporter* reporter) {
+ GrUniqueKey key1, key2;
+ make_unique_key<0>(&key1, 1);
+ make_unique_key<0>(&key2, 2);
+ int foo = 4132;
+ SkAutoTUnref<SkData> data(SkData::NewWithCopy(&foo, sizeof(foo)));
+ key1.setCustomData(data.get());
+ REPORTER_ASSERT(reporter, *(int*) key1.getCustomData()->data() == 4132);
+ REPORTER_ASSERT(reporter, key2.getCustomData() == nullptr);
+
+ // Test that copying a key also takes a ref on its custom data.
+ GrUniqueKey key3 = key1;
+ REPORTER_ASSERT(reporter, *(int*) key3.getCustomData()->data() == 4132);
+}
+
////////////////////////////////////////////////////////////////////////////////
DEF_GPUTEST(ResourceCache, reporter, factory) {
for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
@@ -1262,6 +1292,7 @@ DEF_GPUTEST(ResourceCache, reporter, factory) {
test_timestamp_wrap(reporter);
test_flush(reporter);
test_large_resource_count(reporter);
+ test_custom_data(reporter);
}
#endif