1772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com /*
2602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com * Copyright 2013 Google Inc.
3602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com *
4602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com * Use of this source code is governed by a BSD-style license that can be
5602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com * found in the LICENSE file.
6602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com */
7602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com
8e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#include "SkDiscardableMemory.h"
9011f39aeb2b9715546eb74d9ebb71be7baf95fdereed#include "SkResourceCache.h"
108f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
11602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com
1204617139f7f715bdc05a32a58e65e3c208bccff4reednamespace {
1304617139f7f715bdc05a32a58e65e3c208bccff4reedstatic void* gGlobalAddress;
14011f39aeb2b9715546eb74d9ebb71be7baf95fdereedstruct TestingKey : public SkResourceCache::Key {
1504617139f7f715bdc05a32a58e65e3c208bccff4reed    void*       fPtr;
1604617139f7f715bdc05a32a58e65e3c208bccff4reed    intptr_t    fValue;
1704617139f7f715bdc05a32a58e65e3c208bccff4reed
1804617139f7f715bdc05a32a58e65e3c208bccff4reed    TestingKey(intptr_t value) : fPtr(&gGlobalAddress), fValue(value) {
1904617139f7f715bdc05a32a58e65e3c208bccff4reed        this->init(sizeof(fPtr) + sizeof(fValue));
2004617139f7f715bdc05a32a58e65e3c208bccff4reed    }
2104617139f7f715bdc05a32a58e65e3c208bccff4reed};
22011f39aeb2b9715546eb74d9ebb71be7baf95fdereedstruct TestingRec : public SkResourceCache::Rec {
23680fb9e8f10d24b5fe35c90338de37c57392f1aareed    TestingRec(const TestingKey& key, uint32_t value) : fKey(key), fValue(value) {}
24680fb9e8f10d24b5fe35c90338de37c57392f1aareed
25680fb9e8f10d24b5fe35c90338de37c57392f1aareed    TestingKey  fKey;
26680fb9e8f10d24b5fe35c90338de37c57392f1aareed    intptr_t    fValue;
2704617139f7f715bdc05a32a58e65e3c208bccff4reed
28680fb9e8f10d24b5fe35c90338de37c57392f1aareed    virtual const Key& getKey() const SK_OVERRIDE { return fKey; }
29680fb9e8f10d24b5fe35c90338de37c57392f1aareed    virtual size_t bytesUsed() const SK_OVERRIDE { return sizeof(fKey) + sizeof(fValue); }
30c90e0149ec530075cae7bf51072a16628311855ereed
31c90e0149ec530075cae7bf51072a16628311855ereed    static bool Visitor(const SkResourceCache::Rec& baseRec, void* context) {
32c90e0149ec530075cae7bf51072a16628311855ereed        const TestingRec& rec = static_cast<const TestingRec&>(baseRec);
33c90e0149ec530075cae7bf51072a16628311855ereed        intptr_t* result = (intptr_t*)context;
34c90e0149ec530075cae7bf51072a16628311855ereed
35c90e0149ec530075cae7bf51072a16628311855ereed        *result = rec.fValue;
36c90e0149ec530075cae7bf51072a16628311855ereed        return true;
37c90e0149ec530075cae7bf51072a16628311855ereed    }
38680fb9e8f10d24b5fe35c90338de37c57392f1aareed};
39602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com}
40602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com
41e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comstatic const int COUNT = 10;
42e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comstatic const int DIM = 256;
43602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com
44c90e0149ec530075cae7bf51072a16628311855ereedstatic void test_cache(skiatest::Reporter* reporter, SkResourceCache& cache, bool testPurge) {
45772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    for (int i = 0; i < COUNT; ++i) {
46680fb9e8f10d24b5fe35c90338de37c57392f1aareed        TestingKey key(i);
47c90e0149ec530075cae7bf51072a16628311855ereed        intptr_t value = -1;
484f3c305a5bf635dd720cad24f587167e576f2170tfarina@chromium.org
49c90e0149ec530075cae7bf51072a16628311855ereed        REPORTER_ASSERT(reporter, !cache.find(key, TestingRec::Visitor, &value));
50c90e0149ec530075cae7bf51072a16628311855ereed        REPORTER_ASSERT(reporter, -1 == value);
51cf0803b46f60d9fcb5ad9a376b638c4c32b655deskia.committer@gmail.com
52c90e0149ec530075cae7bf51072a16628311855ereed        cache.add(SkNEW_ARGS(TestingRec, (key, i)));
53cf0803b46f60d9fcb5ad9a376b638c4c32b655deskia.committer@gmail.com
54c90e0149ec530075cae7bf51072a16628311855ereed        REPORTER_ASSERT(reporter, cache.find(key, TestingRec::Visitor, &value));
55c90e0149ec530075cae7bf51072a16628311855ereed        REPORTER_ASSERT(reporter, i == value);
56602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com    }
57cf0803b46f60d9fcb5ad9a376b638c4c32b655deskia.committer@gmail.com
58e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com    if (testPurge) {
59e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com        // stress test, should trigger purges
60e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com        for (size_t i = 0; i < COUNT * 100; ++i) {
6104617139f7f715bdc05a32a58e65e3c208bccff4reed            TestingKey key(i);
62c90e0149ec530075cae7bf51072a16628311855ereed            cache.add(SkNEW_ARGS(TestingRec, (key, i)));
63e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com        }
64602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com    }
65772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com
66772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    // test the originals after all that purging
67772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    for (int i = 0; i < COUNT; ++i) {
68c90e0149ec530075cae7bf51072a16628311855ereed        intptr_t value;
69c90e0149ec530075cae7bf51072a16628311855ereed        (void)cache.find(TestingKey(i), TestingRec::Visitor, &value);
70772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    }
71772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com
72805ef159d197007b9529e60e5b918ee0f9d3802dhalcanary    cache.setTotalByteLimit(0);
73602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com}
74602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com
75772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com#include "SkDiscardableMemoryPool.h"
76772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com
77772443a3e6428422f20ca4f40ed453a5c3604884reed@google.comstatic SkDiscardableMemoryPool* gPool;
78772443a3e6428422f20ca4f40ed453a5c3604884reed@google.comstatic SkDiscardableMemory* pool_factory(size_t bytes) {
79cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org    SkASSERT(gPool);
80772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    return gPool->create(bytes);
81772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com}
82772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com
83e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(ImageCache, reporter) {
84772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    static const size_t defLimit = DIM * DIM * 4 * COUNT + 1024;    // 1K slop
85772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com
86e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com    {
87011f39aeb2b9715546eb74d9ebb71be7baf95fdereed        SkResourceCache cache(defLimit);
88e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com        test_cache(reporter, cache, true);
89e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com    }
90e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com    {
91cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org        SkAutoTUnref<SkDiscardableMemoryPool> pool(
92cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org                SkDiscardableMemoryPool::Create(defLimit, NULL));
93cf2f00872c559c892bb4b466bf678c7667490ccecommit-bot@chromium.org        gPool = pool.get();
94011f39aeb2b9715546eb74d9ebb71be7baf95fdereed        SkResourceCache cache(pool_factory);
95772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com        test_cache(reporter, cache, true);
96772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    }
97772443a3e6428422f20ca4f40ed453a5c3604884reed@google.com    {
98011f39aeb2b9715546eb74d9ebb71be7baf95fdereed        SkResourceCache cache(SkDiscardableMemory::Create);
99e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com        test_cache(reporter, cache, false);
100e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com    }
101e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com}
102e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com
103d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comDEF_TEST(ImageCache_doubleAdd, r) {
104d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    // Adding the same key twice should be safe.
105011f39aeb2b9715546eb74d9ebb71be7baf95fdereed    SkResourceCache cache(4096);
106d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
107680fb9e8f10d24b5fe35c90338de37c57392f1aareed    TestingKey key(1);
10804617139f7f715bdc05a32a58e65e3c208bccff4reed
109c90e0149ec530075cae7bf51072a16628311855ereed    cache.add(SkNEW_ARGS(TestingRec, (key, 2)));
110c90e0149ec530075cae7bf51072a16628311855ereed    cache.add(SkNEW_ARGS(TestingRec, (key, 3)));
1115e4112b33aeecbb773ed4c8e33994dec14becb84commit-bot@chromium.org
112680fb9e8f10d24b5fe35c90338de37c57392f1aareed    // Lookup can return either value.
113c90e0149ec530075cae7bf51072a16628311855ereed    intptr_t value = -1;
114c90e0149ec530075cae7bf51072a16628311855ereed    REPORTER_ASSERT(r, cache.find(key, TestingRec::Visitor, &value));
115c90e0149ec530075cae7bf51072a16628311855ereed    REPORTER_ASSERT(r, 2 == value || 3 == value);
116d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com}
117