1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2014 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCachedData.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDiscardableMemoryPool.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum LockedState { 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kUnlocked, 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kLocked, 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum CachedState { 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kNotInCache, 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kInCache, 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void check_data(skiatest::Reporter* reporter, SkCachedData* data, 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int refcnt, CachedState cacheState, LockedState lockedState) { 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, data->testing_only_getRefCnt() == refcnt); 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, data->testing_only_isInCache() == (kInCache == cacheState)); 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, data->testing_only_isLocked() == (lockedState == kLocked)); 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkCachedData* make_data(size_t size, SkDiscardableMemoryPool* pool) { 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (pool) { 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDiscardableMemory* dm = pool->create(size); 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the pool "can" return null, but it shouldn't in these controlled conditions 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT_RELEASE(dm); 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new SkCachedData(size, dm); 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return new SkCachedData(sk_malloc_throw(size), size); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// returns with the data locked by client and cache 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkCachedData* test_locking(skiatest::Reporter* reporter, 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size, SkDiscardableMemoryPool* pool) { 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCachedData* data = make_data(size, pool); 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memset(data->writable_data(), 0x80, size); // just to use writable_data() 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 1, kNotInCache, kLocked); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->ref(); 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 2, kNotInCache, kLocked); 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->unref(); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 1, kNotInCache, kLocked); 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->attachToCacheAndRef(); 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 2, kInCache, kLocked); 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->unref(); 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 1, kInCache, kUnlocked); 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->ref(); 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 2, kInCache, kLocked); 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return data; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * SkCachedData behaves differently (regarding its locked/unlocked state) depending on 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * when it is in the cache or not. Being in the cache is signaled by calling attachToCacheAndRef() 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * instead of ref(). (and balanced by detachFromCacheAndUnref). 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Thus, among other things, we test the end-of-life behavior when the client is the last owner 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * and when the cache is. 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(CachedData, reporter) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkDiscardableMemoryPool> pool(SkDiscardableMemoryPool::Make(1000)); 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int useDiscardable = 0; useDiscardable <= 1; ++useDiscardable) { 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t size = 100; 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // test with client as last owner 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCachedData* data = test_locking(reporter, size, useDiscardable ? pool.get() : nullptr); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 2, kInCache, kLocked); 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->detachFromCacheAndUnref(); 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 1, kNotInCache, kLocked); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->unref(); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // test with cache as last owner 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data = test_locking(reporter, size, useDiscardable ? pool.get() : nullptr); 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 2, kInCache, kLocked); 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->unref(); 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot check_data(reporter, data, 1, kInCache, kUnlocked); 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot data->detachFromCacheAndUnref(); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 95