| Index: tests/CachedDataTest.cpp
|
| diff --git a/tests/CachedDataTest.cpp b/tests/CachedDataTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f65a46b770d0ecabda70654036e70e8ec86c90f8
|
| --- /dev/null
|
| +++ b/tests/CachedDataTest.cpp
|
| @@ -0,0 +1,95 @@
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkCachedData.h"
|
| +#include "SkDiscardableMemoryPool.h"
|
| +#include "Test.h"
|
| +
|
| +enum LockedState {
|
| + kUnlocked,
|
| + kLocked,
|
| +};
|
| +
|
| +enum CachedState {
|
| + kNotInCache,
|
| + kInCache,
|
| +};
|
| +
|
| +static void check_data(skiatest::Reporter* reporter, SkCachedData* data,
|
| + int refcnt, CachedState cacheState, LockedState lockedState) {
|
| + REPORTER_ASSERT(reporter, data->testing_only_getRefCnt() == refcnt);
|
| + REPORTER_ASSERT(reporter, data->testing_only_isInCache() == (kInCache == cacheState));
|
| + REPORTER_ASSERT(reporter, data->testing_only_isLocked() == (lockedState == kLocked));
|
| +}
|
| +
|
| +static SkCachedData* make_data(size_t size, SkDiscardableMemoryPool* pool) {
|
| + if (pool) {
|
| + SkDiscardableMemory* dm = pool->create(size);
|
| + // the pool "can" return null, but it shouldn't in these controlled conditions
|
| + SK_ALWAYSBREAK(dm);
|
| + return SkNEW_ARGS(SkCachedData, (size, dm));
|
| + } else {
|
| + return SkNEW_ARGS(SkCachedData, (sk_malloc_throw(size), size));
|
| + }
|
| +}
|
| +
|
| +// returns with the data locked by client and cache
|
| +static SkCachedData* test_locking(skiatest::Reporter* reporter,
|
| + size_t size, SkDiscardableMemoryPool* pool) {
|
| + SkCachedData* data = make_data(size, pool);
|
| +
|
| + memset(data->writable_data(), 0x80, size); // just to use writable_data()
|
| +
|
| + check_data(reporter, data, 1, kNotInCache, kLocked);
|
| +
|
| + data->ref();
|
| + check_data(reporter, data, 2, kNotInCache, kLocked);
|
| + data->unref();
|
| + check_data(reporter, data, 1, kNotInCache, kLocked);
|
| +
|
| + data->attachToCacheAndRef();
|
| + check_data(reporter, data, 2, kInCache, kLocked);
|
| +
|
| + data->unref();
|
| + check_data(reporter, data, 1, kInCache, kUnlocked);
|
| +
|
| + data->ref();
|
| + check_data(reporter, data, 2, kInCache, kLocked);
|
| +
|
| + return data;
|
| +}
|
| +
|
| +/*
|
| + * SkCachedData behaves differently (regarding its locked/unlocked state) depending on
|
| + * when it is in the cache or not. Being in the cache is signaled by calling attachToCacheAndRef()
|
| + * instead of ref(). (and balanced by detachFromCacheAndUnref).
|
| + *
|
| + * Thus, among other things, we test the end-of-life behavior when the client is the last owner
|
| + * and when the cache is.
|
| + */
|
| +DEF_TEST(CachedData, reporter) {
|
| + SkAutoTUnref<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Create(1000));
|
| +
|
| + for (int useDiscardable = 0; useDiscardable <= 1; ++useDiscardable) {
|
| + const size_t size = 100;
|
| +
|
| + // test with client as last owner
|
| + SkCachedData* data = test_locking(reporter, size, useDiscardable ? pool.get() : NULL);
|
| + check_data(reporter, data, 2, kInCache, kLocked);
|
| + data->detachFromCacheAndUnref();
|
| + check_data(reporter, data, 1, kNotInCache, kLocked);
|
| + data->unref();
|
| +
|
| + // test with cache as last owner
|
| + data = test_locking(reporter, size, useDiscardable ? pool.get() : NULL);
|
| + check_data(reporter, data, 2, kInCache, kLocked);
|
| + data->unref();
|
| + check_data(reporter, data, 1, kInCache, kUnlocked);
|
| + data->detachFromCacheAndUnref();
|
| + }
|
| +}
|
| +
|
|
|